1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2024 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
123 ;; For SSE/MMX support:
136 ;; Different from generic us_truncate RTX
137 ;; as it does unsigned saturation of signed source.
140 ;; For AVX/AVX512F support
146 ;; Generic math support
147 UNSPEC_IEEE_MIN ; not commutative
148 UNSPEC_IEEE_MAX ; not commutative
150 ;; x87 Floating point
163 UNSPEC_FRNDINT_ROUNDEVEN
170 ;; x87 Double output FP
195 ;; For LZCNT suppoprt
207 UNSPEC_INTERRUPT_RETURN
209 ;; For MOVDIRI and MOVDIR64B support
213 ;; For insn_callee_abi:
216 ;; For APX PUSH2/POP2 support
221 ;; For APX PPX support
224 ;; For APX CCMP support
225 ;; DFV = default flag value
229 (define_c_enum "unspecv" [
233 UNSPECV_PROBE_STACK_RANGE
236 UNSPECV_SPLIT_STACK_RETURN
242 UNSPECV_LLWP_INTRINSIC
243 UNSPECV_SLWP_INTRINSIC
244 UNSPECV_LWPVAL_INTRINSIC
245 UNSPECV_LWPINS_INTRINSIC
271 ;; For atomic compound assignments.
277 ;; For RDRAND support
280 ;; For RDSEED support
294 ;; For CLFLUSHOPT support
297 ;; For MONITORX and MWAITX support
301 ;; For CLZERO support
304 ;; For RDPKRU and WRPKRU support
321 ;; For TSXLDTRK support
325 ;; For WAITPKG support
336 ;; For CLDEMOTE support
339 ;; For Speculation Barrier support
340 UNSPECV_SPECULATION_BARRIER
344 ;; For ENQCMD and ENQCMDS support
348 ;; For SERIALIZE support
351 ;; For patchable area support
352 UNSPECV_PATCHABLE_AREA
354 ;; For HRESET support
357 ;; For PREFETCHI support
360 ;; For USER_MSR support
369 ;; Constants to represent rounding modes in the ROUND instruction
371 [(ROUND_ROUNDEVEN 0x0)
379 ;; Constants to represent AVX512F embeded rounding
381 [(ROUND_NEAREST_INT 0)
389 ;; Constants to represent pcomtrue/pcomfalse variants
399 ;; Constants used in the XOP pperm instruction
401 [(PPERM_SRC 0x00) /* copy source */
402 (PPERM_INVERT 0x20) /* invert source */
403 (PPERM_REVERSE 0x40) /* bit reverse source */
404 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
405 (PPERM_ZERO 0x80) /* all 0's */
406 (PPERM_ONES 0xa0) /* all 1's */
407 (PPERM_SIGN 0xc0) /* propagate sign bit */
408 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
409 (PPERM_SRC1 0x00) /* use first source byte */
410 (PPERM_SRC2 0x10) /* use second source byte */
413 ;; Registers by name.
507 (FIRST_PSEUDO_REG 92)
510 ;; Insn callee abi index.
516 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
519 ;; In C guard expressions, put expressions which may be compile-time
520 ;; constants first. This allows for better optimization. For
521 ;; example, write "TARGET_64BIT && reload_completed", not
522 ;; "reload_completed && TARGET_64BIT".
526 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
527 atom,slm,glm,haswell,generic,lujiazui,yongfeng,amdfam10,bdver1,
528 bdver2,bdver3,bdver4,btver2,znver1,znver2,znver3,znver4,
530 (const (symbol_ref "ix86_schedule")))
532 ;; A basic instruction type. Refinements due to arguments to be
533 ;; provided in other attributes.
536 alu,alu1,negnot,imov,imovx,lea,
537 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
538 imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
539 push,pop,call,callv,leave,
541 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
542 fxch,fistp,fisttp,frndint,
543 sse,ssemov,ssemov2,sseadd,sseadd1,sseiadd,sseiadd1,
544 ssemul,sseimul,ssediv,sselog,sselog1,
545 sseishft,sseishft1,ssecmp,ssecomi,
546 ssecvt,ssecvt1,sseicvt,sseicvt2,sseins,
547 sseshuf,sseshuf1,ssemuladd,sse4arg,
549 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
550 (const_string "other"))
552 ;; Main data type used by the insn
554 "unknown,none,QI,HI,SI,DI,TI,OI,XI,HF,BF,SF,DF,XF,TF,
555 V32HF,V16HF,V8HF,V4HF,V2HF,V32BF,V16BF,V8BF,V4BF,V2BF,
556 V16SF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF,V8DF"
557 (const_string "unknown"))
559 ;; The CPU unit operations uses.
560 (define_attr "unit" "integer,i387,sse,mmx,unknown"
561 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
562 fxch,fistp,fisttp,frndint")
563 (const_string "i387")
564 (eq_attr "type" "sse,ssemov,ssemov2,sseadd,sseadd1,sseiadd,sseiadd1,
565 ssemul,sseimul,ssediv,sselog,sselog1,
566 sseishft,sseishft1,ssecmp,ssecomi,
567 ssecvt,ssecvt1,sseicvt,sseicvt2,sseins,
568 sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
570 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
572 (eq_attr "type" "other")
573 (const_string "unknown")]
574 (const_string "integer")))
576 ;; Used to control the "enabled" attribute on a per-instruction basis.
577 (define_attr "isa" "base,x64,nox64,x64_sse2,x64_sse4,x64_sse4_noavx,
578 x64_avx,x64_avx512bw,x64_avx512dq,apx_ndd,apx_ndd_64,
579 sse_noavx,sse2,sse2_noavx,sse3,sse3_noavx,sse4,sse4_noavx,
580 avx,noavx,avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,avx512f_512,
581 noavx512f,avx512bw,avx512bw_512,noavx512bw,avx512dq,
582 noavx512dq,fma_or_avx512vl,avx512vl,noavx512vl,avxvnni,
583 avx512vnnivl,avx512fp16,avxifma,avx512ifmavl,avxneconvert,
584 avx512bf16vl,vpclmulqdqvl,avx_noavx512f,avx_noavx512vl,
585 vaes_avx512vl,noapx_nf,avx10_2"
586 (const_string "base"))
588 ;; The (bounding maximum) length of an instruction immediate.
589 (define_attr "length_immediate" ""
590 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
591 bitmanip,imulx,msklog,mskmov")
593 (ior (eq_attr "type" "sse4arg")
594 (eq_attr "isa" "fma4"))
596 (eq_attr "unit" "i387,sse,mmx")
598 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
599 rotate,rotatex,rotate1,imul,icmp,push,pop")
600 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
601 (eq_attr "type" "imov,test")
602 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
603 (eq_attr "type" "call")
604 (if_then_else (match_operand 0 "constant_call_address_operand")
607 (eq_attr "type" "callv")
608 (if_then_else (match_operand 1 "constant_call_address_operand")
611 ;; We don't know the size before shorten_branches. Expect
612 ;; the instruction to fit for better scheduling.
613 (eq_attr "type" "ibr")
616 (symbol_ref "/* Update immediate_length and other attributes! */
617 gcc_unreachable (),1")))
619 ;; The (bounding maximum) length of an instruction address.
620 (define_attr "length_address" ""
621 (cond [(eq_attr "type" "str,other,multi,fxch")
623 (and (eq_attr "type" "call")
624 (match_operand 0 "constant_call_address_operand"))
626 (and (eq_attr "type" "callv")
627 (match_operand 1 "constant_call_address_operand"))
630 (symbol_ref "ix86_attr_length_address_default (insn)")))
632 ;; Set when length prefix is used.
633 (define_attr "prefix_data16" ""
634 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
636 (eq_attr "mode" "HI")
638 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
643 ;; Set when string REP prefix is used.
644 (define_attr "prefix_rep" ""
645 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
647 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
652 ;; Set when 0f opcode prefix is used.
653 (define_attr "prefix_0f" ""
655 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov")
656 (eq_attr "unit" "sse,mmx"))
660 ;; Set when REX opcode prefix is used.
661 (define_attr "prefix_rex" ""
662 (cond [(not (match_test "TARGET_64BIT"))
664 (and (eq_attr "mode" "DI")
665 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
666 (eq_attr "unit" "!mmx")))
668 (and (eq_attr "mode" "QI")
669 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
671 (match_test "x86_extended_reg_mentioned_p (insn)")
673 (and (eq_attr "type" "imovx")
674 (match_operand:QI 1 "ext_QIreg_operand"))
679 ;; There are also additional prefixes in 3DNOW, SSSE3.
680 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
681 ;; While generally inapplicable to VEX/XOP/EVEX encodings, "length_vex" uses
682 ;; the attribute evaluating to zero to know that VEX2 encoding may be usable.
683 (define_attr "prefix_extra" ""
684 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
689 ;; Prefix used: original, VEX or maybe VEX.
690 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
691 (cond [(eq_attr "mode" "OI,V8SF,V4DF")
693 (eq_attr "mode" "XI,V16SF,V8DF")
694 (const_string "evex")
695 (eq_attr "type" "ssemuladd")
696 (if_then_else (eq_attr "isa" "fma4")
698 (const_string "maybe_evex"))
699 (eq_attr "type" "sse4arg")
702 (const_string "orig")))
704 ;; VEX W bit is used.
705 (define_attr "prefix_vex_w" "" (const_int 0))
707 ;; The length of VEX prefix
708 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
709 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
710 ;; still prefix_0f 1, with prefix_extra 1.
711 (define_attr "length_vex" ""
712 (if_then_else (and (eq_attr "prefix_0f" "1")
713 (eq_attr "prefix_extra" "0"))
714 (if_then_else (eq_attr "prefix_vex_w" "1")
715 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
716 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
717 (if_then_else (eq_attr "prefix_vex_w" "1")
718 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
719 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
721 ;; 4-bytes evex prefix and 1 byte opcode.
722 (define_attr "length_evex" "" (const_int 5))
724 ;; Set when modrm byte is used.
725 (define_attr "modrm" ""
726 (cond [(eq_attr "type" "str,leave")
728 (eq_attr "unit" "i387")
730 (and (eq_attr "type" "incdec")
731 (and (not (match_test "TARGET_64BIT"))
732 (ior (match_operand:SI 1 "register_operand")
733 (match_operand:HI 1 "register_operand"))))
735 (and (eq_attr "type" "push")
736 (not (match_operand 1 "memory_operand")))
738 (and (eq_attr "type" "pop")
739 (not (match_operand 0 "memory_operand")))
741 (and (eq_attr "type" "imov")
742 (and (not (eq_attr "mode" "DI"))
743 (ior (and (match_operand 0 "register_operand")
744 (match_operand 1 "immediate_operand"))
745 (ior (and (match_operand 0 "ax_reg_operand")
746 (match_operand 1 "memory_displacement_only_operand"))
747 (and (match_operand 0 "memory_displacement_only_operand")
748 (match_operand 1 "ax_reg_operand"))))))
750 (and (eq_attr "type" "call")
751 (match_operand 0 "constant_call_address_operand"))
753 (and (eq_attr "type" "callv")
754 (match_operand 1 "constant_call_address_operand"))
756 (and (eq_attr "type" "alu,alu1,icmp,test")
757 (match_operand 0 "ax_reg_operand"))
758 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
762 ;; The (bounding maximum) length of an instruction in bytes.
763 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
764 ;; Later we may want to split them and compute proper length as for
766 (define_attr "length" ""
767 (cond [(eq_attr "type" "other,multi,fistp,frndint")
769 (eq_attr "type" "fcmp")
771 (eq_attr "unit" "i387")
773 (plus (attr "prefix_data16")
774 (attr "length_address")))
775 (ior (eq_attr "prefix" "evex")
776 (and (ior (eq_attr "prefix" "maybe_evex")
777 (eq_attr "prefix" "maybe_vex"))
778 (match_test "TARGET_AVX512F")))
779 (plus (attr "length_evex")
780 (plus (attr "length_immediate")
782 (attr "length_address"))))
783 (ior (eq_attr "prefix" "vex")
784 (and (ior (eq_attr "prefix" "maybe_vex")
785 (eq_attr "prefix" "maybe_evex"))
786 (match_test "TARGET_AVX")))
787 (plus (attr "length_vex")
788 (plus (attr "length_immediate")
790 (attr "length_address"))))]
791 (plus (plus (attr "modrm")
792 (plus (attr "prefix_0f")
793 (plus (attr "prefix_rex")
794 (plus (attr "prefix_extra")
796 (plus (attr "prefix_rep")
797 (plus (attr "prefix_data16")
798 (plus (attr "length_immediate")
799 (attr "length_address")))))))
801 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
802 ;; `store' if there is a simple memory reference therein, or `unknown'
803 ;; if the instruction is complex.
805 (define_attr "memory" "none,load,store,both,unknown"
806 (cond [(eq_attr "type" "other,multi,str,lwp")
807 (const_string "unknown")
808 (eq_attr "type" "lea,fcmov,fpspc")
809 (const_string "none")
810 (eq_attr "type" "fistp,leave")
811 (const_string "both")
812 (eq_attr "type" "frndint")
813 (const_string "load")
814 (eq_attr "type" "push")
815 (if_then_else (match_operand 1 "memory_operand")
816 (const_string "both")
817 (const_string "store"))
818 (eq_attr "type" "pop")
819 (if_then_else (match_operand 0 "memory_operand")
820 (const_string "both")
821 (const_string "load"))
822 (eq_attr "type" "setcc")
823 (if_then_else (match_operand 0 "memory_operand")
824 (const_string "store")
825 (const_string "none"))
826 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
827 (if_then_else (ior (match_operand 0 "memory_operand")
828 (match_operand 1 "memory_operand"))
829 (const_string "load")
830 (const_string "none"))
831 (eq_attr "type" "ibr")
832 (if_then_else (match_operand 0 "memory_operand")
833 (const_string "load")
834 (const_string "none"))
835 (eq_attr "type" "call")
836 (if_then_else (match_operand 0 "constant_call_address_operand")
837 (const_string "none")
838 (const_string "load"))
839 (eq_attr "type" "callv")
840 (if_then_else (match_operand 1 "constant_call_address_operand")
841 (const_string "none")
842 (const_string "load"))
843 (and (eq_attr "type" "alu1,negnot,ishift1,rotate1,sselog1,sseshuf1")
844 (match_operand 1 "memory_operand"))
845 (const_string "both")
846 (and (match_operand 0 "memory_operand")
847 (match_operand 1 "memory_operand"))
848 (const_string "both")
849 (match_operand 0 "memory_operand")
850 (const_string "store")
851 (match_operand 1 "memory_operand")
852 (const_string "load")
854 "!alu1,negnot,ishift1,rotate1,
855 imov,imovx,icmp,test,bitmanip,
857 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
858 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
859 mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog")
860 (match_operand 2 "memory_operand"))
861 (const_string "load")
862 (and (eq_attr "type" "ssemov2,sseicvt2")
863 (match_operand 2 "memory_operand"))
864 (const_string "load")
865 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
866 (match_operand 3 "memory_operand"))
867 (const_string "load")
869 (const_string "none")))
871 ;; Indicates if an instruction has both an immediate and a displacement.
873 (define_attr "imm_disp" "false,true,unknown"
874 (cond [(eq_attr "type" "other,multi")
875 (const_string "unknown")
876 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
877 (and (match_operand 0 "memory_displacement_operand")
878 (match_operand 1 "immediate_operand")))
879 (const_string "true")
880 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
881 (and (match_operand 0 "memory_displacement_operand")
882 (match_operand 2 "immediate_operand")))
883 (const_string "true")
885 (const_string "false")))
887 ;; Indicates if an FP operation has an integer source.
889 (define_attr "fp_int_src" "false,true"
890 (const_string "false"))
892 ;; Defines rounding mode of an FP operation.
894 (define_attr "i387_cw" "roundeven,floor,ceil,trunc,uninitialized,any"
895 (const_string "any"))
897 ;; Define attribute to indicate AVX insns with partial XMM register update.
898 (define_attr "avx_partial_xmm_update" "false,true"
899 (const_string "false"))
901 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
902 (define_attr "use_carry" "0,1" (const_string "0"))
904 ;; Define attribute to indicate unaligned ssemov insns
905 (define_attr "movu" "0,1" (const_string "0"))
907 ;; Define attribute to limit memory address register set.
908 (define_attr "addr" "gpr8,gpr16,gpr32" (const_string "gpr32"))
910 ;; Define instruction set of MMX instructions
911 (define_attr "mmx_isa" "base,native,sse,sse_noavx,avx"
912 (const_string "base"))
914 (define_attr "enabled" ""
915 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
916 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
917 (eq_attr "isa" "x64_sse2")
918 (symbol_ref "TARGET_64BIT && TARGET_SSE2")
919 (eq_attr "isa" "x64_sse4")
920 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
921 (eq_attr "isa" "x64_sse4_noavx")
922 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
923 (eq_attr "isa" "x64_avx")
924 (symbol_ref "TARGET_64BIT && TARGET_AVX")
925 (eq_attr "isa" "x64_avx512bw")
926 (symbol_ref "TARGET_64BIT && TARGET_AVX512BW")
927 (eq_attr "isa" "x64_avx512dq")
928 (symbol_ref "TARGET_64BIT && TARGET_AVX512DQ")
929 (eq_attr "isa" "sse_noavx")
930 (symbol_ref "TARGET_SSE && !TARGET_AVX")
931 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
932 (eq_attr "isa" "sse2_noavx")
933 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
934 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
935 (eq_attr "isa" "sse3_noavx")
936 (symbol_ref "TARGET_SSE3 && !TARGET_AVX")
937 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
938 (eq_attr "isa" "sse4_noavx")
939 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
940 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
941 (eq_attr "isa" "avx_noavx512f")
942 (symbol_ref "TARGET_AVX && !TARGET_AVX512F")
943 (eq_attr "isa" "avx_noavx512vl")
944 (symbol_ref "TARGET_AVX && !TARGET_AVX512VL")
945 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
946 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
947 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
948 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
949 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
950 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
951 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
952 (eq_attr "isa" "fma_or_avx512vl")
953 (symbol_ref "TARGET_FMA || TARGET_AVX512VL")
954 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
955 (eq_attr "isa" "avx512f_512")
956 (symbol_ref "TARGET_AVX512F && TARGET_EVEX512")
957 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
958 (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
959 (eq_attr "isa" "avx512bw_512")
960 (symbol_ref "TARGET_AVX512BW && TARGET_EVEX512")
961 (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
962 (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
963 (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
964 (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
965 (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
966 (eq_attr "isa" "avxvnni") (symbol_ref "TARGET_AVXVNNI")
967 (eq_attr "isa" "avx512vnnivl")
968 (symbol_ref "TARGET_AVX512VNNI && TARGET_AVX512VL")
969 (eq_attr "isa" "avx512fp16")
970 (symbol_ref "TARGET_AVX512FP16")
971 (eq_attr "isa" "avxifma") (symbol_ref "TARGET_AVXIFMA")
972 (eq_attr "isa" "avx512ifmavl")
973 (symbol_ref "TARGET_AVX512IFMA && TARGET_AVX512VL")
974 (eq_attr "isa" "avxneconvert") (symbol_ref "TARGET_AVXNECONVERT")
975 (eq_attr "isa" "avx512bf16vl")
976 (symbol_ref "TARGET_AVX512BF16 && TARGET_AVX512VL")
977 (eq_attr "isa" "vpclmulqdqvl")
978 (symbol_ref "TARGET_VPCLMULQDQ && TARGET_AVX512VL")
979 (eq_attr "isa" "apx_ndd")
980 (symbol_ref "TARGET_APX_NDD")
981 (eq_attr "isa" "apx_ndd_64")
982 (symbol_ref "TARGET_APX_NDD && Pmode == DImode")
983 (eq_attr "isa" "vaes_avx512vl")
984 (symbol_ref "TARGET_VAES && TARGET_AVX512VL")
985 (eq_attr "isa" "avx10_2") (symbol_ref "TARGET_AVX10_2_256")
987 (eq_attr "mmx_isa" "native")
988 (symbol_ref "!TARGET_MMX_WITH_SSE")
989 (eq_attr "mmx_isa" "sse")
990 (symbol_ref "TARGET_MMX_WITH_SSE")
991 (eq_attr "mmx_isa" "sse_noavx")
992 (symbol_ref "TARGET_MMX_WITH_SSE && !TARGET_AVX")
993 (eq_attr "mmx_isa" "avx")
994 (symbol_ref "TARGET_MMX_WITH_SSE && TARGET_AVX")
995 (eq_attr "isa" "noapx_nf") (symbol_ref "!TARGET_APX_NF")
999 (define_attr "preferred_for_size" "" (const_int 1))
1000 (define_attr "preferred_for_speed" "" (const_int 1))
1002 ;; Define attribute to mark the insn has nf variant.
1003 (define_attr "has_nf" "0,1" (const_string "0"))
1005 ;; Describe a user's asm statement.
1006 (define_asm_attributes
1007 [(set_attr "length" "128")
1008 (set_attr "type" "multi")])
1010 (define_code_iterator plusminus [plus minus])
1011 (define_code_iterator plusminusmult [plus minus mult])
1012 (define_code_iterator plusminusmultdiv [plus minus mult div])
1014 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
1016 ;; Base name for insn mnemonic.
1017 (define_code_attr plusminus_mnemonic
1018 [(plus "add") (ss_plus "adds") (us_plus "addus")
1019 (minus "sub") (ss_minus "subs") (us_minus "subus")])
1021 (define_code_iterator multdiv [mult div])
1023 (define_code_attr multdiv_mnemonic
1024 [(mult "mul") (div "div")])
1026 ;; Mark commutative operators as such in constraints.
1027 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
1028 (minus "") (ss_minus "") (us_minus "")
1029 (mult "%") (div "")])
1031 ;; Mapping of max and min
1032 (define_code_iterator maxmin [smax smin umax umin])
1034 ;; Mapping of signed max and min
1035 (define_code_iterator smaxmin [smax smin])
1037 ;; Mapping of unsigned max and min
1038 (define_code_iterator umaxmin [umax umin])
1040 ;; Base name for integer and FP insn mnemonic
1041 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
1042 (umax "maxu") (umin "minu")])
1043 (define_code_attr maxmin_float [(smax "max") (smin "min")])
1045 (define_int_iterator IEEE_MAXMIN
1049 (define_int_attr ieee_maxmin
1050 [(UNSPEC_IEEE_MAX "max")
1051 (UNSPEC_IEEE_MIN "min")])
1053 ;; Mapping of logic operators
1054 (define_code_iterator any_logic [and ior xor])
1055 (define_code_iterator any_or [ior xor])
1056 (define_code_iterator fpint_logic [and xor])
1058 ;; Base name for insn mnemonic.
1059 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
1061 ;; Mapping of logic-shift operators
1062 (define_code_iterator any_lshift [ashift lshiftrt])
1064 ;; Mapping of shift-right operators
1065 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
1067 ;; Mapping of all shift operators
1068 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
1070 ;; Base name for insn mnemonic.
1071 (define_code_attr shift [(ashift "sal") (lshiftrt "shr") (ashiftrt "sar")])
1072 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
1074 ;; Mapping of rotate operators
1075 (define_code_iterator any_rotate [rotate rotatert])
1077 ;; Base name for insn mnemonic.
1078 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
1080 ;; Mapping of abs neg operators
1081 (define_code_iterator absneg [abs neg])
1083 ;; Mapping of abs neg operators to logic operation
1084 (define_code_attr absneg_op [(abs "and") (neg "xor")])
1086 ;; Base name for x87 insn mnemonic.
1087 (define_code_attr absneg_mnemonic [(abs "fabs") (neg "fchs")])
1089 ;; Mapping of extend operators
1090 (define_code_iterator any_extend [sign_extend zero_extend])
1092 ;; Mapping of highpart multiply operators
1093 (define_code_iterator any_mul_highpart [smul_highpart umul_highpart])
1095 ;; Prefix for insn menmonic.
1096 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
1097 (smul_highpart "i") (umul_highpart "")
1098 (div "i") (udiv "")])
1099 ;; Prefix for define_insn
1100 (define_code_attr s [(sign_extend "s") (zero_extend "u")
1101 (smul_highpart "s") (umul_highpart "u")])
1102 (define_code_attr u [(sign_extend "") (zero_extend "u")
1103 (div "") (udiv "u")])
1104 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")
1105 (div "false") (udiv "true")])
1107 ;; Used in signed and unsigned truncations.
1108 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
1109 ;; Instruction suffix for truncations.
1110 (define_code_attr trunsuffix
1111 [(ss_truncate "s") (truncate "") (us_truncate "us")])
1113 ;; Instruction suffix for SSE sign and zero extensions.
1114 (define_code_attr extsuffix [(sign_extend "sx") (zero_extend "zx")])
1116 ;; Used in signed and unsigned fix.
1117 (define_code_iterator any_fix [fix unsigned_fix])
1118 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
1119 (define_code_attr fixunssuffix [(fix "") (unsigned_fix "uns")])
1120 (define_code_attr fixprefix [(fix "s") (unsigned_fix "u")])
1122 ;; Used in signed and unsigned float.
1123 (define_code_iterator any_float [float unsigned_float])
1124 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
1125 (define_code_attr floatunssuffix [(float "") (unsigned_float "uns")])
1126 (define_code_attr floatprefix [(float "s") (unsigned_float "u")])
1128 ;; Base name for expression
1129 (define_code_attr insn
1130 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
1131 (minus "sub") (ss_minus "sssub") (us_minus "ussub")
1132 (sign_extend "extend") (zero_extend "zero_extend")
1133 (ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")
1134 (rotate "rotl") (rotatert "rotr")
1135 (mult "mul") (div "div")])
1137 ;; All integer modes.
1138 (define_mode_iterator SWI1248x [QI HI SI DI])
1140 ;; All integer modes without QImode.
1141 (define_mode_iterator SWI248x [HI SI DI])
1143 ;; All integer modes without QImode and HImode.
1144 (define_mode_iterator SWI48x [SI DI])
1146 ;; All integer modes without SImode and DImode.
1147 (define_mode_iterator SWI12 [QI HI])
1149 ;; All integer modes without DImode.
1150 (define_mode_iterator SWI124 [QI HI SI])
1152 ;; All integer modes without QImode and DImode.
1153 (define_mode_iterator SWI24 [HI SI])
1155 ;; Single word integer modes.
1156 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
1158 ;; Single word integer modes without QImode.
1159 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
1161 ;; Single word integer modes without QImode and HImode.
1162 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
1164 ;; All math-dependant single and double word integer modes.
1165 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
1166 (HI "TARGET_HIMODE_MATH")
1167 SI DI (TI "TARGET_64BIT")])
1169 ;; Math-dependant single word integer modes.
1170 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
1171 (HI "TARGET_HIMODE_MATH")
1172 SI (DI "TARGET_64BIT")])
1174 ;; Math-dependant integer modes without DImode.
1175 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
1176 (HI "TARGET_HIMODE_MATH")
1179 ;; Math-dependant integer modes with DImode.
1180 (define_mode_iterator SWIM1248x
1181 [(QI "TARGET_QIMODE_MATH")
1182 (HI "TARGET_HIMODE_MATH")
1185 ;; Math-dependant single word integer modes without QImode.
1186 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
1187 SI (DI "TARGET_64BIT")])
1189 ;; Double word integer modes.
1190 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
1191 (TI "TARGET_64BIT")])
1193 ;; SWI and DWI together.
1194 (define_mode_iterator SWIDWI [QI HI SI DI (TI "TARGET_64BIT")])
1196 ;; SWI48 and DWI together.
1197 (define_mode_iterator SWI48DWI [SI DI (TI "TARGET_64BIT")])
1199 ;; GET_MODE_SIZE for selected modes. As GET_MODE_SIZE is not
1200 ;; compile time constant, it is faster to use <MODE_SIZE> than
1201 ;; GET_MODE_SIZE (<MODE>mode). For XFmode which depends on
1202 ;; command line options just use GET_MODE_SIZE macro.
1203 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8")
1204 (TI "16") (HF "2") (BF "2") (SF "4") (DF "8")
1205 (XF "GET_MODE_SIZE (XFmode)")
1206 (V16QI "16") (V32QI "32") (V64QI "64")
1207 (V8HI "16") (V16HI "32") (V32HI "64")
1208 (V4SI "16") (V8SI "32") (V16SI "64")
1209 (V2DI "16") (V4DI "32") (V8DI "64")
1210 (V1TI "16") (V2TI "32") (V4TI "64")
1211 (V2DF "16") (V4DF "32") (V8DF "64")
1212 (V4SF "16") (V8SF "32") (V16SF "64")
1213 (V8HF "16") (V16HF "32") (V32HF "64")
1214 (V4HF "8") (V2HF "4")
1215 (V8BF "16") (V16BF "32") (V32BF "64")
1216 (V4BF "8") (V2BF "4")])
1218 ;; Double word integer modes as mode attribute.
1219 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI") (TI "OI")])
1220 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti") (TI "oi")])
1222 ;; Half sized integer modes.
1223 (define_mode_attr HALF [(TI "DI") (DI "SI")])
1224 (define_mode_attr half [(TI "di") (DI "si")])
1226 ;; LEA mode corresponding to an integer mode
1227 (define_mode_attr LEAMODE [(QI "SI") (HI "SI") (SI "SI") (DI "DI")])
1229 ;; Half mode for double word integer modes.
1230 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1231 (DI "TARGET_64BIT")])
1233 ;; Instruction suffix for integer modes.
1234 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1236 ;; Instruction suffix for masks.
1237 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1239 ;; Pointer size prefix for integer modes (Intel asm dialect)
1240 (define_mode_attr iptrsize [(QI "BYTE")
1245 ;; Register class for integer modes.
1246 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1248 ;; Immediate operand constraint for integer modes.
1249 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1251 ;; General operand constraint for word modes.
1252 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1254 ;; Memory operand constraint for word modes.
1255 (define_mode_attr m [(QI "m") (HI "m") (SI "BM") (DI "BM")])
1257 ;; Immediate operand constraint for double integer modes.
1258 (define_mode_attr di [(SI "nF") (DI "Wd")])
1260 ;; Immediate operand constraint for shifts.
1261 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1262 (define_mode_attr KS [(QI "Wb") (HI "Ww") (SI "I") (DI "J")])
1264 ;; Print register name in the specified mode.
1265 (define_mode_attr k [(QI "b") (HI "w") (SI "k") (DI "q")])
1267 ;; General operand predicate for integer modes.
1268 (define_mode_attr general_operand
1269 [(QI "general_operand")
1270 (HI "general_operand")
1271 (SI "x86_64_general_operand")
1272 (DI "x86_64_general_operand")
1273 (TI "x86_64_general_operand")])
1275 ;; General operand predicate for integer modes, where for TImode
1276 ;; we need both words of the operand to be general operands.
1277 (define_mode_attr general_hilo_operand
1278 [(QI "general_operand")
1279 (HI "general_operand")
1280 (SI "x86_64_general_operand")
1281 (DI "x86_64_general_operand")
1282 (TI "x86_64_hilo_general_operand")])
1284 ;; General sign extend operand predicate for integer modes,
1285 ;; which disallows VOIDmode operands and thus it is suitable
1286 ;; for use inside sign_extend.
1287 (define_mode_attr general_sext_operand
1288 [(QI "sext_operand")
1290 (SI "x86_64_sext_operand")
1291 (DI "x86_64_sext_operand")])
1293 ;; General sign/zero extend operand predicate for integer modes.
1294 (define_mode_attr general_szext_operand
1295 [(QI "general_operand")
1296 (HI "general_operand")
1297 (SI "x86_64_szext_general_operand")
1298 (DI "x86_64_szext_general_operand")
1299 (TI "x86_64_hilo_general_operand")])
1301 (define_mode_attr nonmemory_szext_operand
1302 [(QI "nonmemory_operand")
1303 (HI "nonmemory_operand")
1304 (SI "x86_64_szext_nonmemory_operand")
1305 (DI "x86_64_szext_nonmemory_operand")])
1307 ;; Immediate operand predicate for integer modes.
1308 (define_mode_attr immediate_operand
1309 [(QI "immediate_operand")
1310 (HI "immediate_operand")
1311 (SI "x86_64_immediate_operand")
1312 (DI "x86_64_immediate_operand")])
1314 ;; Nonmemory operand predicate for integer modes.
1315 (define_mode_attr nonmemory_operand
1316 [(QI "nonmemory_operand")
1317 (HI "nonmemory_operand")
1318 (SI "x86_64_nonmemory_operand")
1319 (DI "x86_64_nonmemory_operand")])
1321 ;; Operand predicate for shifts.
1322 (define_mode_attr shift_operand
1323 [(QI "nonimmediate_operand")
1324 (HI "nonimmediate_operand")
1325 (SI "nonimmediate_operand")
1326 (DI "shiftdi_operand")
1327 (TI "register_operand")])
1329 ;; Operand predicate for shift argument.
1330 (define_mode_attr shift_immediate_operand
1331 [(QI "const_1_to_31_operand")
1332 (HI "const_1_to_31_operand")
1333 (SI "const_1_to_31_operand")
1334 (DI "const_1_to_63_operand")])
1336 ;; Input operand predicate for arithmetic left shifts.
1337 (define_mode_attr ashl_input_operand
1338 [(QI "nonimmediate_operand")
1339 (HI "nonimmediate_operand")
1340 (SI "nonimmediate_operand")
1341 (DI "ashldi_input_operand")
1342 (TI "reg_or_pm1_operand")])
1344 ;; SSE and x87 SFmode and DFmode floating point modes
1345 (define_mode_iterator MODEF [SF DF])
1347 (define_mode_iterator MODEF248 [BF HF SF (DF "TARGET_SSE2")])
1349 ;; SSE floating point modes
1350 (define_mode_iterator MODEFH [(HF "TARGET_AVX512FP16") SF DF])
1352 ;; All x87 floating point modes
1353 (define_mode_iterator X87MODEF [SF DF XF])
1355 ;; All x87 floating point modes plus HFmode
1356 (define_mode_iterator X87MODEFH [HF SF DF XF BF])
1358 ;; All SSE floating point modes
1359 (define_mode_iterator SSEMODEF [HF SF DF TF])
1360 (define_mode_attr ssevecmodef [(HF "V8HF") (SF "V4SF") (DF "V2DF") (TF "TF")])
1362 ;; SSE instruction suffix for various modes
1363 (define_mode_attr ssemodesuffix
1364 [(HF "sh") (SF "ss") (DF "sd")
1365 (V32HF "ph") (V16SF "ps") (V8DF "pd")
1366 (V16HF "ph") (V16BF "bf") (V8SF "ps") (V4DF "pd")
1367 (V8HF "ph") (V8BF "bf") (V4SF "ps") (V2DF "pd")
1368 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1369 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1370 (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1372 ;; SSE vector suffix for floating point modes
1373 ;; BF HF use same suffix as SF for logic operations.
1374 (define_mode_attr ssevecmodesuffix [(BF "ps") (HF "ps") (SF "ps") (DF "pd")])
1376 ;; SSE vector mode corresponding to a scalar mode
1377 (define_mode_attr ssevecmode
1378 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (HF "V8HF") (BF "V8BF") (SF "V4SF") (DF "V2DF")])
1379 (define_mode_attr ssevecmodelower
1380 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1382 ;; AVX512F vector mode corresponding to a scalar mode
1383 (define_mode_attr avx512fvecmode
1384 [(QI "V64QI") (HI "V32HI") (SI "V16SI") (DI "V8DI")
1385 (HF "V32HF") (BF "V32BF") (SF "V16SF") (DF "V8DF")])
1387 ;; Instruction suffix for REX 64bit operators.
1388 (define_mode_attr rex64suffix [(SI "{l}") (DI "{q}")])
1389 (define_mode_attr rex64namesuffix [(SI "") (DI "q")])
1391 ;; This mode iterator allows :P to be used for patterns that operate on
1392 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1393 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1395 ;; This mode iterator allows :W to be used for patterns that operate on
1396 ;; word_mode sized quantities.
1397 (define_mode_iterator W
1398 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1400 ;; This mode iterator allows :PTR to be used for patterns that operate on
1401 ;; ptr_mode sized quantities.
1402 (define_mode_iterator PTR
1403 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1405 ;; Scheduling descriptions
1407 (include "pentium.md")
1410 (include "athlon.md")
1411 (include "bdver1.md")
1412 (include "bdver3.md")
1413 (include "btver2.md")
1414 (include "znver.md")
1415 (include "zn4zn5.md")
1416 (include "geode.md")
1420 (include "core2.md")
1421 (include "haswell.md")
1422 (include "lujiazui.md")
1423 (include "yongfeng.md")
1426 ;; Operand and operator predicates and constraints
1428 (include "predicates.md")
1429 (include "constraints.md")
1432 ;; Compare and branch/compare and store instructions.
1434 (define_expand "cbranch<mode>4"
1435 [(set (reg:CC FLAGS_REG)
1436 (compare:CC (match_operand:SWIM1248x 1 "nonimmediate_operand")
1437 (match_operand:SWIM1248x 2 "<general_operand>")))
1438 (set (pc) (if_then_else
1439 (match_operator 0 "ordered_comparison_operator"
1440 [(reg:CC FLAGS_REG) (const_int 0)])
1441 (label_ref (match_operand 3))
1445 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1446 operands[1] = force_reg (<MODE>mode, operands[1]);
1447 ix86_expand_branch (GET_CODE (operands[0]),
1448 operands[1], operands[2], operands[3]);
1452 (define_expand "cbranchti4"
1453 [(set (reg:CC FLAGS_REG)
1454 (compare:CC (match_operand:TI 1 "nonimmediate_operand")
1455 (match_operand:TI 2 "ix86_timode_comparison_operand")))
1456 (set (pc) (if_then_else
1457 (match_operator 0 "ix86_timode_comparison_operator"
1458 [(reg:CC FLAGS_REG) (const_int 0)])
1459 (label_ref (match_operand 3))
1461 "TARGET_64BIT || TARGET_SSE4_1"
1463 ix86_expand_branch (GET_CODE (operands[0]),
1464 operands[1], operands[2], operands[3]);
1468 (define_expand "cbranchoi4"
1469 [(set (reg:CC FLAGS_REG)
1470 (compare:CC (match_operand:OI 1 "nonimmediate_operand")
1471 (match_operand:OI 2 "nonimmediate_operand")))
1472 (set (pc) (if_then_else
1473 (match_operator 0 "bt_comparison_operator"
1474 [(reg:CC FLAGS_REG) (const_int 0)])
1475 (label_ref (match_operand 3))
1479 ix86_expand_branch (GET_CODE (operands[0]),
1480 operands[1], operands[2], operands[3]);
1484 (define_expand "cbranchxi4"
1485 [(set (reg:CC FLAGS_REG)
1486 (compare:CC (match_operand:XI 1 "nonimmediate_operand")
1487 (match_operand:XI 2 "nonimmediate_operand")))
1488 (set (pc) (if_then_else
1489 (match_operator 0 "bt_comparison_operator"
1490 [(reg:CC FLAGS_REG) (const_int 0)])
1491 (label_ref (match_operand 3))
1493 "TARGET_AVX512F && TARGET_EVEX512 && !TARGET_PREFER_AVX256"
1495 ix86_expand_branch (GET_CODE (operands[0]),
1496 operands[1], operands[2], operands[3]);
1500 (define_expand "cstore<mode>4"
1501 [(set (reg:CC FLAGS_REG)
1502 (compare:CC (match_operand:SDWIM 2 "nonimmediate_operand")
1503 (match_operand:SDWIM 3 "<general_operand>")))
1504 (set (match_operand:QI 0 "register_operand")
1505 (match_operator 1 "ordered_comparison_operator"
1506 [(reg:CC FLAGS_REG) (const_int 0)]))]
1509 if (<MODE>mode == (TARGET_64BIT ? TImode : DImode))
1511 if (GET_CODE (operands[1]) != EQ
1512 && GET_CODE (operands[1]) != NE)
1515 else if (MEM_P (operands[2]) && MEM_P (operands[3]))
1516 operands[2] = force_reg (<MODE>mode, operands[2]);
1517 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1518 operands[2], operands[3]);
1522 (define_insn "@ccmp<mode>"
1523 [(set (match_operand:CC 0 "flags_reg_operand")
1525 (match_operator 1 "comparison_operator"
1526 [(reg:CC FLAGS_REG) (const_int 0)])
1528 (minus:SWI (match_operand:SWI 2 "nonimmediate_operand" "<r>,<r>m,<r>")
1529 (match_operand:SWI 3 "<general_operand>" "C,<r><i>,<m>"))
1532 [(match_operand:SI 4 "const_0_to_15_operand")]
1536 ctest%C1{<imodesuffix>}\t%G4 %2, %2
1537 ccmp%C1{<imodesuffix>}\t%G4 {%3, %2|%2, %3}
1538 ccmp%C1{<imodesuffix>}\t%G4 {%3, %2|%2, %3}"
1539 [(set_attr "type" "icmp")
1540 (set_attr "mode" "<MODE>")
1541 (set_attr "length_immediate" "1")
1542 (set_attr "prefix" "evex")])
1544 (define_expand "@cmp<mode>_1"
1545 [(set (reg:CC FLAGS_REG)
1546 (compare:CC (match_operand:SWI 0 "nonimmediate_operand")
1547 (match_operand:SWI 1 "<general_operand>")))])
1549 (define_mode_iterator SWI1248_AVX512BWDQ_64
1550 [(QI "TARGET_AVX512DQ") HI
1551 (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW && TARGET_64BIT")])
1553 (define_insn "*cmp<mode>_ccz_1"
1554 [(set (reg FLAGS_REG)
1555 (compare (match_operand:SWI1248_AVX512BWDQ_64 0
1556 "nonimmediate_operand" "<r>,?m<r>,$k")
1557 (match_operand:SWI1248_AVX512BWDQ_64 1 "const0_operand")))]
1558 "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
1560 test{<imodesuffix>}\t%0, %0
1561 cmp{<imodesuffix>}\t{%1, %0|%0, %1}
1562 kortest<mskmodesuffix>\t%0, %0"
1563 [(set_attr "type" "test,icmp,msklog")
1564 (set_attr "length_immediate" "0,1,*")
1565 (set_attr "prefix" "*,*,vex")
1566 (set_attr "mode" "<MODE>")])
1568 (define_insn "*cmp<mode>_ccno_1"
1569 [(set (reg FLAGS_REG)
1570 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1571 (match_operand:SWI 1 "const0_operand")))]
1572 "ix86_match_ccmode (insn, CCNOmode)"
1574 test{<imodesuffix>}\t%0, %0
1575 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1576 [(set_attr "type" "test,icmp")
1577 (set_attr "length_immediate" "0,1")
1578 (set_attr "mode" "<MODE>")])
1580 (define_insn "*cmp<mode>_1"
1581 [(set (reg FLAGS_REG)
1582 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1583 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r><m>")))]
1584 "ix86_match_ccmode (insn, CCmode)"
1585 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1586 [(set_attr "type" "icmp")
1587 (set_attr "mode" "<MODE>")])
1589 (define_insn "*cmp<mode>_minus_1"
1590 [(set (reg FLAGS_REG)
1592 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1593 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r><m>"))
1595 "ix86_match_ccmode (insn, CCGOCmode)"
1596 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1597 [(set_attr "type" "icmp")
1598 (set_attr "mode" "<MODE>")])
1600 (define_insn "*cmpqi_ext<mode>_1"
1601 [(set (reg FLAGS_REG)
1603 (match_operand:QI 0 "nonimmediate_operand" "QBn")
1605 (match_operator:SWI248 2 "extract_operator"
1606 [(match_operand 1 "int248_register_operand" "Q")
1608 (const_int 8)]) 0)))]
1609 "ix86_match_ccmode (insn, CCmode)"
1610 "cmp{b}\t{%h1, %0|%0, %h1}"
1611 [(set_attr "addr" "gpr8")
1612 (set_attr "type" "icmp")
1613 (set_attr "mode" "QI")])
1615 (define_insn "*cmpqi_ext<mode>_2"
1616 [(set (reg FLAGS_REG)
1619 (match_operator:SWI248 2 "extract_operator"
1620 [(match_operand 0 "int248_register_operand" "Q")
1623 (match_operand:QI 1 "const0_operand")))]
1624 "ix86_match_ccmode (insn, CCNOmode)"
1626 [(set_attr "type" "test")
1627 (set_attr "length_immediate" "0")
1628 (set_attr "mode" "QI")])
1630 (define_expand "cmpqi_ext_3"
1631 [(set (reg:CC FLAGS_REG)
1635 (match_operand:HI 0 "register_operand")
1638 (match_operand:QI 1 "const_int_operand")))])
1640 (define_insn "*cmpqi_ext<mode>_3"
1641 [(set (reg FLAGS_REG)
1644 (match_operator:SWI248 2 "extract_operator"
1645 [(match_operand 0 "int248_register_operand" "Q")
1648 (match_operand:QI 1 "general_operand" "QnBn")))]
1649 "ix86_match_ccmode (insn, CCmode)"
1650 "cmp{b}\t{%1, %h0|%h0, %1}"
1651 [(set_attr "addr" "gpr8")
1652 (set_attr "type" "icmp")
1653 (set_attr "mode" "QI")])
1655 (define_insn "*cmpqi_ext<mode>_4"
1656 [(set (reg FLAGS_REG)
1659 (match_operator:SWI248 2 "extract_operator"
1660 [(match_operand 0 "int248_register_operand" "Q")
1664 (match_operator:SWI248 3 "extract_operator"
1665 [(match_operand 1 "int248_register_operand" "Q")
1667 (const_int 8)]) 0)))]
1668 "ix86_match_ccmode (insn, CCmode)"
1669 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1670 [(set_attr "type" "icmp")
1671 (set_attr "mode" "QI")])
1673 (define_insn_and_split "*cmp<dwi>_doubleword"
1674 [(set (reg:CCZ FLAGS_REG)
1675 (compare:CCZ (match_operand:<DWI> 0 "nonimmediate_operand")
1676 (match_operand:<DWI> 1 "general_operand")))]
1677 "ix86_pre_reload_split ()"
1680 [(parallel [(set (reg:CCZ FLAGS_REG)
1681 (compare:CCZ (ior:DWIH (match_dup 4) (match_dup 5))
1683 (set (match_dup 4) (ior:DWIH (match_dup 4) (match_dup 5)))])]
1685 split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);
1687 operands[4] = gen_reg_rtx (<MODE>mode);
1689 /* Special case comparisons against -1. */
1690 if (operands[1] == constm1_rtx && operands[3] == constm1_rtx)
1692 emit_insn (gen_and<mode>3 (operands[4], operands[0], operands[2]));
1693 emit_insn (gen_cmp_1 (<MODE>mode, operands[4], constm1_rtx));
1697 if (operands[1] == const0_rtx)
1698 emit_move_insn (operands[4], operands[0]);
1699 else if (operands[0] == const0_rtx)
1700 emit_move_insn (operands[4], operands[1]);
1701 else if (operands[1] == constm1_rtx)
1702 emit_insn (gen_one_cmpl<mode>2 (operands[4], operands[0]));
1703 else if (operands[0] == constm1_rtx)
1704 emit_insn (gen_one_cmpl<mode>2 (operands[4], operands[1]));
1707 if (CONST_SCALAR_INT_P (operands[1])
1708 && !x86_64_immediate_operand (operands[1], <MODE>mode))
1709 operands[1] = force_reg (<MODE>mode, operands[1]);
1710 emit_insn (gen_xor<mode>3 (operands[4], operands[0], operands[1]));
1713 if (operands[3] == const0_rtx)
1714 operands[5] = operands[2];
1715 else if (operands[2] == const0_rtx)
1716 operands[5] = operands[3];
1719 operands[5] = gen_reg_rtx (<MODE>mode);
1720 if (operands[3] == constm1_rtx)
1721 emit_insn (gen_one_cmpl<mode>2 (operands[5], operands[2]));
1722 else if (operands[2] == constm1_rtx)
1723 emit_insn (gen_one_cmpl<mode>2 (operands[5], operands[3]));
1726 if (CONST_SCALAR_INT_P (operands[3])
1727 && !x86_64_immediate_operand (operands[3], <MODE>mode))
1728 operands[3] = force_reg (<MODE>mode, operands[3]);
1729 emit_insn (gen_xor<mode>3 (operands[5], operands[2], operands[3]));
1734 ;; These implement float point compares.
1735 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1736 ;; which would allow mix and match FP modes on the compares. Which is what
1737 ;; the old patterns did, but with many more of them.
1739 (define_expand "cbranchxf4"
1740 [(set (reg:CC FLAGS_REG)
1741 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1742 (match_operand:XF 2 "nonmemory_operand")))
1743 (set (pc) (if_then_else
1744 (match_operator 0 "ix86_fp_comparison_operator_xf"
1747 (label_ref (match_operand 3))
1751 ix86_expand_branch (GET_CODE (operands[0]),
1752 operands[1], operands[2], operands[3]);
1756 (define_expand "cstorexf4"
1757 [(set (reg:CC FLAGS_REG)
1758 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1759 (match_operand:XF 3 "nonmemory_operand")))
1760 (set (match_operand:QI 0 "register_operand")
1761 (match_operator 1 "ix86_fp_comparison_operator_xf"
1766 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1767 operands[2], operands[3]);
1771 (define_expand "cbranchhf4"
1772 [(set (reg:CC FLAGS_REG)
1773 (compare:CC (match_operand:HF 1 "cmp_fp_expander_operand")
1774 (match_operand:HF 2 "cmp_fp_expander_operand")))
1775 (set (pc) (if_then_else
1776 (match_operator 0 "ix86_fp_comparison_operator"
1779 (label_ref (match_operand 3))
1783 ix86_expand_branch (GET_CODE (operands[0]),
1784 operands[1], operands[2], operands[3]);
1788 (define_expand "cbranch<mode>4"
1789 [(set (reg:CC FLAGS_REG)
1790 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1791 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1792 (set (pc) (if_then_else
1793 (match_operator 0 "ix86_fp_comparison_operator"
1796 (label_ref (match_operand 3))
1798 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1800 ix86_expand_branch (GET_CODE (operands[0]),
1801 operands[1], operands[2], operands[3]);
1805 (define_expand "cbranchbf4"
1806 [(set (reg:CC FLAGS_REG)
1807 (compare:CC (match_operand:BF 1 "cmp_fp_expander_operand")
1808 (match_operand:BF 2 "cmp_fp_expander_operand")))
1809 (set (pc) (if_then_else
1810 (match_operator 0 "comparison_operator"
1813 (label_ref (match_operand 3))
1815 "TARGET_80387 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
1817 rtx op1 = ix86_expand_fast_convert_bf_to_sf (operands[1]);
1818 rtx op2 = ix86_expand_fast_convert_bf_to_sf (operands[2]);
1819 do_compare_rtx_and_jump (op1, op2, GET_CODE (operands[0]), 0,
1820 SFmode, NULL_RTX, NULL,
1821 as_a <rtx_code_label *> (operands[3]),
1822 /* Unfortunately this isn't propagated. */
1823 profile_probability::even ());
1827 (define_expand "cstorehf4"
1828 [(set (reg:CC FLAGS_REG)
1829 (compare:CC (match_operand:HF 2 "cmp_fp_expander_operand")
1830 (match_operand:HF 3 "cmp_fp_expander_operand")))
1831 (set (match_operand:QI 0 "register_operand")
1832 (match_operator 1 "ix86_fp_comparison_operator"
1837 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1838 operands[2], operands[3]);
1842 (define_expand "cstorebf4"
1843 [(set (reg:CC FLAGS_REG)
1844 (compare:CC (match_operand:BF 2 "cmp_fp_expander_operand")
1845 (match_operand:BF 3 "cmp_fp_expander_operand")))
1846 (set (match_operand:QI 0 "register_operand")
1847 (match_operator 1 "comparison_operator"
1850 "TARGET_80387 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
1852 rtx op1 = ix86_expand_fast_convert_bf_to_sf (operands[2]);
1853 rtx op2 = ix86_expand_fast_convert_bf_to_sf (operands[3]);
1854 rtx res = emit_store_flag_force (operands[0], GET_CODE (operands[1]),
1855 op1, op2, SFmode, 0, 1);
1856 if (!rtx_equal_p (res, operands[0]))
1857 emit_move_insn (operands[0], res);
1861 (define_expand "cstore<mode>4"
1862 [(set (reg:CC FLAGS_REG)
1863 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1864 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1865 (set (match_operand:QI 0 "register_operand")
1866 (match_operator 1 "ix86_fp_comparison_operator"
1869 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1871 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1872 operands[2], operands[3]);
1876 (define_expand "cbranchcc4"
1877 [(set (pc) (if_then_else
1878 (match_operator 0 "comparison_operator"
1879 [(match_operand 1 "flags_reg_operand")
1880 (match_operand 2 "const0_operand")])
1881 (label_ref (match_operand 3))
1885 ix86_expand_branch (GET_CODE (operands[0]),
1886 operands[1], operands[2], operands[3]);
1890 ;; For conditonal compare, the middle-end hook will convert
1891 ;; CCmode to sub-CCmode using SELECT_CC_MODE macro and try
1892 ;; to find cstore<submodes> in optab. Add ALL_CC to support
1893 ;; the cstore after ccmp sequence.
1895 (define_mode_iterator ALL_CC
1896 [CCGC CCGOC CCNO CCGZ CCA CCC CCO CCP CCS CCZ CC])
1898 (define_expand "cstore<mode>4"
1899 [(set (match_operand:QI 0 "register_operand")
1900 (match_operator 1 "comparison_operator"
1901 [(match_operand:ALL_CC 2 "flags_reg_operand")
1902 (match_operand 3 "const0_operand")]))]
1905 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1906 operands[2], operands[3]);
1910 ;; FP compares, step 1:
1911 ;; Set the FP condition codes and move fpsr to ax.
1913 ;; We may not use "#" to split and emit these
1914 ;; due to reg-stack pops killing fpsr.
1916 (define_insn "*cmpxf_i387"
1917 [(set (match_operand:HI 0 "register_operand" "=a")
1920 (match_operand:XF 1 "register_operand" "f")
1921 (match_operand:XF 2 "reg_or_0_operand" "fC"))]
1924 "* return output_fp_compare (insn, operands, false, false);"
1925 [(set_attr "type" "multi")
1926 (set_attr "unit" "i387")
1927 (set_attr "mode" "XF")])
1929 (define_insn "*cmp<mode>_i387"
1930 [(set (match_operand:HI 0 "register_operand" "=a")
1933 (match_operand:MODEF 1 "register_operand" "f")
1934 (match_operand:MODEF 2 "nonimm_or_0_operand" "fmC"))]
1937 "* return output_fp_compare (insn, operands, false, false);"
1938 [(set_attr "type" "multi")
1939 (set_attr "unit" "i387")
1940 (set_attr "mode" "<MODE>")])
1942 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1943 [(set (match_operand:HI 0 "register_operand" "=a")
1946 (match_operand:X87MODEF 1 "register_operand" "f")
1948 (match_operand:SWI24 2 "nonimmediate_operand" "m")))]
1951 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1952 || optimize_function_for_size_p (cfun))"
1953 "* return output_fp_compare (insn, operands, false, false);"
1954 [(set_attr "type" "multi")
1955 (set_attr "unit" "i387")
1956 (set_attr "fp_int_src" "true")
1957 (set_attr "mode" "<SWI24:MODE>")])
1959 (define_insn "*cmpu<mode>_i387"
1960 [(set (match_operand:HI 0 "register_operand" "=a")
1964 (match_operand:X87MODEF 1 "register_operand" "f")
1965 (match_operand:X87MODEF 2 "register_operand" "f"))]
1969 "* return output_fp_compare (insn, operands, false, true);"
1970 [(set_attr "type" "multi")
1971 (set_attr "unit" "i387")
1972 (set_attr "mode" "<MODE>")])
1974 ;; FP compares, step 2:
1975 ;; Get ax into flags, general case.
1977 (define_insn "x86_sahf_1"
1978 [(set (reg:CC FLAGS_REG)
1979 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1983 #ifndef HAVE_AS_IX86_SAHF
1985 return ASM_BYTE "0x9e";
1990 [(set_attr "length" "1")
1991 (set_attr "athlon_decode" "vector")
1992 (set_attr "amdfam10_decode" "direct")
1993 (set_attr "bdver1_decode" "direct")
1994 (set_attr "mode" "SI")])
1996 ;; Pentium Pro can do both steps in one go.
1997 ;; (these instructions set flags directly)
1999 (define_subst_attr "unord" "unord_subst" "" "u")
2000 (define_subst_attr "unordered" "unord_subst" "false" "true")
2002 (define_subst "unord_subst"
2003 [(set (match_operand:CCFP 0)
2004 (match_operand:CCFP 1))]
2011 (define_insn "*cmpi<unord>xf_i387"
2012 [(set (reg:CCFP FLAGS_REG)
2014 (match_operand:XF 0 "register_operand" "f")
2015 (match_operand:XF 1 "register_operand" "f")))]
2016 "TARGET_80387 && TARGET_CMOVE"
2017 "* return output_fp_compare (insn, operands, true, <unordered>);"
2018 [(set_attr "type" "fcmp")
2019 (set_attr "mode" "XF")
2020 (set_attr "athlon_decode" "vector")
2021 (set_attr "amdfam10_decode" "direct")
2022 (set_attr "bdver1_decode" "double")
2023 (set_attr "znver1_decode" "double")])
2025 (define_insn "*cmpx<unord><MODEF:mode>"
2026 [(set (reg:CCFP FLAGS_REG)
2029 (match_operand:MODEF 0 "register_operand" "v")
2030 (match_operand:MODEF 1 "nonimmediate_operand" "vm"))]
2032 "TARGET_AVX10_2_256"
2033 "%v<unord>comx<MODEF:ssemodesuffix>\t{%1, %0|%0, %1}"
2034 [(set_attr "type" "ssecomi")
2035 (set_attr "prefix" "evex")
2036 (set_attr "mode" "<MODEF:MODE>")])
2038 (define_insn "*cmpx<unord>hf"
2039 [(set (reg:CCFP FLAGS_REG)
2042 (match_operand:HF 0 "register_operand" "v")
2043 (match_operand:HF 1 "nonimmediate_operand" "vm"))]
2045 "TARGET_AVX10_2_256"
2046 "v<unord>comxsh\t{%1, %0|%0, %1}"
2047 [(set_attr "type" "ssecomi")
2048 (set_attr "prefix" "evex")
2049 (set_attr "mode" "HF")])
2051 (define_insn "*cmpi<unord><MODEF:mode>"
2052 [(set (reg:CCFP FLAGS_REG)
2054 (match_operand:MODEF 0 "register_operand" "f,v")
2055 (match_operand:MODEF 1 "register_ssemem_operand" "f,vm")))]
2056 "(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
2057 || (TARGET_80387 && TARGET_CMOVE)"
2059 * return output_fp_compare (insn, operands, true, <unordered>);
2060 %v<unord>comi<MODEF:ssemodesuffix>\t{%1, %0|%0, %1}"
2061 [(set_attr "type" "fcmp,ssecomi")
2062 (set_attr "prefix" "orig,maybe_vex")
2063 (set_attr "mode" "<MODEF:MODE>")
2064 (set_attr "prefix_rep" "*,0")
2065 (set (attr "prefix_data16")
2066 (cond [(eq_attr "alternative" "0")
2068 (eq_attr "mode" "DF")
2071 (const_string "0")))
2072 (set_attr "athlon_decode" "vector")
2073 (set_attr "amdfam10_decode" "direct")
2074 (set_attr "bdver1_decode" "double")
2075 (set_attr "znver1_decode" "double")
2076 (set (attr "enabled")
2078 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
2080 (eq_attr "alternative" "0")
2081 (symbol_ref "TARGET_MIX_SSE_I387")
2082 (symbol_ref "true"))
2084 (eq_attr "alternative" "0")
2086 (symbol_ref "false"))))])
2088 (define_insn "*cmpi<unord>hf"
2089 [(set (reg:CCFP FLAGS_REG)
2091 (match_operand:HF 0 "register_operand" "v")
2092 (match_operand:HF 1 "nonimmediate_operand" "vm")))]
2094 "v<unord>comish\t{%1, %0|%0, %1}"
2095 [(set_attr "type" "ssecomi")
2096 (set_attr "prefix" "evex")
2097 (set_attr "mode" "HF")])
2100 (define_insn "x86_stc"
2101 [(set (reg:CCC FLAGS_REG) (unspec:CCC [(const_int 0)] UNSPEC_STC))]
2104 [(set_attr "length" "1")
2105 (set_attr "length_immediate" "0")
2106 (set_attr "modrm" "0")])
2108 ;; On Pentium 4, set the carry flag using mov $1,%al;addb $-1,%al.
2110 [(match_scratch:QI 0 "r")
2111 (set (reg:CCC FLAGS_REG) (unspec:CCC [(const_int 0)] UNSPEC_STC))]
2112 "TARGET_SLOW_STC && !optimize_insn_for_size_p ()"
2113 [(set (match_dup 0) (const_int 1))
2115 [(set (reg:CCC FLAGS_REG)
2116 (compare:CCC (plus:QI (match_dup 0) (const_int -1))
2118 (set (match_dup 0) (plus:QI (match_dup 0) (const_int -1)))])])
2120 ;; Complement carry flag.
2121 (define_insn "*x86_cmc"
2122 [(set (reg:CCC FLAGS_REG)
2123 (compare:CCC (neg:QI (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
2124 (geu:QI (reg:CCC FLAGS_REG) (const_int 0))))]
2127 [(set_attr "length" "1")
2128 (set_attr "length_immediate" "0")
2129 (set_attr "use_carry" "1")
2130 (set_attr "modrm" "0")])
2132 ;; On Pentium 4, cmc is replaced with setnc %al;addb $-1,%al.
2134 [(match_scratch:QI 0 "r")
2135 (set (reg:CCC FLAGS_REG)
2136 (compare:CCC (neg:QI (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
2137 (geu:QI (reg:CCC FLAGS_REG) (const_int 0))))]
2138 "TARGET_SLOW_STC && !optimize_insn_for_size_p ()"
2139 [(set (match_dup 0) (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))
2141 [(set (reg:CCC FLAGS_REG)
2142 (compare:CCC (plus:QI (match_dup 0) (const_int -1))
2144 (set (match_dup 0) (plus:QI (match_dup 0) (const_int -1)))])])
2146 ;; Push/pop instructions.
2148 (define_insn_and_split "*pushv1ti2"
2149 [(set (match_operand:V1TI 0 "push_operand" "=<")
2150 (match_operand:V1TI 1 "register_operand" "v"))]
2151 "TARGET_64BIT && TARGET_STV"
2153 "&& reload_completed"
2154 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2155 (set (match_dup 0) (match_dup 1))]
2157 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (V1TImode)));
2158 /* Preserve memory attributes. */
2159 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2161 [(set_attr "type" "multi")
2162 (set_attr "mode" "TI")])
2164 (define_insn "*push<mode>2"
2165 [(set (match_operand:DWI 0 "push_operand" "=<,<")
2166 (match_operand:DWI 1 "general_no_elim_operand" "riF*o,*v"))]
2169 [(set_attr "type" "multi")
2170 (set_attr "mode" "<MODE>")])
2173 [(set (match_operand:DWI 0 "push_operand")
2174 (match_operand:DWI 1 "general_gr_operand"))]
2177 "ix86_split_long_move (operands); DONE;")
2179 (define_insn "*pushdi2_rex64"
2180 [(set (match_operand:DI 0 "push_operand" "=<,<,!<")
2181 (match_operand:DI 1 "general_no_elim_operand" "re*m,*v,n"))]
2187 [(set_attr "type" "push,multi,multi")
2188 (set_attr "mode" "DI")])
2190 ;; Convert impossible pushes of immediate to existing instructions.
2191 ;; First try to get scratch register and go through it. In case this
2192 ;; fails, push sign extended lower part first and then overwrite
2193 ;; upper part by 32bit move.
2196 [(match_scratch:DI 2 "r")
2197 (set (match_operand:DI 0 "push_operand")
2198 (match_operand:DI 1 "immediate_operand"))]
2200 && !symbolic_operand (operands[1], DImode)
2201 && !x86_64_immediate_operand (operands[1], DImode)"
2202 [(set (match_dup 2) (match_dup 1))
2203 (set (match_dup 0) (match_dup 2))])
2206 [(set (match_operand:DI 0 "push_operand")
2207 (match_operand:DI 1 "immediate_operand"))]
2208 "TARGET_64BIT && epilogue_completed
2209 && !symbolic_operand (operands[1], DImode)
2210 && !x86_64_immediate_operand (operands[1], DImode)"
2211 [(set (match_dup 0) (match_dup 1))
2212 (set (match_dup 2) (match_dup 3))]
2214 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
2216 operands[1] = gen_lowpart (DImode, operands[2]);
2217 operands[2] = gen_rtx_MEM (SImode,
2218 plus_constant (Pmode, stack_pointer_rtx, 4));
2221 ;; For TARGET_64BIT we always round up to 8 bytes.
2222 (define_insn "*pushsi2_rex64"
2223 [(set (match_operand:SI 0 "push_operand" "=X,X")
2224 (match_operand:SI 1 "nonmemory_no_elim_operand" "re,*v"))]
2229 [(set_attr "type" "push,multi")
2230 (set_attr "mode" "DI")])
2232 (define_insn "*pushsi2"
2233 [(set (match_operand:SI 0 "push_operand" "=<,<")
2234 (match_operand:SI 1 "general_no_elim_operand" "ri*m,*v"))]
2239 [(set_attr "type" "push,multi")
2240 (set_attr "mode" "SI")])
2243 [(set (match_operand:SWI48DWI 0 "push_operand")
2244 (match_operand:SWI48DWI 1 "sse_reg_operand"))]
2245 "TARGET_SSE && reload_completed"
2246 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2247 (set (match_dup 0) (match_dup 1))]
2249 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (<SWI48DWI:MODE>mode)));
2250 /* Preserve memory attributes. */
2251 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2254 ;; emit_push_insn when it calls move_by_pieces requires an insn to
2255 ;; "push a byte/word". But actually we use push{l,q}, which has
2256 ;; the effect of rounding the amount pushed up to a word.
2258 (define_insn "*push<mode>2"
2259 [(set (match_operand:SWI12 0 "push_operand" "=X")
2260 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
2262 "* return TARGET_64BIT ? \"push{q}\t%q1\" : \"push{l}\t%k1\";"
2263 [(set_attr "type" "push")
2265 (if_then_else (match_test "TARGET_64BIT")
2267 (const_string "SI")))])
2269 (define_insn "*push<mode>2_prologue"
2270 [(set (match_operand:W 0 "push_operand" "=<")
2271 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
2272 (clobber (mem:BLK (scratch)))]
2274 "push{<imodesuffix>}\t%1"
2275 [(set_attr "type" "push")
2276 (set_attr "mode" "<MODE>")])
2278 (define_insn "*pop<mode>1"
2279 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
2280 (match_operand:W 1 "pop_operand" ">"))]
2282 "pop{<imodesuffix>}\t%0"
2283 [(set_attr "type" "pop")
2284 (set_attr "mode" "<MODE>")])
2286 (define_insn "*pop<mode>1_epilogue"
2287 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
2288 (match_operand:W 1 "pop_operand" ">"))
2289 (clobber (mem:BLK (scratch)))]
2291 "pop{<imodesuffix>}\t%0"
2292 [(set_attr "type" "pop")
2293 (set_attr "mode" "<MODE>")])
2295 (define_insn "@pushfl<mode>2"
2296 [(set (match_operand:W 0 "push_operand" "=<")
2297 (unspec:W [(match_operand 1 "flags_reg_operand")]
2299 "GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_CC"
2300 "pushf{<imodesuffix>}"
2301 [(set_attr "type" "push")
2302 (set_attr "mode" "<MODE>")])
2304 (define_insn "@popfl<mode>1"
2305 [(set (match_operand:CC 0 "flags_reg_operand")
2306 (unspec:CC [(match_operand:W 1 "pop_operand" ">")]
2309 "popf{<imodesuffix>}"
2310 [(set_attr "type" "pop")
2311 (set_attr "mode" "<MODE>")])
2314 ;; Reload patterns to support multi-word load/store
2315 ;; with non-offsetable address.
2316 (define_expand "reload_noff_store"
2317 [(parallel [(match_operand 0 "memory_operand" "=m")
2318 (match_operand 1 "register_operand" "r")
2319 (match_operand:DI 2 "register_operand" "=&r")])]
2322 rtx mem = operands[0];
2323 rtx addr = XEXP (mem, 0);
2325 emit_move_insn (operands[2], addr);
2326 mem = replace_equiv_address_nv (mem, operands[2]);
2328 emit_insn (gen_rtx_SET (mem, operands[1]));
2332 (define_expand "reload_noff_load"
2333 [(parallel [(match_operand 0 "register_operand" "=r")
2334 (match_operand 1 "memory_operand" "m")
2335 (match_operand:DI 2 "register_operand" "=r")])]
2338 rtx mem = operands[1];
2339 rtx addr = XEXP (mem, 0);
2341 emit_move_insn (operands[2], addr);
2342 mem = replace_equiv_address_nv (mem, operands[2]);
2344 emit_insn (gen_rtx_SET (operands[0], mem));
2348 ;; Move instructions.
2350 (define_expand "movxi"
2351 [(set (match_operand:XI 0 "nonimmediate_operand")
2352 (match_operand:XI 1 "general_operand"))]
2353 "TARGET_AVX512F && TARGET_EVEX512"
2354 "ix86_expand_vector_move (XImode, operands); DONE;")
2356 (define_expand "movoi"
2357 [(set (match_operand:OI 0 "nonimmediate_operand")
2358 (match_operand:OI 1 "general_operand"))]
2360 "ix86_expand_vector_move (OImode, operands); DONE;")
2362 (define_expand "movti"
2363 [(set (match_operand:TI 0 "nonimmediate_operand")
2364 (match_operand:TI 1 "general_operand"))]
2365 "TARGET_64BIT || TARGET_SSE"
2368 ix86_expand_move (TImode, operands);
2370 ix86_expand_vector_move (TImode, operands);
2374 ;; This expands to what emit_move_complex would generate if we didn't
2375 ;; have a movti pattern. Having this avoids problems with reload on
2376 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2377 ;; to have around all the time.
2378 (define_expand "movcdi"
2379 [(set (match_operand:CDI 0 "nonimmediate_operand")
2380 (match_operand:CDI 1 "general_operand"))]
2383 if (push_operand (operands[0], CDImode))
2384 emit_move_complex_push (CDImode, operands[0], operands[1]);
2386 emit_move_complex_parts (operands[0], operands[1]);
2390 (define_expand "mov<mode>"
2391 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
2392 (match_operand:SWI1248x 1 "general_operand"))]
2394 "ix86_expand_move (<MODE>mode, operands); DONE;")
2396 (define_insn "*mov<mode>_xor"
2397 [(set (match_operand:SWI48 0 "register_operand" "=r")
2398 (match_operand:SWI48 1 "const0_operand"))
2399 (clobber (reg:CC FLAGS_REG))]
2402 [(set_attr "type" "alu1")
2403 (set_attr "mode" "SI")
2404 (set_attr "length_immediate" "0")])
2406 (define_insn "*mov<mode>_and"
2407 [(set (match_operand:SWI248 0 "memory_operand" "=m")
2408 (match_operand:SWI248 1 "const0_operand"))
2409 (clobber (reg:CC FLAGS_REG))]
2411 "and{<imodesuffix>}\t{%1, %0|%0, %1}"
2412 [(set_attr "type" "alu1")
2413 (set_attr "mode" "<MODE>")
2414 (set_attr "length_immediate" "1")])
2416 (define_insn "*mov<mode>_or"
2417 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
2418 (match_operand:SWI248 1 "constm1_operand"))
2419 (clobber (reg:CC FLAGS_REG))]
2421 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
2422 [(set_attr "type" "alu1")
2423 (set_attr "mode" "<MODE>")
2424 (set_attr "length_immediate" "1")])
2426 (define_insn "*movxi_internal_avx512f"
2427 [(set (match_operand:XI 0 "nonimmediate_operand" "=v,v ,v ,m")
2428 (match_operand:XI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2429 "TARGET_AVX512F && TARGET_EVEX512
2430 && (register_operand (operands[0], XImode)
2431 || register_operand (operands[1], XImode))"
2433 switch (get_attr_type (insn))
2436 return standard_sse_constant_opcode (insn, operands);
2439 return ix86_output_ssemov (insn, operands);
2445 [(set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2446 (set_attr "prefix" "evex")
2447 (set_attr "mode" "XI")])
2449 (define_insn "*movoi_internal_avx"
2450 [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,v ,m")
2451 (match_operand:OI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2453 && (register_operand (operands[0], OImode)
2454 || register_operand (operands[1], OImode))"
2456 switch (get_attr_type (insn))
2459 return standard_sse_constant_opcode (insn, operands);
2462 return ix86_output_ssemov (insn, operands);
2468 [(set_attr "isa" "*,avx2,*,*")
2469 (set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2470 (set_attr "prefix" "vex")
2471 (set_attr "mode" "OI")])
2473 (define_insn "*movti_internal"
2474 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,v ,m,?jc,?Yd")
2475 (match_operand:TI 1 "general_operand" "riFo,re,C,BC,vm,v,Yd,jc"))]
2477 && !(MEM_P (operands[0]) && MEM_P (operands[1])))
2479 && nonimmediate_or_sse_const_operand (operands[1], TImode)
2480 && (register_operand (operands[0], TImode)
2481 || register_operand (operands[1], TImode)))"
2483 switch (get_attr_type (insn))
2489 return standard_sse_constant_opcode (insn, operands);
2492 return ix86_output_ssemov (insn, operands);
2499 (cond [(eq_attr "alternative" "0,1,6,7")
2500 (const_string "x64")
2501 (eq_attr "alternative" "3")
2502 (const_string "sse2")
2504 (const_string "*")))
2506 (cond [(eq_attr "alternative" "0,1,6,7")
2507 (const_string "multi")
2508 (eq_attr "alternative" "2,3")
2509 (const_string "sselog1")
2511 (const_string "ssemov")))
2512 (set (attr "prefix")
2513 (if_then_else (eq_attr "type" "sselog1,ssemov")
2514 (const_string "maybe_vex")
2515 (const_string "orig")))
2517 (cond [(eq_attr "alternative" "0,1")
2519 (match_test "TARGET_AVX")
2521 (ior (not (match_test "TARGET_SSE2"))
2522 (match_test "optimize_function_for_size_p (cfun)"))
2523 (const_string "V4SF")
2524 (and (eq_attr "alternative" "5")
2525 (match_test "TARGET_SSE_TYPELESS_STORES"))
2526 (const_string "V4SF")
2528 (const_string "TI")))
2529 (set (attr "preferred_for_speed")
2530 (cond [(eq_attr "alternative" "6")
2531 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2532 (eq_attr "alternative" "7")
2533 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2535 (symbol_ref "true")))])
2538 [(set (match_operand:TI 0 "sse_reg_operand")
2539 (match_operand:TI 1 "general_reg_operand"))]
2540 "TARGET_64BIT && TARGET_SSE4_1
2541 && reload_completed"
2544 (vec_duplicate:V2DI (match_dup 3))
2548 operands[2] = lowpart_subreg (V2DImode, operands[0], TImode);
2549 operands[3] = gen_highpart (DImode, operands[1]);
2551 emit_move_insn (gen_lowpart (DImode, operands[0]),
2552 gen_lowpart (DImode, operands[1]));
2555 (define_insn "*movdi_internal"
2556 [(set (match_operand:DI 0 "nonimmediate_operand"
2557 "=r ,o ,r,r ,r,m ,*y,*y,?*y,?m,?r,?*y,?Yv,?v,?v,m ,m,?jc,?*Yd,?r,?v,?*y,?*x,*k,*k ,*r,*m,*k")
2558 (match_operand:DI 1 "general_operand"
2559 "riFo,riF,Z,rem,i,re,C ,*y,Bk ,*y,*y,r ,C ,?v,Bk,?v,v,*Yd,jc ,?v,r ,*x ,*y ,*r,*kBk,*k,*k,CBC"))]
2560 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2561 && ix86_hardreg_mov_ok (operands[0], operands[1])"
2563 switch (get_attr_type (insn))
2566 return "kmovq\t{%1, %0|%0, %1}";
2569 if (operands[1] == const0_rtx)
2570 return "kxorq\t%0, %0, %0";
2571 else if (operands[1] == constm1_rtx)
2572 return "kxnorq\t%0, %0, %0";
2579 return "pxor\t%0, %0";
2582 /* Handle broken assemblers that require movd instead of movq. */
2583 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2584 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2585 return "movd\t{%1, %0|%0, %1}";
2586 return "movq\t{%1, %0|%0, %1}";
2589 return standard_sse_constant_opcode (insn, operands);
2592 return ix86_output_ssemov (insn, operands);
2595 if (SSE_REG_P (operands[0]))
2596 return "movq2dq\t{%1, %0|%0, %1}";
2598 return "movdq2q\t{%1, %0|%0, %1}";
2601 return "lea{q}\t{%E1, %0|%0, %E1}";
2604 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2605 if (get_attr_mode (insn) == MODE_SI)
2606 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2607 else if (which_alternative == 4)
2608 return "movabs{q}\t{%1, %0|%0, %1}";
2609 else if (ix86_use_lea_for_mov (insn, operands))
2610 return "lea{q}\t{%E1, %0|%0, %E1}";
2612 return "mov{q}\t{%1, %0|%0, %1}";
2619 (cond [(eq_attr "alternative" "0,1,17,18")
2620 (const_string "nox64")
2621 (eq_attr "alternative" "2,3,4,5,10,11,23,25")
2622 (const_string "x64")
2623 (eq_attr "alternative" "19,20")
2624 (const_string "x64_sse2")
2625 (eq_attr "alternative" "21,22")
2626 (const_string "sse2")
2628 (const_string "*")))
2630 (cond [(eq_attr "alternative" "0,1,17,18")
2631 (const_string "multi")
2632 (eq_attr "alternative" "6")
2633 (const_string "mmx")
2634 (eq_attr "alternative" "7,8,9,10,11")
2635 (const_string "mmxmov")
2636 (eq_attr "alternative" "12")
2637 (const_string "sselog1")
2638 (eq_attr "alternative" "13,14,15,16,19,20")
2639 (const_string "ssemov")
2640 (eq_attr "alternative" "21,22")
2641 (const_string "ssecvt")
2642 (eq_attr "alternative" "23,24,25,26")
2643 (const_string "mskmov")
2644 (eq_attr "alternative" "27")
2645 (const_string "msklog")
2646 (and (match_operand 0 "register_operand")
2647 (match_operand 1 "pic_32bit_operand"))
2648 (const_string "lea")
2650 (const_string "imov")))
2653 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2655 (const_string "*")))
2656 (set (attr "length_immediate")
2658 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2660 (const_string "*")))
2661 (set (attr "prefix_rex")
2663 (eq_attr "alternative" "10,11,19,20")
2665 (const_string "*")))
2666 (set (attr "prefix")
2667 (if_then_else (eq_attr "type" "sselog1,ssemov")
2668 (const_string "maybe_vex")
2669 (const_string "orig")))
2670 (set (attr "prefix_data16")
2671 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2673 (const_string "*")))
2675 (cond [(eq_attr "alternative" "2")
2677 (eq_attr "alternative" "12")
2678 (cond [(match_test "TARGET_AVX")
2680 (ior (not (match_test "TARGET_SSE2"))
2681 (match_test "optimize_function_for_size_p (cfun)"))
2682 (const_string "V4SF")
2684 (const_string "TI"))
2685 (eq_attr "alternative" "13")
2686 (cond [(match_test "TARGET_AVX512VL")
2688 (match_test "TARGET_AVX512F")
2690 (match_test "TARGET_AVX")
2692 (ior (not (match_test "TARGET_SSE2"))
2693 (match_test "optimize_function_for_size_p (cfun)"))
2694 (const_string "V4SF")
2696 (const_string "TI"))
2698 (and (eq_attr "alternative" "14,15,16")
2699 (not (match_test "TARGET_SSE2")))
2700 (const_string "V2SF")
2702 (const_string "DI")))
2703 (set (attr "preferred_for_speed")
2704 (cond [(eq_attr "alternative" "10,17,19")
2705 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2706 (eq_attr "alternative" "11,18,20")
2707 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2709 (symbol_ref "true")))
2710 (set (attr "enabled")
2711 (cond [(eq_attr "alternative" "15")
2713 (match_test "TARGET_STV && TARGET_SSE2")
2714 (symbol_ref "false")
2716 (eq_attr "alternative" "16")
2718 (match_test "TARGET_STV && TARGET_SSE2")
2720 (symbol_ref "false"))
2722 (const_string "*")))])
2725 [(set (match_operand:<DWI> 0 "general_reg_operand")
2726 (match_operand:<DWI> 1 "sse_reg_operand"))]
2728 && reload_completed"
2732 (parallel [(const_int 1)])))]
2734 operands[2] = gen_highpart (<MODE>mode, operands[0]);
2735 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[1], <DWI>mode);
2737 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]),
2738 gen_lowpart (<MODE>mode, operands[1]));
2742 [(set (match_operand:DWI 0 "nonimmediate_gr_operand")
2743 (match_operand:DWI 1 "general_gr_operand"))]
2746 "ix86_split_long_move (operands); DONE;")
2749 [(set (match_operand:DI 0 "sse_reg_operand")
2750 (match_operand:DI 1 "general_reg_operand"))]
2751 "!TARGET_64BIT && TARGET_SSE4_1
2752 && reload_completed"
2755 (vec_duplicate:V4SI (match_dup 3))
2759 operands[2] = lowpart_subreg (V4SImode, operands[0], DImode);
2760 operands[3] = gen_highpart (SImode, operands[1]);
2762 emit_move_insn (gen_lowpart (SImode, operands[0]),
2763 gen_lowpart (SImode, operands[1]));
2766 ;; movabsq $0x0012345678000000, %rax is longer
2767 ;; than movl $0x12345678, %eax; shlq $24, %rax.
2769 [(set (match_operand:DI 0 "register_operand")
2770 (match_operand:DI 1 "const_int_operand"))]
2772 && optimize_insn_for_size_p ()
2773 && LEGACY_INT_REG_P (operands[0])
2774 && !x86_64_immediate_operand (operands[1], DImode)
2775 && !x86_64_zext_immediate_operand (operands[1], DImode)
2776 && !((UINTVAL (operands[1]) >> ctz_hwi (UINTVAL (operands[1])))
2777 & ~HOST_WIDE_INT_C (0xffffffff))
2778 && peep2_regno_dead_p (0, FLAGS_REG)"
2779 [(set (match_dup 0) (match_dup 1))
2780 (parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
2781 (clobber (reg:CC FLAGS_REG))])]
2783 int shift = ctz_hwi (UINTVAL (operands[1]));
2784 rtx op1 = gen_int_mode (UINTVAL (operands[1]) >> shift, DImode);
2785 if (ix86_endbr_immediate_operand (op1, VOIDmode))
2788 operands[2] = gen_int_mode (shift, QImode);
2791 (define_insn "*movsi_internal"
2792 [(set (match_operand:SI 0 "nonimmediate_operand"
2793 "=r,m ,*y,*y,?*y,?m,?r,?*y,?Yv,?v,?v,m ,?r,?v,*k,*k ,*rm,*k")
2794 (match_operand:SI 1 "general_operand"
2795 "g ,re,C ,*y,Bk ,*y,*y,r ,C ,?v,Bk,?v,?v,r ,*r,*kBk,*k ,CBC"))]
2796 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2797 && ix86_hardreg_mov_ok (operands[0], operands[1])"
2799 switch (get_attr_type (insn))
2802 return standard_sse_constant_opcode (insn, operands);
2805 return "kmovd\t{%1, %0|%0, %1}";
2808 if (operands[1] == const0_rtx)
2809 return "kxord\t%0, %0, %0";
2810 else if (operands[1] == constm1_rtx)
2811 return "kxnord\t%0, %0, %0";
2815 return ix86_output_ssemov (insn, operands);
2818 return "pxor\t%0, %0";
2821 switch (get_attr_mode (insn))
2824 return "movq\t{%1, %0|%0, %1}";
2826 return "movd\t{%1, %0|%0, %1}";
2833 return "lea{l}\t{%E1, %0|%0, %E1}";
2836 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2837 if (ix86_use_lea_for_mov (insn, operands))
2838 return "lea{l}\t{%E1, %0|%0, %E1}";
2840 return "mov{l}\t{%1, %0|%0, %1}";
2847 (cond [(eq_attr "alternative" "12,13")
2848 (const_string "sse2")
2850 (const_string "*")))
2852 (cond [(eq_attr "alternative" "2")
2853 (const_string "mmx")
2854 (eq_attr "alternative" "3,4,5,6,7")
2855 (const_string "mmxmov")
2856 (eq_attr "alternative" "8")
2857 (const_string "sselog1")
2858 (eq_attr "alternative" "9,10,11,12,13")
2859 (const_string "ssemov")
2860 (eq_attr "alternative" "14,15,16")
2861 (const_string "mskmov")
2862 (eq_attr "alternative" "17")
2863 (const_string "msklog")
2864 (and (match_operand 0 "register_operand")
2865 (match_operand 1 "pic_32bit_operand"))
2866 (const_string "lea")
2868 (const_string "imov")))
2869 (set (attr "prefix")
2870 (if_then_else (eq_attr "type" "sselog1,ssemov")
2871 (const_string "maybe_vex")
2872 (const_string "orig")))
2873 (set (attr "prefix_data16")
2874 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2876 (const_string "*")))
2878 (cond [(eq_attr "alternative" "2,3")
2880 (eq_attr "alternative" "8")
2881 (cond [(match_test "TARGET_AVX")
2883 (ior (not (match_test "TARGET_SSE2"))
2884 (match_test "optimize_function_for_size_p (cfun)"))
2885 (const_string "V4SF")
2887 (const_string "TI"))
2888 (eq_attr "alternative" "9")
2889 (cond [(match_test "TARGET_AVX512VL")
2891 (match_test "TARGET_AVX512F")
2893 (match_test "TARGET_AVX")
2895 (ior (not (match_test "TARGET_SSE2"))
2896 (match_test "optimize_function_for_size_p (cfun)"))
2897 (const_string "V4SF")
2899 (const_string "TI"))
2901 (and (eq_attr "alternative" "10,11")
2902 (not (match_test "TARGET_SSE2")))
2905 (const_string "SI")))
2906 (set (attr "preferred_for_speed")
2907 (cond [(eq_attr "alternative" "6,12")
2908 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2909 (eq_attr "alternative" "7,13")
2910 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2912 (symbol_ref "true")))])
2914 ;; With -Oz, transform mov $imm,reg to the shorter push $imm; pop reg.
2916 [(set (match_operand:SWI248 0 "general_reg_operand")
2917 (match_operand:SWI248 1 "const_int_operand"))]
2918 "optimize_insn_for_size_p () && optimize_size > 1
2919 && operands[1] != const0_rtx
2920 && IN_RANGE (INTVAL (operands[1]), -128, 127)
2921 && !ix86_red_zone_used
2922 && REGNO (operands[0]) != SP_REG"
2923 [(set (match_dup 2) (match_dup 1))
2924 (set (match_dup 0) (match_dup 3))]
2926 if (GET_MODE (operands[0]) != word_mode)
2927 operands[0] = gen_rtx_REG (word_mode, REGNO (operands[0]));
2929 operands[2] = gen_rtx_MEM (word_mode,
2930 gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
2931 operands[3] = gen_rtx_MEM (word_mode,
2932 gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
2935 ;; With -Oz, transform mov $0,mem to the shorter and $0,mem.
2936 ;; Likewise, transform mov $-1,mem to the shorter or $-1,mem.
2938 [(set (match_operand:SWI248 0 "memory_operand")
2939 (match_operand:SWI248 1 "const_int_operand"))]
2940 "(operands[1] == const0_rtx || operands[1] == constm1_rtx)
2941 && optimize_insn_for_size_p () && optimize_size > 1
2942 && peep2_regno_dead_p (0, FLAGS_REG)"
2943 [(parallel [(set (match_dup 0) (match_dup 1))
2944 (clobber (reg:CC FLAGS_REG))])])
2946 (define_insn "*movhi_internal"
2947 [(set (match_operand:HI 0 "nonimmediate_operand"
2948 "=r,r,r,m ,*k,*k ,r ,m ,*k ,?r,?*v,*Yv,*v,*v,jm,m")
2949 (match_operand:HI 1 "general_operand"
2950 "r ,n,m,rn,r ,*km,*k,*k,CBC,*v,r ,C ,*v,m ,*x,*v"))]
2951 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2952 && ix86_hardreg_mov_ok (operands[0], operands[1])"
2954 switch (get_attr_type (insn))
2957 /* movzwl is faster than movw on p2 due to partial word stalls,
2958 though not as fast as an aligned movl. */
2959 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2962 switch (which_alternative)
2965 return "kmovw\t{%k1, %0|%0, %k1}";
2967 return "kmovw\t{%1, %k0|%k0, %1}";
2970 return "kmovw\t{%1, %0|%0, %1}";
2976 return ix86_output_ssemov (insn, operands);
2979 if (satisfies_constraint_C (operands[1]))
2980 return standard_sse_constant_opcode (insn, operands);
2982 if (SSE_REG_P (operands[0]))
2983 return "%vpinsrw\t{$0, %1, %d0|%d0, %1, 0}";
2985 return "%vpextrw\t{$0, %1, %0|%0, %1, 0}";
2988 if (operands[1] == const0_rtx)
2989 return "kxorw\t%0, %0, %0";
2990 else if (operands[1] == constm1_rtx)
2991 return "kxnorw\t%0, %0, %0";
2995 if (get_attr_mode (insn) == MODE_SI)
2996 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2998 return "mov{w}\t{%1, %0|%0, %1}";
3002 (cond [(eq_attr "alternative" "9,10,11,12,13")
3003 (const_string "sse2")
3004 (eq_attr "alternative" "14")
3005 (const_string "sse4_noavx")
3006 (eq_attr "alternative" "15")
3007 (const_string "avx")
3009 (const_string "*")))
3011 (if_then_else (eq_attr "alternative" "14")
3012 (const_string "gpr16")
3013 (const_string "*")))
3015 (cond [(eq_attr "alternative" "4,5,6,7")
3016 (const_string "mskmov")
3017 (eq_attr "alternative" "8")
3018 (const_string "msklog")
3019 (eq_attr "alternative" "13,14,15")
3020 (if_then_else (match_test "TARGET_AVX512FP16")
3021 (const_string "ssemov")
3022 (const_string "sselog1"))
3023 (eq_attr "alternative" "11")
3024 (const_string "sselog1")
3025 (eq_attr "alternative" "9,10,12")
3026 (const_string "ssemov")
3027 (match_test "optimize_function_for_size_p (cfun)")
3028 (const_string "imov")
3029 (and (eq_attr "alternative" "0")
3030 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
3031 (not (match_test "TARGET_HIMODE_MATH"))))
3032 (const_string "imov")
3033 (and (eq_attr "alternative" "1,2")
3034 (match_operand:HI 1 "aligned_operand"))
3035 (const_string "imov")
3036 (and (match_test "TARGET_MOVX")
3037 (eq_attr "alternative" "0,2"))
3038 (const_string "imovx")
3040 (const_string "imov")))
3041 (set (attr "prefix")
3042 (cond [(eq_attr "alternative" "4,5,6,7,8")
3043 (const_string "vex")
3044 (eq_attr "alternative" "9,10,11,12,13,14,15")
3045 (const_string "maybe_evex")
3047 (const_string "orig")))
3049 (cond [(eq_attr "alternative" "9,10")
3050 (if_then_else (match_test "TARGET_AVX512FP16")
3052 (const_string "SI"))
3053 (eq_attr "alternative" "13,14,15")
3054 (if_then_else (match_test "TARGET_AVX512FP16")
3056 (const_string "TI"))
3057 (eq_attr "alternative" "11")
3058 (cond [(match_test "TARGET_AVX")
3060 (ior (not (match_test "TARGET_SSE2"))
3061 (match_test "optimize_function_for_size_p (cfun)"))
3062 (const_string "V4SF")
3064 (const_string "TI"))
3065 (eq_attr "alternative" "12")
3066 (cond [(match_test "TARGET_AVX512VL")
3068 (match_test "TARGET_AVX512FP16")
3070 (match_test "TARGET_AVX512F")
3072 (match_test "TARGET_AVX")
3074 (ior (not (match_test "TARGET_SSE2"))
3075 (match_test "optimize_function_for_size_p (cfun)"))
3076 (const_string "V4SF")
3078 (const_string "TI"))
3079 (eq_attr "type" "imovx")
3081 (and (eq_attr "alternative" "1,2")
3082 (match_operand:HI 1 "aligned_operand"))
3084 (and (eq_attr "alternative" "0")
3085 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
3086 (not (match_test "TARGET_HIMODE_MATH"))))
3089 (const_string "HI")))
3090 (set (attr "preferred_for_speed")
3091 (cond [(eq_attr "alternative" "9")
3092 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3093 (eq_attr "alternative" "10")
3094 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3096 (symbol_ref "true")))])
3098 ;; Situation is quite tricky about when to choose full sized (SImode) move
3099 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
3100 ;; partial register dependency machines (such as AMD Athlon), where QImode
3101 ;; moves issue extra dependency and for partial register stalls machines
3102 ;; that don't use QImode patterns (and QImode move cause stall on the next
3105 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
3106 ;; register stall machines with, where we use QImode instructions, since
3107 ;; partial register stall can be caused there. Then we use movzx.
3109 (define_insn "*movqi_internal"
3110 [(set (match_operand:QI 0 "nonimmediate_operand"
3111 "=Q,R,r,q,q,r,r ,?r,m ,*k,*k,*r,*m,*k,*k,*k")
3112 (match_operand:QI 1 "general_operand"
3113 "Q ,R,r,n,m,q,rn, m,qn,*r,*k,*k,*k,*m,C,BC"))]
3114 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3115 && ix86_hardreg_mov_ok (operands[0], operands[1])"
3122 switch (get_attr_type (insn))
3125 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
3126 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
3129 switch (which_alternative)
3132 ops = "kmov%s\t{%%k1, %%0|%%0, %%k1}";
3135 ops = "kmov%s\t{%%1, %%k0|%%k0, %%1}";
3139 gcc_assert (TARGET_AVX512DQ);
3142 ops = "kmov%s\t{%%1, %%0|%%0, %%1}";
3148 suffix = (get_attr_mode (insn) == MODE_HI) ? "w" : "b";
3150 snprintf (buf, sizeof (buf), ops, suffix);
3151 output_asm_insn (buf, operands);
3155 if (operands[1] == const0_rtx)
3157 if (get_attr_mode (insn) == MODE_HI)
3158 return "kxorw\t%0, %0, %0";
3160 return "kxorb\t%0, %0, %0";
3162 else if (operands[1] == constm1_rtx)
3164 gcc_assert (TARGET_AVX512DQ);
3165 return "kxnorb\t%0, %0, %0";
3170 if (get_attr_mode (insn) == MODE_SI)
3171 return "mov{l}\t{%k1, %k0|%k0, %k1}";
3173 return "mov{b}\t{%1, %0|%0, %1}";
3177 (cond [(eq_attr "alternative" "1,2")
3178 (const_string "x64")
3179 (eq_attr "alternative" "12,13,15")
3180 (const_string "avx512dq")
3182 (const_string "*")))
3184 (cond [(eq_attr "alternative" "9,10,11,12,13")
3185 (const_string "mskmov")
3186 (eq_attr "alternative" "14,15")
3187 (const_string "msklog")
3188 (and (eq_attr "alternative" "7")
3189 (not (match_operand:QI 1 "aligned_operand")))
3190 (const_string "imovx")
3191 (match_test "optimize_function_for_size_p (cfun)")
3192 (const_string "imov")
3193 (and (eq_attr "alternative" "5")
3194 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
3195 (not (match_test "TARGET_QIMODE_MATH"))))
3196 (const_string "imov")
3197 (eq_attr "alternative" "5,7")
3198 (const_string "imovx")
3199 (and (match_test "TARGET_MOVX")
3200 (eq_attr "alternative" "4"))
3201 (const_string "imovx")
3203 (const_string "imov")))
3204 (set (attr "prefix")
3205 (if_then_else (eq_attr "alternative" "9,10,11,12,13,14,15")
3206 (const_string "vex")
3207 (const_string "orig")))
3209 (cond [(eq_attr "alternative" "5,6,7")
3211 (eq_attr "alternative" "8")
3213 (and (eq_attr "alternative" "9,10,11,14")
3214 (not (match_test "TARGET_AVX512DQ")))
3216 (eq_attr "type" "imovx")
3218 ;; For -Os, 8-bit immediates are always shorter than 32-bit
3220 (and (eq_attr "type" "imov")
3221 (and (eq_attr "alternative" "3")
3222 (match_test "optimize_function_for_size_p (cfun)")))
3224 ;; For -Os, movl where one or both operands are NON_Q_REGS
3225 ;; and both are LEGACY_REGS is shorter than movb.
3226 ;; Otherwise movb and movl sizes are the same, so decide purely
3227 ;; based on speed factors.
3228 (and (eq_attr "type" "imov")
3229 (and (eq_attr "alternative" "1")
3230 (match_test "optimize_function_for_size_p (cfun)")))
3232 (and (eq_attr "type" "imov")
3233 (and (eq_attr "alternative" "0,1,2,3")
3234 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
3235 (not (match_test "TARGET_PARTIAL_REG_STALL")))))
3237 ;; Avoid partial register stalls when not using QImode arithmetic
3238 (and (eq_attr "type" "imov")
3239 (and (eq_attr "alternative" "0,1,2,3")
3240 (and (match_test "TARGET_PARTIAL_REG_STALL")
3241 (not (match_test "TARGET_QIMODE_MATH")))))
3244 (const_string "QI")))])
3246 /* Reload dislikes loading 0/-1 directly into mask registers.
3247 Try to tidy things up here. */
3249 [(set (match_operand:SWI 0 "general_reg_operand")
3250 (match_operand:SWI 1 "immediate_operand"))
3251 (set (match_operand:SWI 2 "mask_reg_operand")
3253 "peep2_reg_dead_p (2, operands[0])
3254 && (const0_operand (operands[1], <MODE>mode)
3255 || (constm1_operand (operands[1], <MODE>mode)
3256 && (<MODE_SIZE> > 1 || TARGET_AVX512DQ)))"
3257 [(set (match_dup 2) (match_dup 1))])
3259 ;; Stores and loads of ax to arbitrary constant address.
3260 ;; We fake an second form of instruction to force reload to load address
3261 ;; into register when rax is not available
3262 (define_insn "*movabs<mode>_1"
3263 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
3264 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
3265 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
3267 /* Recover the full memory rtx. */
3268 operands[0] = SET_DEST (PATTERN (insn));
3269 switch (which_alternative)
3272 return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}";
3274 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
3279 [(set_attr "type" "imov")
3280 (set_attr "modrm" "0,*")
3281 (set_attr "length_address" "8,0")
3282 (set_attr "length_immediate" "0,*")
3283 (set_attr "memory" "store")
3284 (set_attr "mode" "<MODE>")])
3286 (define_insn "*movabs<mode>_2"
3287 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
3288 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
3289 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
3291 /* Recover the full memory rtx. */
3292 operands[1] = SET_SRC (PATTERN (insn));
3293 switch (which_alternative)
3296 return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}";
3298 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
3303 [(set_attr "type" "imov")
3304 (set_attr "modrm" "0,*")
3305 (set_attr "length_address" "8,0")
3306 (set_attr "length_immediate" "0")
3307 (set_attr "memory" "load")
3308 (set_attr "mode" "<MODE>")])
3310 (define_insn "swap<mode>"
3311 [(set (match_operand:SWI48 0 "register_operand" "+r")
3312 (match_operand:SWI48 1 "register_operand" "+r"))
3316 "xchg{<imodesuffix>}\t%1, %0"
3317 [(set_attr "type" "imov")
3318 (set_attr "mode" "<MODE>")
3319 (set_attr "pent_pair" "np")
3320 (set_attr "athlon_decode" "vector")
3321 (set_attr "amdfam10_decode" "double")
3322 (set_attr "bdver1_decode" "double")])
3324 (define_insn "*swap<mode>"
3325 [(set (match_operand:SWI12 0 "register_operand" "+<r>,r")
3326 (match_operand:SWI12 1 "register_operand" "+<r>,r"))
3331 xchg{<imodesuffix>}\t%1, %0
3333 [(set_attr "type" "imov")
3334 (set_attr "mode" "<MODE>,SI")
3335 (set (attr "preferred_for_size")
3336 (cond [(eq_attr "alternative" "0")
3337 (symbol_ref "false")]
3338 (symbol_ref "true")))
3339 ;; Potential partial reg stall on alternative 1.
3340 (set (attr "preferred_for_speed")
3341 (cond [(eq_attr "alternative" "1")
3342 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
3343 (symbol_ref "true")))
3344 (set_attr "pent_pair" "np")
3345 (set_attr "athlon_decode" "vector")
3346 (set_attr "amdfam10_decode" "double")
3347 (set_attr "bdver1_decode" "double")])
3350 [(set (match_operand:SWI 0 "general_reg_operand")
3351 (match_operand:SWI 1 "general_reg_operand"))
3353 (match_operand:SWI 2 "general_reg_operand"))
3354 (set (match_dup 2) (match_dup 0))]
3355 "peep2_reg_dead_p (3, operands[0])
3356 && optimize_insn_for_size_p ()"
3357 [(parallel [(set (match_dup 1) (match_dup 2))
3358 (set (match_dup 2) (match_dup 1))])])
3360 ;; Convert xchg with a REG_UNUSED note to a mov (variant #1).
3362 [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
3363 (match_operand:SWI 1 "general_reg_operand"))
3364 (set (match_dup 1) (match_dup 0))])]
3365 "((REGNO (operands[0]) != AX_REG
3366 && REGNO (operands[1]) != AX_REG)
3367 || optimize_size < 2
3368 || !optimize_insn_for_size_p ())
3369 && peep2_reg_dead_p (1, operands[0])"
3370 [(set (match_dup 1) (match_dup 0))])
3372 ;; Convert xchg with a REG_UNUSED note to a mov (variant #2).
3374 [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
3375 (match_operand:SWI 1 "general_reg_operand"))
3376 (set (match_dup 1) (match_dup 0))])]
3377 "((REGNO (operands[0]) != AX_REG
3378 && REGNO (operands[1]) != AX_REG)
3379 || optimize_size < 2
3380 || !optimize_insn_for_size_p ())
3381 && peep2_reg_dead_p (1, operands[1])"
3382 [(set (match_dup 0) (match_dup 1))])
3384 ;; Convert moves to/from AX_REG into xchg with -Oz.
3386 [(set (match_operand:SWI48 0 "general_reg_operand")
3387 (match_operand:SWI48 1 "general_reg_operand"))]
3389 && ((REGNO (operands[0]) == AX_REG)
3390 != (REGNO (operands[1]) == AX_REG))
3391 && optimize_insn_for_size_p ()
3392 && peep2_reg_dead_p (1, operands[1])"
3393 [(parallel [(set (match_dup 0) (match_dup 1))
3394 (set (match_dup 1) (match_dup 0))])])
3396 (define_expand "movstrict<mode>"
3397 [(set (strict_low_part (match_operand:SWI12 0 "register_operand"))
3398 (match_operand:SWI12 1 "general_operand"))]
3401 gcc_assert (SUBREG_P (operands[0]));
3402 if ((TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
3403 || !VALID_INT_MODE_P (GET_MODE (SUBREG_REG (operands[0]))))
3407 (define_insn "*movstrict<mode>_1"
3408 [(set (strict_low_part
3409 (match_operand:SWI12 0 "register_operand" "+<r>"))
3410 (match_operand:SWI12 1 "general_operand" "<r>mn"))]
3411 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
3412 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
3413 [(set_attr "type" "imov")
3414 (set_attr "mode" "<MODE>")])
3416 (define_insn "*movstrict<mode>_xor"
3417 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
3418 (match_operand:SWI12 1 "const0_operand"))
3419 (clobber (reg:CC FLAGS_REG))]
3421 "xor{<imodesuffix>}\t%0, %0"
3422 [(set_attr "type" "alu1")
3423 (set_attr "mode" "<MODE>")
3424 (set_attr "length_immediate" "0")])
3426 (define_insn "*movstrictqi_ext<mode>_1"
3427 [(set (strict_low_part
3428 (match_operand:QI 0 "register_operand" "+Q"))
3430 (match_operator:SWI248 2 "extract_operator"
3431 [(match_operand 1 "int248_register_operand" "Q")
3433 (const_int 8)]) 0))]
3434 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
3435 "mov{b}\t{%h1, %0|%0, %h1}"
3436 [(set_attr "type" "imov")
3437 (set_attr "mode" "QI")])
3439 (define_expand "extv<mode>"
3440 [(set (match_operand:SWI24 0 "register_operand")
3441 (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
3442 (match_operand:QI 2 "const_int_operand")
3443 (match_operand:QI 3 "const_int_operand")))]
3446 /* Handle extractions from %ah et al. */
3447 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
3450 unsigned int regno = reg_or_subregno (operands[1]);
3452 /* Be careful to expand only with registers having upper parts. */
3453 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3454 operands[1] = copy_to_reg (operands[1]);
3457 (define_insn "*extv<mode>"
3458 [(set (match_operand:SWI24 0 "register_operand" "=R")
3459 (sign_extract:SWI24 (match_operand 1 "int248_register_operand" "Q")
3463 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
3464 [(set_attr "type" "imovx")
3465 (set_attr "mode" "SI")])
3467 ;; Split sign-extension of single least significant bit as and x,$1;neg x
3468 (define_insn_and_split "*extv<mode>_1_0"
3469 [(set (match_operand:SWI48 0 "register_operand" "=r")
3470 (sign_extract:SWI48 (match_operand:SWI48 1 "register_operand" "0")
3473 (clobber (reg:CC FLAGS_REG))]
3477 [(parallel [(set (match_dup 0) (and:SWI48 (match_dup 1) (const_int 1)))
3478 (clobber (reg:CC FLAGS_REG))])
3479 (parallel [(set (match_dup 0) (neg:SWI48 (match_dup 0)))
3480 (clobber (reg:CC FLAGS_REG))])])
3482 (define_expand "extzv<mode>"
3483 [(set (match_operand:SWI248 0 "register_operand")
3484 (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
3485 (match_operand:QI 2 "const_int_operand")
3486 (match_operand:QI 3 "const_int_operand")))]
3489 if (ix86_expand_pextr (operands))
3492 /* Handle extractions from %ah et al. */
3493 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
3496 unsigned int regno = reg_or_subregno (operands[1]);
3498 /* Be careful to expand only with registers having upper parts. */
3499 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3500 operands[1] = copy_to_reg (operands[1]);
3503 (define_insn "*extzv<mode>"
3504 [(set (match_operand:SWI248 0 "register_operand" "=R")
3505 (zero_extract:SWI248 (match_operand 1 "int248_register_operand" "Q")
3509 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
3510 [(set_attr "type" "imovx")
3511 (set_attr "mode" "SI")])
3513 (define_insn "*extzvqi"
3514 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn,?R")
3516 (match_operator:SWI248 2 "extract_operator"
3517 [(match_operand 1 "int248_register_operand" "Q,Q")
3519 (const_int 8)]) 0))]
3522 switch (get_attr_type (insn))
3525 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
3527 return "mov{b}\t{%h1, %0|%0, %h1}";
3530 [(set_attr "addr" "gpr8,*")
3532 (if_then_else (and (match_operand:QI 0 "register_operand")
3533 (ior (not (match_operand:QI 0 "QIreg_operand"))
3534 (match_test "TARGET_MOVX")))
3535 (const_string "imovx")
3536 (const_string "imov")))
3538 (if_then_else (eq_attr "type" "imovx")
3540 (const_string "QI")))])
3542 (define_expand "insv<mode>"
3543 [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
3544 (match_operand:QI 1 "const_int_operand")
3545 (match_operand:QI 2 "const_int_operand"))
3546 (match_operand:SWI248 3 "register_operand"))]
3551 if (ix86_expand_pinsr (operands))
3554 /* Handle insertions to %ah et al. */
3555 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
3558 unsigned int regno = reg_or_subregno (operands[0]);
3560 /* Be careful to expand only with registers having upper parts. */
3561 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3562 dst = copy_to_reg (operands[0]);
3566 emit_insn (gen_insv_1 (<MODE>mode, dst, operands[3]));
3568 /* Fix up the destination if needed. */
3569 if (dst != operands[0])
3570 emit_move_insn (operands[0], dst);
3575 (define_insn "@insv<mode>_1"
3576 [(set (zero_extract:SWI248
3577 (match_operand 0 "int248_register_operand" "+Q")
3580 (match_operand:SWI248 1 "general_operand" "QnBn"))]
3583 if (CONST_INT_P (operands[1]))
3584 operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
3585 return "mov{b}\t{%b1, %h0|%h0, %b1}";
3587 [(set_attr "addr" "gpr8")
3588 (set_attr "type" "imov")
3589 (set_attr "mode" "QI")])
3591 (define_insn "*insvqi_1"
3592 [(set (zero_extract:SWI248
3593 (match_operand 0 "int248_register_operand" "+Q")
3597 (match_operand:QI 1 "general_operand" "QnBn") 0))]
3599 "mov{b}\t{%1, %h0|%h0, %1}"
3600 [(set_attr "addr" "gpr8")
3601 (set_attr "type" "imov")
3602 (set_attr "mode" "QI")])
3604 ;; Eliminate redundant insv, e.g. xorl %eax,%eax; movb $0, %ah
3606 [(parallel [(set (match_operand:SWI48 0 "general_reg_operand")
3608 (clobber (reg:CC FLAGS_REG))])
3609 (set (zero_extract:SWI248 (match_operand 1 "int248_register_operand")
3613 "REGNO (operands[0]) == REGNO (operands[1])"
3614 [(parallel [(set (match_operand:SWI48 0 "general_reg_operand")
3616 (clobber (reg:CC FLAGS_REG))])])
3618 ;; Combine movl followed by movb.
3620 [(set (match_operand:SWI48 0 "general_reg_operand")
3621 (match_operand:SWI48 1 "const_int_operand"))
3622 (set (zero_extract:SWI248 (match_operand 2 "int248_register_operand")
3625 (match_operand:SWI248 3 "const_int_operand"))]
3626 "REGNO (operands[0]) == REGNO (operands[2])"
3627 [(set (match_operand:SWI48 0 "general_reg_operand")
3630 HOST_WIDE_INT tmp = INTVAL (operands[1]) & ~HOST_WIDE_INT_C (0xff00);
3631 tmp |= (INTVAL (operands[3]) & 0xff) << 8;
3632 operands[4] = gen_int_mode (tmp, <SWI48:MODE>mode);
3635 (define_insn "*insvqi_2"
3636 [(set (zero_extract:SWI248
3637 (match_operand 0 "int248_register_operand" "+Q")
3640 (match_operator:SWI248 2 "extract_operator"
3641 [(match_operand 1 "int248_register_operand" "Q")
3645 "mov{b}\t{%h1, %h0|%h0, %h1}"
3646 [(set_attr "type" "imov")
3647 (set_attr "mode" "QI")])
3649 (define_insn "*insvqi_3"
3650 [(set (zero_extract:SWI248
3651 (match_operand 0 "int248_register_operand" "+Q")
3655 (match_operand:SWI248 1 "register_operand" "Q")
3658 "mov{b}\t{%h1, %h0|%h0, %h1}"
3659 [(set_attr "type" "imov")
3660 (set_attr "mode" "QI")])
3662 (define_code_iterator any_or_plus [plus ior xor])
3664 (define_insn_and_split "*insvti_highpart_1"
3665 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro,r,r,&r")
3668 (match_operand:TI 1 "nonimmediate_operand" "r,m,r,m")
3669 (match_operand:TI 3 "const_scalar_int_operand" "n,n,n,n"))
3672 (match_operand:DI 2 "nonimmediate_operand" "r,r,m,m"))
3675 && CONST_WIDE_INT_P (operands[3])
3676 && CONST_WIDE_INT_NUNITS (operands[3]) == 2
3677 && CONST_WIDE_INT_ELT (operands[3], 0) == -1
3678 && CONST_WIDE_INT_ELT (operands[3], 1) == 0"
3680 "&& reload_completed"
3683 operands[4] = gen_lowpart (DImode, operands[1]);
3684 split_double_concat (TImode, operands[0], operands[4], operands[2]);
3688 (define_insn_and_split "*insvti_lowpart_1"
3689 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro,r,r,&r")
3692 (match_operand:TI 1 "nonimmediate_operand" "r,o,r,o")
3693 (match_operand:TI 3 "const_scalar_int_operand" "n,n,n,n"))
3695 (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) == 0
3700 && CONST_WIDE_INT_ELT (operands[3], 1) == -1"
3702 "&& reload_completed"
3705 operands[4] = gen_highpart (DImode, operands[1]);
3706 split_double_concat (TImode, operands[0], operands[2], operands[4]);
3710 (define_insn_and_split "*insvdi_lowpart_1"
3711 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro,r,r,&r")
3714 (match_operand:DI 1 "nonimmediate_operand" "r,o,r,o")
3715 (match_operand:DI 3 "const_int_operand" "n,n,n,n"))
3717 (match_operand:SI 2 "nonimmediate_operand" "r,r,m,m"))))]
3719 && CONST_INT_P (operands[3])
3720 && UINTVAL (operands[3]) == 0xffffffff00000000ll"
3722 "&& reload_completed"
3725 operands[4] = gen_highpart (SImode, operands[1]);
3726 split_double_concat (DImode, operands[0], operands[2], operands[4]);
3730 ;; Floating point push instructions.
3732 (define_insn "*pushtf"
3733 [(set (match_operand:TF 0 "push_operand" "=<,<")
3734 (match_operand:TF 1 "general_no_elim_operand" "v,*roC"))]
3735 "TARGET_64BIT || TARGET_SSE"
3737 /* This insn should be already split before reg-stack. */
3740 [(set_attr "isa" "*,x64")
3741 (set_attr "type" "multi")
3742 (set_attr "unit" "sse,*")
3743 (set_attr "mode" "TF,DI")])
3745 ;; %%% Kill this when call knows how to work this out.
3747 [(set (match_operand:TF 0 "push_operand")
3748 (match_operand:TF 1 "sse_reg_operand"))]
3749 "TARGET_SSE && reload_completed"
3750 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3751 (set (match_dup 0) (match_dup 1))]
3753 /* Preserve memory attributes. */
3754 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3757 (define_insn "*pushxf"
3758 [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<")
3759 (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF,oC"))]
3762 /* This insn should be already split before reg-stack. */
3765 [(set_attr "isa" "*,*,*,nox64,x64")
3766 (set_attr "type" "multi")
3767 (set_attr "unit" "i387,*,*,*,*")
3769 (cond [(eq_attr "alternative" "1,2,3,4")
3770 (if_then_else (match_test "TARGET_64BIT")
3772 (const_string "SI"))
3774 (const_string "XF")))
3775 (set (attr "preferred_for_size")
3776 (cond [(eq_attr "alternative" "1")
3777 (symbol_ref "false")]
3778 (symbol_ref "true")))])
3780 ;; %%% Kill this when call knows how to work this out.
3782 [(set (match_operand:XF 0 "push_operand")
3783 (match_operand:XF 1 "fp_register_operand"))]
3785 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3786 (set (match_dup 0) (match_dup 1))]
3788 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (XFmode)));
3789 /* Preserve memory attributes. */
3790 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3793 (define_insn "*pushdf"
3794 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
3795 (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmC,v"))]
3798 /* This insn should be already split before reg-stack. */
3801 [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
3802 (set_attr "type" "multi")
3803 (set_attr "unit" "i387,*,*,*,*,sse")
3804 (set_attr "mode" "DF,SI,SI,SI,DI,DF")
3805 (set (attr "preferred_for_size")
3806 (cond [(eq_attr "alternative" "1")
3807 (symbol_ref "false")]
3808 (symbol_ref "true")))
3809 (set (attr "preferred_for_speed")
3810 (cond [(eq_attr "alternative" "1")
3811 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3812 (symbol_ref "true")))])
3814 ;; %%% Kill this when call knows how to work this out.
3816 [(set (match_operand:DF 0 "push_operand")
3817 (match_operand:DF 1 "any_fp_register_operand"))]
3819 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3820 (set (match_dup 0) (match_dup 1))]
3822 /* Preserve memory attributes. */
3823 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3826 (define_mode_iterator HFBF [HF BF])
3828 (define_insn "*push<mode>_rex64"
3829 [(set (match_operand:HFBF 0 "push_operand" "=X,X")
3830 (match_operand:HFBF 1 "nonmemory_no_elim_operand" "r,x"))]
3833 /* Anything else should be already split before reg-stack. */
3834 gcc_assert (which_alternative == 0);
3835 return "push{q}\t%q1";
3837 [(set_attr "isa" "*,sse4")
3838 (set_attr "type" "push,multi")
3839 (set_attr "mode" "DI,TI")])
3841 (define_insn "*push<mode>"
3842 [(set (match_operand:HFBF 0 "push_operand" "=X,X")
3843 (match_operand:HFBF 1 "general_no_elim_operand" "rmF,x"))]
3846 /* Anything else should be already split before reg-stack. */
3847 gcc_assert (which_alternative == 0);
3848 return "push{l}\t%k1";
3850 [(set_attr "isa" "*,sse4")
3851 (set_attr "type" "push,multi")
3852 (set_attr "mode" "SI,TI")])
3854 (define_insn "push2_di"
3855 [(set (match_operand:TI 0 "push_operand" "=<")
3856 (unspec:TI [(match_operand:DI 1 "register_operand" "r")
3857 (match_operand:DI 2 "register_operand" "r")]
3859 "TARGET_APX_PUSH2POP2"
3860 "push2\t{%2, %1|%1, %2}"
3861 [(set_attr "mode" "TI")
3862 (set_attr "type" "multi")
3863 (set_attr "prefix" "evex")])
3865 (define_insn "pop2_di"
3866 [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
3867 (unspec:DI [(match_operand:TI 1 "pop_operand" ">")]
3868 UNSPEC_APXPOP2_LOW))
3869 (set (match_operand:DI 2 "register_operand" "=r")
3870 (unspec:DI [(const_int 0)] UNSPEC_APXPOP2_HIGH))])]
3871 "TARGET_APX_PUSH2POP2"
3872 "pop2\t{%2, %0|%0, %2}"
3873 [(set_attr "mode" "TI")
3874 (set_attr "prefix" "evex")])
3876 (define_insn "pushp_di"
3877 [(set (match_operand:DI 0 "push_operand" "=<")
3878 (match_operand:DI 1 "register_operand" "r"))
3879 (unspec:DI [(const_int 0)] UNSPEC_APX_PPX)]
3882 [(set_attr "mode" "DI")])
3884 (define_insn "popp_di"
3885 [(set (match_operand:DI 0 "register_operand" "=r")
3886 (match_operand:DI 1 "pop_operand" ">"))
3887 (unspec:DI [(const_int 0)] UNSPEC_APX_PPX)]
3890 [(set_attr "mode" "DI")])
3892 (define_insn "push2p_di"
3893 [(set (match_operand:TI 0 "push_operand" "=<")
3894 (unspec:TI [(match_operand:DI 1 "register_operand" "r")
3895 (match_operand:DI 2 "register_operand" "r")]
3897 (unspec:DI [(const_int 0)] UNSPEC_APX_PPX)]
3898 "TARGET_APX_PUSH2POP2 && TARGET_APX_PPX"
3899 "push2p\t{%2, %1|%1, %2}"
3900 [(set_attr "mode" "TI")
3901 (set_attr "type" "multi")
3902 (set_attr "prefix" "evex")])
3904 (define_insn "pop2p_di"
3905 [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
3906 (unspec:DI [(match_operand:TI 1 "pop_operand" ">")]
3907 UNSPEC_APXPOP2_LOW))
3908 (set (match_operand:DI 2 "register_operand" "=r")
3909 (unspec:DI [(const_int 0)] UNSPEC_APXPOP2_HIGH))
3910 (unspec:DI [(const_int 0)] UNSPEC_APX_PPX)])]
3911 "TARGET_APX_PUSH2POP2 && TARGET_APX_PPX"
3912 "pop2p\t{%2, %0|%0, %2}"
3913 [(set_attr "mode" "TI")
3914 (set_attr "prefix" "evex")])
3916 (define_insn "*pushsf_rex64"
3917 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3918 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,v"))]
3921 /* Anything else should be already split before reg-stack. */
3922 if (which_alternative != 1)
3924 return "push{q}\t%q1";
3926 [(set_attr "type" "multi,push,multi")
3927 (set_attr "unit" "i387,*,*")
3928 (set_attr "mode" "SF,DI,SF")])
3930 (define_insn "*pushsf"
3931 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3932 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,v"))]
3935 /* Anything else should be already split before reg-stack. */
3936 if (which_alternative != 1)
3938 return "push{l}\t%1";
3940 [(set_attr "type" "multi,push,multi")
3941 (set_attr "unit" "i387,*,*")
3942 (set_attr "mode" "SF,SI,SF")])
3944 (define_mode_iterator MODESH [SF HF BF])
3945 ;; %%% Kill this when call knows how to work this out.
3947 [(set (match_operand:MODESH 0 "push_operand")
3948 (match_operand:MODESH 1 "any_fp_register_operand"))]
3950 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3951 (set (match_dup 0) (match_dup 1))]
3953 rtx op = XEXP (operands[0], 0);
3954 if (GET_CODE (op) == PRE_DEC)
3956 gcc_assert (!TARGET_64BIT);
3961 op = XEXP (XEXP (op, 1), 1);
3962 gcc_assert (CONST_INT_P (op));
3965 /* Preserve memory attributes. */
3966 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3970 [(set (match_operand:SF 0 "push_operand")
3971 (match_operand:SF 1 "memory_operand"))]
3973 && find_constant_src (insn)"
3974 [(set (match_dup 0) (match_dup 2))]
3975 "operands[2] = find_constant_src (curr_insn);")
3978 [(set (match_operand 0 "push_operand")
3979 (match_operand 1 "general_gr_operand"))]
3981 && (GET_MODE (operands[0]) == TFmode
3982 || GET_MODE (operands[0]) == XFmode
3983 || GET_MODE (operands[0]) == DFmode)"
3985 "ix86_split_long_move (operands); DONE;")
3987 ;; Floating point move instructions.
3989 (define_expand "movtf"
3990 [(set (match_operand:TF 0 "nonimmediate_operand")
3991 (match_operand:TF 1 "nonimmediate_operand"))]
3992 "TARGET_64BIT || TARGET_SSE"
3993 "ix86_expand_move (TFmode, operands); DONE;")
3995 (define_expand "mov<mode>"
3996 [(set (match_operand:X87MODEFH 0 "nonimmediate_operand")
3997 (match_operand:X87MODEFH 1 "general_operand"))]
3999 "ix86_expand_move (<MODE>mode, operands); DONE;")
4001 (define_insn "*movtf_internal"
4002 [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o")
4003 (match_operand:TF 1 "general_operand" "C ,vm,v,*roF,*rC"))]
4004 "(TARGET_64BIT || TARGET_SSE)
4005 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
4006 && (lra_in_progress || reload_completed
4007 || !CONST_DOUBLE_P (operands[1])
4008 || (standard_sse_constant_p (operands[1], TFmode) == 1
4009 && !memory_operand (operands[0], TFmode))
4010 || (!TARGET_MEMORY_MISMATCH_STALL
4011 && memory_operand (operands[0], TFmode)))"
4013 switch (get_attr_type (insn))
4016 return standard_sse_constant_opcode (insn, operands);
4019 return ix86_output_ssemov (insn, operands);
4028 [(set_attr "isa" "*,*,*,x64,x64")
4029 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
4030 (set (attr "prefix")
4031 (if_then_else (eq_attr "type" "sselog1,ssemov")
4032 (const_string "maybe_vex")
4033 (const_string "orig")))
4035 (cond [(eq_attr "alternative" "3,4")
4037 (match_test "TARGET_AVX")
4039 (ior (not (match_test "TARGET_SSE2"))
4040 (match_test "optimize_function_for_size_p (cfun)"))
4041 (const_string "V4SF")
4042 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
4043 (const_string "V4SF")
4044 (and (eq_attr "alternative" "2")
4045 (match_test "TARGET_SSE_TYPELESS_STORES"))
4046 (const_string "V4SF")
4048 (const_string "TI")))])
4051 [(set (match_operand:TF 0 "nonimmediate_gr_operand")
4052 (match_operand:TF 1 "general_gr_operand"))]
4055 "ix86_split_long_move (operands); DONE;")
4057 ;; Possible store forwarding (partial memory) stall
4058 ;; in alternatives 4, 6, 7 and 8.
4059 (define_insn "*movxf_internal"
4060 [(set (match_operand:XF 0 "nonimmediate_operand"
4061 "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r ,o ,o")
4062 (match_operand:XF 1 "general_operand"
4063 "fm,f,G,roF,r ,*roF,*r,F ,C ,roF,rF,rC"))]
4064 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
4065 && (lra_in_progress || reload_completed
4066 || !CONST_DOUBLE_P (operands[1])
4067 || ((optimize_function_for_size_p (cfun)
4068 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
4069 && standard_80387_constant_p (operands[1]) > 0
4070 && !memory_operand (operands[0], XFmode))
4071 || (!TARGET_MEMORY_MISMATCH_STALL
4072 && memory_operand (operands[0], XFmode))
4073 || !TARGET_HARD_XF_REGS)"
4075 switch (get_attr_type (insn))
4078 if (which_alternative == 2)
4079 return standard_80387_constant_opcode (operands[1]);
4080 return output_387_reg_move (insn, operands);
4090 (cond [(eq_attr "alternative" "7,10")
4091 (const_string "nox64")
4092 (eq_attr "alternative" "8,11")
4093 (const_string "x64")
4095 (const_string "*")))
4097 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
4098 (const_string "multi")
4100 (const_string "fmov")))
4102 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
4103 (if_then_else (match_test "TARGET_64BIT")
4105 (const_string "SI"))
4107 (const_string "XF")))
4108 (set (attr "preferred_for_size")
4109 (cond [(eq_attr "alternative" "3,4")
4110 (symbol_ref "false")]
4111 (symbol_ref "true")))
4112 (set (attr "enabled")
4113 (cond [(eq_attr "alternative" "9,10,11")
4115 (match_test "TARGET_HARD_XF_REGS")
4116 (symbol_ref "false")
4118 (not (match_test "TARGET_HARD_XF_REGS"))
4119 (symbol_ref "false")
4121 (const_string "*")))])
4124 [(set (match_operand:XF 0 "nonimmediate_gr_operand")
4125 (match_operand:XF 1 "general_gr_operand"))]
4128 "ix86_split_long_move (operands); DONE;")
4130 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
4131 (define_insn "*movdf_internal"
4132 [(set (match_operand:DF 0 "nonimmediate_operand"
4133 "=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")
4134 (match_operand:DF 1 "general_operand"
4135 "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"))]
4136 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
4137 && (lra_in_progress || reload_completed
4138 || !CONST_DOUBLE_P (operands[1])
4139 || ((optimize_function_for_size_p (cfun)
4140 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
4141 && IS_STACK_MODE (DFmode)
4142 && standard_80387_constant_p (operands[1]) > 0
4143 && !memory_operand (operands[0], DFmode))
4144 || (TARGET_SSE2 && TARGET_SSE_MATH
4145 && standard_sse_constant_p (operands[1], DFmode) == 1
4146 && !memory_operand (operands[0], DFmode))
4147 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
4148 && memory_operand (operands[0], DFmode))
4149 || !TARGET_HARD_DF_REGS)"
4151 switch (get_attr_type (insn))
4154 if (which_alternative == 2)
4155 return standard_80387_constant_opcode (operands[1]);
4156 return output_387_reg_move (insn, operands);
4162 if (get_attr_mode (insn) == MODE_SI)
4163 return "mov{l}\t{%1, %k0|%k0, %1}";
4164 else if (which_alternative == 11)
4165 return "movabs{q}\t{%1, %0|%0, %1}";
4167 return "mov{q}\t{%1, %0|%0, %1}";
4170 return standard_sse_constant_opcode (insn, operands);
4173 return ix86_output_ssemov (insn, operands);
4180 (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
4181 (const_string "nox64")
4182 (eq_attr "alternative" "8,9,10,11,24,25")
4183 (const_string "x64")
4184 (eq_attr "alternative" "12,13,14,15")
4185 (const_string "sse2")
4186 (eq_attr "alternative" "20,21")
4187 (const_string "x64_sse2")
4189 (const_string "*")))
4191 (cond [(eq_attr "alternative" "0,1,2")
4192 (const_string "fmov")
4193 (eq_attr "alternative" "3,4,5,6,7,22,23")
4194 (const_string "multi")
4195 (eq_attr "alternative" "8,9,10,11,24,25")
4196 (const_string "imov")
4197 (eq_attr "alternative" "12,16")
4198 (const_string "sselog1")
4200 (const_string "ssemov")))
4202 (if_then_else (eq_attr "alternative" "11")
4204 (const_string "*")))
4205 (set (attr "length_immediate")
4206 (if_then_else (eq_attr "alternative" "11")
4208 (const_string "*")))
4209 (set (attr "prefix")
4210 (if_then_else (eq_attr "type" "sselog1,ssemov")
4211 (const_string "maybe_vex")
4212 (const_string "orig")))
4213 (set (attr "prefix_data16")
4215 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
4216 (eq_attr "mode" "V1DF"))
4218 (const_string "*")))
4220 (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
4222 (eq_attr "alternative" "8,9,11,20,21,24,25")
4225 /* xorps is one byte shorter for non-AVX targets. */
4226 (eq_attr "alternative" "12,16")
4227 (cond [(match_test "TARGET_AVX")
4228 (const_string "V2DF")
4229 (ior (not (match_test "TARGET_SSE2"))
4230 (match_test "optimize_function_for_size_p (cfun)"))
4231 (const_string "V4SF")
4232 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
4235 (const_string "V2DF"))
4237 /* For architectures resolving dependencies on
4238 whole SSE registers use movapd to break dependency
4239 chains, otherwise use short move to avoid extra work. */
4241 /* movaps is one byte shorter for non-AVX targets. */
4242 (eq_attr "alternative" "13,17")
4243 (cond [(match_test "TARGET_AVX512VL")
4244 (const_string "V2DF")
4245 (match_test "TARGET_AVX512F")
4247 (match_test "TARGET_AVX")
4248 (const_string "V2DF")
4249 (ior (not (match_test "TARGET_SSE2"))
4250 (match_test "optimize_function_for_size_p (cfun)"))
4251 (const_string "V4SF")
4252 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
4253 (const_string "V4SF")
4254 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
4255 (const_string "V2DF")
4257 (const_string "DF"))
4259 /* For architectures resolving dependencies on register
4260 parts we may avoid extra work to zero out upper part
4262 (eq_attr "alternative" "14,18")
4263 (cond [(not (match_test "TARGET_SSE2"))
4264 (const_string "V2SF")
4265 (match_test "TARGET_AVX")
4267 (match_test "TARGET_SSE_SPLIT_REGS")
4268 (const_string "V1DF")
4270 (const_string "DF"))
4272 (and (eq_attr "alternative" "15,19")
4273 (not (match_test "TARGET_SSE2")))
4274 (const_string "V2SF")
4276 (const_string "DF")))
4277 (set (attr "preferred_for_size")
4278 (cond [(eq_attr "alternative" "3,4")
4279 (symbol_ref "false")]
4280 (symbol_ref "true")))
4281 (set (attr "preferred_for_speed")
4282 (cond [(eq_attr "alternative" "3,4")
4283 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")
4284 (eq_attr "alternative" "20")
4285 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4286 (eq_attr "alternative" "21")
4287 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4289 (symbol_ref "true")))
4290 (set (attr "enabled")
4291 (cond [(eq_attr "alternative" "22,23,24,25")
4293 (match_test "TARGET_HARD_DF_REGS")
4294 (symbol_ref "false")
4296 (not (match_test "TARGET_HARD_DF_REGS"))
4297 (symbol_ref "false")
4299 (const_string "*")))])
4302 [(set (match_operand:DF 0 "nonimmediate_gr_operand")
4303 (match_operand:DF 1 "general_gr_operand"))]
4304 "!TARGET_64BIT && reload_completed"
4306 "ix86_split_long_move (operands); DONE;")
4308 (define_insn "*movsf_internal"
4309 [(set (match_operand:SF 0 "nonimmediate_operand"
4310 "=Yf*f,m ,Yf*f,?r ,?m,Yv,v,v,m,?r,?v,!*y,!*y,!m,!r,!*y,r ,m")
4311 (match_operand:SF 1 "general_operand"
4312 "Yf*fm,Yf*f,G ,rmF,rF,C ,v,m,v,v ,r ,*y ,m ,*y,*y,r ,rmF,rF"))]
4313 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
4314 && (lra_in_progress || reload_completed
4315 || !CONST_DOUBLE_P (operands[1])
4316 || ((optimize_function_for_size_p (cfun)
4317 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
4318 && IS_STACK_MODE (SFmode)
4319 && standard_80387_constant_p (operands[1]) > 0)
4320 || (TARGET_SSE && TARGET_SSE_MATH
4321 && standard_sse_constant_p (operands[1], SFmode) == 1)
4322 || memory_operand (operands[0], SFmode)
4323 || !TARGET_HARD_SF_REGS)"
4325 switch (get_attr_type (insn))
4328 if (which_alternative == 2)
4329 return standard_80387_constant_opcode (operands[1]);
4330 return output_387_reg_move (insn, operands);
4333 return "mov{l}\t{%1, %0|%0, %1}";
4336 return standard_sse_constant_opcode (insn, operands);
4339 return ix86_output_ssemov (insn, operands);
4342 switch (get_attr_mode (insn))
4345 return "movq\t{%1, %0|%0, %1}";
4347 return "movd\t{%1, %0|%0, %1}";
4358 (cond [(eq_attr "alternative" "9,10")
4359 (const_string "sse2")
4361 (const_string "*")))
4363 (cond [(eq_attr "alternative" "0,1,2")
4364 (const_string "fmov")
4365 (eq_attr "alternative" "3,4,16,17")
4366 (const_string "imov")
4367 (eq_attr "alternative" "5")
4368 (const_string "sselog1")
4369 (eq_attr "alternative" "11,12,13,14,15")
4370 (const_string "mmxmov")
4372 (const_string "ssemov")))
4373 (set (attr "prefix")
4374 (if_then_else (eq_attr "type" "sselog1,ssemov")
4375 (const_string "maybe_vex")
4376 (const_string "orig")))
4377 (set (attr "prefix_data16")
4378 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
4380 (const_string "*")))
4382 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
4384 (eq_attr "alternative" "11")
4386 (eq_attr "alternative" "5")
4387 (cond [(and (match_test "TARGET_AVX512F && TARGET_EVEX512")
4388 (not (match_test "TARGET_PREFER_AVX256")))
4389 (const_string "V16SF")
4390 (match_test "TARGET_AVX")
4391 (const_string "V4SF")
4392 (ior (not (match_test "TARGET_SSE2"))
4393 (match_test "optimize_function_for_size_p (cfun)"))
4394 (const_string "V4SF")
4395 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
4398 (const_string "V4SF"))
4400 /* For architectures resolving dependencies on
4401 whole SSE registers use APS move to break dependency
4402 chains, otherwise use short move to avoid extra work.
4404 Do the same for architectures resolving dependencies on
4405 the parts. While in DF mode it is better to always handle
4406 just register parts, the SF mode is different due to lack
4407 of instructions to load just part of the register. It is
4408 better to maintain the whole registers in single format
4409 to avoid problems on using packed logical operations. */
4410 (eq_attr "alternative" "6")
4411 (cond [(match_test "TARGET_AVX512VL")
4412 (const_string "V4SF")
4413 (match_test "TARGET_AVX512F")
4415 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
4416 (match_test "TARGET_SSE_SPLIT_REGS"))
4417 (const_string "V4SF")
4419 (const_string "SF"))
4421 (const_string "SF")))
4422 (set (attr "preferred_for_speed")
4423 (cond [(eq_attr "alternative" "9,14")
4424 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4425 (eq_attr "alternative" "10,15")
4426 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4428 (symbol_ref "true")))
4429 (set (attr "enabled")
4430 (cond [(eq_attr "alternative" "16,17")
4432 (match_test "TARGET_HARD_SF_REGS")
4433 (symbol_ref "false")
4435 (not (match_test "TARGET_HARD_SF_REGS"))
4436 (symbol_ref "false")
4438 (const_string "*")))])
4440 (define_mode_attr hfbfconstf
4443 (define_insn "*mov<mode>_internal"
4444 [(set (match_operand:HFBF 0 "nonimmediate_operand"
4445 "=?r,?r,?r,?m ,Yv,v,?r,jm,m,?v,v")
4446 (match_operand:HFBF 1 "general_operand"
4447 "r ,F ,m ,r<hfbfconstf>,C ,v, v,v ,v,r ,m"))]
4448 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
4451 || !CONST_DOUBLE_P (operands[1])
4453 && standard_sse_constant_p (operands[1], <MODE>mode) == 1)
4454 || memory_operand (operands[0], <MODE>mode))"
4456 switch (get_attr_type (insn))
4459 /* movzwl is faster than movw on p2 due to partial word stalls,
4460 though not as fast as an aligned movl. */
4461 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
4464 return ix86_output_ssemov (insn, operands);
4467 if (satisfies_constraint_C (operands[1]))
4468 return standard_sse_constant_opcode (insn, operands);
4470 if (SSE_REG_P (operands[0]))
4471 return "%vpinsrw\t{$0, %1, %d0|%d0, %1, 0}";
4473 return "%vpextrw\t{$0, %1, %0|%0, %1, 0}";
4476 if (get_attr_mode (insn) == MODE_SI)
4477 return "mov{l}\t{%k1, %k0|%k0, %k1}";
4479 return "mov{w}\t{%1, %0|%0, %1}";
4483 (cond [(eq_attr "alternative" "4,5,6,9,10")
4484 (const_string "sse2")
4485 (eq_attr "alternative" "7")
4486 (const_string "sse4_noavx")
4487 (eq_attr "alternative" "8")
4488 (const_string "avx")
4490 (const_string "*")))
4492 (if_then_else (eq_attr "alternative" "7")
4493 (const_string "gpr16")
4494 (const_string "*")))
4496 (cond [(eq_attr "alternative" "4")
4497 (const_string "sselog1")
4498 (eq_attr "alternative" "5,6,9")
4499 (const_string "ssemov")
4500 (eq_attr "alternative" "7,8,10")
4502 (match_test ("TARGET_AVX512FP16"))
4503 (const_string "ssemov")
4504 (const_string "sselog1"))
4505 (match_test "optimize_function_for_size_p (cfun)")
4506 (const_string "imov")
4507 (and (eq_attr "alternative" "0")
4508 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
4509 (not (match_test "TARGET_HIMODE_MATH"))))
4510 (const_string "imov")
4511 (and (eq_attr "alternative" "1,2")
4512 (match_operand:HI 1 "aligned_operand"))
4513 (const_string "imov")
4514 (and (match_test "TARGET_MOVX")
4515 (eq_attr "alternative" "0,2"))
4516 (const_string "imovx")
4518 (const_string "imov")))
4519 (set (attr "prefix")
4520 (cond [(eq_attr "alternative" "4,5,6,7,8,9,10")
4521 (const_string "maybe_vex")
4523 (const_string "orig")))
4525 (cond [(eq_attr "alternative" "4")
4526 (const_string "V4SF")
4527 (eq_attr "alternative" "6,9")
4529 (match_test "TARGET_AVX512FP16")
4531 (const_string "SI"))
4532 (eq_attr "alternative" "7,8,10")
4534 (match_test "TARGET_AVX512FP16")
4536 (const_string "TI"))
4537 (eq_attr "alternative" "5")
4538 (cond [(match_test "TARGET_AVX512VL")
4539 (const_string "V4SF")
4540 (match_test "TARGET_AVX512FP16")
4542 (match_test "TARGET_AVX512F")
4544 (match_test "TARGET_AVX")
4545 (const_string "V4SF")
4546 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
4547 (match_test "TARGET_SSE_SPLIT_REGS"))
4548 (const_string "V4SF")
4550 (const_string "SF"))
4551 (eq_attr "type" "imovx")
4553 (and (eq_attr "alternative" "1,2")
4554 (match_operand:HI 1 "aligned_operand"))
4556 (and (eq_attr "alternative" "0")
4557 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
4558 (not (match_test "TARGET_HIMODE_MATH"))))
4561 (const_string "HI")))
4562 (set (attr "enabled")
4563 (cond [(and (match_test "<MODE>mode == BFmode")
4564 (eq_attr "alternative" "1"))
4565 (symbol_ref "false")
4567 (const_string "*")))])
4570 [(set (match_operand 0 "any_fp_register_operand")
4571 (match_operand 1 "memory_operand"))]
4573 && (GET_MODE (operands[0]) == TFmode
4574 || GET_MODE (operands[0]) == XFmode
4575 || GET_MODE (operands[0]) == DFmode
4576 || GET_MODE (operands[0]) == SFmode)
4577 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
4578 [(set (match_dup 0) (match_dup 2))]
4579 "operands[2] = find_constant_src (curr_insn);")
4582 [(set (match_operand 0 "any_fp_register_operand")
4583 (float_extend (match_operand 1 "memory_operand")))]
4585 && (GET_MODE (operands[0]) == TFmode
4586 || GET_MODE (operands[0]) == XFmode
4587 || GET_MODE (operands[0]) == DFmode)
4588 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
4589 [(set (match_dup 0) (match_dup 2))]
4590 "operands[2] = find_constant_src (curr_insn);")
4592 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
4594 [(set (match_operand:X87MODEF 0 "fp_register_operand")
4595 (match_operand:X87MODEF 1 "immediate_operand"))]
4597 && (standard_80387_constant_p (operands[1]) == 8
4598 || standard_80387_constant_p (operands[1]) == 9)"
4599 [(set (match_dup 0)(match_dup 1))
4601 (neg:X87MODEF (match_dup 0)))]
4603 if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
4604 operands[1] = CONST0_RTX (<MODE>mode);
4606 operands[1] = CONST1_RTX (<MODE>mode);
4609 (define_insn "*swapxf"
4610 [(set (match_operand:XF 0 "register_operand" "+f")
4611 (match_operand:XF 1 "register_operand" "+f"))
4616 if (STACK_TOP_P (operands[0]))
4621 [(set_attr "type" "fxch")
4622 (set_attr "mode" "XF")])
4625 ;; Zero extension instructions
4627 (define_insn_and_split "zero_extendditi2"
4628 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4629 (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "rm,r")))]
4632 "&& reload_completed"
4633 [(set (match_dup 3) (match_dup 1))
4634 (set (match_dup 4) (const_int 0))]
4635 "split_double_mode (TImode, &operands[0], 1, &operands[3], &operands[4]);")
4637 (define_expand "zero_extendsidi2"
4638 [(set (match_operand:DI 0 "nonimmediate_operand")
4639 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
4641 (define_insn "*zero_extendsidi2"
4642 [(set (match_operand:DI 0 "nonimmediate_operand"
4643 "=r,?r,?o,r ,o,?*y,?!*y,$r,$v,$x,*x,*v,?r,?k")
4645 (match_operand:SI 1 "x86_64_zext_operand"
4646 "0 ,rm,r ,rmWz,0,r ,m ,v ,r ,m ,*x,*v,?k,?km")))]
4649 switch (get_attr_type (insn))
4652 if (ix86_use_lea_for_mov (insn, operands))
4653 return "lea{l}\t{%E1, %k0|%k0, %E1}";
4655 return "mov{l}\t{%1, %k0|%k0, %1}";
4661 return "movd\t{%1, %0|%0, %1}";
4664 if (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1]))
4666 if (EXT_REX_SSE_REG_P (operands[0])
4667 || EXT_REX_SSE_REG_P (operands[1]))
4668 return "vpmovzxdq\t{%t1, %g0|%g0, %t1}";
4670 return "%vpmovzxdq\t{%1, %0|%0, %1}";
4673 if (GENERAL_REG_P (operands[0]))
4674 return "%vmovd\t{%1, %k0|%k0, %1}";
4676 return "%vmovd\t{%1, %0|%0, %1}";
4679 return "kmovd\t{%1, %k0|%k0, %1}";
4686 (cond [(eq_attr "alternative" "0,1,2")
4687 (const_string "nox64")
4688 (eq_attr "alternative" "3")
4689 (const_string "x64")
4690 (eq_attr "alternative" "7,8,9")
4691 (const_string "sse2")
4692 (eq_attr "alternative" "10")
4693 (const_string "sse4")
4694 (eq_attr "alternative" "11")
4695 (const_string "avx512f")
4696 (eq_attr "alternative" "12")
4697 (const_string "x64_avx512bw")
4698 (eq_attr "alternative" "13")
4699 (const_string "avx512bw")
4701 (const_string "*")))
4702 (set (attr "mmx_isa")
4703 (if_then_else (eq_attr "alternative" "5,6")
4704 (const_string "native")
4705 (const_string "*")))
4707 (cond [(eq_attr "alternative" "0,1,2,4")
4708 (const_string "multi")
4709 (eq_attr "alternative" "5,6")
4710 (const_string "mmxmov")
4711 (eq_attr "alternative" "7")
4712 (if_then_else (match_test "TARGET_64BIT")
4713 (const_string "ssemov")
4714 (const_string "multi"))
4715 (eq_attr "alternative" "8,9,10,11")
4716 (const_string "ssemov")
4717 (eq_attr "alternative" "12,13")
4718 (const_string "mskmov")
4720 (const_string "imovx")))
4721 (set (attr "prefix_extra")
4722 (if_then_else (eq_attr "alternative" "10,11")
4724 (const_string "*")))
4725 (set (attr "prefix")
4726 (if_then_else (eq_attr "type" "ssemov")
4727 (const_string "maybe_vex")
4728 (const_string "orig")))
4729 (set (attr "prefix_0f")
4730 (if_then_else (eq_attr "type" "imovx")
4732 (const_string "*")))
4734 (cond [(eq_attr "alternative" "5,6")
4736 (and (eq_attr "alternative" "7")
4737 (match_test "TARGET_64BIT"))
4739 (eq_attr "alternative" "8,10,11")
4742 (const_string "SI")))
4743 (set (attr "preferred_for_speed")
4744 (cond [(eq_attr "alternative" "7")
4745 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4746 (eq_attr "alternative" "5,8")
4747 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4749 (symbol_ref "true")))])
4752 [(set (match_operand:DI 0 "memory_operand")
4753 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
4755 [(set (match_dup 4) (const_int 0))]
4756 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4759 [(set (match_operand:DI 0 "general_reg_operand")
4760 (zero_extend:DI (match_operand:SI 1 "general_reg_operand")))]
4761 "!TARGET_64BIT && reload_completed
4762 && REGNO (operands[0]) == REGNO (operands[1])"
4763 [(set (match_dup 4) (const_int 0))]
4764 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4767 [(set (match_operand:DI 0 "nonimmediate_gr_operand")
4768 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
4769 "!TARGET_64BIT && reload_completed
4770 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
4771 [(set (match_dup 3) (match_dup 1))
4772 (set (match_dup 4) (const_int 0))]
4773 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4775 (define_mode_attr kmov_isa
4776 [(QI "avx512dq") (HI "avx512f") (SI "avx512bw") (DI "avx512bw")])
4778 (define_insn "zero_extend<mode>di2"
4779 [(set (match_operand:DI 0 "register_operand" "=r,?r,?k")
4781 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,?k,?km")))]
4784 movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}
4785 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}
4786 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}"
4787 [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
4788 (set_attr "type" "imovx,mskmov,mskmov")
4789 (set_attr "mode" "SI,<MODE>,<MODE>")])
4791 (define_expand "zero_extend<mode>si2"
4792 [(set (match_operand:SI 0 "register_operand")
4793 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
4796 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4798 operands[1] = force_reg (<MODE>mode, operands[1]);
4799 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
4804 (define_insn_and_split "zero_extend<mode>si2_and"
4805 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
4807 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
4808 (clobber (reg:CC FLAGS_REG))]
4809 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4811 "&& reload_completed"
4812 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
4813 (clobber (reg:CC FLAGS_REG))])]
4815 if (!REG_P (operands[1])
4816 || REGNO (operands[0]) != REGNO (operands[1]))
4818 ix86_expand_clear (operands[0]);
4820 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4821 emit_insn (gen_rtx_SET
4822 (gen_rtx_STRICT_LOW_PART
4823 (VOIDmode, gen_lowpart (<MODE>mode, operands[0])),
4828 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
4830 [(set_attr "type" "alu1")
4831 (set_attr "mode" "SI")])
4833 (define_insn "*zero_extend<mode>si2"
4834 [(set (match_operand:SI 0 "register_operand" "=r,?r,?k")
4836 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,?k,?km")))]
4837 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4839 movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}
4840 kmov<mskmodesuffix>\t{%1, %0|%0, %1}
4841 kmov<mskmodesuffix>\t{%1, %0|%0, %1}"
4842 [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
4843 (set_attr "type" "imovx,mskmov,mskmov")
4844 (set_attr "mode" "SI,<MODE>,<MODE>")])
4846 (define_expand "zero_extendqihi2"
4847 [(set (match_operand:HI 0 "register_operand")
4848 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
4851 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4853 operands[1] = force_reg (QImode, operands[1]);
4854 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
4859 (define_insn_and_split "zero_extendqihi2_and"
4860 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
4861 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4862 (clobber (reg:CC FLAGS_REG))]
4863 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4865 "&& reload_completed"
4866 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4867 (clobber (reg:CC FLAGS_REG))])]
4869 if (!REG_P (operands[1])
4870 || REGNO (operands[0]) != REGNO (operands[1]))
4872 ix86_expand_clear (operands[0]);
4874 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4875 emit_insn (gen_rtx_SET
4876 (gen_rtx_STRICT_LOW_PART
4877 (VOIDmode, gen_lowpart (QImode, operands[0])),
4882 operands[0] = gen_lowpart (SImode, operands[0]);
4884 [(set_attr "type" "alu1")
4885 (set_attr "mode" "SI")])
4887 ; zero extend to SImode to avoid partial register stalls
4888 (define_insn "*zero_extendqihi2"
4889 [(set (match_operand:HI 0 "register_operand" "=r,?r,?k")
4890 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,?k,?km")))]
4891 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4893 movz{bl|x}\t{%1, %k0|%k0, %1}
4894 kmovb\t{%1, %k0|%k0, %1}
4895 kmovb\t{%1, %0|%0, %1}"
4896 [(set_attr "isa" "*,avx512dq,avx512dq")
4897 (set_attr "type" "imovx,mskmov,mskmov")
4898 (set_attr "mode" "SI,QI,QI")])
4900 ;; Transform xorl; mov[bw] (set strict_low_part) into movz[bw]l.
4902 [(parallel [(set (match_operand:SWI48 0 "general_reg_operand")
4904 (clobber (reg:CC FLAGS_REG))])
4905 (set (strict_low_part (match_operand:SWI12 1 "general_reg_operand"))
4906 (match_operand:SWI12 2 "nonimmediate_operand"))]
4907 "REGNO (operands[0]) == REGNO (operands[1])
4908 && (<SWI48:MODE>mode != SImode
4909 || !TARGET_ZERO_EXTEND_WITH_AND
4910 || !optimize_function_for_speed_p (cfun))"
4911 [(set (match_dup 0) (zero_extend:SWI48 (match_dup 2)))])
4913 ;; Likewise, but preserving FLAGS_REG.
4915 [(set (match_operand:SWI48 0 "general_reg_operand") (const_int 0))
4916 (set (strict_low_part (match_operand:SWI12 1 "general_reg_operand"))
4917 (match_operand:SWI12 2 "nonimmediate_operand"))]
4918 "REGNO (operands[0]) == REGNO (operands[1])
4919 && (<SWI48:MODE>mode != SImode
4920 || !TARGET_ZERO_EXTEND_WITH_AND
4921 || !optimize_function_for_speed_p (cfun))"
4922 [(set (match_dup 0) (zero_extend:SWI48 (match_dup 2)))])
4924 ;; Sign extension instructions
4926 (define_expand "extendsidi2"
4927 [(set (match_operand:DI 0 "register_operand")
4928 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
4933 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
4938 (define_insn "*extendsidi2_rex64"
4939 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4940 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4944 movs{lq|x}\t{%1, %0|%0, %1}"
4945 [(set_attr "type" "imovx")
4946 (set_attr "mode" "DI")
4947 (set_attr "prefix_0f" "0")
4948 (set_attr "modrm" "0,1")])
4950 (define_insn "extendsidi2_1"
4951 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4952 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4953 (clobber (reg:CC FLAGS_REG))
4954 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4958 (define_insn "extendditi2"
4959 [(set (match_operand:TI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4960 (sign_extend:TI (match_operand:DI 1 "register_operand" "0,0,r,r")))
4961 (clobber (reg:CC FLAGS_REG))
4962 (clobber (match_scratch:DI 2 "=X,X,X,&r"))]
4966 ;; Split the memory case. If the source register doesn't die, it will stay
4967 ;; this way, if it does die, following peephole2s take care of it.
4969 [(set (match_operand:<DWI> 0 "memory_operand")
4970 (sign_extend:<DWI> (match_operand:DWIH 1 "register_operand")))
4971 (clobber (reg:CC FLAGS_REG))
4972 (clobber (match_operand:DWIH 2 "register_operand"))]
4976 rtx bits = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
4978 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
4980 emit_move_insn (operands[3], operands[1]);
4982 /* Generate a cltd if possible and doing so it profitable. */
4983 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4984 && REGNO (operands[1]) == AX_REG
4985 && REGNO (operands[2]) == DX_REG)
4987 emit_insn (gen_ashr<mode>3_cvt (operands[2], operands[1], bits));
4991 emit_move_insn (operands[2], operands[1]);
4992 emit_insn (gen_ashr<mode>3_cvt (operands[2], operands[2], bits));
4994 emit_move_insn (operands[4], operands[2]);
4998 ;; Peepholes for the case where the source register does die, after
4999 ;; being split with the above splitter.
5001 [(set (match_operand:DWIH 0 "memory_operand")
5002 (match_operand:DWIH 1 "general_reg_operand"))
5003 (set (match_operand:DWIH 2 "general_reg_operand") (match_dup 1))
5004 (parallel [(set (match_dup 2)
5005 (ashiftrt:DWIH (match_dup 2)
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 "REGNO (operands[1]) != REGNO (operands[2])
5010 && INTVAL (operands[4]) == (<MODE_SIZE> * BITS_PER_UNIT - 1)
5011 && peep2_reg_dead_p (2, operands[1])
5012 && peep2_reg_dead_p (4, operands[2])
5013 && !reg_mentioned_p (operands[2], operands[3])"
5014 [(set (match_dup 0) (match_dup 1))
5015 (parallel [(set (match_dup 1) (ashiftrt:DWIH (match_dup 1) (match_dup 4)))
5016 (clobber (reg:CC FLAGS_REG))])
5017 (set (match_dup 3) (match_dup 1))])
5020 [(set (match_operand:DWIH 0 "memory_operand")
5021 (match_operand:DWIH 1 "general_reg_operand"))
5022 (parallel [(set (match_operand:DWIH 2 "general_reg_operand")
5023 (ashiftrt:DWIH (match_dup 1)
5024 (match_operand 4 "const_int_operand")))
5025 (clobber (reg:CC FLAGS_REG))])
5026 (set (match_operand:DWIH 3 "memory_operand") (match_dup 2))]
5027 "/* cltd is shorter than sarl $31, %eax */
5028 !optimize_function_for_size_p (cfun)
5029 && REGNO (operands[1]) == AX_REG
5030 && REGNO (operands[2]) == DX_REG
5031 && INTVAL (operands[4]) == (<MODE_SIZE> * BITS_PER_UNIT - 1)
5032 && peep2_reg_dead_p (2, operands[1])
5033 && peep2_reg_dead_p (3, operands[2])
5034 && !reg_mentioned_p (operands[2], operands[3])"
5035 [(set (match_dup 0) (match_dup 1))
5036 (parallel [(set (match_dup 1) (ashiftrt:DWIH (match_dup 1) (match_dup 4)))
5037 (clobber (reg:CC FLAGS_REG))])
5038 (set (match_dup 3) (match_dup 1))])
5040 ;; Extend to register case. Optimize case where source and destination
5041 ;; registers match and cases where we can use cltd.
5043 [(set (match_operand:<DWI> 0 "register_operand")
5044 (sign_extend:<DWI> (match_operand:DWIH 1 "register_operand")))
5045 (clobber (reg:CC FLAGS_REG))
5046 (clobber (match_scratch:DWIH 2))]
5050 rtx bits = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
5052 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
5054 if (REGNO (operands[3]) != REGNO (operands[1]))
5055 emit_move_insn (operands[3], operands[1]);
5057 rtx src = operands[1];
5058 if (REGNO (operands[3]) == AX_REG)
5061 /* Generate a cltd if possible and doing so it profitable. */
5062 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
5063 && REGNO (src) == AX_REG
5064 && REGNO (operands[4]) == DX_REG)
5066 emit_insn (gen_ashr<mode>3_cvt (operands[4], src, bits));
5070 if (REGNO (operands[4]) != REGNO (operands[1]))
5071 emit_move_insn (operands[4], operands[1]);
5073 emit_insn (gen_ashr<mode>3_cvt (operands[4], operands[4], bits));
5078 [(set (match_operand:DI 0 "general_reg_operand")
5079 (match_operand:DI 1 "general_reg_operand"))
5080 (parallel [(set (match_dup 0)
5081 (ashiftrt:DI (match_dup 0)
5083 (clobber (reg:CC FLAGS_REG))])
5084 (set (match_operand:DI 2 "general_reg_operand") (match_dup 1))
5085 (set (match_operand:DI 3 "general_reg_operand") (match_dup 0))]
5086 "(optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
5087 && REGNO (operands[2]) == AX_REG
5088 && REGNO (operands[3]) == DX_REG
5089 && peep2_reg_dead_p (4, operands[0])
5090 && !reg_mentioned_p (operands[0], operands[1])
5091 && !reg_mentioned_p (operands[2], operands[0])"
5092 [(set (match_dup 2) (match_dup 1))
5093 (parallel [(set (match_dup 3) (ashiftrt:DI (match_dup 2) (const_int 63)))
5094 (clobber (reg:CC FLAGS_REG))])])
5096 (define_insn "extend<mode>di2"
5097 [(set (match_operand:DI 0 "register_operand" "=r")
5099 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
5101 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
5102 [(set_attr "type" "imovx")
5103 (set_attr "mode" "DI")])
5105 (define_insn "extendhisi2"
5106 [(set (match_operand:SI 0 "register_operand" "=*a,r")
5107 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
5110 switch (get_attr_prefix_0f (insn))
5113 return "{cwtl|cwde}";
5115 return "movs{wl|x}\t{%1, %0|%0, %1}";
5118 [(set_attr "type" "imovx")
5119 (set_attr "mode" "SI")
5120 (set (attr "prefix_0f")
5121 ;; movsx is short decodable while cwtl is vector decoded.
5122 (if_then_else (and (eq_attr "cpu" "!k6")
5123 (eq_attr "alternative" "0"))
5125 (const_string "1")))
5126 (set (attr "znver1_decode")
5127 (if_then_else (eq_attr "prefix_0f" "0")
5128 (const_string "double")
5129 (const_string "direct")))
5131 (if_then_else (eq_attr "prefix_0f" "0")
5133 (const_string "1")))])
5135 (define_insn "*extendhisi2_zext"
5136 [(set (match_operand:DI 0 "register_operand" "=*a,r")
5139 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
5142 switch (get_attr_prefix_0f (insn))
5145 return "{cwtl|cwde}";
5147 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
5150 [(set_attr "type" "imovx")
5151 (set_attr "mode" "SI")
5152 (set (attr "prefix_0f")
5153 ;; movsx is short decodable while cwtl is vector decoded.
5154 (if_then_else (and (eq_attr "cpu" "!k6")
5155 (eq_attr "alternative" "0"))
5157 (const_string "1")))
5159 (if_then_else (eq_attr "prefix_0f" "0")
5161 (const_string "1")))])
5163 (define_insn "extendqisi2"
5164 [(set (match_operand:SI 0 "register_operand" "=r")
5165 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
5167 "movs{bl|x}\t{%1, %0|%0, %1}"
5168 [(set_attr "type" "imovx")
5169 (set_attr "mode" "SI")])
5171 (define_insn "*extendqisi2_zext"
5172 [(set (match_operand:DI 0 "register_operand" "=r")
5174 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
5176 "movs{bl|x}\t{%1, %k0|%k0, %1}"
5177 [(set_attr "type" "imovx")
5178 (set_attr "mode" "SI")])
5180 (define_insn "extendqihi2"
5181 [(set (match_operand:HI 0 "register_operand" "=*a,r")
5182 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
5185 switch (get_attr_prefix_0f (insn))
5188 return "{cbtw|cbw}";
5190 return "movs{bw|x}\t{%1, %0|%0, %1}";
5193 [(set_attr "type" "imovx")
5194 (set_attr "mode" "HI")
5195 (set (attr "prefix_0f")
5196 ;; movsx is short decodable while cwtl is vector decoded.
5197 (if_then_else (and (eq_attr "cpu" "!k6")
5198 (eq_attr "alternative" "0"))
5200 (const_string "1")))
5202 (if_then_else (eq_attr "prefix_0f" "0")
5204 (const_string "1")))])
5206 (define_insn "*extendqi<SWI24:mode>_ext_1"
5207 [(set (match_operand:SWI24 0 "register_operand" "=R")
5210 (match_operator:SWI248 2 "extract_operator"
5211 [(match_operand 1 "int248_register_operand" "Q")
5213 (const_int 8)]) 0)))]
5215 "movs{b<SWI24:imodesuffix>|x}\t{%h1, %0|%0, %h1}"
5216 [(set_attr "type" "imovx")
5217 (set_attr "mode" "<SWI24:MODE>")])
5219 ;; Conversions between float and double.
5221 ;; These are all no-ops in the model used for the 80387.
5222 ;; So just emit moves.
5224 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
5226 [(set (match_operand:DF 0 "push_operand")
5227 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
5229 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
5230 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
5233 [(set (match_operand:XF 0 "push_operand")
5234 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
5236 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
5237 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
5238 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
5240 (define_expand "extendsfdf2"
5241 [(set (match_operand:DF 0 "nonimm_ssenomem_operand")
5242 (float_extend:DF (match_operand:SF 1 "general_operand")))]
5243 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5245 /* ??? Needed for compress_float_constant since all fp constants
5246 are TARGET_LEGITIMATE_CONSTANT_P. */
5247 if (CONST_DOUBLE_P (operands[1]))
5249 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
5250 && standard_80387_constant_p (operands[1]) > 0)
5252 operands[1] = simplify_const_unary_operation
5253 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
5254 emit_move_insn_1 (operands[0], operands[1]);
5257 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
5261 (define_insn "*extendsfdf2"
5262 [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v,v")
5264 (match_operand:SF 1 "nonimmediate_operand" "fm,f,v,m")))]
5265 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5267 switch (which_alternative)
5271 return output_387_reg_move (insn, operands);
5274 return "%vcvtss2sd\t{%d1, %0|%0, %d1}";
5276 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
5282 [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
5283 (set_attr "avx_partial_xmm_update" "false,false,false,true")
5284 (set_attr "prefix" "orig,orig,maybe_vex,maybe_vex")
5285 (set_attr "mode" "SF,XF,DF,DF")
5286 (set (attr "enabled")
5288 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
5290 (eq_attr "alternative" "0,1")
5291 (symbol_ref "TARGET_MIX_SSE_I387")
5292 (symbol_ref "true"))
5294 (eq_attr "alternative" "0,1")
5296 (symbol_ref "false"))))])
5298 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
5300 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
5302 We do the conversion post reload to avoid producing of 128bit spills
5303 that might lead to ICE on 32bit target. The sequence unlikely combine
5306 [(set (match_operand:DF 0 "sse_reg_operand")
5308 (match_operand:SF 1 "nonimmediate_operand")))]
5309 "TARGET_USE_VECTOR_FP_CONVERTS
5310 && optimize_insn_for_speed_p ()
5312 && (!EXT_REX_SSE_REG_P (operands[0])
5313 || TARGET_AVX512VL)"
5318 (parallel [(const_int 0) (const_int 1)]))))]
5320 operands[2] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5321 operands[3] = lowpart_subreg (V4SFmode, operands[0], DFmode);
5322 /* Use movss for loading from memory, unpcklps reg, reg for registers.
5323 Try to avoid move when unpacking can be done in source. */
5324 if (REG_P (operands[1]))
5326 /* If it is unsafe to overwrite upper half of source, we need
5327 to move to destination and unpack there. */
5328 if (REGNO (operands[0]) != REGNO (operands[1])
5329 || (EXT_REX_SSE_REG_P (operands[1]) && !TARGET_AVX512VL))
5331 rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode);
5332 emit_move_insn (tmp, operands[1]);
5335 operands[3] = lowpart_subreg (V4SFmode, operands[1], SFmode);
5336 /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
5337 =v, v, then vbroadcastss will be only needed for AVX512F without
5339 if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3])))
5340 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
5344 rtx tmp = lowpart_subreg (V16SFmode, operands[3], V4SFmode);
5345 emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
5349 emit_insn (gen_vec_setv4sf_0 (operands[3],
5350 CONST0_RTX (V4SFmode), operands[1]));
5353 ;; It's more profitable to split and then extend in the same register.
5355 [(set (match_operand:DF 0 "sse_reg_operand")
5357 (match_operand:SF 1 "memory_operand")))]
5358 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
5359 && optimize_insn_for_speed_p ()"
5360 [(set (match_dup 2) (match_dup 1))
5361 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
5362 "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);")
5364 ;; Break partial SSE register dependency stall. This splitter should split
5365 ;; late in the pass sequence (after register rename pass), so allocated
5366 ;; registers won't change anymore
5369 [(set (match_operand:DF 0 "sse_reg_operand")
5371 (match_operand:SF 1 "nonimmediate_operand")))]
5373 && TARGET_SSE_PARTIAL_REG_FP_CONVERTS_DEPENDENCY
5374 && epilogue_completed
5375 && optimize_function_for_speed_p (cfun)
5376 && (!REG_P (operands[1])
5377 || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
5378 && (!EXT_REX_SSE_REG_P (operands[0])
5379 || TARGET_AVX512VL)"
5388 operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5389 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5392 (define_expand "extendhfsf2"
5393 [(set (match_operand:SF 0 "register_operand")
5395 (match_operand:HF 1 "nonimmediate_operand")))]
5396 "TARGET_AVX512FP16 || TARGET_F16C || TARGET_AVX512VL"
5398 if (!TARGET_AVX512FP16)
5400 rtx res = gen_reg_rtx (V4SFmode);
5401 rtx tmp = gen_reg_rtx (V8HFmode);
5402 rtx zero = force_reg (V8HFmode, CONST0_RTX (V8HFmode));
5404 emit_insn (gen_vec_setv8hf_0 (tmp, zero, operands[1]));
5405 emit_insn (gen_vcvtph2ps (res, gen_lowpart (V8HImode, tmp)));
5406 emit_move_insn (operands[0], gen_lowpart (SFmode, res));
5411 (define_expand "extendhfdf2"
5412 [(set (match_operand:DF 0 "register_operand")
5414 (match_operand:HF 1 "nonimmediate_operand")))]
5415 "TARGET_AVX512FP16")
5417 (define_insn "*extendhf<mode>2"
5418 [(set (match_operand:MODEF 0 "register_operand" "=v")
5420 (match_operand:HF 1 "nonimmediate_operand" "vm")))]
5422 "vcvtsh2<ssemodesuffix>\t{%1, %0, %0|%0, %0, %1}"
5423 [(set_attr "type" "ssecvt")
5424 (set_attr "prefix" "evex")
5425 (set_attr "mode" "<MODE>")])
5427 (define_expand "extendbfsf2"
5428 [(set (match_operand:SF 0 "register_operand")
5430 [(match_operand:BF 1 "register_operand")]
5432 "TARGET_SSE2 && !HONOR_NANS (BFmode)")
5434 ;; Don't use float_extend since psrlld doesn't raise
5435 ;; exceptions and turn a sNaN into a qNaN.
5436 (define_insn "extendbfsf2_1"
5437 [(set (match_operand:SF 0 "register_operand" "=x,Yv,v")
5439 [(match_operand:BF 1 "register_operand" " 0,Yv,v")]
5443 pslld\t{$16, %0|%0, 16}
5444 vpslld\t{$16, %1, %0|%0, %1, 16}
5445 vpslld\t{$16, %g1, %g0|%g0, %g1, 16}"
5446 [(set_attr "isa" "noavx,avx,*")
5447 (set_attr "type" "sseishft1")
5448 (set_attr "length_immediate" "1")
5449 (set_attr "prefix_data16" "1,*,*")
5450 (set_attr "prefix" "orig,maybe_evex,evex")
5451 (set_attr "mode" "TI,TI,XI")
5452 (set_attr "memory" "none")
5453 (set (attr "enabled")
5454 (if_then_else (eq_attr "alternative" "2")
5455 (symbol_ref "TARGET_AVX512F && TARGET_EVEX512
5456 && !TARGET_AVX512VL && !TARGET_PREFER_AVX256")
5457 (const_string "*")))])
5459 (define_expand "extend<mode>xf2"
5460 [(set (match_operand:XF 0 "nonimmediate_operand")
5461 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
5464 /* ??? Needed for compress_float_constant since all fp constants
5465 are TARGET_LEGITIMATE_CONSTANT_P. */
5466 if (CONST_DOUBLE_P (operands[1]))
5468 if (standard_80387_constant_p (operands[1]) > 0)
5470 operands[1] = simplify_const_unary_operation
5471 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
5472 emit_move_insn_1 (operands[0], operands[1]);
5475 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
5479 (define_insn "*extend<mode>xf2_i387"
5480 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
5482 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
5484 "* return output_387_reg_move (insn, operands);"
5485 [(set_attr "type" "fmov")
5486 (set_attr "mode" "<MODE>,XF")])
5488 ;; %%% This seems like bad news.
5489 ;; This cannot output into an f-reg because there is no way to be sure
5490 ;; of truncating in that case. Otherwise this is just like a simple move
5491 ;; insn. So we pretend we can output to a reg in order to get better
5492 ;; register preferencing, but we really use a stack slot.
5494 ;; Conversion from DFmode to SFmode.
5496 (define_insn "truncdfsf2"
5497 [(set (match_operand:SF 0 "nonimm_ssenomem_operand" "=m,f,v,v")
5499 (match_operand:DF 1 "register_ssemem_operand" "f,f,v,m")))]
5500 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5502 switch (which_alternative)
5506 return output_387_reg_move (insn, operands);
5509 return "%vcvtsd2ss\t{%d1, %0|%0, %d1}";
5511 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
5517 [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
5518 (set_attr "avx_partial_xmm_update" "false,false,false,true")
5519 (set_attr "mode" "SF")
5520 (set (attr "enabled")
5522 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
5523 (cond [(eq_attr "alternative" "0")
5524 (symbol_ref "TARGET_MIX_SSE_I387")
5525 (eq_attr "alternative" "1")
5526 (symbol_ref "TARGET_MIX_SSE_I387
5527 && flag_unsafe_math_optimizations")
5529 (symbol_ref "true"))
5530 (cond [(eq_attr "alternative" "0")
5532 (eq_attr "alternative" "1")
5533 (symbol_ref "flag_unsafe_math_optimizations")
5535 (symbol_ref "false"))))])
5537 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
5539 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
5541 We do the conversion post reload to avoid producing of 128bit spills
5542 that might lead to ICE on 32bit target. The sequence unlikely combine
5545 [(set (match_operand:SF 0 "sse_reg_operand")
5547 (match_operand:DF 1 "nonimmediate_operand")))]
5548 "TARGET_USE_VECTOR_FP_CONVERTS
5549 && optimize_insn_for_speed_p ()
5551 && (!EXT_REX_SSE_REG_P (operands[0])
5552 || TARGET_AVX512VL)"
5555 (float_truncate:V2SF
5559 operands[2] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5560 operands[3] = CONST0_RTX (V2SFmode);
5561 operands[4] = lowpart_subreg (V2DFmode, operands[0], SFmode);
5562 /* Use movsd for loading from memory, unpcklpd for registers.
5563 Try to avoid move when unpacking can be done in source, or SSE3
5564 movddup is available. */
5565 if (REG_P (operands[1]))
5567 if ((!TARGET_SSE3 && REGNO (operands[0]) != REGNO (operands[1]))
5568 || (EXT_REX_SSE_REG_P (operands[1]) && !TARGET_AVX512VL))
5570 rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode);
5571 emit_move_insn (tmp, operands[1]);
5574 else if (!TARGET_SSE3)
5575 operands[4] = lowpart_subreg (V2DFmode, operands[1], DFmode);
5576 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
5579 emit_insn (gen_vec_concatv2df (operands[4], operands[1],
5580 CONST0_RTX (DFmode)));
5583 ;; It's more profitable to split and then truncate in the same register.
5585 [(set (match_operand:SF 0 "sse_reg_operand")
5587 (match_operand:DF 1 "memory_operand")))]
5588 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
5589 && optimize_insn_for_speed_p ()"
5590 [(set (match_dup 2) (match_dup 1))
5591 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
5592 "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
5594 ;; Break partial SSE register dependency stall. This splitter should split
5595 ;; late in the pass sequence (after register rename pass), so allocated
5596 ;; registers won't change anymore
5599 [(set (match_operand:SF 0 "sse_reg_operand")
5601 (match_operand:DF 1 "nonimmediate_operand")))]
5603 && TARGET_SSE_PARTIAL_REG_FP_CONVERTS_DEPENDENCY
5604 && epilogue_completed
5605 && optimize_function_for_speed_p (cfun)
5606 && (!REG_P (operands[1])
5607 || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
5608 && (!EXT_REX_SSE_REG_P (operands[0])
5609 || TARGET_AVX512VL)"
5618 operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5619 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5622 ;; Conversion from XFmode to {SF,DF}mode
5624 (define_insn "truncxf<mode>2"
5625 [(set (match_operand:MODEF 0 "nonimmediate_operand" "=m,f")
5626 (float_truncate:MODEF
5627 (match_operand:XF 1 "register_operand" "f,f")))]
5629 "* return output_387_reg_move (insn, operands);"
5630 [(set_attr "type" "fmov")
5631 (set_attr "mode" "<MODE>")
5632 (set (attr "enabled")
5633 (cond [(eq_attr "alternative" "1")
5634 (symbol_ref "flag_unsafe_math_optimizations")
5636 (symbol_ref "true")))])
5638 ;; Conversion from {SF,DF}mode to HFmode.
5640 (define_expand "truncsfhf2"
5641 [(set (match_operand:HF 0 "register_operand")
5643 (match_operand:SF 1 "nonimmediate_operand")))]
5644 "TARGET_AVX512FP16 || TARGET_F16C || TARGET_AVX512VL"
5646 if (!TARGET_AVX512FP16)
5648 rtx res = gen_reg_rtx (V8HFmode);
5649 rtx tmp = gen_reg_rtx (V4SFmode);
5650 rtx zero = force_reg (V4SFmode, CONST0_RTX (V4SFmode));
5652 emit_insn (gen_vec_setv4sf_0 (tmp, zero, operands[1]));
5653 emit_insn (gen_vcvtps2ph (gen_lowpart (V8HImode, res), tmp, GEN_INT (4)));
5654 emit_move_insn (operands[0], gen_lowpart (HFmode, res));
5659 (define_expand "truncdfhf2"
5660 [(set (match_operand:HF 0 "register_operand")
5662 (match_operand:DF 1 "nonimmediate_operand")))]
5663 "TARGET_AVX512FP16")
5665 (define_insn "*trunc<mode>hf2"
5666 [(set (match_operand:HF 0 "register_operand" "=v")
5668 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5670 "vcvt<ssemodesuffix>2sh\t{%1, %d0|%d0, %1}"
5671 [(set_attr "type" "ssecvt")
5672 (set_attr "prefix" "evex")
5673 (set_attr "mode" "HF")])
5675 (define_insn "truncsfbf2"
5676 [(set (match_operand:BF 0 "register_operand" "=x,x,v,Yv")
5678 (match_operand:SF 1 "register_operand" "0,x,v,Yv")))]
5679 "TARGET_SSE2 && flag_unsafe_math_optimizations && !HONOR_NANS (BFmode)"
5681 psrld\t{$16, %0|%0, 16}
5682 %{vex%} vcvtneps2bf16\t{%1, %0|%0, %1}
5683 vcvtneps2bf16\t{%1, %0|%0, %1}
5684 vpsrld\t{$16, %1, %0|%0, %1, 16}"
5685 [(set_attr "isa" "noavx,avxneconvert,avx512bf16vl,avx")
5686 (set_attr "prefix" "orig,vex,evex,vex")
5687 (set_attr "type" "sseishft1,ssecvt,ssecvt,sseishft1")])
5689 ;; Signed conversion to DImode.
5691 (define_expand "fix_truncxfdi2"
5692 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
5693 (fix:DI (match_operand:XF 1 "register_operand")))
5694 (clobber (reg:CC FLAGS_REG))])]
5699 emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
5704 (define_expand "fix_trunc<mode>di2"
5705 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
5706 (fix:DI (match_operand:MODEF 1 "register_operand")))
5707 (clobber (reg:CC FLAGS_REG))])]
5708 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
5711 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
5713 emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
5716 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
5718 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
5719 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
5720 if (out != operands[0])
5721 emit_move_insn (operands[0], out);
5726 (define_insn "fix<fixunssuffix>_trunchf<mode>2"
5727 [(set (match_operand:SWI48 0 "register_operand" "=r")
5729 (match_operand:HF 1 "nonimmediate_operand" "vm")))]
5731 "vcvttsh2<fixsuffix>si\t{%1, %0|%0, %1}"
5732 [(set_attr "type" "sseicvt")
5733 (set_attr "prefix" "evex")
5734 (set_attr "mode" "<MODE>")])
5736 ;; Signed conversion to SImode.
5738 (define_expand "fix_truncxfsi2"
5739 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
5740 (fix:SI (match_operand:XF 1 "register_operand")))
5741 (clobber (reg:CC FLAGS_REG))])]
5746 emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
5751 (define_expand "fix_trunc<mode>si2"
5752 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
5753 (fix:SI (match_operand:MODEF 1 "register_operand")))
5754 (clobber (reg:CC FLAGS_REG))])]
5755 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
5758 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
5760 emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
5763 if (SSE_FLOAT_MODE_P (<MODE>mode))
5765 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
5766 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
5767 if (out != operands[0])
5768 emit_move_insn (operands[0], out);
5773 ;; Signed conversion to HImode.
5775 (define_expand "fix_trunc<mode>hi2"
5776 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
5777 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
5778 (clobber (reg:CC FLAGS_REG))])]
5780 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
5784 emit_insn (gen_fix_trunchi_i387_fisttp (operands[0], operands[1]));
5789 ;; Unsigned conversion to DImode
5791 (define_insn "fixuns_trunc<mode>di2"
5792 [(set (match_operand:DI 0 "register_operand" "=r")
5794 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5795 "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
5796 "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
5797 [(set_attr "type" "sseicvt")
5798 (set_attr "prefix" "evex")
5799 (set_attr "mode" "DI")])
5801 ;; Unsigned conversion to SImode.
5803 (define_expand "fixuns_trunc<mode>si2"
5805 [(set (match_operand:SI 0 "register_operand")
5807 (match_operand:MODEF 1 "nonimmediate_operand")))
5809 (clobber (scratch:<ssevecmode>))
5810 (clobber (scratch:<ssevecmode>))])]
5811 "(!TARGET_64BIT || TARGET_AVX512F) && TARGET_SSE2 && TARGET_SSE_MATH"
5813 machine_mode mode = <MODE>mode;
5814 machine_mode vecmode = <ssevecmode>mode;
5815 REAL_VALUE_TYPE TWO31r;
5820 emit_insn (gen_fixuns_trunc<mode>si2_avx512f (operands[0], operands[1]));
5824 if (optimize_insn_for_size_p ())
5827 real_ldexp (&TWO31r, &dconst1, 31);
5828 two31 = const_double_from_real_value (TWO31r, mode);
5829 two31 = ix86_build_const_vector (vecmode, true, two31);
5830 operands[2] = force_reg (vecmode, two31);
5833 (define_insn "fixuns_trunc<mode>si2_avx512f"
5834 [(set (match_operand:SI 0 "register_operand" "=r")
5836 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5837 "TARGET_AVX512F && TARGET_SSE_MATH"
5838 "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
5839 [(set_attr "type" "sseicvt")
5840 (set_attr "prefix" "evex")
5841 (set_attr "mode" "SI")])
5843 (define_insn "*fixuns_trunchfsi2zext"
5844 [(set (match_operand:DI 0 "register_operand" "=r")
5847 (match_operand:HF 1 "nonimmediate_operand" "vm"))))]
5848 "TARGET_64BIT && TARGET_AVX512FP16"
5849 "vcvttsh2usi\t{%1, %k0|%k0, %1}"
5850 [(set_attr "type" "sseicvt")
5851 (set_attr "prefix" "evex")
5852 (set_attr "mode" "SI")])
5854 (define_insn "*fixuns_trunc<mode>si2_avx512f_zext"
5855 [(set (match_operand:DI 0 "register_operand" "=r")
5858 (match_operand:MODEF 1 "nonimmediate_operand" "vm"))))]
5859 "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
5860 "vcvtt<ssemodesuffix>2usi\t{%1, %k0|%k0, %1}"
5861 [(set_attr "type" "sseicvt")
5862 (set_attr "prefix" "evex")
5863 (set_attr "mode" "SI")])
5865 (define_insn_and_split "*fixuns_trunc<mode>_1"
5866 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
5868 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
5869 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
5870 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
5871 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
5872 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5873 && optimize_function_for_speed_p (cfun)"
5875 "&& reload_completed"
5878 ix86_split_convert_uns_si_sse (operands);
5882 ;; Unsigned conversion to HImode.
5883 ;; Without these patterns, we'll try the unsigned SI conversion which
5884 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
5886 (define_expand "fixuns_trunchfhi2"
5888 (fix:SI (match_operand:HF 1 "nonimmediate_operand")))
5889 (set (match_operand:HI 0 "nonimmediate_operand")
5890 (subreg:HI (match_dup 2) 0))]
5892 "operands[2] = gen_reg_rtx (SImode);")
5894 (define_expand "fixuns_trunc<mode>hi2"
5896 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
5897 (set (match_operand:HI 0 "nonimmediate_operand")
5898 (subreg:HI (match_dup 2) 0))]
5899 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
5900 "operands[2] = gen_reg_rtx (SImode);")
5902 ;; When SSE is available, it is always faster to use it!
5903 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
5904 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
5905 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
5906 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5907 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
5908 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
5909 [(set_attr "type" "sseicvt")
5910 (set_attr "prefix" "maybe_vex")
5911 (set (attr "prefix_rex")
5913 (match_test "<SWI48:MODE>mode == DImode")
5915 (const_string "*")))
5916 (set_attr "mode" "<MODEF:MODE>")
5917 (set_attr "athlon_decode" "double,vector")
5918 (set_attr "amdfam10_decode" "double,double")
5919 (set_attr "bdver1_decode" "double,double")])
5921 ;; Avoid vector decoded forms of the instruction.
5923 [(match_scratch:MODEF 2 "x")
5924 (set (match_operand:SWI48 0 "register_operand")
5925 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
5926 "TARGET_AVOID_VECTOR_DECODE
5927 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5928 && optimize_insn_for_speed_p ()"
5929 [(set (match_dup 2) (match_dup 1))
5930 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
5932 (define_insn "fix_trunc<mode>_i387_fisttp"
5933 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m")
5934 (fix:SWI248x (match_operand 1 "register_operand" "f")))
5935 (clobber (match_scratch:XF 2 "=&f"))]
5936 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5938 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5939 && (TARGET_64BIT || <MODE>mode != DImode))
5940 && TARGET_SSE_MATH)"
5941 "* return output_fix_trunc (insn, operands, true);"
5942 [(set_attr "type" "fisttp")
5943 (set_attr "mode" "<MODE>")])
5945 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5946 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5947 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5948 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5949 ;; function in i386.cc.
5950 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5951 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
5952 (fix:SWI248x (match_operand 1 "register_operand")))
5953 (clobber (reg:CC FLAGS_REG))]
5954 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5956 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5957 && (TARGET_64BIT || <MODE>mode != DImode))
5958 && ix86_pre_reload_split ()"
5963 ix86_optimize_mode_switching[I387_TRUNC] = 1;
5965 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5966 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5968 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5969 operands[2], operands[3]));
5972 [(set_attr "type" "fistp")
5973 (set_attr "i387_cw" "trunc")
5974 (set_attr "mode" "<MODE>")])
5976 (define_insn "fix_truncdi_i387"
5977 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
5978 (fix:DI (match_operand 1 "register_operand" "f")))
5979 (use (match_operand:HI 2 "memory_operand" "m"))
5980 (use (match_operand:HI 3 "memory_operand" "m"))
5981 (clobber (match_scratch:XF 4 "=&f"))]
5982 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5984 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5985 "* return output_fix_trunc (insn, operands, false);"
5986 [(set_attr "type" "fistp")
5987 (set_attr "i387_cw" "trunc")
5988 (set_attr "mode" "DI")])
5990 (define_insn "fix_trunc<mode>_i387"
5991 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
5992 (fix:SWI24 (match_operand 1 "register_operand" "f")))
5993 (use (match_operand:HI 2 "memory_operand" "m"))
5994 (use (match_operand:HI 3 "memory_operand" "m"))]
5995 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5997 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5998 "* return output_fix_trunc (insn, operands, false);"
5999 [(set_attr "type" "fistp")
6000 (set_attr "i387_cw" "trunc")
6001 (set_attr "mode" "<MODE>")])
6003 (define_insn "x86_fnstcw_1"
6004 [(set (match_operand:HI 0 "memory_operand" "=m")
6005 (unspec:HI [(const_int 0)] UNSPEC_FSTCW))]
6008 [(set (attr "length")
6009 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
6010 (set_attr "mode" "HI")
6011 (set_attr "unit" "i387")
6012 (set_attr "bdver1_decode" "vector")])
6014 ;; Conversion between fixed point and floating point.
6016 ;; Even though we only accept memory inputs, the backend _really_
6017 ;; wants to be able to do this between registers. Thankfully, LRA
6018 ;; will fix this up for us during register allocation.
6020 (define_insn "floathi<mode>2"
6021 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
6022 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
6024 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
6025 || TARGET_MIX_SSE_I387)"
6027 [(set_attr "type" "fmov")
6028 (set_attr "mode" "<MODE>")
6029 (set_attr "znver1_decode" "double")
6030 (set_attr "fp_int_src" "true")])
6032 (define_insn "float<SWI48x:mode>xf2"
6033 [(set (match_operand:XF 0 "register_operand" "=f")
6034 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
6037 [(set_attr "type" "fmov")
6038 (set_attr "mode" "XF")
6039 (set_attr "znver1_decode" "double")
6040 (set_attr "fp_int_src" "true")])
6042 (define_expand "float<SWI48x:mode><MODEF:mode>2"
6043 [(set (match_operand:MODEF 0 "register_operand")
6044 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand")))]
6045 "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode))
6046 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
6047 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT))")
6049 (define_insn "*float<SWI48:mode><MODEF:mode>2"
6050 [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
6052 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
6053 "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
6054 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
6057 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
6058 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
6059 [(set_attr "type" "fmov,sseicvt,sseicvt")
6060 (set_attr "avx_partial_xmm_update" "false,true,true")
6061 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
6062 (set_attr "mode" "<MODEF:MODE>")
6063 (set (attr "prefix_rex")
6065 (and (eq_attr "prefix" "maybe_vex")
6066 (match_test "<SWI48:MODE>mode == DImode"))
6068 (const_string "*")))
6069 (set_attr "unit" "i387,*,*")
6070 (set_attr "athlon_decode" "*,double,direct")
6071 (set_attr "amdfam10_decode" "*,vector,double")
6072 (set_attr "bdver1_decode" "*,double,direct")
6073 (set_attr "znver1_decode" "double,*,*")
6074 (set_attr "fp_int_src" "true")
6075 (set (attr "enabled")
6077 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
6079 (eq_attr "alternative" "0")
6080 (symbol_ref "TARGET_MIX_SSE_I387
6081 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
6083 (symbol_ref "true"))
6085 (eq_attr "alternative" "0")
6087 (symbol_ref "false"))))
6088 (set (attr "preferred_for_speed")
6089 (cond [(eq_attr "alternative" "1")
6090 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
6091 (symbol_ref "true")))])
6093 (define_insn "float<floatunssuffix><mode>hf2"
6094 [(set (match_operand:HF 0 "register_operand" "=v")
6096 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
6098 "vcvt<floatsuffix>si2sh<rex64suffix>\t{%1, %d0|%d0, %1}"
6099 [(set_attr "type" "sseicvt")
6100 (set_attr "prefix" "evex")
6101 (set_attr "mode" "HF")])
6103 (define_insn "*floatdi<MODEF:mode>2_i387"
6104 [(set (match_operand:MODEF 0 "register_operand" "=f")
6105 (float:MODEF (match_operand:DI 1 "nonimmediate_operand" "m")))]
6107 && TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, DImode)"
6109 [(set_attr "type" "fmov")
6110 (set_attr "mode" "<MODEF:MODE>")
6111 (set_attr "znver1_decode" "double")
6112 (set_attr "fp_int_src" "true")])
6114 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
6115 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
6116 ;; alternative in sse2_loadld.
6118 [(set (match_operand:MODEF 0 "sse_reg_operand")
6119 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
6121 && TARGET_USE_VECTOR_CONVERTS
6122 && optimize_function_for_speed_p (cfun)
6124 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
6125 && (!EXT_REX_SSE_REG_P (operands[0])
6126 || TARGET_AVX512VL)"
6129 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode);
6130 operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode);
6132 emit_insn (gen_sse2_loadld (operands[4],
6133 CONST0_RTX (V4SImode), operands[1]));
6135 if (<ssevecmode>mode == V4SFmode)
6136 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
6138 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
6142 ;; Avoid store forwarding (partial memory) stall penalty
6143 ;; by passing DImode value through XMM registers. */
6146 [(set (match_operand:X87MODEF 0 "register_operand")
6148 (match_operand:DI 1 "register_operand")))]
6149 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
6150 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6151 && TARGET_SSE2 && optimize_function_for_speed_p (cfun)
6152 && can_create_pseudo_p ()"
6155 rtx s = assign_386_stack_local (DImode, SLOT_FLOATxFDI_387);
6156 emit_insn (gen_floatdi<mode>2_i387_with_xmm (operands[0], operands[1], s));
6160 (define_insn_and_split "floatdi<X87MODEF:mode>2_i387_with_xmm"
6161 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
6163 (match_operand:DI 1 "register_operand" "r,r")))
6164 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
6165 (clobber (match_scratch:V4SI 3 "=x,x"))
6166 (clobber (match_scratch:V4SI 4 "=X,x"))]
6167 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
6168 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6169 && TARGET_SSE2 && optimize_function_for_speed_p (cfun)"
6171 "&& reload_completed"
6172 [(set (match_dup 2) (match_dup 3))
6173 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
6175 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
6176 Assemble the 64-bit DImode value in an xmm register. */
6177 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
6178 gen_lowpart (SImode, operands[1])));
6180 emit_insn (gen_sse4_1_pinsrd (operands[3], operands[3],
6181 gen_highpart (SImode, operands[1]),
6185 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
6186 gen_highpart (SImode, operands[1])));
6187 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
6190 operands[3] = gen_lowpart (DImode, operands[3]);
6192 [(set_attr "isa" "sse4,*")
6193 (set_attr "type" "multi")
6194 (set_attr "mode" "<X87MODEF:MODE>")
6195 (set_attr "unit" "i387")
6196 (set_attr "fp_int_src" "true")])
6198 ;; Break partial SSE register dependency stall. This splitter should split
6199 ;; late in the pass sequence (after register rename pass), so allocated
6200 ;; registers won't change anymore
6203 [(set (match_operand:MODEF 0 "sse_reg_operand")
6204 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
6206 && TARGET_SSE_PARTIAL_REG_CONVERTS_DEPENDENCY
6207 && epilogue_completed
6208 && optimize_function_for_speed_p (cfun)
6209 && (!EXT_REX_SSE_REG_P (operands[0])
6210 || TARGET_AVX512VL)"
6212 (vec_merge:<MODEF:ssevecmode>
6213 (vec_duplicate:<MODEF:ssevecmode>
6219 const machine_mode vmode = <MODEF:ssevecmode>mode;
6221 operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode);
6222 emit_move_insn (operands[0], CONST0_RTX (vmode));
6225 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
6226 [(set (match_operand:MODEF 0 "register_operand")
6227 (unsigned_float:MODEF
6228 (match_operand:SWI12 1 "nonimmediate_operand")))]
6230 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
6232 operands[1] = convert_to_mode (SImode, operands[1], 1);
6233 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
6237 (define_insn "*floatuns<SWI48:mode><MODEF:mode>2_avx512"
6238 [(set (match_operand:MODEF 0 "register_operand" "=v")
6239 (unsigned_float:MODEF
6240 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
6241 "TARGET_AVX512F && TARGET_SSE_MATH"
6242 "vcvtusi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %0, %0|%0, %0, %1}"
6243 [(set_attr "type" "sseicvt")
6244 (set_attr "avx_partial_xmm_update" "true")
6245 (set_attr "prefix" "evex")
6246 (set_attr "mode" "<MODEF:MODE>")])
6248 ;; Avoid store forwarding (partial memory) stall penalty by extending
6249 ;; SImode value to DImode through XMM register instead of pushing two
6250 ;; SImode values to stack. Also note that fild loads from memory only.
6252 (define_insn_and_split "floatunssi<mode>2_i387_with_xmm"
6253 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
6254 (unsigned_float:X87MODEF
6255 (match_operand:SI 1 "nonimmediate_operand" "rm")))
6256 (clobber (match_operand:DI 2 "memory_operand" "=m"))
6257 (clobber (match_scratch:DI 3 "=x"))]
6259 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6260 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
6262 "&& reload_completed"
6263 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
6264 (set (match_dup 2) (match_dup 3))
6266 (float:X87MODEF (match_dup 2)))]
6268 [(set_attr "type" "multi")
6269 (set_attr "mode" "<MODE>")])
6271 (define_expand "floatunssi<mode>2"
6272 [(set (match_operand:X87MODEF 0 "register_operand")
6273 (unsigned_float:X87MODEF
6274 (match_operand:SI 1 "nonimmediate_operand")))]
6276 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6277 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
6278 || ((!TARGET_64BIT || TARGET_AVX512F)
6279 && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
6281 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
6283 emit_insn (gen_floatunssi<mode>2_i387_with_xmm
6284 (operands[0], operands[1],
6285 assign_386_stack_local (DImode, SLOT_TEMP)));
6288 if (!TARGET_AVX512F)
6290 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
6295 (define_expand "floatunsdisf2"
6296 [(set (match_operand:SF 0 "register_operand")
6298 (match_operand:DI 1 "nonimmediate_operand")))]
6299 "TARGET_64BIT && TARGET_SSE && TARGET_SSE_MATH"
6301 if (!TARGET_AVX512F)
6303 x86_emit_floatuns (operands);
6308 (define_expand "floatunsdidf2"
6309 [(set (match_operand:DF 0 "register_operand")
6311 (match_operand:DI 1 "nonimmediate_operand")))]
6312 "((TARGET_64BIT && TARGET_AVX512F)
6313 || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
6314 && TARGET_SSE2 && TARGET_SSE_MATH"
6318 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
6321 if (!TARGET_AVX512F)
6323 x86_emit_floatuns (operands);
6328 ;; Load effective address instructions
6330 (define_insn "*lea<mode>"
6331 [(set (match_operand:SWI48 0 "register_operand" "=r")
6332 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
6333 "ix86_hardreg_mov_ok (operands[0], operands[1])"
6335 if (SImode_address_operand (operands[1], VOIDmode))
6337 gcc_assert (TARGET_64BIT);
6338 return "lea{l}\t{%E1, %k0|%k0, %E1}";
6341 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
6343 [(set_attr "type" "lea")
6346 (match_operand 1 "SImode_address_operand")
6348 (const_string "<MODE>")))])
6351 [(set (match_operand:SWI48 0 "register_operand")
6352 (match_operand:SWI48 1 "address_no_seg_operand"))]
6353 "ix86_hardreg_mov_ok (operands[0], operands[1])
6354 && peep2_regno_dead_p (0, FLAGS_REG)
6355 && ix86_avoid_lea_for_addr (peep2_next_insn (0), operands)"
6358 machine_mode mode = <MODE>mode;
6360 /* Emit all operations in SImode for zero-extended addresses. */
6361 if (SImode_address_operand (operands[1], VOIDmode))
6364 ix86_split_lea_for_addr (peep2_next_insn (0), operands, mode);
6366 /* Zero-extend return register to DImode for zero-extended addresses. */
6367 if (mode != <MODE>mode)
6368 emit_insn (gen_zero_extendsidi2 (operands[0],
6369 gen_lowpart (mode, operands[0])));
6374 ;; ix86_split_lea_for_addr emits the shifts as MULT to avoid it from being
6375 ;; peephole2 optimized back into a lea. Split that into the shift during
6376 ;; the following split pass.
6378 [(set (match_operand:SWI48 0 "general_reg_operand")
6379 (mult:SWI48 (match_dup 0) (match_operand:SWI48 1 "const1248_operand")))
6380 (clobber (reg:CC FLAGS_REG))]
6382 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
6383 (clobber (reg:CC FLAGS_REG))])]
6384 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
6387 [(set (match_operand:SWI48 0 "general_reg_operand")
6388 (mult:SWI48 (match_dup 0) (match_operand:SWI48 1 "const1248_operand")))]
6389 "TARGET_APX_NF && reload_completed"
6390 [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))]
6391 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
6393 ;; The peephole2 pass may expose consecutive additions suitable for lea.
6395 [(parallel [(set (match_operand:SWI48 0 "register_operand")
6396 (plus:SWI48 (match_dup 0)
6397 (match_operand 1 "register_operand")))
6398 (clobber (reg:CC FLAGS_REG))])
6399 (parallel [(set (match_dup 0)
6400 (plus:SWI48 (match_dup 0)
6401 (match_operand 2 "x86_64_immediate_operand")))
6402 (clobber (reg:CC FLAGS_REG))])]
6403 "!TARGET_AVOID_LEA_FOR_ADDR || optimize_function_for_size_p (cfun)"
6404 [(set (match_dup 0) (plus:SWI48 (plus:SWI48 (match_dup 0)
6410 (define_expand "add<mode>3"
6411 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6412 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6413 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
6416 ix86_expand_binary_operator (PLUS, <MODE>mode, operands, TARGET_APX_NDD);
6420 (define_insn_and_split "*add<dwi>3_doubleword"
6421 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,&r,&r,&r,&r,&r")
6423 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0,ro,r,ro,jO,r")
6424 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o,r,<di>,K,<di>,r")))
6425 (clobber (reg:CC FLAGS_REG))]
6426 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands, TARGET_APX_NDD)"
6428 "&& reload_completed"
6429 [(parallel [(set (reg:CCC FLAGS_REG)
6431 (plus:DWIH (match_dup 1) (match_dup 2))
6434 (plus:DWIH (match_dup 1) (match_dup 2)))])
6435 (parallel [(set (match_dup 3)
6438 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6441 (clobber (reg:CC FLAGS_REG))])]
6443 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6444 if (operands[2] == const0_rtx)
6446 /* Under NDD op0 and op1 may not equal, do not delete insn then. */
6447 bool emit_insn_deleted_note_p = true;
6448 if (!rtx_equal_p (operands[0], operands[1]))
6450 emit_move_insn (operands[0], operands[1]);
6451 emit_insn_deleted_note_p = false;
6453 if (operands[5] != const0_rtx)
6454 ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3],
6456 else if (!rtx_equal_p (operands[3], operands[4]))
6457 emit_move_insn (operands[3], operands[4]);
6458 else if (emit_insn_deleted_note_p)
6459 emit_note (NOTE_INSN_DELETED);
6463 [(set_attr "isa" "*,*,apx_ndd,apx_ndd,apx_ndd,apx_ndd_64,apx_ndd")])
6465 (define_insn_and_split "*add<dwi>3_doubleword_zext"
6466 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,&r,&r")
6469 (match_operand:DWIH 2 "nonimmediate_operand" "rm,r,rm,r"))
6470 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0,r,o")))
6471 (clobber (reg:CC FLAGS_REG))]
6472 "ix86_binary_operator_ok (UNKNOWN, <DWI>mode, operands, TARGET_APX_NDD)"
6474 "&& reload_completed"
6475 [(parallel [(set (reg:CCC FLAGS_REG)
6477 (plus:DWIH (match_dup 1) (match_dup 2))
6480 (plus:DWIH (match_dup 1) (match_dup 2)))])
6481 (parallel [(set (match_dup 3)
6484 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6487 (clobber (reg:CC FLAGS_REG))])]
6488 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[3]);"
6489 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")])
6491 (define_insn_and_split "*add<dwi>3_doubleword_concat"
6492 [(set (match_operand:<DWI> 0 "register_operand" "=&r")
6497 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))
6498 (match_operand:QI 3 "const_int_operand"))
6500 (match_operand:DWIH 4 "nonimmediate_operand" "rm")))
6501 (match_operand:<DWI> 1 "register_operand" "0")))
6502 (clobber (reg:CC FLAGS_REG))]
6503 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
6505 "&& reload_completed"
6506 [(parallel [(set (reg:CCC FLAGS_REG)
6508 (plus:DWIH (match_dup 1) (match_dup 4))
6511 (plus:DWIH (match_dup 1) (match_dup 4)))])
6512 (parallel [(set (match_dup 5)
6515 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6518 (clobber (reg:CC FLAGS_REG))])]
6519 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[5]);")
6521 (define_insn_and_split "*add<dwi>3_doubleword_concat_zext"
6522 [(set (match_operand:<DWI> 0 "register_operand" "=&r")
6527 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))
6528 (match_operand:QI 3 "const_int_operand"))
6530 (match_operand:DWIH 4 "nonimmediate_operand" "rm")))
6532 (match_operand:DWIH 1 "nonimmediate_operand" "rm"))))
6533 (clobber (reg:CC FLAGS_REG))]
6534 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
6536 "&& reload_completed"
6537 [(set (match_dup 0) (match_dup 4))
6538 (parallel [(set (reg:CCC FLAGS_REG)
6540 (plus:DWIH (match_dup 0) (match_dup 1))
6543 (plus:DWIH (match_dup 0) (match_dup 1)))])
6544 (set (match_dup 5) (match_dup 2))
6545 (parallel [(set (match_dup 5)
6548 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6551 (clobber (reg:CC FLAGS_REG))])]
6552 "split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[5]);")
6554 (define_subst_attr "nf_name" "nf_subst" "_nf" "")
6555 (define_subst_attr "nf_prefix" "nf_subst" "%{nf%} " "")
6556 (define_subst_attr "nf_condition" "nf_subst" "TARGET_APX_NF" "true")
6557 (define_subst_attr "nf_add_mem_constraint" "nf_subst" "je" "m")
6558 (define_subst_attr "nf_mem_constraint" "nf_subst" "jM" "m")
6559 (define_subst_attr "nf_applied" "nf_subst" "true" "false")
6560 (define_subst_attr "nf_nonf_attr" "nf_subst" "noapx_nf" "*")
6561 (define_subst_attr "nf_nonf_x64_attr" "nf_subst" "noapx_nf" "x64")
6563 (define_subst "nf_subst"
6564 [(set (match_operand:SWIDWI 0)
6565 (match_operand:SWIDWI 1))]
6569 (clobber (reg:CC FLAGS_REG))])
6571 (define_insn "*add<mode>_1<nf_name>"
6572 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r<nf_add_mem_constraint>,r<nf_mem_constraint>,r,r,r,r,r,r")
6574 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,0,r,r,rje,jM,r")
6575 (match_operand:SWI48 2 "x86_64_general_operand" "r,e,BM,0,le,r,e,BM")))]
6576 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)
6579 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
6580 switch (get_attr_type (insn))
6583 if (TARGET_APX_NDD && <nf_applied>)
6584 return "%{nf%} add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}";
6589 if (operands[2] == const1_rtx)
6590 return use_ndd ? "<nf_prefix>inc{<imodesuffix>}\t{%1, %0|%0, %1}"
6591 : "<nf_prefix>inc{<imodesuffix>}\t%0";
6594 gcc_assert (operands[2] == constm1_rtx);
6595 return use_ndd ? "<nf_prefix>dec{<imodesuffix>}\t{%1, %0|%0, %1}"
6596 : "<nf_prefix>dec{<imodesuffix>}\t%0";
6600 /* For most processors, ADD is faster than LEA. This alternative
6601 was added to use ADD as much as possible. */
6602 if (which_alternative == 3)
6603 std::swap (operands[1], operands[2]);
6605 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6606 return use_ndd ? "<nf_prefix>sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
6607 : "<nf_prefix>sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6609 return use_ndd ? "<nf_prefix>add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
6610 : "<nf_prefix>add{<imodesuffix>}\t{%2, %0|%0, %2}";
6613 [(set_attr "isa" "*,*,*,*,*,apx_ndd,apx_ndd,apx_ndd")
6615 (cond [(eq_attr "alternative" "4")
6616 (const_string "lea")
6617 (match_operand:SWI48 2 "incdec_operand")
6618 (const_string "incdec")
6620 (const_string "alu")))
6621 (set (attr "length_immediate")
6623 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6625 (const_string "*")))
6626 (set_attr "has_nf" "1")
6627 (set_attr "mode" "<MODE>")])
6629 ;; For APX instruction with an NDD, the destination GPR will get the
6630 ;; instruction’s result in bits [OSIZE-1:0] and, if OSIZE < 64b, have
6631 ;; its upper bits [63:OSIZE] zeroed.
6633 (define_insn "*addqi_1_zext<mode><nf_name>"
6634 [(set (match_operand:SWI248x 0 "register_operand" "=r,r")
6635 (zero_extend:SWI248x
6636 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%rm,r")
6637 (match_operand:QI 2 "general_operand" "rn,m"))))]
6638 "TARGET_APX_NDD && <nf_condition>
6639 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6641 switch (get_attr_type (insn))
6644 if (operands[2] == const1_rtx)
6645 return "<nf_prefix>inc{b}\t{%1, %b0|%b0, %1}";
6648 gcc_assert (operands[2] == constm1_rtx);
6649 return "<nf_prefix>dec{b}\t{%1, %b0|%b0, %1}";
6653 if (x86_maybe_negate_const_int (&operands[2], QImode))
6654 return "<nf_prefix>sub{b}\t{%2, %1, %b0|%b0, %1, %2}";
6655 return "<nf_prefix>add{b}\t{%2, %1, %b0|%b0, %1, %2}";
6659 (cond [(match_operand:QI 2 "incdec_operand")
6660 (const_string "incdec")
6662 (const_string "alu")))
6663 (set (attr "length_immediate")
6665 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6667 (const_string "*")))
6668 (set_attr "has_nf" "1")
6669 (set_attr "mode" "QI")])
6671 (define_insn "*addhi_1_zext<mode><nf_name>"
6672 [(set (match_operand:SWI48x 0 "register_operand" "=r,r")
6674 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,r")
6675 (match_operand:HI 2 "general_operand" "rn,m"))))]
6676 "TARGET_APX_NDD && <nf_condition>
6677 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6679 switch (get_attr_type (insn))
6682 if (operands[2] == const1_rtx)
6683 return "<nf_prefix>inc{w}\t{%1, %w0|%w0, %1}";
6686 gcc_assert (operands[2] == constm1_rtx);
6687 return "<nf_prefix>dec{w}\t{%1, %w0|%w0, %1}";
6691 if (x86_maybe_negate_const_int (&operands[2], HImode))
6692 return "<nf_prefix>sub{w}\t{%2, %1, %w0|%w0, %1, %2}";
6693 return "<nf_prefix>add{w}\t{%2, %1, %w0|%w0, %1, %2}";
6697 (cond [(match_operand:QI 2 "incdec_operand")
6698 (const_string "incdec")
6700 (const_string "alu")))
6701 (set (attr "length_immediate")
6703 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6705 (const_string "*")))
6706 (set_attr "has_nf" "1")
6707 (set_attr "mode" "HI")])
6709 ;; It may seem that nonimmediate operand is proper one for operand 1.
6710 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6711 ;; we take care in ix86_binary_operator_ok to not allow two memory
6712 ;; operands so proper swapping will be done in reload. This allow
6713 ;; patterns constructed from addsi_1 to match.
6715 (define_insn "addsi_1_zext"
6716 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r")
6718 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r,r,rm,rjM")
6719 (match_operand:SI 2 "x86_64_general_operand" "rBMe,0,le,rBMe,r,e"))))
6720 (clobber (reg:CC FLAGS_REG))]
6722 && ix86_binary_operator_ok (PLUS, SImode, operands, TARGET_APX_NDD)"
6724 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
6725 switch (get_attr_type (insn))
6731 if (operands[2] == const1_rtx)
6732 return use_ndd ? "inc{l}\t{%1, %k0|%k0, %1}"
6736 gcc_assert (operands[2] == constm1_rtx);
6737 return use_ndd ? "dec{l}\t{%1, %k0|%k0, %1}"
6742 /* For most processors, ADD is faster than LEA. This alternative
6743 was added to use ADD as much as possible. */
6744 if (which_alternative == 1)
6745 std::swap (operands[1], operands[2]);
6747 if (x86_maybe_negate_const_int (&operands[2], SImode))
6748 return use_ndd ? "sub{l}\t{%2 ,%1, %k0|%k0, %1, %2}"
6749 : "sub{l}\t{%2, %k0|%k0, %2}";
6751 return use_ndd ? "add{l}\t{%2 ,%1, %k0|%k0, %1, %2}"
6752 : "add{l}\t{%2, %k0|%k0, %2}";
6755 [(set_attr "isa" "*,*,*,apx_ndd,apx_ndd,apx_ndd")
6757 (cond [(eq_attr "alternative" "2")
6758 (const_string "lea")
6759 (match_operand:SI 2 "incdec_operand")
6760 (const_string "incdec")
6762 (const_string "alu")))
6763 (set (attr "length_immediate")
6765 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6767 (const_string "*")))
6768 (set_attr "mode" "SI")])
6770 (define_insn "*addhi_1<nf_name>"
6771 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp,r,r")
6772 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp,rm,r")
6773 (match_operand:HI 2 "general_operand" "rn,m,0,ln,rn,m")))]
6774 "ix86_binary_operator_ok (PLUS, HImode, operands, TARGET_APX_NDD)
6777 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
6778 switch (get_attr_type (insn))
6781 if (TARGET_APX_NDD && <nf_applied>)
6782 return "%{nf%} add{w}\t{%2, %1, %0|%0, %1, %2}";
6787 if (operands[2] == const1_rtx)
6788 return use_ndd ? "<nf_prefix>inc{w}\t{%1, %0|%0, %1}"
6789 : "<nf_prefix>inc{w}\t%0";
6792 gcc_assert (operands[2] == constm1_rtx);
6793 return use_ndd ? "<nf_prefix>dec{w}\t{%1, %0|%0, %1}"
6794 : "<nf_prefix>dec{w}\t%0";
6798 /* For most processors, ADD is faster than LEA. This alternative
6799 was added to use ADD as much as possible. */
6800 if (which_alternative == 2)
6801 std::swap (operands[1], operands[2]);
6803 if (x86_maybe_negate_const_int (&operands[2], HImode))
6804 return use_ndd ? "<nf_prefix>sub{w}\t{%2, %1, %0|%0, %1, %2}"
6805 : "<nf_prefix>sub{w}\t{%2, %0|%0, %2}";
6807 return use_ndd ? "<nf_prefix>add{w}\t{%2, %1, %0|%0, %1, %2}"
6808 : "<nf_prefix>add{w}\t{%2, %0|%0, %2}";
6811 [(set_attr "isa" "*,*,*,*,apx_ndd,apx_ndd")
6813 (cond [(eq_attr "alternative" "3")
6814 (const_string "lea")
6815 (match_operand:HI 2 "incdec_operand")
6816 (const_string "incdec")
6818 (const_string "alu")))
6819 (set (attr "length_immediate")
6821 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6823 (const_string "*")))
6824 (set_attr "has_nf" "1")
6825 (set_attr "mode" "HI,HI,HI,SI,HI,HI")])
6827 (define_insn "*addqi_1<nf_name>"
6828 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp,r,r")
6829 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp,rm,r")
6830 (match_operand:QI 2 "general_operand" "qn,m,0,rn,0,ln,rn,m")))]
6831 "ix86_binary_operator_ok (PLUS, QImode, operands, TARGET_APX_NDD)
6834 bool widen = (get_attr_mode (insn) != MODE_QI);
6835 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
6836 switch (get_attr_type (insn))
6839 if (TARGET_APX_NDD && <nf_applied>)
6840 return "%{nf%} add{b}\t{%2, %1, %0|%0, %1, %2}";
6845 if (operands[2] == const1_rtx)
6847 return "<nf_prefix>inc{b}\t{%1, %0|%0, %1}";
6849 return widen ? "<nf_prefix>inc{l}\t%k0" : "<nf_prefix>inc{b}\t%0";
6852 gcc_assert (operands[2] == constm1_rtx);
6854 return "<nf_prefix>dec{b}\t{%1, %0|%0, %1}";
6856 return widen ? "<nf_prefix>dec{l}\t%k0" : "<nf_prefix>dec{b}\t%0";
6860 /* For most processors, ADD is faster than LEA. These alternatives
6861 were added to use ADD as much as possible. */
6862 if (which_alternative == 2 || which_alternative == 4)
6863 std::swap (operands[1], operands[2]);
6865 if (x86_maybe_negate_const_int (&operands[2], QImode))
6868 return "<nf_prefix>sub{b}\t{%2, %1, %0|%0, %1, %2}";
6870 return widen ? "<nf_prefix>sub{l}\t{%2, %k0|%k0, %2}"
6871 : "<nf_prefix>sub{b}\t{%2, %0|%0, %2}";
6874 return "<nf_prefix>add{b}\t{%2, %1, %0|%0, %1, %2}";
6876 return widen ? "<nf_prefix>add{l}\t{%k2, %k0|%k0, %k2}"
6877 : "<nf_prefix>add{b}\t{%2, %0|%0, %2}";
6880 [(set_attr "isa" "*,*,*,*,*,*,apx_ndd,apx_ndd")
6882 (cond [(eq_attr "alternative" "5")
6883 (const_string "lea")
6884 (match_operand:QI 2 "incdec_operand")
6885 (const_string "incdec")
6887 (const_string "alu")))
6888 (set (attr "length_immediate")
6890 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6892 (const_string "*")))
6893 (set_attr "has_nf" "1")
6894 (set_attr "mode" "QI,QI,QI,SI,SI,SI,QI,QI")
6895 ;; Potential partial reg stall on alternatives 3 and 4.
6896 (set (attr "preferred_for_speed")
6897 (cond [(eq_attr "alternative" "3,4")
6898 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
6899 (symbol_ref "true")))])
6901 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
6902 (define_insn_and_split "*add<mode>_1_slp"
6903 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
6904 (plus:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0,!<r>")
6905 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
6906 (clobber (reg:CC FLAGS_REG))]
6907 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6909 if (which_alternative)
6912 switch (get_attr_type (insn))
6915 if (operands[2] == const1_rtx)
6916 return "inc{<imodesuffix>}\t%0";
6919 gcc_assert (operands[2] == constm1_rtx);
6920 return "dec{<imodesuffix>}\t%0";
6924 if (x86_maybe_negate_const_int (&operands[2], QImode))
6925 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6927 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6930 "&& reload_completed
6931 && !(rtx_equal_p (operands[0], operands[1])
6932 || rtx_equal_p (operands[0], operands[2]))"
6933 [(set (strict_low_part (match_dup 0)) (match_dup 1))
6935 [(set (strict_low_part (match_dup 0))
6936 (plus:SWI12 (match_dup 0) (match_dup 2)))
6937 (clobber (reg:CC FLAGS_REG))])]
6940 (if_then_else (match_operand:QI 2 "incdec_operand")
6941 (const_string "incdec")
6942 (const_string "alu")))
6943 (set_attr "mode" "<MODE>")])
6945 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
6946 (define_insn_and_split "*addqi_ext<mode>_1_slp"
6947 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+Q,&Q"))
6950 (match_operator:SWI248 3 "extract_operator"
6951 [(match_operand 2 "int248_register_operand" "Q,Q")
6954 (match_operand:QI 1 "nonimmediate_operand" "0,!qm")))
6955 (clobber (reg:CC FLAGS_REG))]
6956 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6958 add{b}\t{%h2, %0|%0, %h2}
6960 "&& reload_completed
6961 && !rtx_equal_p (operands[0], operands[1])"
6962 [(set (strict_low_part (match_dup 0)) (match_dup 1))
6964 [(set (strict_low_part (match_dup 0))
6968 [(match_dup 2) (const_int 8) (const_int 8)]) 0)
6970 (clobber (reg:CC FLAGS_REG))])]
6972 [(set_attr "type" "alu")
6973 (set_attr "mode" "QI")])
6975 (define_insn_and_split "*addqi_ext<mode>_2_slp"
6976 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+&Q"))
6979 (match_operator:SWI248 3 "extract_operator"
6980 [(match_operand 1 "int248_register_operand" "Q")
6984 (match_operator:SWI248 4 "extract_operator"
6985 [(match_operand 2 "int248_register_operand" "Q")
6987 (const_int 8)]) 0)))
6988 (clobber (reg:CC FLAGS_REG))]
6989 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6991 "&& reload_completed"
6992 [(set (strict_low_part (match_dup 0))
6995 [(match_dup 2) (const_int 8) (const_int 8)]) 0))
6997 [(set (strict_low_part (match_dup 0))
7001 [(match_dup 1) (const_int 8) (const_int 8)]) 0)
7003 (clobber (reg:CC FLAGS_REG))])]
7005 [(set_attr "type" "alu")
7006 (set_attr "mode" "QI")])
7008 ;; Split non destructive adds if we cannot use lea.
7010 [(set (match_operand:SWI48 0 "register_operand")
7011 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
7012 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
7013 (clobber (reg:CC FLAGS_REG))]
7014 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
7015 [(set (match_dup 0) (match_dup 1))
7016 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
7017 (clobber (reg:CC FLAGS_REG))])])
7019 ;; Split non destructive adds if we cannot use lea.
7021 [(set (match_operand:DI 0 "register_operand")
7023 (plus:SI (match_operand:SI 1 "register_operand")
7024 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
7025 (clobber (reg:CC FLAGS_REG))]
7027 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
7028 [(set (match_dup 3) (match_dup 1))
7029 (parallel [(set (match_dup 0)
7030 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
7031 (clobber (reg:CC FLAGS_REG))])]
7032 "operands[3] = gen_lowpart (SImode, operands[0]);")
7034 ;; Convert add to the lea pattern to avoid flags dependency.
7036 [(set (match_operand:SWI 0 "register_operand")
7037 (plus:SWI (match_operand:SWI 1 "register_operand")
7038 (match_operand:SWI 2 "<nonmemory_operand>")))
7039 (clobber (reg:CC FLAGS_REG))]
7040 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
7042 (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
7044 if (<MODE>mode != <LEAMODE>mode)
7046 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
7047 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
7048 operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
7053 [(set (match_operand:SWI 0 "register_operand")
7054 (plus:SWI (match_operand:SWI 1 "register_operand")
7055 (match_operand:SWI 2 "<nonmemory_operand>")))]
7056 "TARGET_APX_NF && reload_completed
7057 && ix86_lea_for_add_ok (insn, operands)"
7059 (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
7061 if (<MODE>mode != <LEAMODE>mode)
7063 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
7064 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
7065 operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
7069 ;; Convert add to the lea pattern to avoid flags dependency.
7071 [(set (match_operand:DI 0 "register_operand")
7073 (plus:SI (match_operand:SI 1 "register_operand")
7074 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
7075 (clobber (reg:CC FLAGS_REG))]
7076 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
7078 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
7080 (define_insn "*add<mode>_2"
7081 [(set (reg FLAGS_REG)
7084 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>,rm,r")
7085 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,0,r<i>,<m>"))
7087 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,<r>,r,r")
7088 (plus:SWI (match_dup 1) (match_dup 2)))]
7089 "ix86_match_ccmode (insn, CCGOCmode)
7090 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)"
7092 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
7093 switch (get_attr_type (insn))
7096 if (operands[2] == const1_rtx)
7097 return use_ndd ? "inc{<imodesuffix>}\t{%1, %0|%0, %1}"
7098 : "inc{<imodesuffix>}\t%0";
7101 gcc_assert (operands[2] == constm1_rtx);
7102 return use_ndd ? "dec{<imodesuffix>}\t{%1, %0|%0, %1}"
7103 : "dec{<imodesuffix>}\t%0";
7107 if (which_alternative == 2)
7108 std::swap (operands[1], operands[2]);
7110 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
7111 return use_ndd ? "sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7112 : "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
7114 return use_ndd ? "add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7115 : "add{<imodesuffix>}\t{%2, %0|%0, %2}";
7118 [(set_attr "isa" "*,*,*,apx_ndd,apx_ndd")
7120 (if_then_else (match_operand:SWI 2 "incdec_operand")
7121 (const_string "incdec")
7122 (const_string "alu")))
7123 (set (attr "length_immediate")
7125 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
7127 (const_string "*")))
7128 (set_attr "mode" "<MODE>")])
7130 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7131 (define_insn "*addsi_2_zext"
7132 [(set (reg FLAGS_REG)
7134 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r,rm")
7135 (match_operand:SI 2 "x86_64_general_operand" "rBMe,0,rBMe,re"))
7137 (set (match_operand:DI 0 "register_operand" "=r,r,r,r")
7138 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
7139 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7140 && ix86_binary_operator_ok (PLUS, SImode, operands, TARGET_APX_NDD)"
7142 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
7143 switch (get_attr_type (insn))
7146 if (operands[2] == const1_rtx)
7147 return use_ndd ? "inc{l}\t{%1, %k0|%k0, %1}"
7151 gcc_assert (operands[2] == constm1_rtx);
7152 return use_ndd ? "dec{l}\t{%1, %k0|%k0, %1}"
7157 if (which_alternative == 1)
7158 std::swap (operands[1], operands[2]);
7160 if (x86_maybe_negate_const_int (&operands[2], SImode))
7161 return use_ndd ? "sub{l}\t{%2, %1, %k0|%k0, %1, %2}"
7162 : "sub{l}\t{%2, %k0|%k0, %2}";
7164 return use_ndd ? "add{l}\t{%2, %1, %k0|%k0, %1, %2}"
7165 : "add{l}\t{%2, %k0|%k0, %2}";
7168 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
7170 (if_then_else (match_operand:SI 2 "incdec_operand")
7171 (const_string "incdec")
7172 (const_string "alu")))
7173 (set (attr "length_immediate")
7175 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
7177 (const_string "*")))
7178 (set_attr "mode" "SI")])
7180 (define_insn "*add<mode>_3"
7181 [(set (reg FLAGS_REG)
7183 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0,<g>,re"))
7184 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>,r,rm")))
7185 (clobber (match_scratch:SWI 0 "=<r>,<r>,r,r"))]
7186 "ix86_match_ccmode (insn, CCZmode)
7187 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7189 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
7190 switch (get_attr_type (insn))
7193 if (operands[2] == const1_rtx)
7194 return use_ndd ? "inc{<imodesuffix>}\t{%1, %0|%0, %1}"
7195 : "inc{<imodesuffix>}\t%0";
7198 gcc_assert (operands[2] == constm1_rtx);
7199 return use_ndd ? "dec{<imodesuffix>}\t{%1, %0|%0, %1}"
7200 : "dec{<imodesuffix>}\t%0";
7204 if (which_alternative == 1)
7205 std::swap (operands[1], operands[2]);
7207 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
7208 return use_ndd ? "sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7209 : "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
7211 return use_ndd ? "add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7212 : "add{<imodesuffix>}\t{%2, %0|%0, %2}";
7215 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
7217 (if_then_else (match_operand:SWI 2 "incdec_operand")
7218 (const_string "incdec")
7219 (const_string "alu")))
7220 (set (attr "length_immediate")
7222 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
7224 (const_string "*")))
7225 (set_attr "mode" "<MODE>")])
7227 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7228 (define_insn "*addsi_3_zext"
7229 [(set (reg FLAGS_REG)
7231 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rBMe,0,rBMe,re"))
7232 (match_operand:SI 1 "nonimmediate_operand" "%0,r,r,rm")))
7233 (set (match_operand:DI 0 "register_operand" "=r,r,r,r")
7234 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
7235 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
7236 && ix86_binary_operator_ok (PLUS, SImode, operands, TARGET_APX_NDD)"
7238 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
7239 switch (get_attr_type (insn))
7242 if (operands[2] == const1_rtx)
7243 return use_ndd ? "inc{l}\t{%1, %k0|%k0, %1}" : "inc{l}\t%k0";
7246 gcc_assert (operands[2] == constm1_rtx);
7247 return use_ndd ? "dec{l}\t{%1, %k0|%k0, %1}" : "dec{l}\t%k0";
7251 if (which_alternative == 1)
7252 std::swap (operands[1], operands[2]);
7254 if (x86_maybe_negate_const_int (&operands[2], SImode))
7255 return use_ndd ? "sub{l}\t{%2, %1, %k0|%k0, %1, %2}"
7256 : "sub{l}\t{%2, %k0|%k0, %2}";
7258 return use_ndd ? "add{l}\t{%2, %1, %k0|%k0, %1, %2}"
7259 : "add{l}\t{%2, %k0|%k0, %2}";
7262 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
7264 (if_then_else (match_operand:SI 2 "incdec_operand")
7265 (const_string "incdec")
7266 (const_string "alu")))
7267 (set (attr "length_immediate")
7269 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
7271 (const_string "*")))
7272 (set_attr "mode" "SI")])
7274 ; For comparisons against 1, -1 and 128, we may generate better code
7275 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
7276 ; is matched then. We can't accept general immediate, because for
7277 ; case of overflows, the result is messed up.
7278 ; Also carry flag is reversed compared to cmp, so this conversion is valid
7279 ; only for comparisons not depending on it.
7281 (define_insn "*adddi_4"
7282 [(set (reg FLAGS_REG)
7284 (match_operand:DI 1 "nonimmediate_operand" "0")
7285 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
7286 (clobber (match_scratch:DI 0 "=r"))]
7288 && ix86_match_ccmode (insn, CCGCmode)"
7290 switch (get_attr_type (insn))
7293 if (operands[2] == constm1_rtx)
7294 return "inc{q}\t%0";
7297 gcc_assert (operands[2] == const1_rtx);
7298 return "dec{q}\t%0";
7302 if (x86_maybe_negate_const_int (&operands[2], DImode))
7303 return "add{q}\t{%2, %0|%0, %2}";
7305 return "sub{q}\t{%2, %0|%0, %2}";
7309 (if_then_else (match_operand:DI 2 "incdec_operand")
7310 (const_string "incdec")
7311 (const_string "alu")))
7312 (set (attr "length_immediate")
7314 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
7316 (const_string "*")))
7317 (set_attr "mode" "DI")])
7319 ; For comparisons against 1, -1 and 128, we may generate better code
7320 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
7321 ; is matched then. We can't accept general immediate, because for
7322 ; case of overflows, the result is messed up.
7323 ; Also carry flag is reversed compared to cmp, so this conversion is valid
7324 ; only for comparisons not depending on it.
7326 (define_insn "*add<mode>_4"
7327 [(set (reg FLAGS_REG)
7329 (match_operand:SWI124 1 "nonimmediate_operand" "0")
7330 (match_operand:SWI124 2 "const_int_operand")))
7331 (clobber (match_scratch:SWI124 0 "=<r>"))]
7332 "ix86_match_ccmode (insn, CCGCmode)"
7334 switch (get_attr_type (insn))
7337 if (operands[2] == constm1_rtx)
7338 return "inc{<imodesuffix>}\t%0";
7341 gcc_assert (operands[2] == const1_rtx);
7342 return "dec{<imodesuffix>}\t%0";
7346 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
7347 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
7349 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
7353 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
7354 (const_string "incdec")
7355 (const_string "alu")))
7356 (set (attr "length_immediate")
7358 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
7360 (const_string "*")))
7361 (set_attr "mode" "<MODE>")])
7363 (define_insn "*add<mode>_5"
7364 [(set (reg FLAGS_REG)
7367 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>,r,rm")
7368 (match_operand:SWI 2 "<general_operand>" "<g>,0,<g>,re"))
7370 (clobber (match_scratch:SWI 0 "=<r>,<r>,r,r"))]
7371 "ix86_match_ccmode (insn, CCGOCmode)
7372 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7374 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
7375 switch (get_attr_type (insn))
7378 if (operands[2] == const1_rtx)
7379 return use_ndd ? "inc{<imodesuffix>}\t{%1, %0|%0, %1}"
7380 : "inc{<imodesuffix>}\t%0";
7383 gcc_assert (operands[2] == constm1_rtx);
7384 return use_ndd ? "dec{<imodesuffix>}\t{%1, %0|%0, %1}"
7385 : "dec{<imodesuffix>}\t%0";
7389 if (which_alternative == 1)
7390 std::swap (operands[1], operands[2]);
7392 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
7393 return use_ndd ? "sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7394 : "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
7396 return use_ndd ? "add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7397 : "add{<imodesuffix>}\t{%2, %0|%0, %2}";
7400 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
7402 (if_then_else (match_operand:SWI 2 "incdec_operand")
7403 (const_string "incdec")
7404 (const_string "alu")))
7405 (set (attr "length_immediate")
7407 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
7409 (const_string "*")))
7410 (set_attr "mode" "<MODE>")])
7412 (define_insn "*addqi_ext<mode>_0"
7413 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn")
7416 (match_operator:SWI248 3 "extract_operator"
7417 [(match_operand 2 "int248_register_operand" "Q")
7420 (match_operand:QI 1 "nonimmediate_operand" "0")))
7421 (clobber (reg:CC FLAGS_REG))]
7423 "add{b}\t{%h2, %0|%0, %h2}"
7424 [(set_attr "addr" "gpr8")
7425 (set_attr "type" "alu")
7426 (set_attr "mode" "QI")])
7428 (define_insn_and_split "*addqi_ext2<mode>_0"
7429 [(set (match_operand:QI 0 "register_operand" "=&Q")
7432 (match_operator:SWI248 3 "extract_operator"
7433 [(match_operand 1 "int248_register_operand" "Q")
7437 (match_operator:SWI248 4 "extract_operator"
7438 [(match_operand 2 "int248_register_operand" "Q")
7440 (const_int 8)]) 0)))
7441 (clobber (reg:CC FLAGS_REG))]
7444 "&& reload_completed"
7448 [(match_dup 2) (const_int 8) (const_int 8)]) 0))
7454 [(match_dup 1) (const_int 8) (const_int 8)]) 0)
7456 (clobber (reg:CC FLAGS_REG))])]
7458 [(set_attr "type" "alu")
7459 (set_attr "mode" "QI")])
7461 (define_expand "addqi_ext_1"
7463 [(set (zero_extract:HI (match_operand:HI 0 "register_operand")
7469 (zero_extract:HI (match_operand:HI 1 "register_operand")
7472 (match_operand:QI 2 "const_int_operand")) 0))
7473 (clobber (reg:CC FLAGS_REG))])])
7475 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
7476 (define_insn_and_split "*addqi_ext<mode>_1"
7477 [(set (zero_extract:SWI248
7478 (match_operand 0 "int248_register_operand" "+Q,&Q")
7484 (match_operator:SWI248 3 "extract_operator"
7485 [(match_operand 1 "int248_register_operand" "0,!Q")
7488 (match_operand:QI 2 "general_operand" "QnBn,QnBn")) 0))
7489 (clobber (reg:CC FLAGS_REG))]
7492 if (which_alternative)
7495 switch (get_attr_type (insn))
7498 if (operands[2] == const1_rtx)
7499 return "inc{b}\t%h0";
7502 gcc_assert (operands[2] == constm1_rtx);
7503 return "dec{b}\t%h0";
7507 return "add{b}\t{%2, %h0|%h0, %2}";
7511 && !rtx_equal_p (operands[0], operands[1])"
7512 [(set (zero_extract:SWI248
7513 (match_dup 0) (const_int 8) (const_int 8))
7514 (zero_extract:SWI248
7515 (match_dup 1) (const_int 8) (const_int 8)))
7517 [(set (zero_extract:SWI248
7518 (match_dup 0) (const_int 8) (const_int 8))
7523 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
7525 (clobber (reg:CC FLAGS_REG))])]
7527 [(set_attr "addr" "gpr8")
7529 (if_then_else (match_operand:QI 2 "incdec_operand")
7530 (const_string "incdec")
7531 (const_string "alu")))
7532 (set_attr "mode" "QI")])
7534 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
7535 (define_insn_and_split "*<insn>qi_ext<mode>_2"
7536 [(set (zero_extract:SWI248
7537 (match_operand 0 "int248_register_operand" "+Q,&Q")
7543 (match_operator:SWI248 3 "extract_operator"
7544 [(match_operand 1 "int248_register_operand" "<comm>0,!Q")
7548 (match_operator:SWI248 4 "extract_operator"
7549 [(match_operand 2 "int248_register_operand" "Q,Q")
7551 (const_int 8)]) 0)) 0))
7552 (clobber (reg:CC FLAGS_REG))]
7555 <insn>{b}\t{%h2, %h0|%h0, %h2}
7558 && !(rtx_equal_p (operands[0], operands[1])
7559 || (<CODE> == PLUS && rtx_equal_p (operands[0], operands[2])))"
7560 [(set (zero_extract:SWI248
7561 (match_dup 0) (const_int 8) (const_int 8))
7562 (zero_extract:SWI248
7563 (match_dup 1) (const_int 8) (const_int 8)))
7565 [(set (zero_extract:SWI248
7566 (match_dup 0) (const_int 8) (const_int 8))
7571 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
7574 [(match_dup 2) (const_int 8) (const_int 8)]) 0)) 0))
7575 (clobber (reg:CC FLAGS_REG))])]
7577 [(set_attr "type" "alu")
7578 (set_attr "mode" "QI")])
7580 ;; Like DWI, but use POImode instead of OImode.
7581 (define_mode_attr DPWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI") (TI "POI")])
7583 ;; Add with jump on overflow.
7584 (define_expand "addv<mode>4"
7585 [(parallel [(set (reg:CCO FLAGS_REG)
7589 (match_operand:SWIDWI 1 "nonimmediate_operand"))
7592 (plus:SWIDWI (match_dup 1)
7593 (match_operand:SWIDWI 2
7594 "<general_hilo_operand>")))))
7595 (set (match_operand:SWIDWI 0 "register_operand")
7596 (plus:SWIDWI (match_dup 1) (match_dup 2)))])
7597 (set (pc) (if_then_else
7598 (eq (reg:CCO FLAGS_REG) (const_int 0))
7599 (label_ref (match_operand 3))
7603 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
7604 if (CONST_SCALAR_INT_P (operands[2]))
7605 operands[4] = operands[2];
7607 operands[4] = gen_rtx_SIGN_EXTEND (<DPWI>mode, operands[2]);
7610 (define_insn "*addv<mode>4"
7611 [(set (reg:CCO FLAGS_REG)
7614 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,rm,r"))
7616 (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m,rWe,m")))
7618 (plus:SWI (match_dup 1) (match_dup 2)))))
7619 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r")
7620 (plus:SWI (match_dup 1) (match_dup 2)))]
7621 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)"
7623 add{<imodesuffix>}\t{%2, %0|%0, %2}
7624 add{<imodesuffix>}\t{%2, %0|%0, %2}
7625 add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7626 add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7627 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
7628 (set_attr "type" "alu")
7629 (set_attr "mode" "<MODE>")])
7631 (define_insn "addv<mode>4_1"
7632 [(set (reg:CCO FLAGS_REG)
7635 (match_operand:SWI 1 "nonimmediate_operand" "0,rm"))
7636 (match_operand:<DWI> 3 "const_int_operand"))
7640 (match_operand:SWI 2 "x86_64_immediate_operand" "<i>,<i>")))))
7641 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,r")
7642 (plus:SWI (match_dup 1) (match_dup 2)))]
7643 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)
7644 && CONST_INT_P (operands[2])
7645 && INTVAL (operands[2]) == INTVAL (operands[3])"
7647 add{<imodesuffix>}\t{%2, %0|%0, %2}
7648 add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7649 [(set_attr "isa" "*,apx_ndd")
7650 (set_attr "type" "alu")
7651 (set_attr "mode" "<MODE>")
7652 (set (attr "length_immediate")
7653 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7655 (match_test "<MODE_SIZE> == 8")
7657 (const_string "<MODE_SIZE>")))])
7659 ;; Quad word integer modes as mode attribute.
7660 (define_mode_attr QPWI [(SI "TI") (DI "POI")])
7662 (define_insn_and_split "*addv<dwi>4_doubleword"
7663 [(set (reg:CCO FLAGS_REG)
7667 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0,ro,r"))
7669 (match_operand:<DWI> 2 "nonimmediate_operand" "r,o,r,o")))
7671 (plus:<DWI> (match_dup 1) (match_dup 2)))))
7672 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,&r,&r")
7673 (plus:<DWI> (match_dup 1) (match_dup 2)))]
7674 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands, TARGET_APX_NDD)"
7676 "&& reload_completed"
7677 [(parallel [(set (reg:CCC FLAGS_REG)
7679 (plus:DWIH (match_dup 1) (match_dup 2))
7682 (plus:DWIH (match_dup 1) (match_dup 2)))])
7683 (parallel [(set (reg:CCO FLAGS_REG)
7687 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7688 (sign_extend:<DWI> (match_dup 4)))
7689 (sign_extend:<DWI> (match_dup 5)))
7693 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7699 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7703 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7705 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")])
7707 (define_insn_and_split "*addv<dwi>4_doubleword_1"
7708 [(set (reg:CCO FLAGS_REG)
7712 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,rjO"))
7713 (match_operand:<QPWI> 3 "const_scalar_int_operand" "n,n"))
7717 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>,<di>")))))
7718 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,&r")
7719 (plus:<DWI> (match_dup 1) (match_dup 2)))]
7720 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands, TARGET_APX_NDD)
7721 && CONST_SCALAR_INT_P (operands[2])
7722 && rtx_equal_p (operands[2], operands[3])"
7724 "&& reload_completed"
7725 [(parallel [(set (reg:CCC FLAGS_REG)
7727 (plus:DWIH (match_dup 1) (match_dup 2))
7730 (plus:DWIH (match_dup 1) (match_dup 2)))])
7731 (parallel [(set (reg:CCO FLAGS_REG)
7735 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7736 (sign_extend:<DWI> (match_dup 4)))
7741 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7747 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7751 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7752 if (operands[2] == const0_rtx)
7754 if (!rtx_equal_p (operands[0], operands[1]))
7755 emit_move_insn (operands[0], operands[1]);
7756 emit_insn (gen_addv<mode>4_1 (operands[3], operands[4], operands[5],
7761 [(set_attr "isa" "*,apx_ndd")])
7763 (define_insn "*addv<mode>4_overflow_1"
7764 [(set (reg:CCO FLAGS_REG)
7768 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7769 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7771 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,rm,r")))
7773 (match_operand:SWI 2 "<general_sext_operand>" "rWe,m,rWe,m")))
7777 (match_operator:SWI 5 "ix86_carry_flag_operator"
7778 [(match_dup 3) (const_int 0)])
7781 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r,r,r")
7784 (match_op_dup 5 [(match_dup 3) (const_int 0)])
7787 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)"
7789 adc{<imodesuffix>}\t{%2, %0|%0, %2}
7790 adc{<imodesuffix>}\t{%2, %0|%0, %2}
7791 adc{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7792 adc{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7793 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
7794 (set_attr "type" "alu")
7795 (set_attr "mode" "<MODE>")])
7797 (define_insn "*addv<mode>4_overflow_2"
7798 [(set (reg:CCO FLAGS_REG)
7802 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7803 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7805 (match_operand:SWI 1 "nonimmediate_operand" "%0,rm")))
7806 (match_operand:<DWI> 6 "const_int_operand" "n,n"))
7810 (match_operator:SWI 5 "ix86_carry_flag_operator"
7811 [(match_dup 3) (const_int 0)])
7813 (match_operand:SWI 2 "x86_64_immediate_operand" "e,e")))))
7814 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r")
7817 (match_op_dup 5 [(match_dup 3) (const_int 0)])
7820 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)
7821 && CONST_INT_P (operands[2])
7822 && INTVAL (operands[2]) == INTVAL (operands[6])"
7824 adc{<imodesuffix>}\t{%2, %0|%0, %2}
7825 adc{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7826 [(set_attr "isa" "*,apx_ndd")
7827 (set_attr "type" "alu")
7828 (set_attr "mode" "<MODE>")
7829 (set (attr "length_immediate")
7830 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7832 (const_string "4")))])
7834 (define_expand "uaddv<mode>4"
7835 [(parallel [(set (reg:CCC FLAGS_REG)
7838 (match_operand:SWIDWI 1 "nonimmediate_operand")
7839 (match_operand:SWIDWI 2 "<general_hilo_operand>"))
7841 (set (match_operand:SWIDWI 0 "register_operand")
7842 (plus:SWIDWI (match_dup 1) (match_dup 2)))])
7843 (set (pc) (if_then_else
7844 (ltu (reg:CCC FLAGS_REG) (const_int 0))
7845 (label_ref (match_operand 3))
7848 "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
7850 ;; The lea patterns for modes less than 32 bits need to be matched by
7851 ;; several insns converted to real lea by splitters.
7853 (define_insn_and_split "*lea<mode>_general_1"
7854 [(set (match_operand:SWI12 0 "register_operand" "=r")
7856 (plus:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7857 (match_operand:SWI12 2 "register_operand" "r"))
7858 (match_operand:SWI12 3 "immediate_operand" "i")))]
7859 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7861 "&& reload_completed"
7864 (plus:SI (match_dup 1) (match_dup 2))
7867 operands[0] = gen_lowpart (SImode, operands[0]);
7868 operands[1] = gen_lowpart (SImode, operands[1]);
7869 operands[2] = gen_lowpart (SImode, operands[2]);
7870 operands[3] = gen_lowpart (SImode, operands[3]);
7872 [(set_attr "type" "lea")
7873 (set_attr "mode" "SI")])
7875 (define_insn_and_split "*lea<mode>_general_2"
7876 [(set (match_operand:SWI12 0 "register_operand" "=r")
7878 (mult:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7879 (match_operand 2 "const248_operand" "n"))
7880 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
7881 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7883 "&& reload_completed"
7886 (mult:SI (match_dup 1) (match_dup 2))
7889 operands[0] = gen_lowpart (SImode, operands[0]);
7890 operands[1] = gen_lowpart (SImode, operands[1]);
7891 operands[3] = gen_lowpart (SImode, operands[3]);
7893 [(set_attr "type" "lea")
7894 (set_attr "mode" "SI")])
7896 (define_insn_and_split "*lea<mode>_general_2b"
7897 [(set (match_operand:SWI12 0 "register_operand" "=r")
7899 (ashift:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7900 (match_operand 2 "const123_operand" "n"))
7901 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
7902 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7904 "&& reload_completed"
7907 (ashift:SI (match_dup 1) (match_dup 2))
7910 operands[0] = gen_lowpart (SImode, operands[0]);
7911 operands[1] = gen_lowpart (SImode, operands[1]);
7912 operands[3] = gen_lowpart (SImode, operands[3]);
7914 [(set_attr "type" "lea")
7915 (set_attr "mode" "SI")])
7917 (define_insn_and_split "*lea<mode>_general_3"
7918 [(set (match_operand:SWI12 0 "register_operand" "=r")
7921 (mult:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7922 (match_operand 2 "const248_operand" "n"))
7923 (match_operand:SWI12 3 "register_operand" "r"))
7924 (match_operand:SWI12 4 "immediate_operand" "i")))]
7925 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7927 "&& reload_completed"
7931 (mult:SI (match_dup 1) (match_dup 2))
7935 operands[0] = gen_lowpart (SImode, operands[0]);
7936 operands[1] = gen_lowpart (SImode, operands[1]);
7937 operands[3] = gen_lowpart (SImode, operands[3]);
7938 operands[4] = gen_lowpart (SImode, operands[4]);
7940 [(set_attr "type" "lea")
7941 (set_attr "mode" "SI")])
7943 (define_insn_and_split "*lea<mode>_general_3b"
7944 [(set (match_operand:SWI12 0 "register_operand" "=r")
7947 (ashift:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7948 (match_operand 2 "const123_operand" "n"))
7949 (match_operand:SWI12 3 "register_operand" "r"))
7950 (match_operand:SWI12 4 "immediate_operand" "i")))]
7951 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7953 "&& reload_completed"
7957 (ashift:SI (match_dup 1) (match_dup 2))
7961 operands[0] = gen_lowpart (SImode, operands[0]);
7962 operands[1] = gen_lowpart (SImode, operands[1]);
7963 operands[3] = gen_lowpart (SImode, operands[3]);
7964 operands[4] = gen_lowpart (SImode, operands[4]);
7966 [(set_attr "type" "lea")
7967 (set_attr "mode" "SI")])
7969 (define_insn_and_split "*lea<mode>_general_4"
7970 [(set (match_operand:SWI12 0 "register_operand" "=r")
7973 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7974 (match_operand 2 "const_0_to_3_operand"))
7975 (match_operand 3 "const_int_operand")))]
7976 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7977 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
7978 < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
7980 "&& reload_completed"
7983 (mult:SI (match_dup 1) (match_dup 2))
7986 operands[0] = gen_lowpart (SImode, operands[0]);
7987 operands[1] = gen_lowpart (SImode, operands[1]);
7988 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
7990 [(set_attr "type" "lea")
7991 (set_attr "mode" "SI")])
7993 (define_insn_and_split "*lea<mode>_general_4"
7994 [(set (match_operand:SWI48 0 "register_operand" "=r")
7997 (match_operand:SWI48 1 "register_no_SP_operand" "l")
7998 (match_operand 2 "const_0_to_3_operand"))
7999 (match_operand 3 "const_int_operand")))]
8000 "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
8001 < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
8003 "&& reload_completed"
8006 (mult:SWI48 (match_dup 1) (match_dup 2))
8008 "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
8009 [(set_attr "type" "lea")
8010 (set_attr "mode" "<MODE>")])
8012 ;; Subtract instructions
8014 (define_expand "sub<mode>3"
8015 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8016 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
8017 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
8020 ix86_expand_binary_operator (MINUS, <MODE>mode, operands, TARGET_APX_NDD);
8024 (define_insn_and_split "*sub<dwi>3_doubleword"
8025 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,&r,&r")
8027 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0,ro,r")
8028 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o,r<di>,o")))
8029 (clobber (reg:CC FLAGS_REG))]
8030 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)"
8032 "&& reload_completed"
8033 [(parallel [(set (reg:CC FLAGS_REG)
8034 (compare:CC (match_dup 1) (match_dup 2)))
8036 (minus:DWIH (match_dup 1) (match_dup 2)))])
8037 (parallel [(set (match_dup 3)
8041 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
8043 (clobber (reg:CC FLAGS_REG))])]
8045 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
8046 if (operands[2] == const0_rtx)
8048 if (!rtx_equal_p (operands[0], operands[1]))
8049 emit_move_insn (operands[0], operands[1]);
8050 ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3],
8055 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")])
8057 (define_insn_and_split "*sub<dwi>3_doubleword_zext"
8058 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,&r,&r")
8060 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0,r,o")
8062 (match_operand:DWIH 2 "nonimmediate_operand" "rm,r,rm,r"))))
8063 (clobber (reg:CC FLAGS_REG))]
8064 "ix86_binary_operator_ok (UNKNOWN, <DWI>mode, operands, TARGET_APX_NDD)"
8066 "&& reload_completed"
8067 [(parallel [(set (reg:CC FLAGS_REG)
8068 (compare:CC (match_dup 1) (match_dup 2)))
8070 (minus:DWIH (match_dup 1) (match_dup 2)))])
8071 (parallel [(set (match_dup 3)
8075 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
8077 (clobber (reg:CC FLAGS_REG))])]
8078 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[3]);"
8079 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")])
8081 (define_insn "*sub<mode>_1<nf_name>"
8082 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,r<nf_mem_constraint>,<r>,r,r,r")
8084 (match_operand:SWI 1 "nonimmediate_operand" "0,0,0,rm,rjM,r")
8085 (match_operand:SWI 2 "<general_operand>" "<r>,<i>,<m>,r,<i>,<m>")))]
8086 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)
8089 <nf_prefix>sub{<imodesuffix>}\t{%2, %0|%0, %2}
8090 <nf_prefix>sub{<imodesuffix>}\t{%2, %0|%0, %2}
8091 <nf_prefix>sub{<imodesuffix>}\t{%2, %0|%0, %2}
8092 <nf_prefix>sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
8093 <nf_prefix>sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
8094 <nf_prefix>sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
8095 [(set_attr "isa" "*,*,*,apx_ndd,apx_ndd,apx_ndd")
8096 (set_attr "type" "alu")
8097 (set_attr "has_nf" "1")
8098 (set_attr "mode" "<MODE>")])
8100 (define_insn "*subqi_1_zext<mode><nf_name>"
8101 [(set (match_operand:SWI248x 0 "register_operand" "=r,r")
8102 (zero_extend:SWI248x
8103 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "rm,r")
8104 (match_operand:QI 2 "x86_64_general_operand" "rn,m"))))]
8105 "TARGET_APX_NDD && <nf_condition>
8106 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8108 <nf_prefix>sub{b}\t{%2, %1, %b0|%b0, %1, %2}
8109 <nf_prefix>sub{b}\t{%2, %1, %b0|%b0, %1, %2}"
8110 [(set_attr "type" "alu")
8111 (set_attr "has_nf" "1")
8112 (set_attr "mode" "QI")])
8114 (define_insn "*subhi_1_zext<mode><nf_name>"
8115 [(set (match_operand:SWI48x 0 "register_operand" "=r,r")
8117 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "rm,r")
8118 (match_operand:HI 2 "x86_64_general_operand" "rn,m"))))]
8119 "TARGET_APX_NDD && <nf_condition>
8120 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8122 <nf_prefix>sub{w}\t{%2, %1, %w0|%w0, %1, %2}
8123 <nf_prefix>sub{w}\t{%2, %1, %w0|%w0, %1, %2}"
8124 [(set_attr "type" "alu")
8125 (set_attr "has_nf" "1")
8126 (set_attr "mode" "HI")])
8128 (define_insn "*subsi_1_zext"
8129 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
8131 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,r,rm")
8132 (match_operand:SI 2 "x86_64_general_operand" "rBMe,rBMe,re"))))
8133 (clobber (reg:CC FLAGS_REG))]
8135 && ix86_binary_operator_ok (MINUS, SImode, operands, TARGET_APX_NDD)"
8137 sub{l}\t{%2, %k0|%k0, %2}
8138 sub{l}\t{%2, %1, %k0|%k0, %1, %2}
8139 sub{l}\t{%2, %1, %k0|%k0, %1, %2}"
8140 [(set_attr "isa" "*,apx_ndd,apx_ndd")
8141 (set_attr "type" "alu")
8142 (set_attr "mode" "SI")])
8144 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
8145 (define_insn_and_split "*sub<mode>_1_slp"
8146 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
8147 (minus:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
8148 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
8149 (clobber (reg:CC FLAGS_REG))]
8150 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8152 sub{<imodesuffix>}\t{%2, %0|%0, %2}
8154 "&& reload_completed
8155 && !(rtx_equal_p (operands[0], operands[1]))"
8156 [(set (strict_low_part (match_dup 0)) (match_dup 1))
8158 [(set (strict_low_part (match_dup 0))
8159 (minus:SWI12 (match_dup 0) (match_dup 2)))
8160 (clobber (reg:CC FLAGS_REG))])]
8162 [(set_attr "type" "alu")
8163 (set_attr "mode" "<MODE>")])
8165 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
8166 (define_insn_and_split "*subqi_ext<mode>_1_slp"
8167 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+Q,&Q"))
8169 (match_operand:QI 1 "nonimmediate_operand" "0,!qm")
8171 (match_operator:SWI248 3 "extract_operator"
8172 [(match_operand 2 "int248_register_operand" "Q,Q")
8174 (const_int 8)]) 0)))
8175 (clobber (reg:CC FLAGS_REG))]
8176 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8178 sub{b}\t{%h2, %0|%0, %h2}
8180 "&& reload_completed
8181 && !rtx_equal_p (operands[0], operands[1])"
8182 [(set (strict_low_part (match_dup 0)) (match_dup 1))
8184 [(set (strict_low_part (match_dup 0))
8189 [(match_dup 2) (const_int 8) (const_int 8)]) 0)))
8190 (clobber (reg:CC FLAGS_REG))])]
8192 [(set_attr "type" "alu")
8193 (set_attr "mode" "QI")])
8195 (define_insn_and_split "*subqi_ext<mode>_2_slp"
8196 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+&Q"))
8199 (match_operator:SWI248 3 "extract_operator"
8200 [(match_operand 1 "int248_register_operand" "Q")
8204 (match_operator:SWI248 4 "extract_operator"
8205 [(match_operand 2 "int248_register_operand" "Q")
8207 (const_int 8)]) 0)))
8208 (clobber (reg:CC FLAGS_REG))]
8209 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8211 "&& reload_completed"
8212 [(set (strict_low_part (match_dup 0))
8215 [(match_dup 1) (const_int 8) (const_int 8)]) 0))
8217 [(set (strict_low_part (match_dup 0))
8222 [(match_dup 2) (const_int 8) (const_int 8)]) 0)))
8223 (clobber (reg:CC FLAGS_REG))])]
8225 [(set_attr "type" "alu")
8226 (set_attr "mode" "QI")])
8228 (define_insn "*sub<mode>_2"
8229 [(set (reg FLAGS_REG)
8232 (match_operand:SWI 1 "nonimmediate_operand" "0,0,rm,r")
8233 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,r<i>,<m>"))
8235 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r")
8236 (minus:SWI (match_dup 1) (match_dup 2)))]
8237 "ix86_match_ccmode (insn, CCGOCmode)
8238 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)"
8240 sub{<imodesuffix>}\t{%2, %0|%0, %2}
8241 sub{<imodesuffix>}\t{%2, %0|%0, %2}
8242 sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
8243 sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
8244 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
8245 (set_attr "type" "alu")
8246 (set_attr "mode" "<MODE>")])
8248 (define_insn "*subsi_2_zext"
8249 [(set (reg FLAGS_REG)
8251 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,r,rm")
8252 (match_operand:SI 2 "x86_64_general_operand" "rBMe,rBMe,re"))
8254 (set (match_operand:DI 0 "register_operand" "=r,r,r")
8256 (minus:SI (match_dup 1)
8258 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
8259 && ix86_binary_operator_ok (MINUS, SImode, operands, TARGET_APX_NDD)"
8261 sub{l}\t{%2, %k0|%k0, %2}
8262 sub{l}\t{%2, %1, %k0|%k0, %1, %2}
8263 sub{l}\t{%2, %1, %k0|%k0, %1, %2}"
8264 [(set_attr "isa" "*,apx_ndd,apx_ndd")
8265 (set_attr "type" "alu")
8266 (set_attr "mode" "SI")])
8268 (define_insn "*subqi_ext<mode>_0"
8269 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn")
8271 (match_operand:QI 1 "nonimmediate_operand" "0")
8273 (match_operator:SWI248 3 "extract_operator"
8274 [(match_operand 2 "int248_register_operand" "Q")
8276 (const_int 8)]) 0)))
8277 (clobber (reg:CC FLAGS_REG))]
8279 "sub{b}\t{%h2, %0|%0, %h2}"
8280 [(set_attr "addr" "gpr8")
8281 (set_attr "type" "alu")
8282 (set_attr "mode" "QI")])
8284 (define_insn_and_split "*subqi_ext2<mode>_0"
8285 [(set (match_operand:QI 0 "register_operand" "=&Q")
8288 (match_operator:SWI248 3 "extract_operator"
8289 [(match_operand 1 "int248_register_operand" "Q")
8293 (match_operator:SWI248 4 "extract_operator"
8294 [(match_operand 2 "int248_register_operand" "Q")
8296 (const_int 8)]) 0)))
8297 (clobber (reg:CC FLAGS_REG))]
8300 "&& reload_completed"
8304 [(match_dup 1) (const_int 8) (const_int 8)]) 0))
8311 [(match_dup 2) (const_int 8) (const_int 8)]) 0)))
8312 (clobber (reg:CC FLAGS_REG))])]
8314 [(set_attr "type" "alu")
8315 (set_attr "mode" "QI")])
8317 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
8318 (define_insn_and_split "*subqi_ext<mode>_1"
8319 [(set (zero_extract:SWI248
8320 (match_operand 0 "int248_register_operand" "+Q,&Q")
8326 (match_operator:SWI248 3 "extract_operator"
8327 [(match_operand 1 "int248_register_operand" "0,!Q")
8330 (match_operand:QI 2 "general_operand" "QnBn,QnBn")) 0))
8331 (clobber (reg:CC FLAGS_REG))]
8334 sub{b}\t{%2, %h0|%h0, %2}
8337 && !(rtx_equal_p (operands[0], operands[1]))"
8338 [(set (zero_extract:SWI248
8339 (match_dup 0) (const_int 8) (const_int 8))
8340 (zero_extract:SWI248
8341 (match_dup 1) (const_int 8) (const_int 8)))
8343 [(set (zero_extract:SWI248
8344 (match_dup 0) (const_int 8) (const_int 8))
8349 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
8351 (clobber (reg:CC FLAGS_REG))])]
8353 [(set_attr "addr" "gpr8")
8354 (set_attr "type" "alu")
8355 (set_attr "mode" "QI")])
8357 ;; Subtract with jump on overflow.
8358 (define_expand "subv<mode>4"
8359 [(parallel [(set (reg:CCO FLAGS_REG)
8363 (match_operand:SWIDWI 1 "nonimmediate_operand"))
8366 (minus:SWIDWI (match_dup 1)
8367 (match_operand:SWIDWI 2
8368 "<general_hilo_operand>")))))
8369 (set (match_operand:SWIDWI 0 "register_operand")
8370 (minus:SWIDWI (match_dup 1) (match_dup 2)))])
8371 (set (pc) (if_then_else
8372 (eq (reg:CCO FLAGS_REG) (const_int 0))
8373 (label_ref (match_operand 3))
8377 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands,
8379 if (CONST_SCALAR_INT_P (operands[2]))
8380 operands[4] = operands[2];
8382 operands[4] = gen_rtx_SIGN_EXTEND (<DPWI>mode, operands[2]);
8385 (define_insn "*subv<mode>4"
8386 [(set (reg:CCO FLAGS_REG)
8387 (eq:CCO (minus:<DWI>
8389 (match_operand:SWI 1 "nonimmediate_operand" "0,0,rm,r"))
8391 (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m,rWe,m")))
8393 (minus:SWI (match_dup 1) (match_dup 2)))))
8394 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r")
8395 (minus:SWI (match_dup 1) (match_dup 2)))]
8396 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)"
8398 sub{<imodesuffix>}\t{%2, %0|%0, %2}
8399 sub{<imodesuffix>}\t{%2, %0|%0, %2}
8400 sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
8401 sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
8402 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
8403 (set_attr "type" "alu")
8404 (set_attr "mode" "<MODE>")])
8406 (define_insn "subv<mode>4_1"
8407 [(set (reg:CCO FLAGS_REG)
8408 (eq:CCO (minus:<DWI>
8410 (match_operand:SWI 1 "nonimmediate_operand" "0,rm"))
8411 (match_operand:<DWI> 3 "const_int_operand"))
8415 (match_operand:SWI 2 "x86_64_immediate_operand" "<i>,<i>")))))
8416 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,r")
8417 (minus:SWI (match_dup 1) (match_dup 2)))]
8418 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)
8419 && CONST_INT_P (operands[2])
8420 && INTVAL (operands[2]) == INTVAL (operands[3])"
8422 sub{<imodesuffix>}\t{%2, %0|%0, %2}
8423 sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
8424 [(set_attr "isa" "*,apx_ndd")
8425 (set_attr "type" "alu")
8426 (set_attr "mode" "<MODE>")
8427 (set (attr "length_immediate")
8428 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
8430 (match_test "<MODE_SIZE> == 8")
8432 (const_string "<MODE_SIZE>")))])
8434 (define_insn_and_split "*subv<dwi>4_doubleword"
8435 [(set (reg:CCO FLAGS_REG)
8439 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0,ro,r"))
8441 (match_operand:<DWI> 2 "nonimmediate_operand" "r,o,r,o")))
8443 (minus:<DWI> (match_dup 1) (match_dup 2)))))
8444 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,&r,&r")
8445 (minus:<DWI> (match_dup 1) (match_dup 2)))]
8446 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)"
8448 "&& reload_completed"
8449 [(parallel [(set (reg:CC FLAGS_REG)
8450 (compare:CC (match_dup 1) (match_dup 2)))
8452 (minus:DWIH (match_dup 1) (match_dup 2)))])
8453 (parallel [(set (reg:CCO FLAGS_REG)
8457 (sign_extend:<DWI> (match_dup 4))
8458 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))
8459 (sign_extend:<DWI> (match_dup 5)))
8464 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
8470 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
8473 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
8475 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")])
8477 (define_insn_and_split "*subv<dwi>4_doubleword_1"
8478 [(set (reg:CCO FLAGS_REG)
8482 (match_operand:<DWI> 1 "nonimmediate_operand" "0,ro"))
8483 (match_operand:<QPWI> 3 "const_scalar_int_operand"))
8487 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>,<di>")))))
8488 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,&r")
8489 (minus:<DWI> (match_dup 1) (match_dup 2)))]
8490 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)
8491 && CONST_SCALAR_INT_P (operands[2])
8492 && rtx_equal_p (operands[2], operands[3])"
8494 "&& reload_completed"
8495 [(parallel [(set (reg:CC FLAGS_REG)
8496 (compare:CC (match_dup 1) (match_dup 2)))
8498 (minus:DWIH (match_dup 1) (match_dup 2)))])
8499 (parallel [(set (reg:CCO FLAGS_REG)
8503 (sign_extend:<DWI> (match_dup 4))
8504 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))
8510 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
8516 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
8519 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
8520 if (operands[2] == const0_rtx)
8522 if (!rtx_equal_p (operands[0], operands[1]))
8523 emit_move_insn (operands[0], operands[1]);
8524 emit_insn (gen_subv<mode>4_1 (operands[3], operands[4], operands[5],
8529 [(set_attr "isa" "*,apx_ndd")])
8531 (define_insn "*subv<mode>4_overflow_1"
8532 [(set (reg:CCO FLAGS_REG)
8537 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,rm,r"))
8538 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8539 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
8541 (match_operand:SWI 2 "<general_sext_operand>" "rWe,m,rWe,m")))
8546 (match_operator:SWI 5 "ix86_carry_flag_operator"
8547 [(match_dup 3) (const_int 0)]))
8549 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r,r,r")
8553 (match_op_dup 5 [(match_dup 3) (const_int 0)]))
8555 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)"
8557 sbb{<imodesuffix>}\t{%2, %0|%0, %2}
8558 sbb{<imodesuffix>}\t{%2, %0|%0, %2}
8559 sbb{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
8560 sbb{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
8561 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
8562 (set_attr "type" "alu")
8563 (set_attr "mode" "<MODE>")])
8565 (define_insn "*subv<mode>4_overflow_2"
8566 [(set (reg:CCO FLAGS_REG)
8571 (match_operand:SWI 1 "nonimmediate_operand" "%0,rm"))
8572 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8573 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
8574 (match_operand:<DWI> 6 "const_int_operand" "n,n"))
8579 (match_operator:SWI 5 "ix86_carry_flag_operator"
8580 [(match_dup 3) (const_int 0)]))
8581 (match_operand:SWI 2 "x86_64_immediate_operand" "e,e")))))
8582 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r")
8586 (match_op_dup 5 [(match_dup 3) (const_int 0)]))
8588 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)
8589 && CONST_INT_P (operands[2])
8590 && INTVAL (operands[2]) == INTVAL (operands[6])"
8592 sbb{<imodesuffix>}\t{%2, %0|%0, %2}
8593 sbb{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
8594 [(set_attr "isa" "*,apx_ndd")
8595 (set_attr "type" "alu")
8596 (set_attr "mode" "<MODE>")
8597 (set (attr "length_immediate")
8598 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
8600 (const_string "4")))])
8602 (define_expand "usubv<mode>4"
8603 [(parallel [(set (reg:CC FLAGS_REG)
8605 (match_operand:SWI 1 "nonimmediate_operand")
8606 (match_operand:SWI 2 "<general_operand>")))
8607 (set (match_operand:SWI 0 "register_operand")
8608 (minus:SWI (match_dup 1) (match_dup 2)))])
8609 (set (pc) (if_then_else
8610 (ltu (reg:CC FLAGS_REG) (const_int 0))
8611 (label_ref (match_operand 3))
8614 "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands,
8617 (define_expand "sub<mode>_3"
8618 [(parallel [(set (reg:CC FLAGS_REG)
8620 (match_operand:SWI 1 "nonimmediate_operand")
8621 (match_operand:SWI 2 "<general_operand>")))
8622 (set (match_operand:SWI 0 "register_operand")
8623 (minus:SWI (match_dup 1) (match_dup 2)))])])
8625 (define_insn "*sub<mode>_3"
8626 [(set (reg FLAGS_REG)
8627 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0,rm,r")
8628 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,r<i>,<m>")))
8629 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>i,r,r")
8630 (minus:SWI (match_dup 1) (match_dup 2)))]
8631 "ix86_match_ccmode (insn, CCmode)
8632 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)"
8634 sub{<imodesuffix>}\t{%2, %0|%0, %2}
8635 sub{<imodesuffix>}\t{%2, %0|%0, %2}
8636 sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
8637 sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
8638 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
8639 (set_attr "type" "alu")
8640 (set_attr "mode" "<MODE>")])
8644 [(set (reg:CC FLAGS_REG)
8645 (compare:CC (match_operand:SWI 0 "general_reg_operand")
8646 (match_operand:SWI 1 "general_gr_operand")))
8648 (minus:SWI (match_dup 0) (match_dup 1)))])]
8649 "find_regno_note (peep2_next_insn (0), REG_UNUSED, REGNO (operands[0])) != 0"
8650 [(set (reg:CC FLAGS_REG)
8651 (compare:CC (match_dup 0) (match_dup 1)))])
8654 [(set (match_operand:SWI 0 "general_reg_operand")
8655 (match_operand:SWI 1 "memory_operand"))
8656 (parallel [(set (reg:CC FLAGS_REG)
8657 (compare:CC (match_dup 0)
8658 (match_operand:SWI 2 "memory_operand")))
8660 (minus:SWI (match_dup 0) (match_dup 2)))])
8661 (set (match_dup 1) (match_dup 0))]
8662 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8663 && peep2_reg_dead_p (3, operands[0])
8664 && !reg_overlap_mentioned_p (operands[0], operands[1])
8665 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8666 [(set (match_dup 0) (match_dup 2))
8667 (parallel [(set (reg:CC FLAGS_REG)
8668 (compare:CC (match_dup 1) (match_dup 0)))
8670 (minus:SWI (match_dup 1) (match_dup 0)))])])
8672 ;; decl %eax; cmpl $-1, %eax; jne .Lxx; can be optimized into
8673 ;; subl $1, %eax; jnc .Lxx;
8676 [(set (match_operand:SWI 0 "general_reg_operand")
8677 (plus:SWI (match_dup 0) (const_int -1)))
8678 (clobber (reg FLAGS_REG))])
8679 (set (reg:CCZ FLAGS_REG)
8680 (compare:CCZ (match_dup 0) (const_int -1)))
8682 (if_then_else (match_operator 1 "bt_comparison_operator"
8683 [(reg:CCZ FLAGS_REG) (const_int 0)])
8686 "peep2_regno_dead_p (3, FLAGS_REG)"
8688 [(set (reg:CC FLAGS_REG)
8689 (compare:CC (match_dup 0) (const_int 1)))
8691 (minus:SWI (match_dup 0) (const_int 1)))])
8693 (if_then_else (match_dup 3)
8697 rtx cc = gen_rtx_REG (CCmode, FLAGS_REG);
8698 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE
8699 ? GEU : LTU, VOIDmode, cc, const0_rtx);
8702 ;; Help combine use borrow flag to test for -1 after dec (add $-1).
8703 (define_insn_and_split "*dec_cmov<mode>"
8704 [(set (match_operand:SWI248 0 "register_operand" "=r")
8705 (if_then_else:SWI248
8706 (match_operator 1 "bt_comparison_operator"
8707 [(match_operand:SWI248 2 "register_operand" "0") (const_int 0)])
8708 (plus:SWI248 (match_dup 2) (const_int -1))
8709 (match_operand:SWI248 3 "nonimmediate_operand" "rm")))
8710 (clobber (reg:CC FLAGS_REG))]
8713 "&& reload_completed"
8714 [(parallel [(set (reg:CC FLAGS_REG)
8715 (compare:CC (match_dup 2) (const_int 1)))
8716 (set (match_dup 0) (minus:SWI248 (match_dup 2) (const_int 1)))])
8718 (if_then_else:SWI248 (match_dup 4) (match_dup 0) (match_dup 3)))]
8720 rtx cc = gen_rtx_REG (CCCmode, FLAGS_REG);
8721 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE
8722 ? GEU : LTU, VOIDmode, cc, const0_rtx);
8725 (define_insn "*subsi_3_zext"
8726 [(set (reg FLAGS_REG)
8727 (compare (match_operand:SI 1 "nonimmediate_operand" "0,r,rm")
8728 (match_operand:SI 2 "x86_64_general_operand" "rBMe,rBMe,re")))
8729 (set (match_operand:DI 0 "register_operand" "=r,r,r")
8731 (minus:SI (match_dup 1)
8733 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
8734 && ix86_binary_operator_ok (MINUS, SImode, operands, TARGET_APX_NDD)"
8736 sub{l}\t{%2, %1|%1, %2}
8737 sub{l}\t{%2, %1, %k0|%k0, %1, %2}
8738 sub{l}\t{%2, %1, %k0|%k0, %1, %2}"
8739 [(set_attr "isa" "*,apx_ndd,apx_ndd")
8740 (set_attr "type" "alu")
8741 (set_attr "mode" "SI")])
8743 ;; Add with carry and subtract with borrow
8745 (define_insn "@add<mode>3_carry"
8746 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r")
8749 (match_operator:SWI 4 "ix86_carry_flag_operator"
8750 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8751 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,rm,r"))
8752 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,r<i>,<m>")))
8753 (clobber (reg:CC FLAGS_REG))]
8754 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)"
8756 adc{<imodesuffix>}\t{%2, %0|%0, %2}
8757 adc{<imodesuffix>}\t{%2, %0|%0, %2}
8758 adc{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
8759 adc{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
8760 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
8761 (set_attr "type" "alu")
8762 (set_attr "use_carry" "1")
8763 (set_attr "pent_pair" "pu")
8764 (set_attr "mode" "<MODE>")])
8767 [(set (match_operand:SWI 0 "general_reg_operand")
8768 (match_operand:SWI 1 "memory_operand"))
8769 (parallel [(set (match_dup 0)
8772 (match_operator:SWI 4 "ix86_carry_flag_operator"
8773 [(match_operand 3 "flags_reg_operand")
8776 (match_operand:SWI 2 "memory_operand")))
8777 (clobber (reg:CC FLAGS_REG))])
8778 (set (match_dup 1) (match_dup 0))]
8779 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8780 && peep2_reg_dead_p (3, operands[0])
8781 && !reg_overlap_mentioned_p (operands[0], operands[1])
8782 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8783 [(set (match_dup 0) (match_dup 2))
8784 (parallel [(set (match_dup 1)
8785 (plus:SWI (plus:SWI (match_op_dup 4
8786 [(match_dup 3) (const_int 0)])
8789 (clobber (reg:CC FLAGS_REG))])])
8792 [(set (match_operand:SWI 0 "general_reg_operand")
8793 (match_operand:SWI 1 "memory_operand"))
8794 (parallel [(set (match_dup 0)
8797 (match_operator:SWI 4 "ix86_carry_flag_operator"
8798 [(match_operand 3 "flags_reg_operand")
8801 (match_operand:SWI 2 "memory_operand")))
8802 (clobber (reg:CC FLAGS_REG))])
8803 (set (match_operand:SWI 5 "general_reg_operand") (match_dup 0))
8804 (set (match_dup 1) (match_dup 5))]
8805 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8806 && peep2_reg_dead_p (3, operands[0])
8807 && peep2_reg_dead_p (4, operands[5])
8808 && !reg_overlap_mentioned_p (operands[0], operands[1])
8809 && !reg_overlap_mentioned_p (operands[0], operands[2])
8810 && !reg_overlap_mentioned_p (operands[5], operands[1])"
8811 [(set (match_dup 0) (match_dup 2))
8812 (parallel [(set (match_dup 1)
8813 (plus:SWI (plus:SWI (match_op_dup 4
8814 [(match_dup 3) (const_int 0)])
8817 (clobber (reg:CC FLAGS_REG))])])
8819 (define_insn "*add<mode>3_carry_0"
8820 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8822 (match_operator:SWI 2 "ix86_carry_flag_operator"
8823 [(reg FLAGS_REG) (const_int 0)])
8824 (match_operand:SWI 1 "nonimmediate_operand" "0")))
8825 (clobber (reg:CC FLAGS_REG))]
8826 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8827 "adc{<imodesuffix>}\t{$0, %0|%0, 0}"
8828 [(set_attr "type" "alu")
8829 (set_attr "use_carry" "1")
8830 (set_attr "pent_pair" "pu")
8831 (set_attr "mode" "<MODE>")])
8833 (define_insn "*add<mode>3_carry_0r"
8834 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8836 (match_operator:SWI 2 "ix86_carry_flag_unset_operator"
8837 [(reg FLAGS_REG) (const_int 0)])
8838 (match_operand:SWI 1 "nonimmediate_operand" "0")))
8839 (clobber (reg:CC FLAGS_REG))]
8840 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8841 "sbb{<imodesuffix>}\t{$-1, %0|%0, -1}"
8842 [(set_attr "type" "alu")
8843 (set_attr "use_carry" "1")
8844 (set_attr "pent_pair" "pu")
8845 (set_attr "mode" "<MODE>")])
8847 (define_insn "*addqi3_carry_zext<mode>"
8848 [(set (match_operand:SWI248x 0 "register_operand" "=r,r")
8849 (zero_extend:SWI248x
8851 (plus:QI (match_operator:QI 3 "ix86_carry_flag_operator"
8852 [(reg FLAGS_REG) (const_int 0)])
8853 (match_operand:QI 1 "nonimmediate_operand" "%rm,r"))
8854 (match_operand:QI 2 "x86_64_general_operand" "rn,m"))))
8855 (clobber (reg:CC FLAGS_REG))]
8857 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8859 adc{b}\t{%2, %1, %b0|%b0, %1, %2}
8860 adc{b}\t{%2, %1, %b0|%b0, %1, %2}"
8861 [(set_attr "type" "alu")
8862 (set_attr "use_carry" "1")
8863 (set_attr "pent_pair" "pu")
8864 (set_attr "mode" "QI")])
8866 (define_insn "*addhi3_carry_zext<mode>"
8867 [(set (match_operand:SWI48x 0 "register_operand" "=r,r")
8870 (plus:HI (match_operator:HI 3 "ix86_carry_flag_operator"
8871 [(reg FLAGS_REG) (const_int 0)])
8872 (match_operand:HI 1 "nonimmediate_operand" "%rm,r"))
8873 (match_operand:HI 2 "x86_64_general_operand" "rn,m"))))
8874 (clobber (reg:CC FLAGS_REG))]
8876 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8878 adc{w}\t{%2, %1, %w0|%w0, %1, %2}
8879 adc{w}\t{%2, %1, %w0|%w0, %1, %2}"
8880 [(set_attr "type" "alu")
8881 (set_attr "use_carry" "1")
8882 (set_attr "pent_pair" "pu")
8883 (set_attr "mode" "HI")])
8885 (define_insn "*addsi3_carry_zext"
8886 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
8889 (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
8890 [(reg FLAGS_REG) (const_int 0)])
8891 (match_operand:SI 1 "nonimmediate_operand" "%0,r,rm"))
8892 (match_operand:SI 2 "x86_64_general_operand" "rBMe,rBMe,re"))))
8893 (clobber (reg:CC FLAGS_REG))]
8895 && ix86_binary_operator_ok (PLUS, SImode, operands, TARGET_APX_NDD)"
8897 adc{l}\t{%2, %k0|%k0, %2}
8898 adc{l}\t{%2, %1, %k0|%k0, %1, %2}
8899 adc{l}\t{%2, %1, %k0|%k0, %1, %2}"
8900 [(set_attr "isa" "*,apx_ndd,apx_ndd")
8901 (set_attr "type" "alu")
8902 (set_attr "use_carry" "1")
8903 (set_attr "pent_pair" "pu")
8904 (set_attr "mode" "SI")])
8906 (define_insn "*addqi3_carry_zext<mode>_0"
8907 [(set (match_operand:SWI248x 0 "register_operand" "=r")
8908 (zero_extend:SWI248x
8909 (plus:QI (match_operator:QI 2 "ix86_carry_flag_operator"
8910 [(reg FLAGS_REG) (const_int 0)])
8911 (match_operand:QI 1 "nonimmediate_operand" "rm"))))
8912 (clobber (reg:CC FLAGS_REG))]
8914 "adc{b}\t{$0, %1, %b0|%b0, %1, 0}"
8915 [(set_attr "type" "alu")
8916 (set_attr "use_carry" "1")
8917 (set_attr "pent_pair" "pu")
8918 (set_attr "mode" "QI")])
8920 (define_insn "*addhi3_carry_zext<mode>_0"
8921 [(set (match_operand:SWI48x 0 "register_operand" "=r")
8923 (plus:HI (match_operator:HI 2 "ix86_carry_flag_operator"
8924 [(reg FLAGS_REG) (const_int 0)])
8925 (match_operand:HI 1 "nonimmediate_operand" "rm"))))
8926 (clobber (reg:CC FLAGS_REG))]
8928 "adc{w}\t{$0, %1, %w0|%w0, %1, 0}"
8929 [(set_attr "type" "alu")
8930 (set_attr "use_carry" "1")
8931 (set_attr "pent_pair" "pu")
8932 (set_attr "mode" "HI")])
8934 (define_insn "*addsi3_carry_zext_0"
8935 [(set (match_operand:DI 0 "register_operand" "=r,r")
8937 (plus:SI (match_operator:SI 2 "ix86_carry_flag_operator"
8938 [(reg FLAGS_REG) (const_int 0)])
8939 (match_operand:SI 1 "nonimmediate_operand" "0,rm"))))
8940 (clobber (reg:CC FLAGS_REG))]
8943 adc{l}\t{$0, %k0|%k0, 0}
8944 adc{l}\t{$0, %1, %k0|%k0, %1, 0}"
8945 [(set_attr "isa" "*,apx_ndd")
8946 (set_attr "type" "alu")
8947 (set_attr "use_carry" "1")
8948 (set_attr "pent_pair" "pu")
8949 (set_attr "mode" "SI")])
8951 (define_insn "*addqi3_carry_zext<mode>_0r"
8952 [(set (match_operand:SWI248x 0 "register_operand" "=r")
8953 (zero_extend:SWI248x
8954 (plus:QI (match_operator:QI 2 "ix86_carry_flag_unset_operator"
8955 [(reg FLAGS_REG) (const_int 0)])
8956 (match_operand:QI 1 "nonimmediate_operand" "rm"))))
8957 (clobber (reg:CC FLAGS_REG))]
8959 "sbb{b}\t{$-1, %1, %b0|%b0, %1, -1}"
8960 [(set_attr "type" "alu")
8961 (set_attr "use_carry" "1")
8962 (set_attr "pent_pair" "pu")
8963 (set_attr "mode" "QI")])
8965 (define_insn "*addhi3_carry_zext<mode>_0r"
8966 [(set (match_operand:SWI48x 0 "register_operand" "=r")
8968 (plus:HI (match_operator:HI 2 "ix86_carry_flag_unset_operator"
8969 [(reg FLAGS_REG) (const_int 0)])
8970 (match_operand:HI 1 "nonimmediate_operand" "rm"))))
8971 (clobber (reg:CC FLAGS_REG))]
8973 "sbb{w}\t{$-1, %1, %w0|%w0, %1, -1}"
8974 [(set_attr "type" "alu")
8975 (set_attr "use_carry" "1")
8976 (set_attr "pent_pair" "pu")
8977 (set_attr "mode" "HI")])
8979 (define_insn "*addsi3_carry_zext_0r"
8980 [(set (match_operand:DI 0 "register_operand" "=r,r")
8982 (plus:SI (match_operator:SI 2 "ix86_carry_flag_unset_operator"
8983 [(reg FLAGS_REG) (const_int 0)])
8984 (match_operand:SI 1 "nonimmediate_operand" "0,rm"))))
8985 (clobber (reg:CC FLAGS_REG))]
8988 sbb{l}\t{$-1, %k0|%k0, -1}
8989 sbb{l}\t{$-1, %1, %k0|%k0, %1, -1}"
8990 [(set_attr "isa" "*,apx_ndd")
8991 (set_attr "type" "alu")
8992 (set_attr "use_carry" "1")
8993 (set_attr "pent_pair" "pu")
8994 (set_attr "mode" "SI")])
8996 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
8998 (define_insn "addcarry<mode>"
8999 [(set (reg:CCC FLAGS_REG)
9004 (match_operator:SWI48 5 "ix86_carry_flag_operator"
9005 [(match_operand 3 "flags_reg_operand") (const_int 0)])
9006 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,rm,r"))
9007 (match_operand:SWI48 2 "nonimmediate_operand" "r,rm,r,m")))
9009 (zero_extend:<DWI> (match_dup 2))
9010 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
9011 [(match_dup 3) (const_int 0)]))))
9012 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,r")
9013 (plus:SWI48 (plus:SWI48 (match_op_dup 5
9014 [(match_dup 3) (const_int 0)])
9017 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)"
9019 adc{<imodesuffix>}\t{%2, %0|%0, %2}
9020 adc{<imodesuffix>}\t{%2, %0|%0, %2}
9021 adc{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9022 adc{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
9023 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
9024 (set_attr "type" "alu")
9025 (set_attr "use_carry" "1")
9026 (set_attr "pent_pair" "pu")
9027 (set_attr "mode" "<MODE>")])
9030 [(parallel [(set (reg:CCC FLAGS_REG)
9035 (match_operator:SWI48 4 "ix86_carry_flag_operator"
9036 [(match_operand 2 "flags_reg_operand")
9038 (match_operand:SWI48 0 "general_reg_operand"))
9039 (match_operand:SWI48 1 "memory_operand")))
9041 (zero_extend:<DWI> (match_dup 1))
9042 (match_operator:<DWI> 3 "ix86_carry_flag_operator"
9043 [(match_dup 2) (const_int 0)]))))
9045 (plus:SWI48 (plus:SWI48 (match_op_dup 4
9046 [(match_dup 2) (const_int 0)])
9049 (set (match_dup 1) (match_dup 0))]
9050 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
9051 && peep2_reg_dead_p (2, operands[0])
9052 && !reg_overlap_mentioned_p (operands[0], operands[1])"
9053 [(parallel [(set (reg:CCC FLAGS_REG)
9059 [(match_dup 2) (const_int 0)])
9063 (zero_extend:<DWI> (match_dup 0))
9065 [(match_dup 2) (const_int 0)]))))
9067 (plus:SWI48 (plus:SWI48 (match_op_dup 4
9068 [(match_dup 2) (const_int 0)])
9073 [(set (match_operand:SWI48 0 "general_reg_operand")
9074 (match_operand:SWI48 1 "memory_operand"))
9075 (parallel [(set (reg:CCC FLAGS_REG)
9080 (match_operator:SWI48 5 "ix86_carry_flag_operator"
9081 [(match_operand 3 "flags_reg_operand")
9084 (match_operand:SWI48 2 "memory_operand")))
9086 (zero_extend:<DWI> (match_dup 2))
9087 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
9088 [(match_dup 3) (const_int 0)]))))
9090 (plus:SWI48 (plus:SWI48 (match_op_dup 5
9091 [(match_dup 3) (const_int 0)])
9094 (set (match_dup 1) (match_dup 0))]
9095 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
9096 && peep2_reg_dead_p (3, operands[0])
9097 && !reg_overlap_mentioned_p (operands[0], operands[1])
9098 && !reg_overlap_mentioned_p (operands[0], operands[2])"
9099 [(set (match_dup 0) (match_dup 2))
9100 (parallel [(set (reg:CCC FLAGS_REG)
9106 [(match_dup 3) (const_int 0)])
9110 (zero_extend:<DWI> (match_dup 0))
9112 [(match_dup 3) (const_int 0)]))))
9114 (plus:SWI48 (plus:SWI48 (match_op_dup 5
9115 [(match_dup 3) (const_int 0)])
9120 [(parallel [(set (reg:CCC FLAGS_REG)
9125 (match_operator:SWI48 4 "ix86_carry_flag_operator"
9126 [(match_operand 2 "flags_reg_operand")
9128 (match_operand:SWI48 0 "general_reg_operand"))
9129 (match_operand:SWI48 1 "memory_operand")))
9131 (zero_extend:<DWI> (match_dup 1))
9132 (match_operator:<DWI> 3 "ix86_carry_flag_operator"
9133 [(match_dup 2) (const_int 0)]))))
9135 (plus:SWI48 (plus:SWI48 (match_op_dup 4
9136 [(match_dup 2) (const_int 0)])
9139 (set (match_operand:QI 5 "general_reg_operand")
9140 (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
9141 (set (match_operand:SWI48 6 "general_reg_operand")
9142 (zero_extend:SWI48 (match_dup 5)))
9143 (set (match_dup 1) (match_dup 0))]
9144 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
9145 && peep2_reg_dead_p (4, operands[0])
9146 && !reg_overlap_mentioned_p (operands[0], operands[1])
9147 && !reg_overlap_mentioned_p (operands[0], operands[5])
9148 && !reg_overlap_mentioned_p (operands[5], operands[1])
9149 && !reg_overlap_mentioned_p (operands[0], operands[6])
9150 && !reg_overlap_mentioned_p (operands[6], operands[1])"
9151 [(parallel [(set (reg:CCC FLAGS_REG)
9157 [(match_dup 2) (const_int 0)])
9161 (zero_extend:<DWI> (match_dup 0))
9163 [(match_dup 2) (const_int 0)]))))
9165 (plus:SWI48 (plus:SWI48 (match_op_dup 4
9166 [(match_dup 2) (const_int 0)])
9169 (set (match_dup 5) (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
9170 (set (match_dup 6) (zero_extend:SWI48 (match_dup 5)))])
9172 (define_expand "addcarry<mode>_0"
9174 [(set (reg:CCC FLAGS_REG)
9177 (match_operand:SWI48 1 "nonimmediate_operand")
9178 (match_operand:SWI48 2 "x86_64_general_operand"))
9180 (set (match_operand:SWI48 0 "nonimmediate_operand")
9181 (plus:SWI48 (match_dup 1) (match_dup 2)))])]
9182 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)")
9184 (define_insn "*addcarry<mode>_1"
9185 [(set (reg:CCC FLAGS_REG)
9190 (match_operator:SWI48 5 "ix86_carry_flag_operator"
9191 [(match_operand 3 "flags_reg_operand") (const_int 0)])
9192 (match_operand:SWI48 1 "nonimmediate_operand" "%0,rm"))
9193 (match_operand:SWI48 2 "x86_64_immediate_operand" "e,e")))
9195 (match_operand:<DWI> 6 "const_scalar_int_operand")
9196 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
9197 [(match_dup 3) (const_int 0)]))))
9198 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9199 (plus:SWI48 (plus:SWI48 (match_op_dup 5
9200 [(match_dup 3) (const_int 0)])
9203 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)
9204 && CONST_INT_P (operands[2])
9205 /* Check that operands[6] is operands[2] zero extended from
9206 <MODE>mode to <DWI>mode. */
9207 && ((<MODE>mode == SImode || INTVAL (operands[2]) >= 0)
9208 ? (CONST_INT_P (operands[6])
9209 && UINTVAL (operands[6]) == (UINTVAL (operands[2])
9210 & GET_MODE_MASK (<MODE>mode)))
9211 : (CONST_WIDE_INT_P (operands[6])
9212 && CONST_WIDE_INT_NUNITS (operands[6]) == 2
9213 && ((unsigned HOST_WIDE_INT) CONST_WIDE_INT_ELT (operands[6], 0)
9214 == UINTVAL (operands[2]))
9215 && CONST_WIDE_INT_ELT (operands[6], 1) == 0))"
9217 adc{<imodesuffix>}\t{%2, %0|%0, %2}
9218 adc{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
9219 [(set_attr "isa" "*,apx_ndd")
9220 (set_attr "type" "alu")
9221 (set_attr "use_carry" "1")
9222 (set_attr "pent_pair" "pu")
9223 (set_attr "mode" "<MODE>")
9224 (set (attr "length_immediate")
9225 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
9227 (const_string "4")))])
9229 (define_insn "@sub<mode>3_carry"
9230 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r")
9233 (match_operand:SWI 1 "nonimmediate_operand" "0,0,rm,r")
9234 (match_operator:SWI 4 "ix86_carry_flag_operator"
9235 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
9236 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,r<i>,<m>")))
9237 (clobber (reg:CC FLAGS_REG))]
9238 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)"
9240 sbb{<imodesuffix>}\t{%2, %0|%0, %2}
9241 sbb{<imodesuffix>}\t{%2, %0|%0, %2}
9242 sbb{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9243 sbb{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
9244 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
9245 (set_attr "type" "alu")
9246 (set_attr "use_carry" "1")
9247 (set_attr "pent_pair" "pu")
9248 (set_attr "mode" "<MODE>")])
9251 [(set (match_operand:SWI 0 "general_reg_operand")
9252 (match_operand:SWI 1 "memory_operand"))
9253 (parallel [(set (match_dup 0)
9257 (match_operator:SWI 4 "ix86_carry_flag_operator"
9258 [(match_operand 3 "flags_reg_operand")
9260 (match_operand:SWI 2 "memory_operand")))
9261 (clobber (reg:CC FLAGS_REG))])
9262 (set (match_dup 1) (match_dup 0))]
9263 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
9264 && peep2_reg_dead_p (3, operands[0])
9265 && !reg_overlap_mentioned_p (operands[0], operands[1])
9266 && !reg_overlap_mentioned_p (operands[0], operands[2])"
9267 [(set (match_dup 0) (match_dup 2))
9268 (parallel [(set (match_dup 1)
9269 (minus:SWI (minus:SWI (match_dup 1)
9271 [(match_dup 3) (const_int 0)]))
9273 (clobber (reg:CC FLAGS_REG))])])
9276 [(set (match_operand:SWI 0 "general_reg_operand")
9277 (match_operand:SWI 1 "memory_operand"))
9278 (parallel [(set (match_dup 0)
9282 (match_operator:SWI 4 "ix86_carry_flag_operator"
9283 [(match_operand 3 "flags_reg_operand")
9285 (match_operand:SWI 2 "memory_operand")))
9286 (clobber (reg:CC FLAGS_REG))])
9287 (set (match_operand:SWI 5 "general_reg_operand") (match_dup 0))
9288 (set (match_dup 1) (match_dup 5))]
9289 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
9290 && peep2_reg_dead_p (3, operands[0])
9291 && peep2_reg_dead_p (4, operands[5])
9292 && !reg_overlap_mentioned_p (operands[0], operands[1])
9293 && !reg_overlap_mentioned_p (operands[0], operands[2])
9294 && !reg_overlap_mentioned_p (operands[5], operands[1])"
9295 [(set (match_dup 0) (match_dup 2))
9296 (parallel [(set (match_dup 1)
9297 (minus:SWI (minus:SWI (match_dup 1)
9299 [(match_dup 3) (const_int 0)]))
9301 (clobber (reg:CC FLAGS_REG))])])
9303 (define_insn "*sub<mode>3_carry_0"
9304 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9306 (match_operand:SWI 1 "nonimmediate_operand" "0")
9307 (match_operator:SWI 2 "ix86_carry_flag_operator"
9308 [(reg FLAGS_REG) (const_int 0)])))
9309 (clobber (reg:CC FLAGS_REG))]
9310 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
9311 "sbb{<imodesuffix>}\t{$0, %0|%0, 0}"
9312 [(set_attr "type" "alu")
9313 (set_attr "use_carry" "1")
9314 (set_attr "pent_pair" "pu")
9315 (set_attr "mode" "<MODE>")])
9317 (define_insn "*sub<mode>3_carry_0r"
9318 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9320 (match_operand:SWI 1 "nonimmediate_operand" "0")
9321 (match_operator:SWI 2 "ix86_carry_flag_unset_operator"
9322 [(reg FLAGS_REG) (const_int 0)])))
9323 (clobber (reg:CC FLAGS_REG))]
9324 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
9325 "adc{<imodesuffix>}\t{$-1, %0|%0, -1}"
9326 [(set_attr "type" "alu")
9327 (set_attr "use_carry" "1")
9328 (set_attr "pent_pair" "pu")
9329 (set_attr "mode" "<MODE>")])
9331 (define_insn "*subqi3_carry_zext<mode>"
9332 [(set (match_operand:SWI248x 0 "register_operand" "=r,r")
9333 (zero_extend:SWI248x
9336 (match_operand:QI 1 "nonimmediate_operand" "r,rm")
9337 (match_operator:QI 3 "ix86_carry_flag_operator"
9338 [(reg FLAGS_REG) (const_int 0)]))
9339 (match_operand:QI 2 "x86_64_general_operand" "rBMe,re"))))
9340 (clobber (reg:CC FLAGS_REG))]
9342 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9344 sbb{b}\t{%2, %1, %b0|%b0, %1, %2}
9345 sbb{b}\t{%2, %1, %b0|%b0, %1, %2}"
9346 [(set_attr "type" "alu")
9347 (set_attr "use_carry" "1")
9348 (set_attr "pent_pair" "pu")
9349 (set_attr "mode" "QI")])
9351 (define_insn "*subhi3_carry_zext<mode>"
9352 [(set (match_operand:SWI48x 0 "register_operand" "=r,r")
9356 (match_operand:HI 1 "nonimmediate_operand" "r,rm")
9357 (match_operator:HI 3 "ix86_carry_flag_operator"
9358 [(reg FLAGS_REG) (const_int 0)]))
9359 (match_operand:HI 2 "x86_64_general_operand" "rBMe,re"))))
9360 (clobber (reg:CC FLAGS_REG))]
9362 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9364 sbb{w}\t{%2, %1, %w0|%w0, %1, %2}
9365 sbb{w}\t{%2, %1, %w0|%w0, %1, %2}"
9366 [(set_attr "type" "alu")
9367 (set_attr "use_carry" "1")
9368 (set_attr "pent_pair" "pu")
9369 (set_attr "mode" "HI")])
9371 (define_insn "*subsi3_carry_zext"
9372 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9376 (match_operand:SI 1 "nonimmediate_operand" "0,r,rm")
9377 (match_operator:SI 3 "ix86_carry_flag_operator"
9378 [(reg FLAGS_REG) (const_int 0)]))
9379 (match_operand:SI 2 "x86_64_general_operand" "rBMe,rBMe,re"))))
9380 (clobber (reg:CC FLAGS_REG))]
9382 && ix86_binary_operator_ok (MINUS, SImode, operands, TARGET_APX_NDD)"
9384 sbb{l}\t{%2, %k0|%k0, %2}
9385 sbb{l}\t{%2, %1, %k0|%k0, %1, %2}
9386 sbb{l}\t{%2, %1, %k0|%k0, %1, %2}"
9387 [(set_attr "isa" "*,apx_ndd,apx_ndd")
9388 (set_attr "type" "alu")
9389 (set_attr "use_carry" "1")
9390 (set_attr "pent_pair" "pu")
9391 (set_attr "mode" "SI")])
9393 (define_insn "*subqi3_carry_zext<mode>_0"
9394 [(set (match_operand:SWI248x 0 "register_operand" "=r")
9395 (zero_extend:SWI248x
9397 (match_operand:QI 1 "nonimmediate_operand" "rm")
9398 (match_operator:QI 2 "ix86_carry_flag_operator"
9399 [(reg FLAGS_REG) (const_int 0)]))))
9400 (clobber (reg:CC FLAGS_REG))]
9402 "sbb{b}\t{$0, %1, %b0|%b0, %1, 0}"
9403 [(set_attr "type" "alu")
9404 (set_attr "use_carry" "1")
9405 (set_attr "pent_pair" "pu")
9406 (set_attr "mode" "QI")])
9408 (define_insn "*subhi3_carry_zext<mode>_0"
9409 [(set (match_operand:SWI48x 0 "register_operand" "=r")
9412 (match_operand:HI 1 "nonimmediate_operand" "rm")
9413 (match_operator:HI 2 "ix86_carry_flag_operator"
9414 [(reg FLAGS_REG) (const_int 0)]))))
9415 (clobber (reg:CC FLAGS_REG))]
9417 "sbb{w}\t{$0, %1, %w0|%w0, %1, 0}"
9418 [(set_attr "type" "alu")
9419 (set_attr "use_carry" "1")
9420 (set_attr "pent_pair" "pu")
9421 (set_attr "mode" "HI")])
9423 (define_insn "*subsi3_carry_zext_0"
9424 [(set (match_operand:DI 0 "register_operand" "=r,r")
9427 (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9428 (match_operator:SI 2 "ix86_carry_flag_operator"
9429 [(reg FLAGS_REG) (const_int 0)]))))
9430 (clobber (reg:CC FLAGS_REG))]
9433 sbb{l}\t{$0, %k0|%k0, 0}
9434 sbb{l}\t{$0, %1, %k0|%k0, %1, 0}"
9435 [(set_attr "isa" "*,apx_ndd")
9436 (set_attr "type" "alu")
9437 (set_attr "use_carry" "1")
9438 (set_attr "pent_pair" "pu")
9439 (set_attr "mode" "SI")])
9441 (define_insn "*subqi3_carry_zext<mode>_0r"
9442 [(set (match_operand:SWI248x 0 "register_operand" "=r")
9443 (zero_extend:SWI248x
9445 (match_operand:QI 1 "nonimmediate_operand" "rm")
9446 (match_operator:QI 2 "ix86_carry_flag_unset_operator"
9447 [(reg FLAGS_REG) (const_int 0)]))))
9448 (clobber (reg:CC FLAGS_REG))]
9450 "adc{b}\t{$-1, %1, %b0|%b0, %1, -1}"
9451 [(set_attr "type" "alu")
9452 (set_attr "use_carry" "1")
9453 (set_attr "pent_pair" "pu")
9454 (set_attr "mode" "QI")])
9456 (define_insn "*subhi3_carry_zext<mode>_0r"
9457 [(set (match_operand:SWI48x 0 "register_operand" "=r")
9460 (match_operand:HI 1 "nonimmediate_operand" "rm")
9461 (match_operator:HI 2 "ix86_carry_flag_unset_operator"
9462 [(reg FLAGS_REG) (const_int 0)]))))
9463 (clobber (reg:CC FLAGS_REG))]
9465 "adc{w}\t{$-1, %1, %w0|%w0, %1, -1}"
9466 [(set_attr "type" "alu")
9467 (set_attr "use_carry" "1")
9468 (set_attr "pent_pair" "pu")
9469 (set_attr "mode" "HI")])
9471 (define_insn "*subsi3_carry_zext_0r"
9472 [(set (match_operand:DI 0 "register_operand" "=r,r")
9475 (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9476 (match_operator:SI 2 "ix86_carry_flag_unset_operator"
9477 [(reg FLAGS_REG) (const_int 0)]))))
9478 (clobber (reg:CC FLAGS_REG))]
9481 adc{l}\t{$-1, %k0|%k0, -1}
9482 adc{l}\t{$-1, %1, %k0|%k0, %1, -1}"
9483 [(set_attr "isa" "*,apx_ndd")
9484 (set_attr "type" "alu")
9485 (set_attr "use_carry" "1")
9486 (set_attr "pent_pair" "pu")
9487 (set_attr "mode" "SI")])
9489 (define_insn "@sub<mode>3_carry_ccc"
9490 [(set (reg:CCC FLAGS_REG)
9492 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
9494 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
9496 (match_operand:DWIH 2 "x86_64_sext_operand" "rmWe")))))
9497 (clobber (match_scratch:DWIH 0 "=r"))]
9499 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
9500 [(set_attr "type" "alu")
9501 (set_attr "mode" "<MODE>")])
9503 (define_insn "*sub<mode>3_carry_ccc_1"
9504 [(set (reg:CCC FLAGS_REG)
9506 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
9508 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
9509 (match_operand:<DWI> 2 "x86_64_dwzext_immediate_operand" "Wf"))))
9510 (clobber (match_scratch:DWIH 0 "=r"))]
9513 operands[3] = simplify_subreg (<MODE>mode, operands[2], <DWI>mode, 0);
9514 return "sbb{<imodesuffix>}\t{%3, %0|%0, %3}";
9516 [(set_attr "type" "alu")
9517 (set_attr "mode" "<MODE>")])
9519 ;; The sign flag is set from the
9520 ;; (compare (match_dup 1) (plus:DWIH (ltu:DWIH ...) (match_dup 2)))
9521 ;; result, the overflow flag likewise, but the overflow flag is also
9522 ;; set if the (plus:DWIH (ltu:DWIH ...) (match_dup 2)) overflows.
9523 (define_insn "@sub<mode>3_carry_ccgz"
9524 [(set (reg:CCGZ FLAGS_REG)
9525 (unspec:CCGZ [(match_operand:DWIH 1 "register_operand" "0")
9526 (match_operand:DWIH 2 "x86_64_general_operand" "rBMe")
9527 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))]
9529 (clobber (match_scratch:DWIH 0 "=r"))]
9531 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
9532 [(set_attr "type" "alu")
9533 (set_attr "mode" "<MODE>")])
9535 (define_insn "subborrow<mode>"
9536 [(set (reg:CCC FLAGS_REG)
9539 (match_operand:SWI48 1 "nonimmediate_operand" "0,0,r,rm"))
9541 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
9542 [(match_operand 3 "flags_reg_operand") (const_int 0)])
9544 (match_operand:SWI48 2 "nonimmediate_operand" "r,rm,rm,r")))))
9545 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,r")
9546 (minus:SWI48 (minus:SWI48
9548 (match_operator:SWI48 5 "ix86_carry_flag_operator"
9549 [(match_dup 3) (const_int 0)]))
9551 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)"
9553 sbb{<imodesuffix>}\t{%2, %0|%0, %2}
9554 sbb{<imodesuffix>}\t{%2, %0|%0, %2}
9555 sbb{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9556 sbb{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
9557 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
9558 (set_attr "type" "alu")
9559 (set_attr "use_carry" "1")
9560 (set_attr "pent_pair" "pu")
9561 (set_attr "mode" "<MODE>")])
9564 [(set (match_operand:SWI48 0 "general_reg_operand")
9565 (match_operand:SWI48 1 "memory_operand"))
9566 (parallel [(set (reg:CCC FLAGS_REG)
9568 (zero_extend:<DWI> (match_dup 0))
9570 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
9571 [(match_operand 3 "flags_reg_operand") (const_int 0)])
9573 (match_operand:SWI48 2 "memory_operand")))))
9578 (match_operator:SWI48 5 "ix86_carry_flag_operator"
9579 [(match_dup 3) (const_int 0)]))
9581 (set (match_dup 1) (match_dup 0))]
9582 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
9583 && peep2_reg_dead_p (3, operands[0])
9584 && !reg_overlap_mentioned_p (operands[0], operands[1])
9585 && !reg_overlap_mentioned_p (operands[0], operands[2])"
9586 [(set (match_dup 0) (match_dup 2))
9587 (parallel [(set (reg:CCC FLAGS_REG)
9589 (zero_extend:<DWI> (match_dup 1))
9590 (plus:<DWI> (match_op_dup 4
9591 [(match_dup 3) (const_int 0)])
9592 (zero_extend:<DWI> (match_dup 0)))))
9594 (minus:SWI48 (minus:SWI48 (match_dup 1)
9596 [(match_dup 3) (const_int 0)]))
9600 [(set (match_operand:SWI48 6 "general_reg_operand")
9601 (match_operand:SWI48 7 "memory_operand"))
9602 (set (match_operand:SWI48 8 "general_reg_operand")
9603 (match_operand:SWI48 9 "memory_operand"))
9604 (parallel [(set (reg:CCC FLAGS_REG)
9607 (match_operand:SWI48 0 "general_reg_operand"))
9609 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
9610 [(match_operand 3 "flags_reg_operand") (const_int 0)])
9612 (match_operand:SWI48 2 "general_reg_operand")))))
9617 (match_operator:SWI48 5 "ix86_carry_flag_operator"
9618 [(match_dup 3) (const_int 0)]))
9620 (set (match_operand:SWI48 1 "memory_operand") (match_dup 0))]
9621 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
9622 && peep2_reg_dead_p (4, operands[0])
9623 && peep2_reg_dead_p (3, operands[2])
9624 && !reg_overlap_mentioned_p (operands[0], operands[1])
9625 && !reg_overlap_mentioned_p (operands[2], operands[1])
9626 && !reg_overlap_mentioned_p (operands[6], operands[9])
9627 && (rtx_equal_p (operands[6], operands[0])
9628 ? (rtx_equal_p (operands[7], operands[1])
9629 && rtx_equal_p (operands[8], operands[2]))
9630 : (rtx_equal_p (operands[8], operands[0])
9631 && rtx_equal_p (operands[9], operands[1])
9632 && rtx_equal_p (operands[6], operands[2])))"
9633 [(set (match_dup 0) (match_dup 9))
9634 (parallel [(set (reg:CCC FLAGS_REG)
9636 (zero_extend:<DWI> (match_dup 1))
9637 (plus:<DWI> (match_op_dup 4
9638 [(match_dup 3) (const_int 0)])
9639 (zero_extend:<DWI> (match_dup 0)))))
9641 (minus:SWI48 (minus:SWI48 (match_dup 1)
9643 [(match_dup 3) (const_int 0)]))
9646 if (!rtx_equal_p (operands[6], operands[0]))
9647 operands[9] = operands[7];
9651 [(set (match_operand:SWI48 6 "general_reg_operand")
9652 (match_operand:SWI48 7 "memory_operand"))
9653 (set (match_operand:SWI48 8 "general_reg_operand")
9654 (match_operand:SWI48 9 "memory_operand"))
9655 (parallel [(set (reg:CCC FLAGS_REG)
9658 (match_operand:SWI48 0 "general_reg_operand"))
9660 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
9661 [(match_operand 3 "flags_reg_operand") (const_int 0)])
9663 (match_operand:SWI48 2 "general_reg_operand")))))
9668 (match_operator:SWI48 5 "ix86_carry_flag_operator"
9669 [(match_dup 3) (const_int 0)]))
9671 (set (match_operand:QI 10 "general_reg_operand")
9672 (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
9673 (set (match_operand:SWI48 11 "general_reg_operand")
9674 (zero_extend:SWI48 (match_dup 10)))
9675 (set (match_operand:SWI48 1 "memory_operand") (match_dup 0))]
9676 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
9677 && peep2_reg_dead_p (6, operands[0])
9678 && peep2_reg_dead_p (3, operands[2])
9679 && !reg_overlap_mentioned_p (operands[0], operands[1])
9680 && !reg_overlap_mentioned_p (operands[2], operands[1])
9681 && !reg_overlap_mentioned_p (operands[6], operands[9])
9682 && !reg_overlap_mentioned_p (operands[0], operands[10])
9683 && !reg_overlap_mentioned_p (operands[10], operands[1])
9684 && !reg_overlap_mentioned_p (operands[0], operands[11])
9685 && !reg_overlap_mentioned_p (operands[11], operands[1])
9686 && (rtx_equal_p (operands[6], operands[0])
9687 ? (rtx_equal_p (operands[7], operands[1])
9688 && rtx_equal_p (operands[8], operands[2]))
9689 : (rtx_equal_p (operands[8], operands[0])
9690 && rtx_equal_p (operands[9], operands[1])
9691 && rtx_equal_p (operands[6], operands[2])))"
9692 [(set (match_dup 0) (match_dup 9))
9693 (parallel [(set (reg:CCC FLAGS_REG)
9695 (zero_extend:<DWI> (match_dup 1))
9696 (plus:<DWI> (match_op_dup 4
9697 [(match_dup 3) (const_int 0)])
9698 (zero_extend:<DWI> (match_dup 0)))))
9700 (minus:SWI48 (minus:SWI48 (match_dup 1)
9702 [(match_dup 3) (const_int 0)]))
9704 (set (match_dup 10) (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
9705 (set (match_dup 11) (zero_extend:SWI48 (match_dup 10)))]
9707 if (!rtx_equal_p (operands[6], operands[0]))
9708 operands[9] = operands[7];
9711 (define_expand "subborrow<mode>_0"
9713 [(set (reg:CC FLAGS_REG)
9715 (match_operand:SWI48 1 "nonimmediate_operand")
9716 (match_operand:SWI48 2 "<general_operand>")))
9717 (set (match_operand:SWI48 0 "register_operand")
9718 (minus:SWI48 (match_dup 1) (match_dup 2)))])]
9719 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)")
9721 (define_expand "uaddc<mode>5"
9722 [(match_operand:SWI48 0 "register_operand")
9723 (match_operand:SWI48 1 "register_operand")
9724 (match_operand:SWI48 2 "register_operand")
9725 (match_operand:SWI48 3 "register_operand")
9726 (match_operand:SWI48 4 "nonmemory_operand")]
9729 rtx cf = gen_rtx_REG (CCCmode, FLAGS_REG), pat, pat2;
9730 if (operands[4] == const0_rtx)
9731 emit_insn (gen_addcarry<mode>_0 (operands[0], operands[2], operands[3]));
9734 ix86_expand_carry (operands[4]);
9735 pat = gen_rtx_LTU (<DWI>mode, cf, const0_rtx);
9736 pat2 = gen_rtx_LTU (<MODE>mode, cf, const0_rtx);
9737 emit_insn (gen_addcarry<mode> (operands[0], operands[2], operands[3],
9740 rtx cc = gen_reg_rtx (QImode);
9741 pat = gen_rtx_LTU (QImode, cf, const0_rtx);
9742 emit_insn (gen_rtx_SET (cc, pat));
9743 emit_insn (gen_zero_extendqi<mode>2 (operands[1], cc));
9747 (define_expand "usubc<mode>5"
9748 [(match_operand:SWI48 0 "register_operand")
9749 (match_operand:SWI48 1 "register_operand")
9750 (match_operand:SWI48 2 "register_operand")
9751 (match_operand:SWI48 3 "register_operand")
9752 (match_operand:SWI48 4 "nonmemory_operand")]
9756 if (operands[4] == const0_rtx)
9758 cf = gen_rtx_REG (CCmode, FLAGS_REG);
9759 emit_insn (gen_subborrow<mode>_0 (operands[0], operands[2],
9764 cf = gen_rtx_REG (CCCmode, FLAGS_REG);
9765 ix86_expand_carry (operands[4]);
9766 pat = gen_rtx_LTU (<DWI>mode, cf, const0_rtx);
9767 pat2 = gen_rtx_LTU (<MODE>mode, cf, const0_rtx);
9768 emit_insn (gen_subborrow<mode> (operands[0], operands[2], operands[3],
9771 rtx cc = gen_reg_rtx (QImode);
9772 pat = gen_rtx_LTU (QImode, cf, const0_rtx);
9773 emit_insn (gen_rtx_SET (cc, pat));
9774 emit_insn (gen_zero_extendqi<mode>2 (operands[1], cc));
9778 (define_mode_iterator CC_CCC [CC CCC])
9780 ;; Pre-reload splitter to optimize
9781 ;; *setcc_qi followed by *addqi3_cconly_overflow_1 with the same QI
9782 ;; operand and no intervening flags modifications into nothing.
9783 (define_insn_and_split "*setcc_qi_addqi3_cconly_overflow_1_<mode>"
9784 [(set (reg:CCC FLAGS_REG)
9785 (compare:CCC (neg:QI (geu:QI (reg:CC_CCC FLAGS_REG) (const_int 0)))
9786 (ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))))]
9787 "ix86_pre_reload_split ()"
9791 "emit_note (NOTE_INSN_DELETED); DONE;")
9793 ;; Set the carry flag from the carry flag.
9794 (define_insn_and_split "*setccc"
9795 [(set (reg:CCC FLAGS_REG)
9796 (reg:CCC FLAGS_REG))]
9797 "ix86_pre_reload_split ()"
9801 "emit_note (NOTE_INSN_DELETED); DONE;")
9803 ;; Set the carry flag from the carry flag.
9804 (define_insn_and_split "*setcc_qi_negqi_ccc_1_<mode>"
9805 [(set (reg:CCC FLAGS_REG)
9806 (ltu:CCC (reg:CC_CCC FLAGS_REG) (const_int 0)))]
9807 "ix86_pre_reload_split ()"
9811 "emit_note (NOTE_INSN_DELETED); DONE;")
9813 ;; Set the carry flag from the carry flag.
9814 (define_insn_and_split "*setcc_qi_negqi_ccc_2_<mode>"
9815 [(set (reg:CCC FLAGS_REG)
9816 (unspec:CCC [(ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))
9817 (const_int 0)] UNSPEC_CC_NE))]
9818 "ix86_pre_reload_split ()"
9822 "emit_note (NOTE_INSN_DELETED); DONE;")
9824 ;; Overflow setting add instructions
9826 (define_expand "addqi3_cconly_overflow"
9828 [(set (reg:CCC FLAGS_REG)
9831 (match_operand:QI 0 "nonimmediate_operand")
9832 (match_operand:QI 1 "general_operand"))
9834 (clobber (scratch:QI))])]
9835 "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
9837 (define_insn "*add<mode>3_cconly_overflow_1"
9838 [(set (reg:CCC FLAGS_REG)
9841 (match_operand:SWI 1 "nonimmediate_operand" "%0,r,rm")
9842 (match_operand:SWI 2 "<general_operand>" "<g>,<g>,re"))
9844 (clobber (match_scratch:SWI 0 "=<r>,r,r"))]
9845 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9847 add{<imodesuffix>}\t{%2, %0|%0, %2}
9848 add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9849 add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
9850 [(set_attr "isa" "*,apx_ndd,apx_ndd")
9851 (set_attr "type" "alu")
9852 (set_attr "mode" "<MODE>")])
9854 (define_insn "@add<mode>3_cc_overflow_1"
9855 [(set (reg:CCC FLAGS_REG)
9858 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,rm,rjM,r")
9859 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,r,<i>,<m>"))
9861 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r,r")
9862 (plus:SWI (match_dup 1) (match_dup 2)))]
9863 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)"
9865 add{<imodesuffix>}\t{%2, %0|%0, %2}
9866 add{<imodesuffix>}\t{%2, %0|%0, %2}
9867 add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9868 add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9869 add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
9870 [(set_attr "isa" "*,*,apx_ndd,apx_ndd,apx_ndd")
9871 (set_attr "type" "alu")
9872 (set_attr "mode" "<MODE>")])
9875 [(parallel [(set (reg:CCC FLAGS_REG)
9877 (plus:SWI (match_operand:SWI 0 "general_reg_operand")
9878 (match_operand:SWI 1 "memory_operand"))
9880 (set (match_dup 0) (plus:SWI (match_dup 0) (match_dup 1)))])
9881 (set (match_dup 1) (match_dup 0))]
9882 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
9883 && peep2_reg_dead_p (2, operands[0])
9884 && !reg_overlap_mentioned_p (operands[0], operands[1])"
9885 [(parallel [(set (reg:CCC FLAGS_REG)
9887 (plus:SWI (match_dup 1) (match_dup 0))
9889 (set (match_dup 1) (plus:SWI (match_dup 1) (match_dup 0)))])])
9892 [(set (match_operand:SWI 0 "general_reg_operand")
9893 (match_operand:SWI 1 "memory_operand"))
9894 (parallel [(set (reg:CCC FLAGS_REG)
9896 (plus:SWI (match_dup 0)
9897 (match_operand:SWI 2 "memory_operand"))
9899 (set (match_dup 0) (plus:SWI (match_dup 0) (match_dup 2)))])
9900 (set (match_dup 1) (match_dup 0))]
9901 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
9902 && peep2_reg_dead_p (3, operands[0])
9903 && !reg_overlap_mentioned_p (operands[0], operands[1])
9904 && !reg_overlap_mentioned_p (operands[0], operands[2])"
9905 [(set (match_dup 0) (match_dup 2))
9906 (parallel [(set (reg:CCC FLAGS_REG)
9908 (plus:SWI (match_dup 1) (match_dup 0))
9910 (set (match_dup 1) (plus:SWI (match_dup 1) (match_dup 0)))])])
9912 (define_insn "*addsi3_zext_cc_overflow_1"
9913 [(set (reg:CCC FLAGS_REG)
9916 (match_operand:SI 1 "nonimmediate_operand" "%0,r,rm")
9917 (match_operand:SI 2 "x86_64_general_operand" "rBMe,rBMe,re"))
9919 (set (match_operand:DI 0 "register_operand" "=r,r,r")
9920 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
9922 && ix86_binary_operator_ok (PLUS, SImode, operands, TARGET_APX_NDD)"
9924 add{l}\t{%2, %k0|%k0, %2}
9925 add{l}\t{%2, %1, %k0|%k0, %1, %2}
9926 add{l}\t{%2, %1, %k0|%k0, %1, %2}"
9927 [(set_attr "isa" "*,apx_ndd,apx_ndd")
9928 (set_attr "type" "alu")
9929 (set_attr "mode" "SI")])
9931 (define_insn "*add<mode>3_cconly_overflow_2"
9932 [(set (reg:CCC FLAGS_REG)
9935 (match_operand:SWI 1 "nonimmediate_operand" "%0,r,rm")
9936 (match_operand:SWI 2 "<general_operand>" "<g>,<g>,re"))
9938 (clobber (match_scratch:SWI 0 "=<r>,r,r"))]
9939 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9941 add{<imodesuffix>}\t{%2, %0|%0, %2}
9942 add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9943 add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
9944 [(set_attr "isa" "*,apx_ndd,apx_ndd")
9945 (set_attr "type" "alu")
9946 (set_attr "mode" "<MODE>")])
9948 (define_insn "*add<mode>3_cc_overflow_2"
9949 [(set (reg:CCC FLAGS_REG)
9952 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,rm,r")
9953 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,r<i>,<m>"))
9955 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r")
9956 (plus:SWI (match_dup 1) (match_dup 2)))]
9957 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)"
9959 add{<imodesuffix>}\t{%2, %0|%0, %2}
9960 add{<imodesuffix>}\t{%2, %0|%0, %2}
9961 add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9962 add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
9963 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
9964 (set_attr "type" "alu")
9965 (set_attr "mode" "<MODE>")])
9967 (define_insn "*addsi3_zext_cc_overflow_2"
9968 [(set (reg:CCC FLAGS_REG)
9971 (match_operand:SI 1 "nonimmediate_operand" "%0,r,rm")
9972 (match_operand:SI 2 "x86_64_general_operand" "rBMe,rBMe,re"))
9974 (set (match_operand:DI 0 "register_operand" "=r,r,r")
9975 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
9977 && ix86_binary_operator_ok (PLUS, SImode, operands, TARGET_APX_NDD)"
9979 add{l}\t{%2, %k0|%k0, %2}
9980 add{l}\t{%2, %1, %k0|%k0, %1, %2}
9981 add{l}\t{%2, %1, %k0|%k0, %1, %2}"
9982 [(set_attr "isa" "*,apx_ndd,apx_ndd")
9983 (set_attr "type" "alu")
9984 (set_attr "mode" "SI")])
9986 (define_insn_and_split "*add<dwi>3_doubleword_cc_overflow_1"
9987 [(set (reg:CCC FLAGS_REG)
9990 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0,ro,r,ro,jO,r")
9991 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o,r,<di>,K,<di>,o"))
9993 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,&r,&r,&r,&r,&r")
9994 (plus:<DWI> (match_dup 1) (match_dup 2)))]
9995 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands, TARGET_APX_NDD)"
9997 "&& reload_completed"
9998 [(parallel [(set (reg:CCC FLAGS_REG)
10000 (plus:DWIH (match_dup 1) (match_dup 2))
10003 (plus:DWIH (match_dup 1) (match_dup 2)))])
10004 (parallel [(set (reg:CCC FLAGS_REG)
10009 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
10014 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))))
10017 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
10021 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
10022 if (operands[2] == const0_rtx)
10024 if (!rtx_equal_p (operands[0], operands[1]))
10025 emit_move_insn (operands[0], operands[1]);
10026 emit_insn (gen_addcarry<mode>_0 (operands[3], operands[4], operands[5]));
10029 if (CONST_INT_P (operands[5]))
10030 operands[6] = simplify_unary_operation (ZERO_EXTEND, <DWI>mode,
10031 operands[5], <MODE>mode);
10033 operands[6] = gen_rtx_ZERO_EXTEND (<DWI>mode, operands[5]);
10035 [(set_attr "isa" "*,*,apx_ndd,apx_ndd,apx_ndd,apx_ndd_64,apx_ndd")])
10037 ;; x == 0 with zero flag test can be done also as x < 1U with carry flag
10038 ;; test, where the latter is preferrable if we have some carry consuming
10040 ;; For x != 0, we need to use x < 1U with negation of carry, i.e.
10042 (define_insn_and_split "*add<mode>3_eq"
10043 [(set (match_operand:SWI 0 "nonimmediate_operand")
10046 (eq:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0))
10047 (match_operand:SWI 1 "nonimmediate_operand"))
10048 (match_operand:SWI 2 "<general_operand>")))
10049 (clobber (reg:CC FLAGS_REG))]
10050 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)
10051 && ix86_pre_reload_split ()"
10054 [(set (reg:CC FLAGS_REG)
10055 (compare:CC (match_dup 3) (const_int 1)))
10056 (parallel [(set (match_dup 0)
10058 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
10061 (clobber (reg:CC FLAGS_REG))])])
10063 (define_insn_and_split "*add<mode>3_ne"
10064 [(set (match_operand:SWI 0 "nonimmediate_operand")
10067 (ne:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0))
10068 (match_operand:SWI 1 "nonimmediate_operand"))
10069 (match_operand:SWI 2 "<immediate_operand>")))
10070 (clobber (reg:CC FLAGS_REG))]
10071 "CONST_INT_P (operands[2])
10072 && (<MODE>mode != DImode
10073 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
10074 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)
10075 && ix86_pre_reload_split ()"
10078 [(set (reg:CC FLAGS_REG)
10079 (compare:CC (match_dup 3) (const_int 1)))
10080 (parallel [(set (match_dup 0)
10082 (minus:SWI (match_dup 1)
10083 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
10085 (clobber (reg:CC FLAGS_REG))])]
10087 operands[2] = gen_int_mode (~INTVAL (operands[2]),
10088 <MODE>mode == DImode ? SImode : <MODE>mode);
10091 (define_insn_and_split "*add<mode>3_eq_0"
10092 [(set (match_operand:SWI 0 "nonimmediate_operand")
10094 (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))
10095 (match_operand:SWI 1 "<general_operand>")))
10096 (clobber (reg:CC FLAGS_REG))]
10097 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)
10098 && ix86_pre_reload_split ()"
10101 [(set (reg:CC FLAGS_REG)
10102 (compare:CC (match_dup 2) (const_int 1)))
10103 (parallel [(set (match_dup 0)
10104 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
10106 (clobber (reg:CC FLAGS_REG))])]
10108 if (!nonimmediate_operand (operands[1], <MODE>mode))
10109 operands[1] = force_reg (<MODE>mode, operands[1]);
10112 (define_insn_and_split "*add<mode>3_ne_0"
10113 [(set (match_operand:SWI 0 "nonimmediate_operand")
10115 (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))
10116 (match_operand:SWI 1 "<general_operand>")))
10117 (clobber (reg:CC FLAGS_REG))]
10118 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)
10119 && ix86_pre_reload_split ()"
10122 [(set (reg:CC FLAGS_REG)
10123 (compare:CC (match_dup 2) (const_int 1)))
10124 (parallel [(set (match_dup 0)
10125 (minus:SWI (minus:SWI
10127 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
10129 (clobber (reg:CC FLAGS_REG))])]
10131 if (!nonimmediate_operand (operands[1], <MODE>mode))
10132 operands[1] = force_reg (<MODE>mode, operands[1]);
10135 (define_insn_and_split "*sub<mode>3_eq"
10136 [(set (match_operand:SWI 0 "nonimmediate_operand")
10139 (match_operand:SWI 1 "nonimmediate_operand")
10140 (eq:SWI (match_operand 3 "int_nonimmediate_operand")
10142 (match_operand:SWI 2 "<general_operand>")))
10143 (clobber (reg:CC FLAGS_REG))]
10144 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)
10145 && ix86_pre_reload_split ()"
10148 [(set (reg:CC FLAGS_REG)
10149 (compare:CC (match_dup 3) (const_int 1)))
10150 (parallel [(set (match_dup 0)
10152 (minus:SWI (match_dup 1)
10153 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
10155 (clobber (reg:CC FLAGS_REG))])])
10157 (define_insn_and_split "*sub<mode>3_ne"
10158 [(set (match_operand:SWI 0 "nonimmediate_operand")
10161 (match_operand:SWI 1 "nonimmediate_operand")
10162 (ne:SWI (match_operand 3 "int_nonimmediate_operand")
10164 (match_operand:SWI 2 "<immediate_operand>")))
10165 (clobber (reg:CC FLAGS_REG))]
10166 "CONST_INT_P (operands[2])
10167 && (<MODE>mode != DImode
10168 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
10169 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)
10170 && ix86_pre_reload_split ()"
10173 [(set (reg:CC FLAGS_REG)
10174 (compare:CC (match_dup 3) (const_int 1)))
10175 (parallel [(set (match_dup 0)
10177 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
10180 (clobber (reg:CC FLAGS_REG))])]
10182 operands[2] = gen_int_mode (INTVAL (operands[2]) - 1,
10183 <MODE>mode == DImode ? SImode : <MODE>mode);
10186 (define_insn_and_split "*sub<mode>3_eq_1"
10187 [(set (match_operand:SWI 0 "nonimmediate_operand")
10190 (match_operand:SWI 1 "nonimmediate_operand")
10191 (eq:SWI (match_operand 3 "int_nonimmediate_operand")
10193 (match_operand:SWI 2 "<immediate_operand>")))
10194 (clobber (reg:CC FLAGS_REG))]
10195 "CONST_INT_P (operands[2])
10196 && (<MODE>mode != DImode
10197 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
10198 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)
10199 && ix86_pre_reload_split ()"
10202 [(set (reg:CC FLAGS_REG)
10203 (compare:CC (match_dup 3) (const_int 1)))
10204 (parallel [(set (match_dup 0)
10206 (minus:SWI (match_dup 1)
10207 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
10209 (clobber (reg:CC FLAGS_REG))])]
10211 operands[2] = gen_int_mode (-INTVAL (operands[2]),
10212 <MODE>mode == DImode ? SImode : <MODE>mode);
10215 (define_insn_and_split "*sub<mode>3_eq_0"
10216 [(set (match_operand:SWI 0 "nonimmediate_operand")
10218 (match_operand:SWI 1 "<general_operand>")
10219 (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))))
10220 (clobber (reg:CC FLAGS_REG))]
10221 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)
10222 && ix86_pre_reload_split ()"
10225 [(set (reg:CC FLAGS_REG)
10226 (compare:CC (match_dup 2) (const_int 1)))
10227 (parallel [(set (match_dup 0)
10228 (minus:SWI (match_dup 1)
10229 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))))
10230 (clobber (reg:CC FLAGS_REG))])]
10232 if (!nonimmediate_operand (operands[1], <MODE>mode))
10233 operands[1] = force_reg (<MODE>mode, operands[1]);
10236 (define_insn_and_split "*sub<mode>3_ne_0"
10237 [(set (match_operand:SWI 0 "nonimmediate_operand")
10239 (match_operand:SWI 1 "<general_operand>")
10240 (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))))
10241 (clobber (reg:CC FLAGS_REG))]
10242 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)
10243 && ix86_pre_reload_split ()"
10246 [(set (reg:CC FLAGS_REG)
10247 (compare:CC (match_dup 2) (const_int 1)))
10248 (parallel [(set (match_dup 0)
10249 (plus:SWI (plus:SWI
10250 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
10253 (clobber (reg:CC FLAGS_REG))])]
10255 if (!nonimmediate_operand (operands[1], <MODE>mode))
10256 operands[1] = force_reg (<MODE>mode, operands[1]);
10259 (define_expand "usadd<mode>3"
10260 [(set (match_operand:SWI 0 "register_operand")
10261 (us_plus:SWI (match_operand:SWI 1 "register_operand")
10262 (match_operand:SWI 2 "<general_operand>")))]
10265 rtx res = gen_reg_rtx (<MODE>mode);
10268 emit_insn (gen_add<mode>3_cc_overflow_1 (res, operands[1], operands[2]));
10272 rtx cmp = gen_rtx_GEU (VOIDmode, gen_rtx_REG (CCCmode, FLAGS_REG),
10275 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
10277 dst = force_reg (<MODE>mode, operands[0]);
10278 emit_insn (gen_movsicc (gen_lowpart (SImode, dst), cmp,
10279 gen_lowpart (SImode, res), constm1_rtx));
10284 emit_insn (gen_mov<mode>cc (dst, cmp, res, constm1_rtx));
10289 rtx msk = gen_reg_rtx (<MODE>mode);
10291 emit_insn (gen_x86_mov<mode>cc_0_m1_neg (msk));
10292 dst = expand_simple_binop (<MODE>mode, IOR, res, msk,
10293 operands[0], 1, OPTAB_WIDEN);
10296 if (!rtx_equal_p (dst, operands[0]))
10297 emit_move_insn (operands[0], dst);
10301 (define_expand "ussub<mode>3"
10302 [(set (match_operand:SWI 0 "register_operand")
10303 (us_minus:SWI (match_operand:SWI 1 "register_operand")
10304 (match_operand:SWI 2 "<general_operand>")))]
10307 rtx res = gen_reg_rtx (<MODE>mode);
10310 emit_insn (gen_sub<mode>_3 (res, operands[1], operands[2]));
10314 rtx cmp = gen_rtx_GEU (VOIDmode, gen_rtx_REG (CCCmode, FLAGS_REG),
10317 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
10319 dst = force_reg (<MODE>mode, operands[0]);
10320 emit_insn (gen_movsicc (gen_lowpart (SImode, dst), cmp,
10321 gen_lowpart (SImode, res), const0_rtx));
10326 emit_insn (gen_mov<mode>cc (dst, cmp, res, const0_rtx));
10331 rtx msk = gen_reg_rtx (<MODE>mode);
10333 emit_insn (gen_x86_mov<mode>cc_0_m1_neg (msk));
10334 msk = expand_simple_unop (<MODE>mode, NOT, msk, NULL, 1);
10335 dst = expand_simple_binop (<MODE>mode, AND, res, msk,
10336 operands[0], 1, OPTAB_WIDEN);
10339 if (!rtx_equal_p (dst, operands[0]))
10340 emit_move_insn (operands[0], dst);
10344 (define_expand "ustruncdi<mode>2"
10345 [(set (match_operand:SWI124 0 "register_operand")
10346 (us_truncate:DI (match_operand:DI 1 "nonimmediate_operand")))]
10349 rtx op1 = force_reg (DImode, operands[1]);
10350 rtx sat = force_reg (DImode, GEN_INT (GET_MODE_MASK (<MODE>mode)));
10353 emit_insn (gen_cmpdi_1 (sat, op1));
10357 rtx cmp = gen_rtx_GEU (VOIDmode, gen_rtx_REG (CCCmode, FLAGS_REG),
10360 dst = force_reg (<MODE>mode, operands[0]);
10361 emit_insn (gen_movsicc (gen_lowpart (SImode, dst), cmp,
10362 gen_lowpart (SImode, op1),
10363 gen_lowpart (SImode, sat)));
10367 rtx msk = gen_reg_rtx (<MODE>mode);
10369 emit_insn (gen_x86_mov<mode>cc_0_m1_neg (msk));
10370 dst = expand_simple_binop (<MODE>mode, IOR,
10371 gen_lowpart (<MODE>mode, op1), msk,
10372 operands[0], 1, OPTAB_WIDEN);
10375 if (!rtx_equal_p (dst, operands[0]))
10376 emit_move_insn (operands[0], dst);
10380 (define_expand "ustruncsi<mode>2"
10381 [(set (match_operand:SWI12 0 "register_operand")
10382 (us_truncate:SI (match_operand:SI 1 "nonimmediate_operand")))]
10385 rtx op1 = force_reg (SImode, operands[1]);
10386 rtx sat = force_reg (SImode, GEN_INT (GET_MODE_MASK (<MODE>mode)));
10389 emit_insn (gen_cmpsi_1 (sat, op1));
10393 rtx cmp = gen_rtx_GEU (VOIDmode, gen_rtx_REG (CCCmode, FLAGS_REG),
10396 dst = force_reg (<MODE>mode, operands[0]);
10397 emit_insn (gen_movsicc (gen_lowpart (SImode, dst), cmp,
10398 gen_lowpart (SImode, op1),
10399 gen_lowpart (SImode, sat)));
10403 rtx msk = gen_reg_rtx (<MODE>mode);
10405 emit_insn (gen_x86_mov<mode>cc_0_m1_neg (msk));
10406 dst = expand_simple_binop (<MODE>mode, IOR,
10407 gen_lowpart (<MODE>mode, op1), msk,
10408 operands[0], 1, OPTAB_WIDEN);
10411 if (!rtx_equal_p (dst, operands[0]))
10412 emit_move_insn (operands[0], dst);
10416 (define_expand "ustrunchiqi2"
10417 [(set (match_operand:QI 0 "register_operand")
10418 (us_truncate:HI (match_operand:HI 1 "nonimmediate_operand")))]
10421 rtx op1 = force_reg (HImode, operands[1]);
10422 rtx sat = force_reg (HImode, GEN_INT (GET_MODE_MASK (QImode)));
10425 emit_insn (gen_cmphi_1 (sat, op1));
10429 rtx cmp = gen_rtx_GEU (VOIDmode, gen_rtx_REG (CCCmode, FLAGS_REG),
10432 dst = force_reg (QImode, operands[0]);
10433 emit_insn (gen_movsicc (gen_lowpart (SImode, dst), cmp,
10434 gen_lowpart (SImode, op1),
10435 gen_lowpart (SImode, sat)));
10439 rtx msk = gen_reg_rtx (QImode);
10441 emit_insn (gen_x86_movqicc_0_m1_neg (msk));
10442 dst = expand_simple_binop (QImode, IOR,
10443 gen_lowpart (QImode, op1), msk,
10444 operands[0], 1, OPTAB_WIDEN);
10447 if (!rtx_equal_p (dst, operands[0]))
10448 emit_move_insn (operands[0], dst);
10452 ;; The patterns that match these are at the end of this file.
10454 (define_expand "<insn>xf3"
10455 [(set (match_operand:XF 0 "register_operand")
10457 (match_operand:XF 1 "register_operand")
10458 (match_operand:XF 2 "register_operand")))]
10461 (define_expand "<insn>hf3"
10462 [(set (match_operand:HF 0 "register_operand")
10464 (match_operand:HF 1 "register_operand")
10465 (match_operand:HF 2 "nonimmediate_operand")))]
10466 "TARGET_AVX512FP16")
10468 (define_expand "<insn><mode>3"
10469 [(set (match_operand:MODEF 0 "register_operand")
10471 (match_operand:MODEF 1 "register_operand")
10472 (match_operand:MODEF 2 "nonimmediate_operand")))]
10473 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
10474 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
10476 ;; Multiply instructions
10478 (define_expand "mul<mode>3"
10479 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
10481 (match_operand:SWIM248 1 "register_operand")
10482 (match_operand:SWIM248 2 "<general_operand>")))
10483 (clobber (reg:CC FLAGS_REG))])])
10485 (define_expand "mulqi3"
10486 [(parallel [(set (match_operand:QI 0 "register_operand")
10488 (match_operand:QI 1 "register_operand")
10489 (match_operand:QI 2 "nonimmediate_operand")))
10490 (clobber (reg:CC FLAGS_REG))])]
10491 "TARGET_QIMODE_MATH")
10494 ;; IMUL reg32/64, reg32/64, imm8 Direct
10495 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
10496 ;; IMUL reg32/64, reg32/64, imm32 Direct
10497 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
10498 ;; IMUL reg32/64, reg32/64 Direct
10499 ;; IMUL reg32/64, mem32/64 Direct
10501 ;; On BDVER1, all above IMULs use DirectPath
10504 ;; IMUL reg16, reg16, imm8 VectorPath
10505 ;; IMUL reg16, mem16, imm8 VectorPath
10506 ;; IMUL reg16, reg16, imm16 VectorPath
10507 ;; IMUL reg16, mem16, imm16 VectorPath
10508 ;; IMUL reg16, reg16 Direct
10509 ;; IMUL reg16, mem16 Direct
10511 ;; On BDVER1, all HI MULs use DoublePath
10513 (define_insn "*mul<mode>3_1<nf_name>"
10514 [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r,r")
10516 (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0,r")
10517 (match_operand:SWIM248 2 "<general_operand>" "K,<i>,<m>r,<m>r")))]
10518 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
10521 <nf_prefix>imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
10522 <nf_prefix>imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
10523 <nf_prefix>imul{<imodesuffix>}\t{%2, %0|%0, %2}
10524 <nf_prefix>imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
10525 [(set_attr "type" "imul")
10526 (set_attr "prefix_0f" "0,0,1,1")
10527 (set_attr "isa" "*,*,*,apx_ndd")
10528 (set (attr "athlon_decode")
10529 (cond [(eq_attr "cpu" "athlon")
10530 (const_string "vector")
10531 (eq_attr "alternative" "1")
10532 (const_string "vector")
10533 (and (eq_attr "alternative" "2,3")
10534 (ior (match_test "<MODE>mode == HImode")
10535 (match_operand 1 "memory_operand")))
10536 (const_string "vector")]
10537 (const_string "direct")))
10538 (set (attr "amdfam10_decode")
10539 (cond [(and (eq_attr "alternative" "0,1")
10540 (ior (match_test "<MODE>mode == HImode")
10541 (match_operand 1 "memory_operand")))
10542 (const_string "vector")]
10543 (const_string "direct")))
10544 (set (attr "bdver1_decode")
10546 (match_test "<MODE>mode == HImode")
10547 (const_string "double")
10548 (const_string "direct")))
10549 (set_attr "has_nf" "1")
10550 (set_attr "mode" "<MODE>")])
10552 (define_insn "*imulhi<mode>zu<nf_name>"
10553 [(set (match_operand:SWI48x 0 "register_operand" "=r,r")
10554 (zero_extend:SWI48x
10555 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm")
10556 (match_operand:HI 2 "immediate_operand" "K,n"))))]
10557 "TARGET_APX_ZU && <nf_condition>"
10559 <nf_prefix>imulzu{w}\t{%2, %1, %w0|%w0, %1, %2}
10560 <nf_prefix>imulzu{w}\t{%2, %1, %w0|%w0, %1, %2}"
10561 [(set_attr "type" "imul")
10562 (set_attr "mode" "HI")])
10564 (define_insn "*mulsi3_1_zext<nf_name>"
10565 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
10567 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0,r")
10568 (match_operand:SI 2 "x86_64_general_operand" "K,e,BMr,BMr"))))]
10570 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
10573 <nf_prefix>imul{l}\t{%2, %1, %k0|%k0, %1, %2}
10574 <nf_prefix>imul{l}\t{%2, %1, %k0|%k0, %1, %2}
10575 <nf_prefix>imul{l}\t{%2, %k0|%k0, %2}
10576 <nf_prefix>imul{l}\t{%2, %1, %k0|%k0, %1, %2}"
10577 [(set_attr "type" "imul")
10578 (set_attr "prefix_0f" "0,0,1,1")
10579 (set_attr "isa" "*,*,*,apx_ndd")
10580 (set (attr "athlon_decode")
10581 (cond [(eq_attr "cpu" "athlon")
10582 (const_string "vector")
10583 (eq_attr "alternative" "1")
10584 (const_string "vector")
10585 (and (eq_attr "alternative" "2")
10586 (match_operand 1 "memory_operand"))
10587 (const_string "vector")]
10588 (const_string "direct")))
10589 (set (attr "amdfam10_decode")
10590 (cond [(and (eq_attr "alternative" "0,1")
10591 (match_operand 1 "memory_operand"))
10592 (const_string "vector")]
10593 (const_string "direct")))
10594 (set_attr "bdver1_decode" "direct")
10595 (set_attr "mode" "SI")])
10597 ;;On AMDFAM10 and BDVER1
10601 (define_insn "*mulqi3_1<nf_name>"
10602 [(set (match_operand:QI 0 "register_operand" "=a")
10603 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
10604 (match_operand:QI 2 "nonimmediate_operand" "qm")))]
10605 "TARGET_QIMODE_MATH
10606 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
10608 "<nf_prefix>mul{b}\t%2"
10609 [(set_attr "type" "imul")
10610 (set_attr "length_immediate" "0")
10611 (set (attr "athlon_decode")
10612 (if_then_else (eq_attr "cpu" "athlon")
10613 (const_string "vector")
10614 (const_string "direct")))
10615 (set_attr "amdfam10_decode" "direct")
10616 (set_attr "bdver1_decode" "direct")
10617 (set_attr "has_nf" "1")
10618 (set_attr "mode" "QI")])
10620 ;; Multiply with jump on overflow.
10621 (define_expand "mulv<mode>4"
10622 [(parallel [(set (reg:CCO FLAGS_REG)
10623 (eq:CCO (mult:<DWI>
10625 (match_operand:SWI248 1 "register_operand"))
10628 (mult:SWI248 (match_dup 1)
10629 (match_operand:SWI248 2
10630 "<general_operand>")))))
10631 (set (match_operand:SWI248 0 "register_operand")
10632 (mult:SWI248 (match_dup 1) (match_dup 2)))])
10633 (set (pc) (if_then_else
10634 (eq (reg:CCO FLAGS_REG) (const_int 0))
10635 (label_ref (match_operand 3))
10639 if (CONST_INT_P (operands[2]))
10640 operands[4] = operands[2];
10642 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
10645 (define_insn "*mulv<mode>4"
10646 [(set (reg:CCO FLAGS_REG)
10647 (eq:CCO (mult:<DWI>
10649 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0,r"))
10651 (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr,mr")))
10653 (mult:SWI48 (match_dup 1) (match_dup 2)))))
10654 (set (match_operand:SWI48 0 "register_operand" "=r,r,r")
10655 (mult:SWI48 (match_dup 1) (match_dup 2)))]
10656 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
10658 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
10659 imul{<imodesuffix>}\t{%2, %0|%0, %2}
10660 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
10661 [(set_attr "type" "imul")
10662 (set_attr "prefix_0f" "0,1,1")
10663 (set_attr "isa" "*,*,apx_ndd")
10664 (set (attr "athlon_decode")
10665 (cond [(eq_attr "cpu" "athlon")
10666 (const_string "vector")
10667 (eq_attr "alternative" "0")
10668 (const_string "vector")
10669 (and (eq_attr "alternative" "1,2")
10670 (match_operand 1 "memory_operand"))
10671 (const_string "vector")]
10672 (const_string "direct")))
10673 (set (attr "amdfam10_decode")
10674 (cond [(and (eq_attr "alternative" "1,2")
10675 (match_operand 1 "memory_operand"))
10676 (const_string "vector")]
10677 (const_string "direct")))
10678 (set_attr "bdver1_decode" "direct")
10679 (set_attr "mode" "<MODE>")])
10681 (define_insn "*mulvhi4"
10682 [(set (reg:CCO FLAGS_REG)
10685 (match_operand:HI 1 "nonimmediate_operand" "%0,r"))
10687 (match_operand:HI 2 "nonimmediate_operand" "mr,mr")))
10689 (mult:HI (match_dup 1) (match_dup 2)))))
10690 (set (match_operand:HI 0 "register_operand" "=r,r")
10691 (mult:HI (match_dup 1) (match_dup 2)))]
10692 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
10694 imul{w}\t{%2, %0|%0, %2}
10695 imul{w}\t{%2, %1, %0|%0, %1, %2}"
10696 [(set_attr "type" "imul")
10697 (set_attr "prefix_0f" "1")
10698 (set_attr "isa" "*,apx_ndd")
10699 (set_attr "athlon_decode" "vector")
10700 (set_attr "amdfam10_decode" "direct")
10701 (set_attr "bdver1_decode" "double")
10702 (set_attr "mode" "HI")])
10704 (define_insn "*mulv<mode>4_1"
10705 [(set (reg:CCO FLAGS_REG)
10706 (eq:CCO (mult:<DWI>
10708 (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
10709 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
10711 (mult:SWI248 (match_dup 1)
10712 (match_operand:SWI248 2
10713 "<immediate_operand>" "K,<i>")))))
10714 (set (match_operand:SWI248 0 "register_operand" "=r,r")
10715 (mult:SWI248 (match_dup 1) (match_dup 2)))]
10716 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
10717 && CONST_INT_P (operands[2])
10718 && INTVAL (operands[2]) == INTVAL (operands[3])"
10719 "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
10720 [(set_attr "type" "imul")
10721 (set (attr "prefix_0f")
10723 (match_test "<MODE>mode == HImode")
10725 (const_string "*")))
10726 (set (attr "athlon_decode")
10727 (cond [(eq_attr "cpu" "athlon")
10728 (const_string "vector")
10729 (eq_attr "alternative" "1")
10730 (const_string "vector")]
10731 (const_string "direct")))
10732 (set (attr "amdfam10_decode")
10733 (cond [(ior (match_test "<MODE>mode == HImode")
10734 (match_operand 1 "memory_operand"))
10735 (const_string "vector")]
10736 (const_string "direct")))
10737 (set (attr "bdver1_decode")
10739 (match_test "<MODE>mode == HImode")
10740 (const_string "double")
10741 (const_string "direct")))
10742 (set_attr "mode" "<MODE>")
10743 (set (attr "length_immediate")
10744 (cond [(eq_attr "alternative" "0")
10746 (match_test "<MODE_SIZE> == 8")
10747 (const_string "4")]
10748 (const_string "<MODE_SIZE>")))])
10750 (define_expand "umulv<mode>4"
10751 [(parallel [(set (reg:CCO FLAGS_REG)
10752 (eq:CCO (mult:<DWI>
10754 (match_operand:SWI248 1
10755 "nonimmediate_operand"))
10757 (match_operand:SWI248 2
10758 "nonimmediate_operand")))
10760 (mult:SWI248 (match_dup 1) (match_dup 2)))))
10761 (set (match_operand:SWI248 0 "register_operand")
10762 (mult:SWI248 (match_dup 1) (match_dup 2)))
10763 (clobber (scratch:SWI248))])
10764 (set (pc) (if_then_else
10765 (eq (reg:CCO FLAGS_REG) (const_int 0))
10766 (label_ref (match_operand 3))
10770 if (MEM_P (operands[1]) && MEM_P (operands[2]))
10771 operands[1] = force_reg (<MODE>mode, operands[1]);
10774 (define_insn "*umulv<mode>4"
10775 [(set (reg:CCO FLAGS_REG)
10776 (eq:CCO (mult:<DWI>
10778 (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
10780 (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
10782 (mult:SWI248 (match_dup 1) (match_dup 2)))))
10783 (set (match_operand:SWI248 0 "register_operand" "=a")
10784 (mult:SWI248 (match_dup 1) (match_dup 2)))
10785 (clobber (match_scratch:SWI248 3 "=d"))]
10786 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
10787 "mul{<imodesuffix>}\t%2"
10788 [(set_attr "type" "imul")
10789 (set_attr "length_immediate" "0")
10790 (set (attr "athlon_decode")
10791 (if_then_else (eq_attr "cpu" "athlon")
10792 (const_string "vector")
10793 (const_string "double")))
10794 (set_attr "amdfam10_decode" "double")
10795 (set_attr "bdver1_decode" "direct")
10796 (set_attr "mode" "<MODE>")])
10798 (define_expand "<u>mulvqi4"
10799 [(parallel [(set (reg:CCO FLAGS_REG)
10802 (match_operand:QI 1 "nonimmediate_operand"))
10804 (match_operand:QI 2 "nonimmediate_operand")))
10806 (mult:QI (match_dup 1) (match_dup 2)))))
10807 (set (match_operand:QI 0 "register_operand")
10808 (mult:QI (match_dup 1) (match_dup 2)))])
10809 (set (pc) (if_then_else
10810 (eq (reg:CCO FLAGS_REG) (const_int 0))
10811 (label_ref (match_operand 3))
10813 "TARGET_QIMODE_MATH"
10815 if (MEM_P (operands[1]) && MEM_P (operands[2]))
10816 operands[1] = force_reg (QImode, operands[1]);
10819 (define_insn "*<u>mulvqi4"
10820 [(set (reg:CCO FLAGS_REG)
10823 (match_operand:QI 1 "nonimmediate_operand" "%0"))
10825 (match_operand:QI 2 "nonimmediate_operand" "qm")))
10827 (mult:QI (match_dup 1) (match_dup 2)))))
10828 (set (match_operand:QI 0 "register_operand" "=a")
10829 (mult:QI (match_dup 1) (match_dup 2)))]
10830 "TARGET_QIMODE_MATH
10831 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10832 "<sgnprefix>mul{b}\t%2"
10833 [(set_attr "type" "imul")
10834 (set_attr "length_immediate" "0")
10835 (set (attr "athlon_decode")
10836 (if_then_else (eq_attr "cpu" "athlon")
10837 (const_string "vector")
10838 (const_string "direct")))
10839 (set_attr "amdfam10_decode" "direct")
10840 (set_attr "bdver1_decode" "direct")
10841 (set_attr "mode" "QI")])
10843 (define_expand "<u>mul<mode><dwi>3"
10844 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
10847 (match_operand:DWIH 1 "register_operand"))
10849 (match_operand:DWIH 2 "nonimmediate_operand"))))
10850 (clobber (reg:CC FLAGS_REG))])])
10852 (define_expand "<u>mulqihi3"
10853 [(parallel [(set (match_operand:HI 0 "register_operand")
10856 (match_operand:QI 1 "register_operand"))
10858 (match_operand:QI 2 "nonimmediate_operand"))))
10859 (clobber (reg:CC FLAGS_REG))])]
10860 "TARGET_QIMODE_MATH")
10862 (define_insn "*bmi2_umul<mode><dwi>3_1"
10863 [(set (match_operand:DWIH 0 "register_operand" "=r")
10865 (match_operand:DWIH 2 "register_operand" "%d")
10866 (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
10867 (set (match_operand:DWIH 1 "register_operand" "=r")
10868 (umul_highpart:DWIH (match_dup 2) (match_dup 3)))]
10870 "mulx\t{%3, %0, %1|%1, %0, %3}"
10871 [(set_attr "type" "imulx")
10872 (set_attr "prefix" "vex")
10873 (set_attr "mode" "<MODE>")])
10875 ;; Tweak *bmi2_umul<mode><dwi>3_1 to eliminate following mov.
10877 [(parallel [(set (match_operand:DWIH 0 "general_reg_operand")
10878 (mult:DWIH (match_operand:DWIH 2 "register_operand")
10879 (match_operand:DWIH 3 "nonimmediate_operand")))
10880 (set (match_operand:DWIH 1 "general_reg_operand")
10881 (umul_highpart:DWIH (match_dup 2) (match_dup 3)))])
10882 (set (match_operand:DWIH 4 "general_reg_operand")
10883 (match_operand:DWIH 5 "general_reg_operand"))]
10885 && ((REGNO (operands[5]) == REGNO (operands[0])
10886 && REGNO (operands[1]) != REGNO (operands[4]))
10887 || (REGNO (operands[5]) == REGNO (operands[1])
10888 && REGNO (operands[0]) != REGNO (operands[4])))
10889 && peep2_reg_dead_p (2, operands[5])"
10890 [(parallel [(set (match_dup 0) (mult:DWIH (match_dup 2) (match_dup 3)))
10892 (umul_highpart:DWIH (match_dup 2) (match_dup 3)))])]
10894 if (REGNO (operands[5]) == REGNO (operands[0]))
10895 operands[0] = operands[4];
10897 operands[1] = operands[4];
10900 (define_insn "*umul<mode><dwi>3_1"
10901 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
10904 (match_operand:DWIH 1 "register_operand" "%d,a"))
10906 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
10907 (clobber (reg:CC FLAGS_REG))]
10908 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
10911 mul{<imodesuffix>}\t%2"
10912 [(set_attr "isa" "bmi2,*")
10913 (set_attr "type" "imulx,imul")
10914 (set_attr "length_immediate" "*,0")
10915 (set (attr "athlon_decode")
10916 (cond [(eq_attr "alternative" "1")
10917 (if_then_else (eq_attr "cpu" "athlon")
10918 (const_string "vector")
10919 (const_string "double"))]
10920 (const_string "*")))
10921 (set_attr "amdfam10_decode" "*,double")
10922 (set_attr "bdver1_decode" "*,direct")
10923 (set_attr "prefix" "vex,orig")
10924 (set_attr "mode" "<MODE>")])
10926 ;; Convert mul to the mulx pattern to avoid flags dependency.
10928 [(set (match_operand:<DWI> 0 "register_operand")
10931 (match_operand:DWIH 1 "register_operand"))
10933 (match_operand:DWIH 2 "nonimmediate_operand"))))
10934 (clobber (reg:CC FLAGS_REG))]
10935 "TARGET_BMI2 && reload_completed
10936 && REGNO (operands[1]) == DX_REG"
10937 [(parallel [(set (match_dup 3)
10938 (mult:DWIH (match_dup 1) (match_dup 2)))
10940 (umul_highpart:DWIH (match_dup 1) (match_dup 2)))])]
10942 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
10944 operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
10947 (define_insn "*mul<mode><dwi>3_1<nf_name>"
10948 [(set (match_operand:<DWI> 0 "register_operand" "=A")
10951 (match_operand:DWIH 1 "register_operand" "%a"))
10953 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))]
10954 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
10956 "<nf_prefix>imul{<imodesuffix>}\t%2"
10957 [(set_attr "type" "imul")
10958 (set_attr "length_immediate" "0")
10959 (set (attr "athlon_decode")
10960 (if_then_else (eq_attr "cpu" "athlon")
10961 (const_string "vector")
10962 (const_string "double")))
10963 (set_attr "amdfam10_decode" "double")
10964 (set_attr "bdver1_decode" "direct")
10965 (set_attr "mode" "<MODE>")])
10967 (define_insn "*<u>mulqihi3_1<nf_name>"
10968 [(set (match_operand:HI 0 "register_operand" "=a")
10971 (match_operand:QI 1 "register_operand" "%0"))
10973 (match_operand:QI 2 "nonimmediate_operand" "qm"))))]
10974 "TARGET_QIMODE_MATH
10975 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
10977 "<nf_prefix><sgnprefix>mul{b}\t%2"
10978 [(set_attr "type" "imul")
10979 (set_attr "length_immediate" "0")
10980 (set (attr "athlon_decode")
10981 (if_then_else (eq_attr "cpu" "athlon")
10982 (const_string "vector")
10983 (const_string "direct")))
10984 (set_attr "amdfam10_decode" "direct")
10985 (set_attr "bdver1_decode" "direct")
10986 (set_attr "mode" "QI")])
10988 ;; Widening multiplication peephole2s to tweak register allocation.
10989 ;; mov imm,%rdx; mov %rdi,%rax; mulq %rdx -> mov imm,%rax; mulq %rdi
10991 [(set (match_operand:DWIH 0 "general_reg_operand")
10992 (match_operand:DWIH 1 "immediate_operand"))
10993 (set (match_operand:DWIH 2 "general_reg_operand")
10994 (match_operand:DWIH 3 "general_reg_operand"))
10995 (parallel [(set (match_operand:<DWI> 4 "general_reg_operand")
10996 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
10997 (zero_extend:<DWI> (match_dup 0))))
10998 (clobber (reg:CC FLAGS_REG))])]
10999 "REGNO (operands[3]) != AX_REG
11000 && REGNO (operands[0]) != REGNO (operands[2])
11001 && REGNO (operands[0]) != REGNO (operands[3])
11002 && (REGNO (operands[0]) == REGNO (operands[4])
11003 || REGNO (operands[0]) == DX_REG
11004 || peep2_reg_dead_p (3, operands[0]))"
11005 [(set (match_dup 2) (match_dup 1))
11006 (parallel [(set (match_dup 4)
11007 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
11008 (zero_extend:<DWI> (match_dup 3))))
11009 (clobber (reg:CC FLAGS_REG))])])
11011 ;; mov imm,%rax; mov %rdi,%rdx; mulx %rax -> mov imm,%rdx; mulx %rdi
11013 [(set (match_operand:DWIH 0 "general_reg_operand")
11014 (match_operand:DWIH 1 "immediate_operand"))
11015 (set (match_operand:DWIH 2 "general_reg_operand")
11016 (match_operand:DWIH 3 "general_reg_operand"))
11017 (parallel [(set (match_operand:DWIH 4 "general_reg_operand")
11018 (mult:DWIH (match_dup 2) (match_dup 0)))
11019 (set (match_operand:DWIH 5 "general_reg_operand")
11020 (umul_highpart:DWIH (match_dup 2) (match_dup 0)))])]
11021 "REGNO (operands[3]) != DX_REG
11022 && REGNO (operands[0]) != REGNO (operands[2])
11023 && REGNO (operands[0]) != REGNO (operands[3])
11024 && (REGNO (operands[0]) == REGNO (operands[4])
11025 || REGNO (operands[0]) == REGNO (operands[5])
11026 || peep2_reg_dead_p (3, operands[0]))
11027 && (REGNO (operands[2]) == REGNO (operands[4])
11028 || REGNO (operands[2]) == REGNO (operands[5])
11029 || peep2_reg_dead_p (3, operands[2]))"
11030 [(set (match_dup 2) (match_dup 1))
11031 (parallel [(set (match_dup 4)
11032 (mult:DWIH (match_dup 2) (match_dup 3)))
11034 (umul_highpart:DWIH (match_dup 2) (match_dup 3)))])])
11036 ;; Highpart multiplication patterns
11037 (define_insn "<s>mul<mode>3_highpart"
11038 [(set (match_operand:DWIH 0 "register_operand" "=d")
11039 (any_mul_highpart:DWIH
11040 (match_operand:DWIH 1 "register_operand" "%a")
11041 (match_operand:DWIH 2 "nonimmediate_operand" "rm")))
11042 (clobber (match_scratch:DWIH 3 "=1"))
11043 (clobber (reg:CC FLAGS_REG))]
11045 "<sgnprefix>mul{<imodesuffix>}\t%2"
11046 [(set_attr "type" "imul")
11047 (set_attr "length_immediate" "0")
11048 (set (attr "athlon_decode")
11049 (if_then_else (eq_attr "cpu" "athlon")
11050 (const_string "vector")
11051 (const_string "double")))
11052 (set_attr "amdfam10_decode" "double")
11053 (set_attr "bdver1_decode" "direct")
11054 (set_attr "mode" "<MODE>")])
11056 (define_insn "*<s>mulsi3_highpart_zext"
11057 [(set (match_operand:DI 0 "register_operand" "=d")
11059 (any_mul_highpart:SI
11060 (match_operand:SI 1 "register_operand" "%a")
11061 (match_operand:SI 2 "nonimmediate_operand" "rm"))))
11062 (clobber (match_scratch:SI 3 "=1"))
11063 (clobber (reg:CC FLAGS_REG))]
11065 "<sgnprefix>mul{l}\t%2"
11066 [(set_attr "type" "imul")
11067 (set_attr "length_immediate" "0")
11068 (set (attr "athlon_decode")
11069 (if_then_else (eq_attr "cpu" "athlon")
11070 (const_string "vector")
11071 (const_string "double")))
11072 (set_attr "amdfam10_decode" "double")
11073 (set_attr "bdver1_decode" "direct")
11074 (set_attr "mode" "SI")])
11076 (define_insn "*<s>muldi3_highpart_1"
11077 [(set (match_operand:DI 0 "register_operand" "=d")
11082 (match_operand:DI 1 "nonimmediate_operand" "%a"))
11084 (match_operand:DI 2 "nonimmediate_operand" "rm")))
11086 (clobber (match_scratch:DI 3 "=1"))
11087 (clobber (reg:CC FLAGS_REG))]
11089 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
11090 "<sgnprefix>mul{q}\t%2"
11091 [(set_attr "type" "imul")
11092 (set_attr "length_immediate" "0")
11093 (set (attr "athlon_decode")
11094 (if_then_else (eq_attr "cpu" "athlon")
11095 (const_string "vector")
11096 (const_string "double")))
11097 (set_attr "amdfam10_decode" "double")
11098 (set_attr "bdver1_decode" "direct")
11099 (set_attr "mode" "DI")])
11101 (define_insn "*<s>mulsi3_highpart_zext"
11102 [(set (match_operand:DI 0 "register_operand" "=d")
11103 (zero_extend:DI (truncate:SI
11105 (mult:DI (any_extend:DI
11106 (match_operand:SI 1 "nonimmediate_operand" "%a"))
11108 (match_operand:SI 2 "nonimmediate_operand" "rm")))
11110 (clobber (match_scratch:SI 3 "=1"))
11111 (clobber (reg:CC FLAGS_REG))]
11113 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
11114 "<sgnprefix>mul{l}\t%2"
11115 [(set_attr "type" "imul")
11116 (set_attr "length_immediate" "0")
11117 (set (attr "athlon_decode")
11118 (if_then_else (eq_attr "cpu" "athlon")
11119 (const_string "vector")
11120 (const_string "double")))
11121 (set_attr "amdfam10_decode" "double")
11122 (set_attr "bdver1_decode" "direct")
11123 (set_attr "mode" "SI")])
11125 (define_insn "*<s>mulsi3_highpart_1"
11126 [(set (match_operand:SI 0 "register_operand" "=d")
11131 (match_operand:SI 1 "nonimmediate_operand" "%a"))
11133 (match_operand:SI 2 "nonimmediate_operand" "rm")))
11135 (clobber (match_scratch:SI 3 "=1"))
11136 (clobber (reg:CC FLAGS_REG))]
11137 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
11138 "<sgnprefix>mul{l}\t%2"
11139 [(set_attr "type" "imul")
11140 (set_attr "length_immediate" "0")
11141 (set (attr "athlon_decode")
11142 (if_then_else (eq_attr "cpu" "athlon")
11143 (const_string "vector")
11144 (const_string "double")))
11145 (set_attr "amdfam10_decode" "double")
11146 (set_attr "bdver1_decode" "direct")
11147 (set_attr "mode" "SI")])
11149 ;; Highpart multiplication peephole2s to tweak register allocation.
11150 ;; mov imm,%rdx; mov %rdi,%rax; imulq %rdx -> mov imm,%rax; imulq %rdi
11152 [(set (match_operand:SWI48 0 "general_reg_operand")
11153 (match_operand:SWI48 1 "immediate_operand"))
11154 (set (match_operand:SWI48 2 "general_reg_operand")
11155 (match_operand:SWI48 3 "general_reg_operand"))
11156 (parallel [(set (match_operand:SWI48 4 "general_reg_operand")
11157 (any_mul_highpart:SWI48 (match_dup 2) (match_dup 0)))
11158 (clobber (match_dup 2))
11159 (clobber (reg:CC FLAGS_REG))])]
11160 "REGNO (operands[3]) != AX_REG
11161 && REGNO (operands[0]) != REGNO (operands[2])
11162 && REGNO (operands[0]) != REGNO (operands[3])
11163 && (REGNO (operands[0]) == REGNO (operands[4])
11164 || peep2_reg_dead_p (3, operands[0]))"
11165 [(set (match_dup 2) (match_dup 1))
11166 (parallel [(set (match_dup 4)
11167 (any_mul_highpart:SWI48 (match_dup 2) (match_dup 3)))
11168 (clobber (match_dup 2))
11169 (clobber (reg:CC FLAGS_REG))])])
11172 [(set (match_operand:SI 0 "general_reg_operand")
11173 (match_operand:SI 1 "immediate_operand"))
11174 (set (match_operand:SI 2 "general_reg_operand")
11175 (match_operand:SI 3 "general_reg_operand"))
11176 (parallel [(set (match_operand:DI 4 "general_reg_operand")
11178 (any_mul_highpart:SI (match_dup 2) (match_dup 0))))
11179 (clobber (match_dup 2))
11180 (clobber (reg:CC FLAGS_REG))])]
11182 && REGNO (operands[3]) != AX_REG
11183 && REGNO (operands[0]) != REGNO (operands[2])
11184 && REGNO (operands[2]) != REGNO (operands[3])
11185 && REGNO (operands[0]) != REGNO (operands[3])
11186 && (REGNO (operands[0]) == REGNO (operands[4])
11187 || peep2_reg_dead_p (3, operands[0]))"
11188 [(set (match_dup 2) (match_dup 1))
11189 (parallel [(set (match_dup 4)
11191 (any_mul_highpart:SI (match_dup 2) (match_dup 3))))
11192 (clobber (match_dup 2))
11193 (clobber (reg:CC FLAGS_REG))])])
11195 ;; The patterns that match these are at the end of this file.
11197 (define_expand "mulxf3"
11198 [(set (match_operand:XF 0 "register_operand")
11199 (mult:XF (match_operand:XF 1 "register_operand")
11200 (match_operand:XF 2 "register_operand")))]
11203 (define_expand "mulhf3"
11204 [(set (match_operand:HF 0 "register_operand")
11205 (mult:HF (match_operand:HF 1 "register_operand")
11206 (match_operand:HF 2 "nonimmediate_operand")))]
11207 "TARGET_AVX512FP16")
11209 (define_expand "mul<mode>3"
11210 [(set (match_operand:MODEF 0 "register_operand")
11211 (mult:MODEF (match_operand:MODEF 1 "register_operand")
11212 (match_operand:MODEF 2 "nonimmediate_operand")))]
11213 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
11214 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
11216 ;; Divide instructions
11218 ;; The patterns that match these are at the end of this file.
11220 (define_expand "divxf3"
11221 [(set (match_operand:XF 0 "register_operand")
11222 (div:XF (match_operand:XF 1 "register_operand")
11223 (match_operand:XF 2 "register_operand")))]
11226 /* There is no more precision loss than Newton-Rhapson approximation
11227 when using HFmode rcp/rsqrt, so do the transformation directly under
11228 TARGET_RECIP_DIV and fast-math. */
11229 (define_expand "divhf3"
11230 [(set (match_operand:HF 0 "register_operand")
11231 (div:HF (match_operand:HF 1 "register_operand")
11232 (match_operand:HF 2 "nonimmediate_operand")))]
11233 "TARGET_AVX512FP16"
11235 if (TARGET_RECIP_DIV
11236 && optimize_insn_for_speed_p ()
11237 && flag_finite_math_only && !flag_trapping_math
11238 && flag_unsafe_math_optimizations)
11240 rtx op = gen_reg_rtx (HFmode);
11241 operands[2] = force_reg (HFmode, operands[2]);
11242 emit_insn (gen_rcphf2 (op, operands[2]));
11243 emit_insn (gen_mulhf3 (operands[0], operands[1], op));
11248 (define_expand "div<mode>3"
11249 [(set (match_operand:MODEF 0 "register_operand")
11250 (div:MODEF (match_operand:MODEF 1 "register_operand")
11251 (match_operand:MODEF 2 "nonimmediate_operand")))]
11252 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
11253 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
11255 if (<MODE>mode == SFmode
11256 && TARGET_SSE && TARGET_SSE_MATH
11257 && TARGET_RECIP_DIV
11258 && optimize_insn_for_speed_p ()
11259 && flag_finite_math_only && !flag_trapping_math
11260 && flag_unsafe_math_optimizations)
11262 ix86_emit_swdivsf (operands[0], operands[1],
11263 operands[2], SFmode);
11268 ;; Divmod instructions.
11270 (define_code_iterator any_div [div udiv])
11271 (define_code_attr paired_mod [(div "mod") (udiv "umod")])
11273 (define_expand "<u>divmod<mode>4"
11274 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
11276 (match_operand:SWIM248 1 "register_operand")
11277 (match_operand:SWIM248 2 "nonimmediate_operand")))
11278 (set (match_operand:SWIM248 3 "register_operand")
11279 (<paired_mod>:SWIM248 (match_dup 1) (match_dup 2)))
11280 (clobber (reg:CC FLAGS_REG))])])
11282 ;; Split with 8bit unsigned divide:
11283 ;; if (dividend an divisor are in [0-255])
11284 ;; use 8bit unsigned integer divide
11286 ;; use original integer divide
11288 [(set (match_operand:SWI48 0 "register_operand")
11289 (any_div:SWI48 (match_operand:SWI48 2 "register_operand")
11290 (match_operand:SWI48 3 "nonimmediate_operand")))
11291 (set (match_operand:SWI48 1 "register_operand")
11292 (<paired_mod>:SWI48 (match_dup 2) (match_dup 3)))
11293 (clobber (reg:CC FLAGS_REG))]
11294 "TARGET_USE_8BIT_IDIV
11295 && TARGET_QIMODE_MATH
11296 && can_create_pseudo_p ()
11297 && !optimize_insn_for_size_p ()"
11299 "ix86_split_idivmod (<MODE>mode, operands, <u_bool>); DONE;")
11302 [(set (match_operand:DI 0 "register_operand")
11304 (any_div:SI (match_operand:SI 2 "register_operand")
11305 (match_operand:SI 3 "nonimmediate_operand"))))
11306 (set (match_operand:SI 1 "register_operand")
11307 (<paired_mod>:SI (match_dup 2) (match_dup 3)))
11308 (clobber (reg:CC FLAGS_REG))]
11310 && TARGET_USE_8BIT_IDIV
11311 && TARGET_QIMODE_MATH
11312 && can_create_pseudo_p ()
11313 && !optimize_insn_for_size_p ()"
11315 "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
11318 [(set (match_operand:DI 1 "register_operand")
11320 (<paired_mod>:SI (match_operand:SI 2 "register_operand")
11321 (match_operand:SI 3 "nonimmediate_operand"))))
11322 (set (match_operand:SI 0 "register_operand")
11323 (any_div:SI (match_dup 2) (match_dup 3)))
11324 (clobber (reg:CC FLAGS_REG))]
11326 && TARGET_USE_8BIT_IDIV
11327 && TARGET_QIMODE_MATH
11328 && can_create_pseudo_p ()
11329 && !optimize_insn_for_size_p ()"
11331 "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
11333 (define_insn_and_split "divmod<mode>4_1"
11334 [(set (match_operand:SWI48 0 "register_operand" "=a")
11335 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
11336 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
11337 (set (match_operand:SWI48 1 "register_operand" "=&d")
11338 (mod:SWI48 (match_dup 2) (match_dup 3)))
11339 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
11340 (clobber (reg:CC FLAGS_REG))]
11344 [(parallel [(set (match_dup 1)
11345 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
11346 (clobber (reg:CC FLAGS_REG))])
11347 (parallel [(set (match_dup 0)
11348 (div:SWI48 (match_dup 2) (match_dup 3)))
11350 (mod:SWI48 (match_dup 2) (match_dup 3)))
11351 (use (match_dup 1))
11352 (clobber (reg:CC FLAGS_REG))])]
11354 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11356 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
11357 operands[4] = operands[2];
11360 /* Avoid use of cltd in favor of a mov+shift. */
11361 emit_move_insn (operands[1], operands[2]);
11362 operands[4] = operands[1];
11365 [(set_attr "type" "multi")
11366 (set_attr "mode" "<MODE>")])
11368 (define_insn_and_split "udivmod<mode>4_1"
11369 [(set (match_operand:SWI48 0 "register_operand" "=a")
11370 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
11371 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
11372 (set (match_operand:SWI48 1 "register_operand" "=&d")
11373 (umod:SWI48 (match_dup 2) (match_dup 3)))
11374 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
11375 (clobber (reg:CC FLAGS_REG))]
11379 [(set (match_dup 1) (const_int 0))
11380 (parallel [(set (match_dup 0)
11381 (udiv:SWI48 (match_dup 2) (match_dup 3)))
11383 (umod:SWI48 (match_dup 2) (match_dup 3)))
11384 (use (match_dup 1))
11385 (clobber (reg:CC FLAGS_REG))])]
11387 [(set_attr "type" "multi")
11388 (set_attr "mode" "<MODE>")])
11390 (define_insn_and_split "divmodsi4_zext_1"
11391 [(set (match_operand:DI 0 "register_operand" "=a")
11393 (div:SI (match_operand:SI 2 "register_operand" "0")
11394 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
11395 (set (match_operand:SI 1 "register_operand" "=&d")
11396 (mod:SI (match_dup 2) (match_dup 3)))
11397 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
11398 (clobber (reg:CC FLAGS_REG))]
11401 "&& reload_completed"
11402 [(parallel [(set (match_dup 1)
11403 (ashiftrt:SI (match_dup 4) (match_dup 5)))
11404 (clobber (reg:CC FLAGS_REG))])
11405 (parallel [(set (match_dup 0)
11406 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
11408 (mod:SI (match_dup 2) (match_dup 3)))
11409 (use (match_dup 1))
11410 (clobber (reg:CC FLAGS_REG))])]
11412 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
11414 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
11415 operands[4] = operands[2];
11418 /* Avoid use of cltd in favor of a mov+shift. */
11419 emit_move_insn (operands[1], operands[2]);
11420 operands[4] = operands[1];
11423 [(set_attr "type" "multi")
11424 (set_attr "mode" "SI")])
11426 (define_insn_and_split "udivmodsi4_zext_1"
11427 [(set (match_operand:DI 0 "register_operand" "=a")
11429 (udiv:SI (match_operand:SI 2 "register_operand" "0")
11430 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
11431 (set (match_operand:SI 1 "register_operand" "=&d")
11432 (umod:SI (match_dup 2) (match_dup 3)))
11433 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
11434 (clobber (reg:CC FLAGS_REG))]
11437 "&& reload_completed"
11438 [(set (match_dup 1) (const_int 0))
11439 (parallel [(set (match_dup 0)
11440 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
11442 (umod:SI (match_dup 2) (match_dup 3)))
11443 (use (match_dup 1))
11444 (clobber (reg:CC FLAGS_REG))])]
11446 [(set_attr "type" "multi")
11447 (set_attr "mode" "SI")])
11449 (define_insn_and_split "divmodsi4_zext_2"
11450 [(set (match_operand:DI 1 "register_operand" "=&d")
11452 (mod:SI (match_operand:SI 2 "register_operand" "0")
11453 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
11454 (set (match_operand:SI 0 "register_operand" "=a")
11455 (div:SI (match_dup 2) (match_dup 3)))
11456 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
11457 (clobber (reg:CC FLAGS_REG))]
11460 "&& reload_completed"
11461 [(parallel [(set (match_dup 6)
11462 (ashiftrt:SI (match_dup 4) (match_dup 5)))
11463 (clobber (reg:CC FLAGS_REG))])
11464 (parallel [(set (match_dup 1)
11465 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
11467 (div:SI (match_dup 2) (match_dup 3)))
11468 (use (match_dup 6))
11469 (clobber (reg:CC FLAGS_REG))])]
11471 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
11472 operands[6] = gen_lowpart (SImode, operands[1]);
11474 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
11475 operands[4] = operands[2];
11478 /* Avoid use of cltd in favor of a mov+shift. */
11479 emit_move_insn (operands[6], operands[2]);
11480 operands[4] = operands[6];
11483 [(set_attr "type" "multi")
11484 (set_attr "mode" "SI")])
11486 (define_insn_and_split "udivmodsi4_zext_2"
11487 [(set (match_operand:DI 1 "register_operand" "=&d")
11489 (umod:SI (match_operand:SI 2 "register_operand" "0")
11490 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
11491 (set (match_operand:SI 0 "register_operand" "=a")
11492 (udiv:SI (match_dup 2) (match_dup 3)))
11493 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
11494 (clobber (reg:CC FLAGS_REG))]
11497 "&& reload_completed"
11498 [(set (match_dup 4) (const_int 0))
11499 (parallel [(set (match_dup 1)
11500 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
11502 (udiv:SI (match_dup 2) (match_dup 3)))
11503 (use (match_dup 4))
11504 (clobber (reg:CC FLAGS_REG))])]
11505 "operands[4] = gen_lowpart (SImode, operands[1]);"
11506 [(set_attr "type" "multi")
11507 (set_attr "mode" "SI")])
11509 (define_insn_and_split "*divmod<mode>4"
11510 [(set (match_operand:SWIM248 0 "register_operand" "=a")
11511 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
11512 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
11513 (set (match_operand:SWIM248 1 "register_operand" "=&d")
11514 (mod:SWIM248 (match_dup 2) (match_dup 3)))
11515 (clobber (reg:CC FLAGS_REG))]
11519 [(parallel [(set (match_dup 1)
11520 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
11521 (clobber (reg:CC FLAGS_REG))])
11522 (parallel [(set (match_dup 0)
11523 (div:SWIM248 (match_dup 2) (match_dup 3)))
11525 (mod:SWIM248 (match_dup 2) (match_dup 3)))
11526 (use (match_dup 1))
11527 (clobber (reg:CC FLAGS_REG))])]
11529 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11531 if (<MODE>mode != HImode
11532 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
11533 operands[4] = operands[2];
11536 /* Avoid use of cltd in favor of a mov+shift. */
11537 emit_move_insn (operands[1], operands[2]);
11538 operands[4] = operands[1];
11541 [(set_attr "type" "multi")
11542 (set_attr "mode" "<MODE>")])
11544 (define_insn_and_split "*udivmod<mode>4"
11545 [(set (match_operand:SWIM248 0 "register_operand" "=a")
11546 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
11547 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
11548 (set (match_operand:SWIM248 1 "register_operand" "=&d")
11549 (umod:SWIM248 (match_dup 2) (match_dup 3)))
11550 (clobber (reg:CC FLAGS_REG))]
11554 [(set (match_dup 1) (const_int 0))
11555 (parallel [(set (match_dup 0)
11556 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
11558 (umod:SWIM248 (match_dup 2) (match_dup 3)))
11559 (use (match_dup 1))
11560 (clobber (reg:CC FLAGS_REG))])]
11562 [(set_attr "type" "multi")
11563 (set_attr "mode" "<MODE>")])
11565 ;; Optimize division or modulo by constant power of 2, if the constant
11566 ;; materializes only after expansion.
11567 (define_insn_and_split "*udivmod<mode>4_pow2"
11568 [(set (match_operand:SWI48 0 "register_operand" "=r")
11569 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
11570 (match_operand:SWI48 3 "const_int_operand")))
11571 (set (match_operand:SWI48 1 "register_operand" "=r")
11572 (umod:SWI48 (match_dup 2) (match_dup 3)))
11573 (clobber (reg:CC FLAGS_REG))]
11574 "IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
11576 "&& reload_completed"
11577 [(set (match_dup 1) (match_dup 2))
11578 (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
11579 (clobber (reg:CC FLAGS_REG))])
11580 (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
11581 (clobber (reg:CC FLAGS_REG))])]
11583 int v = exact_log2 (UINTVAL (operands[3]));
11584 operands[4] = GEN_INT (v);
11585 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
11587 [(set_attr "type" "multi")
11588 (set_attr "mode" "<MODE>")])
11590 (define_insn_and_split "*divmodsi4_zext_1"
11591 [(set (match_operand:DI 0 "register_operand" "=a")
11593 (div:SI (match_operand:SI 2 "register_operand" "0")
11594 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
11595 (set (match_operand:SI 1 "register_operand" "=&d")
11596 (mod:SI (match_dup 2) (match_dup 3)))
11597 (clobber (reg:CC FLAGS_REG))]
11600 "&& reload_completed"
11601 [(parallel [(set (match_dup 1)
11602 (ashiftrt:SI (match_dup 4) (match_dup 5)))
11603 (clobber (reg:CC FLAGS_REG))])
11604 (parallel [(set (match_dup 0)
11605 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
11607 (mod:SI (match_dup 2) (match_dup 3)))
11608 (use (match_dup 1))
11609 (clobber (reg:CC FLAGS_REG))])]
11611 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
11613 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
11614 operands[4] = operands[2];
11617 /* Avoid use of cltd in favor of a mov+shift. */
11618 emit_move_insn (operands[1], operands[2]);
11619 operands[4] = operands[1];
11622 [(set_attr "type" "multi")
11623 (set_attr "mode" "SI")])
11625 (define_insn_and_split "*udivmodsi4_zext_1"
11626 [(set (match_operand:DI 0 "register_operand" "=a")
11628 (udiv:SI (match_operand:SI 2 "register_operand" "0")
11629 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
11630 (set (match_operand:SI 1 "register_operand" "=&d")
11631 (umod:SI (match_dup 2) (match_dup 3)))
11632 (clobber (reg:CC FLAGS_REG))]
11635 "&& reload_completed"
11636 [(set (match_dup 1) (const_int 0))
11637 (parallel [(set (match_dup 0)
11638 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
11640 (umod:SI (match_dup 2) (match_dup 3)))
11641 (use (match_dup 1))
11642 (clobber (reg:CC FLAGS_REG))])]
11644 [(set_attr "type" "multi")
11645 (set_attr "mode" "SI")])
11647 (define_insn_and_split "*udivmodsi4_pow2_zext_1"
11648 [(set (match_operand:DI 0 "register_operand" "=r")
11650 (udiv:SI (match_operand:SI 2 "register_operand" "0")
11651 (match_operand:SI 3 "const_int_operand"))))
11652 (set (match_operand:SI 1 "register_operand" "=r")
11653 (umod:SI (match_dup 2) (match_dup 3)))
11654 (clobber (reg:CC FLAGS_REG))]
11656 && IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
11658 "&& reload_completed"
11659 [(set (match_dup 1) (match_dup 2))
11660 (parallel [(set (match_dup 0)
11661 (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4))))
11662 (clobber (reg:CC FLAGS_REG))])
11663 (parallel [(set (match_dup 1) (and:SI (match_dup 1) (match_dup 5)))
11664 (clobber (reg:CC FLAGS_REG))])]
11666 int v = exact_log2 (UINTVAL (operands[3]));
11667 operands[4] = GEN_INT (v);
11668 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
11670 [(set_attr "type" "multi")
11671 (set_attr "mode" "SI")])
11673 (define_insn_and_split "*divmodsi4_zext_2"
11674 [(set (match_operand:DI 1 "register_operand" "=&d")
11676 (mod:SI (match_operand:SI 2 "register_operand" "0")
11677 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
11678 (set (match_operand:SI 0 "register_operand" "=a")
11679 (div:SI (match_dup 2) (match_dup 3)))
11680 (clobber (reg:CC FLAGS_REG))]
11683 "&& reload_completed"
11684 [(parallel [(set (match_dup 6)
11685 (ashiftrt:SI (match_dup 4) (match_dup 5)))
11686 (clobber (reg:CC FLAGS_REG))])
11687 (parallel [(set (match_dup 1)
11688 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
11690 (div:SI (match_dup 2) (match_dup 3)))
11691 (use (match_dup 6))
11692 (clobber (reg:CC FLAGS_REG))])]
11694 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
11695 operands[6] = gen_lowpart (SImode, operands[1]);
11697 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
11698 operands[4] = operands[2];
11701 /* Avoid use of cltd in favor of a mov+shift. */
11702 emit_move_insn (operands[6], operands[2]);
11703 operands[4] = operands[6];
11706 [(set_attr "type" "multi")
11707 (set_attr "mode" "SI")])
11709 (define_insn_and_split "*udivmodsi4_zext_2"
11710 [(set (match_operand:DI 1 "register_operand" "=&d")
11712 (umod:SI (match_operand:SI 2 "register_operand" "0")
11713 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
11714 (set (match_operand:SI 0 "register_operand" "=a")
11715 (udiv:SI (match_dup 2) (match_dup 3)))
11716 (clobber (reg:CC FLAGS_REG))]
11719 "&& reload_completed"
11720 [(set (match_dup 4) (const_int 0))
11721 (parallel [(set (match_dup 1)
11722 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
11724 (udiv:SI (match_dup 2) (match_dup 3)))
11725 (use (match_dup 4))
11726 (clobber (reg:CC FLAGS_REG))])]
11727 "operands[4] = gen_lowpart (SImode, operands[1]);"
11728 [(set_attr "type" "multi")
11729 (set_attr "mode" "SI")])
11731 (define_insn_and_split "*udivmodsi4_pow2_zext_2"
11732 [(set (match_operand:DI 1 "register_operand" "=r")
11734 (umod:SI (match_operand:SI 2 "register_operand" "0")
11735 (match_operand:SI 3 "const_int_operand"))))
11736 (set (match_operand:SI 0 "register_operand" "=r")
11737 (udiv:SI (match_dup 2) (match_dup 3)))
11738 (clobber (reg:CC FLAGS_REG))]
11740 && IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
11742 "&& reload_completed"
11743 [(set (match_dup 1) (match_dup 2))
11744 (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4)))
11745 (clobber (reg:CC FLAGS_REG))])
11746 (parallel [(set (match_dup 1)
11747 (zero_extend:DI (and:SI (match_dup 1) (match_dup 5))))
11748 (clobber (reg:CC FLAGS_REG))])]
11750 int v = exact_log2 (UINTVAL (operands[3]));
11751 operands[4] = GEN_INT (v);
11752 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
11754 [(set_attr "type" "multi")
11755 (set_attr "mode" "SI")])
11757 (define_insn "*<u>divmod<mode>4_noext_nf"
11758 [(set (match_operand:SWIM248 0 "register_operand" "=a")
11760 (match_operand:SWIM248 2 "register_operand" "0")
11761 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
11762 (set (match_operand:SWIM248 1 "register_operand" "=d")
11763 (<paired_mod>:SWIM248 (match_dup 2) (match_dup 3)))
11764 (use (match_operand:SWIM248 4 "register_operand" "1"))]
11766 "%{nf%} <sgnprefix>div{<imodesuffix>}\t%3"
11767 [(set_attr "type" "idiv")
11768 (set_attr "mode" "<MODE>")])
11770 (define_insn "*<u>divmod<mode>4_noext"
11771 [(set (match_operand:SWIM248 0 "register_operand" "=a")
11773 (match_operand:SWIM248 2 "register_operand" "0")
11774 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
11775 (set (match_operand:SWIM248 1 "register_operand" "=d")
11776 (<paired_mod>:SWIM248 (match_dup 2) (match_dup 3)))
11777 (use (match_operand:SWIM248 4 "register_operand" "1"))
11778 (clobber (reg:CC FLAGS_REG))]
11780 "<sgnprefix>div{<imodesuffix>}\t%3"
11781 [(set_attr "type" "idiv")
11782 (set_attr "has_nf" "1")
11783 (set_attr "mode" "<MODE>")])
11785 (define_insn "*<u>divmodsi4_noext_zext_1"
11786 [(set (match_operand:DI 0 "register_operand" "=a")
11788 (any_div:SI (match_operand:SI 2 "register_operand" "0")
11789 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
11790 (set (match_operand:SI 1 "register_operand" "=d")
11791 (<paired_mod>:SI (match_dup 2) (match_dup 3)))
11792 (use (match_operand:SI 4 "register_operand" "1"))
11793 (clobber (reg:CC FLAGS_REG))]
11795 "<sgnprefix>div{l}\t%3"
11796 [(set_attr "type" "idiv")
11797 (set_attr "mode" "SI")])
11799 (define_insn "*<u>divmodsi4_noext_zext_2"
11800 [(set (match_operand:DI 1 "register_operand" "=d")
11802 (<paired_mod>:SI (match_operand:SI 2 "register_operand" "0")
11803 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
11804 (set (match_operand:SI 0 "register_operand" "=a")
11805 (any_div:SI (match_dup 2) (match_dup 3)))
11806 (use (match_operand:SI 4 "register_operand" "1"))
11807 (clobber (reg:CC FLAGS_REG))]
11809 "<sgnprefix>div{l}\t%3"
11810 [(set_attr "type" "idiv")
11811 (set_attr "mode" "SI")])
11813 ;; Avoid sign-extension (using cdq) for constant numerators.
11814 (define_insn_and_split "*divmodsi4_const"
11815 [(set (match_operand:SI 0 "register_operand" "=&a")
11816 (div:SI (match_operand:SI 2 "const_int_operand")
11817 (match_operand:SI 3 "nonimmediate_operand" "rm")))
11818 (set (match_operand:SI 1 "register_operand" "=&d")
11819 (mod:SI (match_dup 2) (match_dup 3)))
11820 (clobber (reg:CC FLAGS_REG))]
11821 "!optimize_function_for_size_p (cfun)"
11823 "&& reload_completed"
11824 [(set (match_dup 0) (match_dup 2))
11825 (set (match_dup 1) (match_dup 4))
11826 (parallel [(set (match_dup 0)
11827 (div:SI (match_dup 0) (match_dup 3)))
11829 (mod:SI (match_dup 0) (match_dup 3)))
11830 (use (match_dup 1))
11831 (clobber (reg:CC FLAGS_REG))])]
11833 operands[4] = INTVAL (operands[2]) < 0 ? constm1_rtx : const0_rtx;
11835 [(set_attr "type" "multi")
11836 (set_attr "mode" "SI")])
11838 (define_expand "divmodqi4"
11839 [(parallel [(set (match_operand:QI 0 "register_operand")
11841 (match_operand:QI 1 "register_operand")
11842 (match_operand:QI 2 "nonimmediate_operand")))
11843 (set (match_operand:QI 3 "register_operand")
11844 (mod:QI (match_dup 1) (match_dup 2)))
11845 (clobber (reg:CC FLAGS_REG))])]
11846 "TARGET_QIMODE_MATH"
11851 tmp0 = gen_reg_rtx (HImode);
11852 tmp1 = gen_reg_rtx (HImode);
11854 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
11855 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
11856 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
11858 /* Extract remainder from AH. */
11859 tmp1 = gen_rtx_ZERO_EXTRACT (HImode, tmp0, GEN_INT (8), GEN_INT (8));
11860 tmp1 = lowpart_subreg (QImode, tmp1, HImode);
11861 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
11863 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
11864 set_unique_reg_note (insn, REG_EQUAL, mod);
11866 /* Extract quotient from AL. */
11867 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
11869 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
11870 set_unique_reg_note (insn, REG_EQUAL, div);
11875 (define_expand "udivmodqi4"
11876 [(parallel [(set (match_operand:QI 0 "register_operand")
11878 (match_operand:QI 1 "register_operand")
11879 (match_operand:QI 2 "nonimmediate_operand")))
11880 (set (match_operand:QI 3 "register_operand")
11881 (umod:QI (match_dup 1) (match_dup 2)))
11882 (clobber (reg:CC FLAGS_REG))])]
11883 "TARGET_QIMODE_MATH"
11888 tmp0 = gen_reg_rtx (HImode);
11889 tmp1 = gen_reg_rtx (HImode);
11891 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
11892 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
11893 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
11895 /* Extract remainder from AH. */
11896 tmp1 = gen_rtx_ZERO_EXTRACT (HImode, tmp0, GEN_INT (8), GEN_INT (8));
11897 tmp1 = lowpart_subreg (QImode, tmp1, HImode);
11898 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
11900 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
11901 set_unique_reg_note (insn, REG_EQUAL, mod);
11903 /* Extract quotient from AL. */
11904 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
11906 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
11907 set_unique_reg_note (insn, REG_EQUAL, div);
11912 ;; Divide AX by r/m8, with result stored in
11915 ;; Change div/mod to HImode and extend the second argument to HImode
11916 ;; so that mode of div/mod matches with mode of arguments. Otherwise
11917 ;; combine may fail.
11918 (define_insn "<u>divmodhiqi3<nf_name>"
11919 [(set (match_operand:HI 0 "register_operand" "=a")
11924 (mod:HI (match_operand:HI 1 "register_operand" "0")
11926 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
11930 (div:HI (match_dup 1) (any_extend:HI (match_dup 2)))))))]
11931 "TARGET_QIMODE_MATH
11933 "<nf_prefix><sgnprefix>div{b}\t%2"
11934 [(set_attr "type" "idiv")
11935 (set_attr "has_nf" "1")
11936 (set_attr "mode" "QI")])
11938 ;; We cannot use div/idiv for double division, because it causes
11939 ;; "division by zero" on the overflow and that's not what we expect
11940 ;; from truncate. Because true (non truncating) double division is
11941 ;; never generated, we can't create this insn anyway.
11944 ; [(set (match_operand:SI 0 "register_operand" "=a")
11946 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
11948 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
11949 ; (set (match_operand:SI 3 "register_operand" "=d")
11951 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
11952 ; (clobber (reg:CC FLAGS_REG))]
11954 ; "div{l}\t{%2, %0|%0, %2}"
11955 ; [(set_attr "type" "idiv")])
11957 ;;- Logical AND instructions
11959 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
11960 ;; Note that this excludes ah.
11962 (define_expand "@test<mode>_ccno_1"
11963 [(set (reg:CCNO FLAGS_REG)
11966 (match_operand:SWI48 0 "nonimmediate_operand")
11967 (match_operand:SWI48 1 "<nonmemory_szext_operand>"))
11970 (define_expand "testqi_ccz_1"
11971 [(set (reg:CCZ FLAGS_REG)
11974 (match_operand:QI 0 "nonimmediate_operand")
11975 (match_operand:QI 1 "nonmemory_operand"))
11978 (define_insn "*testdi_1"
11979 [(set (reg FLAGS_REG)
11982 (match_operand:DI 0 "nonimmediate_operand" "%r,rm")
11983 (match_operand:DI 1 "x86_64_szext_nonmemory_operand" "Z,re"))
11986 && ix86_match_ccmode
11988 /* If we are going to emit testl instead of testq, and the operands[1]
11989 constant might have the SImode sign bit set, make sure the sign
11990 flag isn't tested, because the instruction will set the sign flag
11991 based on bit 31 rather than bit 63. If it isn't CONST_INT,
11992 conservatively assume it might have bit 31 set. */
11993 (satisfies_constraint_Z (operands[1])
11994 && (!CONST_INT_P (operands[1])
11995 || val_signbit_known_set_p (SImode, INTVAL (operands[1]))))
11996 ? CCZmode : CCNOmode)"
11998 test{l}\t{%k1, %k0|%k0, %k1}
11999 test{q}\t{%1, %0|%0, %1}"
12000 [(set_attr "type" "test")
12001 (set_attr "mode" "SI,DI")])
12003 (define_insn "*testqi_1_maybe_si"
12004 [(set (reg FLAGS_REG)
12007 (match_operand:QI 0 "nonimmediate_operand" "%qm,qm,r")
12008 (match_operand:QI 1 "nonmemory_operand" "q,n,n"))
12010 "ix86_match_ccmode (insn,
12011 CONST_INT_P (operands[1])
12012 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
12014 if (get_attr_mode (insn) == MODE_SI)
12016 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
12017 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
12018 return "test{l}\t{%1, %k0|%k0, %1}";
12020 return "test{b}\t{%1, %0|%0, %1}";
12022 [(set_attr "type" "test")
12024 (cond [(eq_attr "alternative" "2")
12025 (const_string "SI")
12026 (and (match_test "optimize_insn_for_size_p ()")
12027 (and (match_operand 0 "ext_QIreg_operand")
12028 (match_operand 1 "const_0_to_127_operand")))
12029 (const_string "SI")
12031 (const_string "QI")))
12032 (set_attr "pent_pair" "uv,np,np")])
12034 (define_insn "*test<mode>_1"
12035 [(set (reg FLAGS_REG)
12038 (match_operand:SWI124 0 "nonimmediate_operand" "%<r>m,*a,<r>m")
12039 (match_operand:SWI124 1 "<nonmemory_szext_operand>" "<r>,<i>,<i>"))
12041 "ix86_match_ccmode (insn, CCNOmode)"
12042 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
12043 [(set_attr "type" "test")
12044 (set_attr "mode" "<MODE>")
12045 (set_attr "pent_pair" "uv,uv,np")])
12047 (define_expand "testqi_ext_1_ccno"
12048 [(set (reg:CCNO FLAGS_REG)
12053 (match_operand:HI 0 "register_operand")
12056 (match_operand:QI 1 "const_int_operand"))
12059 (define_insn "*testqi_ext<mode>_1"
12060 [(set (reg FLAGS_REG)
12064 (match_operator:SWI248 2 "extract_operator"
12065 [(match_operand 0 "int248_register_operand" "Q")
12068 (match_operand:QI 1 "general_operand" "QnBn"))
12070 "ix86_match_ccmode (insn, CCNOmode)"
12071 "test{b}\t{%1, %h0|%h0, %1}"
12072 [(set_attr "addr" "gpr8")
12073 (set_attr "type" "test")
12074 (set_attr "mode" "QI")])
12076 (define_insn "*testqi_ext<mode>_2"
12077 [(set (reg FLAGS_REG)
12081 (match_operator:SWI248 2 "extract_operator"
12082 [(match_operand 0 "int248_register_operand" "Q")
12086 (match_operator:SWI248 3 "extract_operator"
12087 [(match_operand 1 "int248_register_operand" "Q")
12089 (const_int 8)]) 0))
12091 "ix86_match_ccmode (insn, CCNOmode)"
12092 "test{b}\t{%h1, %h0|%h0, %h1}"
12093 [(set_attr "type" "test")
12094 (set_attr "mode" "QI")])
12096 ;; Provide a *testti instruction that STV can implement using ptest.
12097 ;; This pattern splits into *andti3_doubleword and *cmpti_doubleword.
12098 (define_insn_and_split "*testti_doubleword"
12099 [(set (reg:CCZ FLAGS_REG)
12101 (and:TI (match_operand:TI 0 "register_operand")
12102 (match_operand:TI 1 "general_operand"))
12105 && ix86_pre_reload_split ()"
12108 [(parallel [(set (match_dup 2) (and:TI (match_dup 0) (match_dup 1)))
12109 (clobber (reg:CC FLAGS_REG))])
12110 (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 2) (const_int 0)))]
12112 operands[2] = gen_reg_rtx (TImode);
12113 if (!x86_64_hilo_general_operand (operands[1], TImode))
12114 operands[1] = force_reg (TImode, operands[1]);
12117 ;; Combine likes to form bit extractions for some tests. Humor it.
12118 (define_insn_and_split "*testqi_ext_3"
12119 [(set (match_operand 0 "flags_reg_operand")
12120 (match_operator 1 "compare_operator"
12121 [(zero_extract:SWI248
12122 (match_operand 2 "int_nonimmediate_operand" "rm")
12123 (match_operand:QI 3 "const_int_operand")
12124 (match_operand:QI 4 "const_int_operand"))
12126 "/* Ensure that resulting mask is zero or sign extended operand. */
12127 INTVAL (operands[4]) >= 0
12128 && ((INTVAL (operands[3]) > 0
12129 && INTVAL (operands[3]) + INTVAL (operands[4]) <= 32)
12130 || (<MODE>mode == DImode
12131 && INTVAL (operands[3]) > 32
12132 && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))
12133 && ix86_match_ccmode (insn,
12134 /* If zero_extract mode precision is the same
12135 as len, the SF of the zero_extract
12136 comparison will be the most significant
12137 extracted bit, but this could be matched
12138 after splitting only for pos 0 len all bits
12139 trivial extractions. Require CCZmode. */
12140 (GET_MODE_PRECISION (<MODE>mode)
12141 == INTVAL (operands[3]))
12142 /* Otherwise, require CCZmode if we'd use a mask
12143 with the most significant bit set and can't
12144 widen it to wider mode. *testdi_1 also
12145 requires CCZmode if the mask has bit
12146 31 set and all bits above it clear. */
12147 || (INTVAL (operands[3]) + INTVAL (operands[4])
12149 /* We can't widen also if val is not a REG. */
12150 || (INTVAL (operands[3]) + INTVAL (operands[4])
12151 == GET_MODE_PRECISION (GET_MODE (operands[2]))
12152 && !register_operand (operands[2],
12153 GET_MODE (operands[2])))
12154 /* And we shouldn't widen if
12155 TARGET_PARTIAL_REG_STALL. */
12156 || (TARGET_PARTIAL_REG_STALL
12157 && (INTVAL (operands[3]) + INTVAL (operands[4])
12158 >= (paradoxical_subreg_p (operands[2])
12160 (GET_MODE (SUBREG_REG (operands[2])))
12162 ? GET_MODE_PRECISION
12163 (GET_MODE (SUBREG_REG (operands[2])))
12164 : GET_MODE_PRECISION
12165 (GET_MODE (operands[2])))))
12166 ? CCZmode : CCNOmode)"
12169 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
12171 rtx val = operands[2];
12172 HOST_WIDE_INT len = INTVAL (operands[3]);
12173 HOST_WIDE_INT pos = INTVAL (operands[4]);
12174 machine_mode mode = GET_MODE (val);
12176 if (SUBREG_P (val))
12178 machine_mode submode = GET_MODE (SUBREG_REG (val));
12180 /* Narrow paradoxical subregs to prevent partial register stalls. */
12181 if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)
12182 && GET_MODE_CLASS (submode) == MODE_INT
12183 && (GET_MODE (operands[0]) == CCZmode
12184 || pos + len < GET_MODE_PRECISION (submode)
12185 || REG_P (SUBREG_REG (val))))
12187 val = SUBREG_REG (val);
12192 /* Small HImode tests can be converted to QImode. */
12194 && register_operand (val, HImode))
12196 rtx nval = gen_lowpart (QImode, val);
12198 || GET_MODE (operands[0]) == CCZmode
12206 gcc_assert (pos + len <= GET_MODE_PRECISION (mode));
12208 /* If the mask is going to have the sign bit set in the mode
12209 we want to do the comparison in and user isn't interested just
12210 in the zero flag, then we must widen the target mode. */
12211 if (pos + len == GET_MODE_PRECISION (mode)
12212 && GET_MODE (operands[0]) != CCZmode)
12214 gcc_assert (pos + len < 32 && !MEM_P (val));
12216 val = gen_lowpart (mode, val);
12220 = wi::shifted_mask (pos, len, false, GET_MODE_PRECISION (mode));
12222 operands[2] = gen_rtx_AND (mode, val, immed_wide_int_const (mask, mode));
12225 ;; Split and;cmp (as optimized by combine) into not;test
12226 ;; Except when TARGET_BMI provides andn (*andn_<mode>_ccno).
12227 (define_insn_and_split "*test<mode>_not"
12228 [(set (reg:CCZ FLAGS_REG)
12231 (not:SWI (match_operand:SWI 0 "register_operand"))
12232 (match_operand:SWI 1 "<nonmemory_szext_operand>"))
12234 "ix86_pre_reload_split ()
12235 && (!TARGET_BMI || !REG_P (operands[1]))"
12238 [(set (match_dup 2) (not:SWI (match_dup 0)))
12239 (set (reg:CCZ FLAGS_REG)
12240 (compare:CCZ (and:SWI (match_dup 2) (match_dup 1))
12242 "operands[2] = gen_reg_rtx (<MODE>mode);")
12244 ;; Split and;cmp (as optimized by combine) into andn;cmp $0
12245 (define_insn_and_split "*test<mode>_not_doubleword"
12246 [(set (reg:CCZ FLAGS_REG)
12249 (not:DWI (match_operand:DWI 0 "nonimmediate_operand"))
12250 (match_operand:DWI 1 "nonimmediate_operand"))
12252 "ix86_pre_reload_split ()"
12256 [(set (match_dup 2) (and:DWI (not:DWI (match_dup 0)) (match_dup 1)))
12257 (clobber (reg:CC FLAGS_REG))])
12258 (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 2) (const_int 0)))]
12260 operands[0] = force_reg (<MODE>mode, operands[0]);
12261 operands[2] = gen_reg_rtx (<MODE>mode);
12264 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
12265 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
12266 ;; this is relatively important trick.
12267 ;; Do the conversion only post-reload to avoid limiting of the register class
12270 [(set (match_operand 0 "flags_reg_operand")
12271 (match_operator 1 "compare_operator"
12272 [(and (match_operand 2 "QIreg_operand")
12273 (match_operand 3 "const_int_operand"))
12276 && GET_MODE (operands[2]) != QImode
12277 && ((ix86_match_ccmode (insn, CCZmode)
12278 && !(INTVAL (operands[3]) & ~(255 << 8)))
12279 || (ix86_match_ccmode (insn, CCNOmode)
12280 && !(INTVAL (operands[3]) & ~(127 << 8))))"
12281 [(set (match_dup 0)
12285 (zero_extract:HI (match_dup 2)
12291 operands[2] = gen_lowpart (HImode, operands[2]);
12292 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, QImode);
12296 [(set (match_operand 0 "flags_reg_operand")
12297 (match_operator 1 "compare_operator"
12298 [(and (match_operand 2 "nonimmediate_operand")
12299 (match_operand 3 "const_int_operand"))
12302 && GET_MODE (operands[2]) != QImode
12303 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
12304 && ((ix86_match_ccmode (insn, CCZmode)
12305 && !(INTVAL (operands[3]) & ~255))
12306 || (ix86_match_ccmode (insn, CCNOmode)
12307 && !(INTVAL (operands[3]) & ~127)))"
12308 [(set (match_dup 0)
12309 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
12312 operands[2] = gen_lowpart (QImode, operands[2]);
12313 operands[3] = gen_int_mode (INTVAL (operands[3]), QImode);
12316 ;; Narrow test instructions with immediate operands that test
12317 ;; memory locations for zero. E.g. testl $0x00aa0000, mem can be
12318 ;; converted to testb $0xaa, mem+2. Reject volatile locations and
12319 ;; targets where reading (possibly unaligned) part of memory
12320 ;; location after a large write to the same address causes
12321 ;; store-to-load forwarding stall.
12323 [(set (reg:CCZ FLAGS_REG)
12325 (and:SWI248 (match_operand:SWI248 0 "memory_operand")
12326 (match_operand 1 "const_int_operand"))
12328 "!TARGET_PARTIAL_MEMORY_READ_STALL && !MEM_VOLATILE_P (operands[0])"
12329 [(set (reg:CCZ FLAGS_REG)
12330 (compare:CCZ (match_dup 2) (const_int 0)))]
12332 unsigned HOST_WIDE_INT ival = UINTVAL (operands[1]);
12333 int first_nonzero_byte, bitsize;
12334 rtx new_addr, new_const;
12335 machine_mode new_mode;
12340 /* Clear bits outside mode width. */
12341 ival &= GET_MODE_MASK (<MODE>mode);
12343 first_nonzero_byte = ctz_hwi (ival) / BITS_PER_UNIT;
12345 ival >>= first_nonzero_byte * BITS_PER_UNIT;
12347 bitsize = sizeof (ival) * BITS_PER_UNIT - clz_hwi (ival);
12349 if (bitsize <= GET_MODE_BITSIZE (QImode))
12351 else if (bitsize <= GET_MODE_BITSIZE (HImode))
12353 else if (bitsize <= GET_MODE_BITSIZE (SImode))
12358 if (GET_MODE_SIZE (new_mode) >= GET_MODE_SIZE (<MODE>mode))
12361 new_addr = adjust_address (operands[0], new_mode, first_nonzero_byte);
12362 new_const = gen_int_mode (ival, new_mode);
12364 operands[2] = gen_rtx_AND (new_mode, new_addr, new_const);
12367 ;; %%% This used to optimize known byte-wide and operations to memory,
12368 ;; and sometimes to QImode registers. If this is considered useful,
12369 ;; it should be done with splitters.
12371 (define_expand "and<mode>3"
12372 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
12373 (and:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
12374 (match_operand:SDWIM 2 "<general_szext_operand>")))]
12377 machine_mode mode = <MODE>mode;
12379 if (GET_MODE_SIZE (<MODE>mode) > UNITS_PER_WORD
12380 && !x86_64_hilo_general_operand (operands[2], <MODE>mode))
12381 operands[2] = force_reg (<MODE>mode, operands[2]);
12383 if (GET_MODE_SIZE (<MODE>mode) <= UNITS_PER_WORD
12384 && const_int_operand (operands[2], <MODE>mode)
12385 && register_operand (operands[0], <MODE>mode)
12386 && !(TARGET_ZERO_EXTEND_WITH_AND
12387 && optimize_function_for_speed_p (cfun)))
12389 unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
12391 if (ival == GET_MODE_MASK (SImode))
12393 else if (ival == GET_MODE_MASK (HImode))
12395 else if (ival == GET_MODE_MASK (QImode))
12399 if (mode != <MODE>mode)
12400 emit_insn (gen_extend_insn
12401 (operands[0], gen_lowpart (mode, operands[1]),
12402 <MODE>mode, mode, 1));
12404 ix86_expand_binary_operator (AND, <MODE>mode, operands, TARGET_APX_NDD);
12409 (define_insn_and_split "*and<dwi>3_doubleword"
12410 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,&r,&r,&r,&r,&r")
12412 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0,ro,r,ro,jO,r")
12413 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o,r,<di>,K,<di>,o")))
12414 (clobber (reg:CC FLAGS_REG))]
12415 "ix86_binary_operator_ok (AND, <DWI>mode, operands, TARGET_APX_NDD)"
12417 "&& reload_completed"
12418 [(const_int:DWIH 0)]
12420 bool emit_insn_deleted_note_p = false;
12422 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
12424 if (operands[2] == const0_rtx)
12425 emit_move_insn (operands[0], const0_rtx);
12426 else if (operands[2] == constm1_rtx)
12428 if (!rtx_equal_p (operands[0], operands[1]))
12429 emit_move_insn (operands[0], operands[1]);
12431 emit_insn_deleted_note_p = true;
12434 ix86_expand_binary_operator (AND, <MODE>mode, &operands[0], TARGET_APX_NDD);
12436 if (operands[5] == const0_rtx)
12437 emit_move_insn (operands[3], const0_rtx);
12438 else if (operands[5] == constm1_rtx)
12440 if (!rtx_equal_p (operands[3], operands[4]))
12441 emit_move_insn (operands[3], operands[4]);
12442 else if (emit_insn_deleted_note_p)
12443 emit_note (NOTE_INSN_DELETED);
12446 ix86_expand_binary_operator (AND, <MODE>mode, &operands[3], TARGET_APX_NDD);
12450 [(set_attr "isa" "*,*,apx_ndd,apx_ndd,apx_ndd,apx_ndd_64,apx_ndd")])
12452 (define_insn "*anddi_1<nf_name>"
12453 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm,r<nf_mem_constraint>,r,r,r,r,r,?k")
12455 (match_operand:DI 1 "nonimmediate_operand" "%0,r,0,0,0,rm,rjM,r,qm,k")
12456 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,Z,r,e,m,r,e,m,L,k")))]
12458 && ix86_binary_operator_ok (AND, DImode, operands, TARGET_APX_NDD)
12461 <nf_prefix>and{l}\t{%k2, %k0|%k0, %k2}
12462 <nf_prefix>and{l}\t{%k2, %k1, %k0|%k0, %k1, %k2}
12463 <nf_prefix>and{q}\t{%2, %0|%0, %2}
12464 <nf_prefix>and{q}\t{%2, %0|%0, %2}
12465 <nf_prefix>and{q}\t{%2, %0|%0, %2}
12466 <nf_prefix>and{q}\t{%2, %1, %0|%0, %1, %2}
12467 <nf_prefix>and{q}\t{%2, %1, %0|%0, %1, %2}
12468 <nf_prefix>and{q}\t{%2, %1, %0|%0, %1, %2}
12471 [(set_attr "isa" "x64,apx_ndd,x64,x64,x64,apx_ndd,apx_ndd,apx_ndd,<nf_nonf_x64_attr>,avx512bw")
12472 (set_attr "type" "alu,alu,alu,alu,alu,alu,alu,alu,imovx,msklog")
12473 (set_attr "length_immediate" "*,*,*,*,*,*,*,*,0,*")
12474 (set (attr "prefix_rex")
12476 (and (eq_attr "type" "imovx")
12477 (and (match_test "INTVAL (operands[2]) == 0xff")
12478 (match_operand 1 "ext_QIreg_operand")))
12480 (const_string "*")))
12481 (set_attr "has_nf" "1")
12482 (set_attr "mode" "SI,SI,DI,DI,DI,DI,DI,DI,SI,DI")])
12484 (define_insn_and_split "*anddi_1_btr"
12485 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12487 (match_operand:DI 1 "nonimmediate_operand" "%0")
12488 (match_operand:DI 2 "const_int_operand" "n")))
12489 (clobber (reg:CC FLAGS_REG))]
12490 "TARGET_64BIT && TARGET_USE_BT
12491 && ix86_binary_operator_ok (AND, DImode, operands)
12492 && IN_RANGE (exact_log2 (~INTVAL (operands[2])), 31, 63)"
12494 "&& reload_completed"
12495 [(parallel [(set (zero_extract:DI (match_dup 0)
12499 (clobber (reg:CC FLAGS_REG))])]
12500 "operands[3] = GEN_INT (exact_log2 (~INTVAL (operands[2])));"
12501 [(set_attr "type" "alu1")
12502 (set_attr "prefix_0f" "1")
12503 (set_attr "znver1_decode" "double")
12504 (set_attr "mode" "DI")])
12506 ;; Turn *anddi_1 into *andsi_1_zext if possible.
12508 [(set (match_operand:DI 0 "register_operand")
12509 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
12510 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
12511 (clobber (reg:CC FLAGS_REG))]
12513 [(parallel [(set (match_dup 0)
12514 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
12515 (clobber (reg:CC FLAGS_REG))])]
12517 if (GET_CODE (operands[2]) == SYMBOL_REF
12518 || GET_CODE (operands[2]) == LABEL_REF)
12520 operands[2] = shallow_copy_rtx (operands[2]);
12521 PUT_MODE (operands[2], SImode);
12523 else if (GET_CODE (operands[2]) == CONST)
12525 /* (const:DI (plus:DI (symbol_ref:DI ("...")) (const_int N))) */
12526 operands[2] = copy_rtx (operands[2]);
12527 PUT_MODE (operands[2], SImode);
12528 PUT_MODE (XEXP (operands[2], 0), SImode);
12529 PUT_MODE (XEXP (XEXP (operands[2], 0), 0), SImode);
12532 operands[2] = gen_lowpart (SImode, operands[2]);
12535 (define_insn "*andqi_1_zext<mode><nf_name>"
12536 [(set (match_operand:SWI248x 0 "register_operand" "=r,r")
12537 (zero_extend:SWI248x
12538 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%rm,r")
12539 (match_operand:QI 2 "x86_64_general_operand" "rn,m"))))]
12540 "TARGET_APX_NDD && <nf_condition>
12541 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12543 <nf_prefix>and{b}\t{%2, %1, %b0|%b0, %1, %2}
12544 <nf_prefix>and{b}\t{%2, %1, %b0|%b0, %1, %2}"
12545 [(set_attr "type" "alu")
12546 (set_attr "has_nf" "1")
12547 (set_attr "mode" "QI")])
12549 (define_insn "*andhi_1_zext<mode><nf_name>"
12550 [(set (match_operand:SWI48x 0 "register_operand" "=r,r")
12551 (zero_extend:SWI48x
12552 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,r")
12553 (match_operand:HI 2 "x86_64_general_operand" "rn,m"))))]
12554 "TARGET_APX_NDD && <nf_condition>
12555 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12557 <nf_prefix>and{w}\t{%2, %1, %w0|%w0, %1, %2}
12558 <nf_prefix>and{w}\t{%2, %1, %w0|%w0, %1, %2}"
12559 [(set_attr "type" "alu")
12560 (set_attr "has_nf" "1")
12561 (set_attr "mode" "HI")])
12563 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
12564 (define_insn "*andsi_1_zext"
12565 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
12567 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,rm,rjM,r")
12568 (match_operand:SI 2 "x86_64_general_operand" "rBMe,r,e,BM"))))
12569 (clobber (reg:CC FLAGS_REG))]
12571 && ix86_binary_operator_ok (AND, SImode, operands, TARGET_APX_NDD)"
12573 and{l}\t{%2, %k0|%k0, %2}
12574 and{l}\t{%2, %1, %k0|%k0, %1, %2}
12575 and{l}\t{%2, %1, %k0|%k0, %1, %2}
12576 and{l}\t{%2, %1, %k0|%k0, %1, %2}"
12577 [(set_attr "type" "alu")
12578 (set_attr "isa" "*,apx_ndd,apx_ndd,apx_ndd")
12579 (set_attr "mode" "SI")])
12581 (define_insn "*and<mode>_1<nf_name>"
12582 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r<nf_mem_constraint>,r,r,r,r,Ya,?k")
12583 (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,0,rm,rjM,r,qm,k")
12584 (match_operand:SWI24 2 "<general_operand>" "r,<i>,<m>,r,<i>,<m>,L,k")))]
12585 "ix86_binary_operator_ok (AND, <MODE>mode, operands, TARGET_APX_NDD)
12588 <nf_prefix>and{<imodesuffix>}\t{%2, %0|%0, %2}
12589 <nf_prefix>and{<imodesuffix>}\t{%2, %0|%0, %2}
12590 <nf_prefix>and{<imodesuffix>}\t{%2, %0|%0, %2}
12591 <nf_prefix>and{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
12592 <nf_prefix>and{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
12593 <nf_prefix>and{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
12597 (cond [(eq_attr "alternative" "3,4,5")
12598 (const_string "apx_ndd")
12599 (eq_attr "alternative" "6")
12600 (const_string "<nf_nonf_attr>")
12601 (eq_attr "alternative" "7")
12602 (if_then_else (eq_attr "mode" "SI")
12603 (const_string "avx512bw")
12604 (const_string "avx512f"))
12606 (const_string "*")))
12607 (set_attr "type" "alu,alu,alu,alu,alu,alu,imovx,msklog")
12608 (set_attr "length_immediate" "*,*,*,*,*,*,0,*")
12609 (set (attr "prefix_rex")
12611 (and (eq_attr "type" "imovx")
12612 (and (match_test "INTVAL (operands[2]) == 0xff")
12613 (match_operand 1 "ext_QIreg_operand")))
12615 (const_string "*")))
12616 (set_attr "has_nf" "1")
12617 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<MODE>,<MODE>,SI,<MODE>")])
12619 (define_insn "*andqi_1<nf_name>"
12620 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r,r,?k")
12621 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,rm,r,k")
12622 (match_operand:QI 2 "general_operand" "qn,m,rn,rn,m,k")))]
12623 "ix86_binary_operator_ok (AND, QImode, operands, TARGET_APX_NDD)
12626 <nf_prefix>and{b}\t{%2, %0|%0, %2}
12627 <nf_prefix>and{b}\t{%2, %0|%0, %2}
12628 <nf_prefix>and{l}\t{%k2, %k0|%k0, %k2}
12629 <nf_prefix>and{b}\t{%2, %1, %0|%0, %1, %2}
12630 <nf_prefix>and{b}\t{%2, %1, %0|%0, %1, %2}
12632 [(set_attr "type" "alu,alu,alu,alu,alu,msklog")
12633 (set_attr "isa" "*,*,*,apx_ndd,apx_ndd,*")
12634 (set_attr "has_nf" "1")
12636 (cond [(eq_attr "alternative" "2")
12637 (const_string "SI")
12638 (and (eq_attr "alternative" "5")
12639 (match_test "!TARGET_AVX512DQ"))
12640 (const_string "HI")
12642 (const_string "QI")))
12643 ;; Potential partial reg stall on alternative 2.
12644 (set (attr "preferred_for_speed")
12645 (cond [(eq_attr "alternative" "2")
12646 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
12647 (symbol_ref "true")))])
12649 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
12650 (define_insn_and_split "*<code><mode>_1_slp"
12651 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
12652 (any_logic:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0,!<r>")
12653 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
12654 (clobber (reg:CC FLAGS_REG))]
12655 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
12657 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
12659 "&& reload_completed
12660 && !(rtx_equal_p (operands[0], operands[1])
12661 || rtx_equal_p (operands[0], operands[2]))"
12662 [(set (strict_low_part (match_dup 0)) (match_dup 1))
12664 [(set (strict_low_part (match_dup 0))
12665 (any_logic:SWI12 (match_dup 0) (match_dup 2)))
12666 (clobber (reg:CC FLAGS_REG))])]
12668 [(set_attr "type" "alu")
12669 (set_attr "mode" "<MODE>")])
12671 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
12672 (define_insn_and_split "*<code>qi_ext<mode>_1_slp"
12673 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+Q,&Q"))
12676 (match_operator:SWI248 3 "extract_operator"
12677 [(match_operand 2 "int248_register_operand" "Q,Q")
12680 (match_operand:QI 1 "nonimmediate_operand" "0,!qm")))
12681 (clobber (reg:CC FLAGS_REG))]
12682 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
12684 <logic>{b}\t{%h2, %0|%0, %h2}
12686 "&& reload_completed
12687 && !rtx_equal_p (operands[0], operands[1])"
12688 [(set (strict_low_part (match_dup 0)) (match_dup 1))
12690 [(set (strict_low_part (match_dup 0))
12694 [(match_dup 2) (const_int 8) (const_int 8)]) 0)
12696 (clobber (reg:CC FLAGS_REG))])]
12698 [(set_attr "type" "alu")
12699 (set_attr "mode" "QI")])
12701 (define_insn_and_split "*<code>qi_ext<mode>_2_slp"
12702 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+&Q"))
12705 (match_operator:SWI248 3 "extract_operator"
12706 [(match_operand 1 "int248_register_operand" "Q")
12710 (match_operator:SWI248 4 "extract_operator"
12711 [(match_operand 2 "int248_register_operand" "Q")
12713 (const_int 8)]) 0)))
12714 (clobber (reg:CC FLAGS_REG))]
12715 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
12717 "&& reload_completed"
12718 [(set (strict_low_part (match_dup 0))
12721 [(match_dup 2) (const_int 8) (const_int 8)]) 0))
12723 [(set (strict_low_part (match_dup 0))
12727 [(match_dup 1) (const_int 8) (const_int 8)]) 0)
12729 (clobber (reg:CC FLAGS_REG))])]
12731 [(set_attr "type" "alu")
12732 (set_attr "mode" "QI")])
12735 [(set (match_operand:SWI248 0 "register_operand")
12736 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
12737 (match_operand:SWI248 2 "const_int_operand")))
12738 (clobber (reg:CC FLAGS_REG))]
12740 && (!REG_P (operands[1])
12741 || REGNO (operands[0]) != REGNO (operands[1]))
12742 && (UINTVAL (operands[2]) == GET_MODE_MASK (SImode)
12743 || UINTVAL (operands[2]) == GET_MODE_MASK (HImode)
12744 || UINTVAL (operands[2]) == GET_MODE_MASK (QImode))"
12747 unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
12750 if (ival == GET_MODE_MASK (SImode))
12752 else if (ival == GET_MODE_MASK (HImode))
12754 else if (ival == GET_MODE_MASK (QImode))
12757 gcc_unreachable ();
12759 /* Zero extend to SImode to avoid partial register stalls. */
12760 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
12761 operands[0] = gen_lowpart (SImode, operands[0]);
12763 emit_insn (gen_extend_insn
12764 (operands[0], gen_lowpart (mode, operands[1]),
12765 GET_MODE (operands[0]), mode, 1));
12770 [(set (match_operand:SWI48 0 "register_operand")
12771 (and:SWI48 (match_dup 0)
12772 (const_int -65536)))
12773 (clobber (reg:CC FLAGS_REG))]
12774 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
12775 || optimize_function_for_size_p (cfun)"
12776 [(set (strict_low_part (match_dup 1)) (const_int 0))]
12777 "operands[1] = gen_lowpart (HImode, operands[0]);")
12780 [(set (match_operand:SWI248 0 "any_QIreg_operand")
12781 (and:SWI248 (match_dup 0)
12783 (clobber (reg:CC FLAGS_REG))]
12784 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12785 && reload_completed"
12786 [(set (strict_low_part (match_dup 1)) (const_int 0))]
12787 "operands[1] = gen_lowpart (QImode, operands[0]);")
12790 [(set (match_operand:SWI248 0 "QIreg_operand")
12791 (and:SWI248 (match_dup 0)
12792 (const_int -65281)))
12793 (clobber (reg:CC FLAGS_REG))]
12794 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12795 && reload_completed"
12797 [(set (zero_extract:HI (match_dup 0)
12803 (zero_extract:HI (match_dup 0)
12807 (zero_extract:HI (match_dup 0)
12809 (const_int 8)) 0)) 0))
12810 (clobber (reg:CC FLAGS_REG))])]
12811 "operands[0] = gen_lowpart (HImode, operands[0]);")
12813 (define_insn "*anddi_2"
12814 [(set (reg FLAGS_REG)
12817 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,r,rm,r")
12818 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m,Z,re,m"))
12820 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,r,r")
12821 (and:DI (match_dup 1) (match_dup 2)))]
12823 && ix86_match_ccmode
12825 /* If we are going to emit andl instead of andq, and the operands[2]
12826 constant might have the SImode sign bit set, make sure the sign
12827 flag isn't tested, because the instruction will set the sign flag
12828 based on bit 31 rather than bit 63. If it isn't CONST_INT,
12829 conservatively assume it might have bit 31 set. */
12830 (satisfies_constraint_Z (operands[2])
12831 && (!CONST_INT_P (operands[2])
12832 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
12833 ? CCZmode : CCNOmode)
12834 && ix86_binary_operator_ok (AND, DImode, operands, TARGET_APX_NDD)"
12836 and{l}\t{%k2, %k0|%k0, %k2}
12837 and{q}\t{%2, %0|%0, %2}
12838 and{q}\t{%2, %0|%0, %2}
12839 and{l}\t{%k2, %k1, %k0|%k0, %k1, %k2}
12840 and{q}\t{%2, %1, %0|%0, %1, %2}
12841 and{q}\t{%2, %1, %0|%0, %1, %2}"
12842 [(set_attr "type" "alu")
12843 (set_attr "isa" "*,*,*,apx_ndd,apx_ndd,apx_ndd")
12844 (set_attr "mode" "SI,DI,DI,SI,DI,DI")])
12846 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
12847 (define_insn "*andsi_2_zext"
12848 [(set (reg FLAGS_REG)
12850 (match_operand:SI 1 "nonimmediate_operand" "%0,rm,r")
12851 (match_operand:SI 2 "x86_64_general_operand" "rBMe,re,BM"))
12853 (set (match_operand:DI 0 "register_operand" "=r,r,r")
12854 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
12855 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
12856 && ix86_binary_operator_ok (AND, SImode, operands, TARGET_APX_NDD)"
12858 and{l}\t{%2, %k0|%k0, %2}
12859 and{l}\t{%2, %1, %k0|%k0, %1, %2}
12860 and{l}\t{%2, %1, %k0|%k0, %1, %2}"
12861 [(set_attr "type" "alu")
12862 (set_attr "isa" "*,apx_ndd,apx_ndd")
12863 (set_attr "mode" "SI")])
12865 (define_insn "*andqi_2_maybe_si"
12866 [(set (reg FLAGS_REG)
12868 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,rm,r")
12869 (match_operand:QI 2 "general_operand" "qn,m,n,rn,m"))
12871 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r,r")
12872 (and:QI (match_dup 1) (match_dup 2)))]
12873 "ix86_binary_operator_ok (AND, QImode, operands, TARGET_APX_NDD)
12874 && ix86_match_ccmode (insn,
12875 CONST_INT_P (operands[2])
12876 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
12878 if (get_attr_mode (insn) == MODE_SI)
12880 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
12881 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
12882 return "and{l}\t{%2, %k0|%k0, %2}";
12884 if (which_alternative > 2)
12885 return "and{b}\t{%2, %1, %0|%0, %1, %2}";
12886 return "and{b}\t{%2, %0|%0, %2}";
12888 [(set_attr "type" "alu")
12889 (set_attr "isa" "*,*,*,apx_ndd,apx_ndd")
12891 (cond [(eq_attr "alternative" "3,4")
12892 (const_string "QI")
12893 (eq_attr "alternative" "2")
12894 (const_string "SI")
12895 (and (match_test "optimize_insn_for_size_p ()")
12896 (and (match_operand 0 "ext_QIreg_operand")
12897 (match_operand 2 "const_0_to_127_operand")))
12898 (const_string "SI")
12900 (const_string "QI")))
12901 ;; Potential partial reg stall on alternative 2.
12902 (set (attr "preferred_for_speed")
12903 (cond [(eq_attr "alternative" "2")
12904 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
12905 (symbol_ref "true")))])
12907 (define_insn "*and<mode>_2"
12908 [(set (reg FLAGS_REG)
12909 (compare (and:SWI124
12910 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0,rm,r")
12911 (match_operand:SWI124 2 "<general_operand>" "<r><i>,<m>,r<i>,<m>"))
12913 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>m,<r>,r,r")
12914 (and:SWI124 (match_dup 1) (match_dup 2)))]
12915 "ix86_match_ccmode (insn, CCNOmode)
12916 && ix86_binary_operator_ok (AND, <MODE>mode, operands, TARGET_APX_NDD)"
12918 and{<imodesuffix>}\t{%2, %0|%0, %2}
12919 and{<imodesuffix>}\t{%2, %0|%0, %2}
12920 and{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
12921 and{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
12922 [(set_attr "type" "alu")
12923 (set_attr "isa" "*,*,apx_ndd,apx_ndd")
12924 (set_attr "mode" "<MODE>")])
12926 (define_insn "*<code>qi_ext<mode>_0"
12927 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn")
12930 (match_operator:SWI248 3 "extract_operator"
12931 [(match_operand 2 "int248_register_operand" "Q")
12934 (match_operand:QI 1 "nonimmediate_operand" "0")))
12935 (clobber (reg:CC FLAGS_REG))]
12937 "<logic>{b}\t{%h2, %0|%0, %h2}"
12938 [(set_attr "addr" "gpr8")
12939 (set_attr "type" "alu")
12940 (set_attr "mode" "QI")])
12942 (define_insn_and_split "*<code>qi_ext2<mode>_0"
12943 [(set (match_operand:QI 0 "register_operand" "=&Q")
12946 (match_operator:SWI248 3 "extract_operator"
12947 [(match_operand 1 "int248_register_operand" "Q")
12951 (match_operator:SWI248 4 "extract_operator"
12952 [(match_operand 2 "int248_register_operand" "Q")
12954 (const_int 8)]) 0)))
12955 (clobber (reg:CC FLAGS_REG))]
12958 "&& reload_completed"
12959 [(set (match_dup 0)
12962 [(match_dup 2) (const_int 8) (const_int 8)]) 0))
12964 [(set (match_dup 0)
12968 [(match_dup 1) (const_int 8) (const_int 8)]) 0)
12970 (clobber (reg:CC FLAGS_REG))])]
12972 [(set_attr "type" "alu")
12973 (set_attr "mode" "QI")])
12975 (define_expand "andqi_ext_1"
12977 [(set (zero_extract:HI (match_operand:HI 0 "register_operand")
12983 (zero_extract:HI (match_operand:HI 1 "register_operand")
12986 (match_operand:QI 2 "const_int_operand")) 0))
12987 (clobber (reg:CC FLAGS_REG))])])
12989 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
12990 (define_insn_and_split "*<code>qi_ext<mode>_1"
12991 [(set (zero_extract:SWI248
12992 (match_operand 0 "int248_register_operand" "+Q,&Q")
12998 (match_operator:SWI248 3 "extract_operator"
12999 [(match_operand 1 "int248_register_operand" "0,!Q")
13002 (match_operand:QI 2 "general_operand" "QnBn,QnBn")) 0))
13003 (clobber (reg:CC FLAGS_REG))]
13006 <logic>{b}\t{%2, %h0|%h0, %2}
13009 && !(rtx_equal_p (operands[0], operands[1]))"
13010 [(set (zero_extract:SWI248
13011 (match_dup 0) (const_int 8) (const_int 8))
13012 (zero_extract:SWI248
13013 (match_dup 1) (const_int 8) (const_int 8)))
13015 [(set (zero_extract:SWI248
13016 (match_dup 0) (const_int 8) (const_int 8))
13021 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
13023 (clobber (reg:CC FLAGS_REG))])]
13025 [(set_attr "addr" "gpr8")
13026 (set_attr "type" "alu")
13027 (set_attr "mode" "QI")])
13029 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
13030 (define_insn_and_split "*<code>qi_ext<mode>_1_cc"
13031 [(set (match_operand 4 "flags_reg_operand")
13032 (match_operator 5 "compare_operator"
13035 (match_operator:SWI248 3 "extract_operator"
13036 [(match_operand 1 "int248_register_operand" "0,!Q")
13039 (match_operand:QI 2 "general_operand" "QnBn,QnBn"))
13041 (set (zero_extract:SWI248
13042 (match_operand 0 "int248_register_operand" "+Q,&Q")
13049 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
13050 (match_dup 2)) 0))]
13051 "ix86_match_ccmode (insn, CCNOmode)"
13053 <logic>{b}\t{%2, %h0|%h0, %2}
13055 "&& reload_completed
13056 && !(rtx_equal_p (operands[0], operands[1]))"
13057 [(set (zero_extract:SWI248
13058 (match_dup 0) (const_int 8) (const_int 8))
13059 (zero_extract:SWI248
13060 (match_dup 1) (const_int 8) (const_int 8)))
13062 [(set (match_dup 4)
13067 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
13070 (set (zero_extract:SWI248
13071 (match_dup 0) (const_int 8) (const_int 8))
13076 [(match_dup 1) (const_int 8) (const_int 8)]) 0)
13077 (match_dup 2)) 0))])]
13079 [(set_attr "addr" "gpr8")
13080 (set_attr "type" "alu")
13081 (set_attr "mode" "QI")])
13083 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
13084 (define_insn_and_split "*<code>qi_ext<mode>_2"
13085 [(set (zero_extract:SWI248
13086 (match_operand 0 "int248_register_operand" "+Q,&Q")
13092 (match_operator:SWI248 3 "extract_operator"
13093 [(match_operand 1 "int248_register_operand" "%0,!Q")
13097 (match_operator:SWI248 4 "extract_operator"
13098 [(match_operand 2 "int248_register_operand" "Q,Q")
13100 (const_int 8)]) 0)) 0))
13101 (clobber (reg:CC FLAGS_REG))]
13104 <logic>{b}\t{%h2, %h0|%h0, %h2}
13107 && !(rtx_equal_p (operands[0], operands[1])
13108 || rtx_equal_p (operands[0], operands[2]))"
13109 [(set (zero_extract:SWI248
13110 (match_dup 0) (const_int 8) (const_int 8))
13111 (zero_extract:SWI248
13112 (match_dup 1) (const_int 8) (const_int 8)))
13114 [(set (zero_extract:SWI248
13115 (match_dup 0) (const_int 8) (const_int 8))
13120 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
13123 [(match_dup 2) (const_int 8) (const_int 8)]) 0)) 0))
13124 (clobber (reg:CC FLAGS_REG))])]
13126 [(set_attr "type" "alu")
13127 (set_attr "mode" "QI")])
13129 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
13130 (define_insn_and_split "*<code>qi_ext<mode>_3"
13131 [(set (zero_extract:SWI248
13132 (match_operand 0 "int248_register_operand" "+Q,&Q")
13135 (match_operator:SWI248 3 "extract_operator"
13137 (match_operand 1 "int248_register_operand" "%0,!Q")
13138 (match_operand 2 "int248_register_operand" "Q,Q"))
13141 (clobber (reg:CC FLAGS_REG))]
13142 "GET_MODE (operands[1]) == GET_MODE (operands[2])"
13144 <logic>{b}\t{%h2, %h0|%h0, %h2}
13146 "&& reload_completed
13147 && !(rtx_equal_p (operands[0], operands[1])
13148 || rtx_equal_p (operands[0], operands[2]))"
13149 [(set (zero_extract:SWI248
13150 (match_dup 0) (const_int 8) (const_int 8))
13151 (zero_extract:SWI248
13152 (match_dup 1) (const_int 8) (const_int 8)))
13154 [(set (zero_extract:SWI248
13155 (match_dup 0) (const_int 8) (const_int 8))
13157 [(any_logic (match_dup 4) (match_dup 2))
13158 (const_int 8) (const_int 8)]))
13159 (clobber (reg:CC FLAGS_REG))])]
13160 "operands[4] = gen_lowpart (GET_MODE (operands[1]), operands[0]);"
13161 [(set_attr "type" "alu")
13162 (set_attr "mode" "QI")])
13164 ;; Convert wide AND instructions with immediate operand to shorter QImode
13165 ;; equivalents when possible.
13166 ;; Don't do the splitting with memory operands, since it introduces risk
13167 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
13168 ;; for size, but that can (should?) be handled by generic code instead.
13169 ;; Don't do the splitting for APX NDD as NDD does not support *h registers.
13171 [(set (match_operand:SWI248 0 "QIreg_operand")
13172 (and:SWI248 (match_operand:SWI248 1 "register_operand")
13173 (match_operand:SWI248 2 "const_int_operand")))
13174 (clobber (reg:CC FLAGS_REG))]
13176 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13177 && !(~INTVAL (operands[2]) & ~(255 << 8))
13178 && !(TARGET_APX_NDD && REGNO (operands[0]) != REGNO (operands[1]))"
13180 [(set (zero_extract:HI (match_dup 0)
13186 (zero_extract:HI (match_dup 1)
13190 (clobber (reg:CC FLAGS_REG))])]
13192 operands[0] = gen_lowpart (HImode, operands[0]);
13193 operands[1] = gen_lowpart (HImode, operands[1]);
13194 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
13197 ;; Since AND can be encoded with sign extended immediate, this is only
13198 ;; profitable when 7th bit is not set.
13200 [(set (match_operand:SWI248 0 "any_QIreg_operand")
13201 (and:SWI248 (match_operand:SWI248 1 "general_operand")
13202 (match_operand:SWI248 2 "const_int_operand")))
13203 (clobber (reg:CC FLAGS_REG))]
13205 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13206 && !(~INTVAL (operands[2]) & ~255)
13207 && !(INTVAL (operands[2]) & 128)
13208 && !(TARGET_APX_NDD
13209 && !rtx_equal_p (operands[0], operands[1]))"
13210 [(parallel [(set (strict_low_part (match_dup 0))
13211 (and:QI (match_dup 1)
13213 (clobber (reg:CC FLAGS_REG))])]
13215 operands[0] = gen_lowpart (QImode, operands[0]);
13216 operands[1] = gen_lowpart (QImode, operands[1]);
13217 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
13220 (define_insn_and_split "*andn<dwi>3_doubleword_bmi"
13221 [(set (match_operand:<DWI> 0 "register_operand" "=&r,&r,r,r")
13223 (not:<DWI> (match_operand:<DWI> 1 "register_operand" "r,r,0,r"))
13224 (match_operand:<DWI> 2 "nonimmediate_operand" "r,o,ro,0")))
13225 (clobber (reg:CC FLAGS_REG))]
13228 "&& reload_completed"
13229 [(parallel [(set (match_dup 0)
13230 (and:DWIH (not:DWIH (match_dup 1)) (match_dup 2)))
13231 (clobber (reg:CC FLAGS_REG))])
13232 (parallel [(set (match_dup 3)
13233 (and:DWIH (not:DWIH (match_dup 4)) (match_dup 5)))
13234 (clobber (reg:CC FLAGS_REG))])]
13235 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);"
13236 [(set_attr "isa" "x64,*,*,*")])
13238 (define_insn_and_split "*andn<mode>3_doubleword"
13239 [(set (match_operand:DWI 0 "register_operand")
13241 (not:DWI (match_operand:DWI 1 "register_operand"))
13242 (match_operand:DWI 2 "nonimmediate_operand")))
13243 (clobber (reg:CC FLAGS_REG))]
13245 && ix86_pre_reload_split ()"
13248 [(set (match_dup 3) (not:DWI (match_dup 1)))
13249 (parallel [(set (match_dup 0)
13250 (and:DWI (match_dup 3) (match_dup 2)))
13251 (clobber (reg:CC FLAGS_REG))])]
13252 "operands[3] = gen_reg_rtx (<MODE>mode);")
13254 (define_insn "*andn<mode>_1"
13255 [(set (match_operand:SWI48 0 "register_operand" "=r,r,?k")
13257 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r,k"))
13258 (match_operand:SWI48 2 "nonimmediate_operand" "r,m,k")))
13259 (clobber (reg:CC FLAGS_REG))]
13260 "TARGET_BMI || TARGET_AVX512BW"
13262 andn\t{%2, %1, %0|%0, %1, %2}
13263 andn\t{%2, %1, %0|%0, %1, %2}
13265 [(set_attr "isa" "bmi,bmi,avx512bw")
13266 (set_attr "type" "bitmanip,bitmanip,msklog")
13267 (set_attr "btver2_decode" "direct, double,*")
13268 (set_attr "mode" "<MODE>")])
13270 (define_insn "*andn<mode>_1"
13271 [(set (match_operand:SWI12 0 "register_operand" "=r,?k")
13273 (not:SWI12 (match_operand:SWI12 1 "register_operand" "r,k"))
13274 (match_operand:SWI12 2 "register_operand" "r,k")))
13275 (clobber (reg:CC FLAGS_REG))]
13276 "TARGET_BMI || TARGET_AVX512BW"
13278 andn\t{%k2, %k1, %k0|%k0, %k1, %k2}
13280 [(set_attr "isa" "bmi,avx512f")
13281 (set_attr "type" "bitmanip,msklog")
13282 (set_attr "btver2_decode" "direct,*")
13284 (cond [(eq_attr "alternative" "0")
13285 (const_string "SI")
13286 (and (eq_attr "alternative" "1")
13287 (match_test "!TARGET_AVX512DQ"))
13288 (const_string "HI")
13290 (const_string "<MODE>")))])
13292 (define_insn "*andn_<mode>_ccno"
13293 [(set (reg FLAGS_REG)
13296 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
13297 (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
13299 (clobber (match_scratch:SWI48 0 "=r,r"))]
13300 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
13301 "andn\t{%2, %1, %0|%0, %1, %2}"
13302 [(set_attr "type" "bitmanip")
13303 (set_attr "btver2_decode" "direct, double")
13304 (set_attr "mode" "<MODE>")])
13306 ;; Split *andnsi_1 after reload with -Oz when not;and is shorter.
13308 [(set (match_operand:SI 0 "register_operand")
13309 (and:SI (not:SI (match_operand:SI 1 "register_operand"))
13310 (match_operand:SI 2 "nonimmediate_operand")))
13311 (clobber (reg:CC FLAGS_REG))]
13313 && optimize_insn_for_size_p () && optimize_size > 1
13314 && REGNO (operands[0]) == REGNO (operands[1])
13315 && LEGACY_INT_REG_P (operands[0])
13316 && !REX_INT_REG_P (operands[2])
13317 && !reg_overlap_mentioned_p (operands[0], operands[2])"
13318 [(set (match_dup 0) (not:SI (match_dup 1)))
13319 (parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
13320 (clobber (reg:CC FLAGS_REG))])])
13322 ;; Split *andn_si_ccno with -Oz when not;test is shorter.
13324 [(set (match_operand 0 "flags_reg_operand")
13325 (match_operator 1 "compare_operator"
13326 [(and:SI (not:SI (match_operand:SI 2 "general_reg_operand"))
13327 (match_operand:SI 3 "nonimmediate_operand"))
13329 (clobber (match_dup 2))]
13331 && optimize_insn_for_size_p () && optimize_size > 1
13332 && LEGACY_INT_REG_P (operands[2])
13333 && !REX_INT_REG_P (operands[3])
13334 && !reg_overlap_mentioned_p (operands[2], operands[3])"
13335 [(set (match_dup 2) (not:SI (match_dup 2)))
13336 (set (match_dup 0) (match_op_dup 1
13337 [(and:SI (match_dup 3) (match_dup 2))
13340 ;; Variant 1 of 4: Split ((A | B) ^ A) ^ C as (B & ~A) ^ C.
13342 [(set (match_operand:SWI48 0 "register_operand")
13345 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
13346 (match_operand:SWI48 2 "nonimmediate_operand"))
13348 (match_operand:SWI48 3 "nonimmediate_operand")))
13349 (clobber (reg:CC FLAGS_REG))]
13352 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 1)) (match_dup 2)))
13353 (clobber (reg:CC FLAGS_REG))])
13355 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
13356 (clobber (reg:CC FLAGS_REG))])]
13357 "operands[4] = gen_reg_rtx (<MODE>mode);")
13359 ;; Variant 2 of 4: Split ((A | B) ^ B) ^ C as (A & ~B) ^ C.
13361 [(set (match_operand:SWI48 0 "register_operand")
13364 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
13365 (match_operand:SWI48 2 "register_operand"))
13367 (match_operand:SWI48 3 "nonimmediate_operand")))
13368 (clobber (reg:CC FLAGS_REG))]
13371 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 2)) (match_dup 1)))
13372 (clobber (reg:CC FLAGS_REG))])
13374 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
13375 (clobber (reg:CC FLAGS_REG))])]
13376 "operands[4] = gen_reg_rtx (<MODE>mode);")
13378 ;; Variant 3 of 4: Split ((A | B) ^ C) ^ A as (B & ~A) ^ C.
13380 [(set (match_operand:SWI48 0 "register_operand")
13383 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
13384 (match_operand:SWI48 2 "nonimmediate_operand"))
13385 (match_operand:SWI48 3 "nonimmediate_operand"))
13387 (clobber (reg:CC FLAGS_REG))]
13390 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 1)) (match_dup 2)))
13391 (clobber (reg:CC FLAGS_REG))])
13393 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
13394 (clobber (reg:CC FLAGS_REG))])]
13395 "operands[4] = gen_reg_rtx (<MODE>mode);")
13397 ;; Variant 4 of 4: Split ((A | B) ^ C) ^ B as (A & ~B) ^ C.
13399 [(set (match_operand:SWI48 0 "register_operand")
13402 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
13403 (match_operand:SWI48 2 "register_operand"))
13404 (match_operand:SWI48 3 "nonimmediate_operand"))
13406 (clobber (reg:CC FLAGS_REG))]
13409 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 2)) (match_dup 1)))
13410 (clobber (reg:CC FLAGS_REG))])
13412 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
13413 (clobber (reg:CC FLAGS_REG))])]
13414 "operands[4] = gen_reg_rtx (<MODE>mode);")
13416 ;; Logical inclusive and exclusive OR instructions
13418 ;; %%% This used to optimize known byte-wide and operations to memory.
13419 ;; If this is considered useful, it should be done with splitters.
13421 (define_expand "<code><mode>3"
13422 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
13423 (any_or:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
13424 (match_operand:SDWIM 2 "<general_operand>")))]
13427 if (GET_MODE_SIZE (<MODE>mode) > UNITS_PER_WORD
13428 && !x86_64_hilo_general_operand (operands[2], <MODE>mode))
13429 operands[2] = force_reg (<MODE>mode, operands[2]);
13431 ix86_expand_binary_operator (<CODE>, <MODE>mode, operands, TARGET_APX_NDD);
13435 (define_insn_and_split "*<code><dwi>3_doubleword"
13436 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,&r,&r,&r,&r,&r")
13438 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0,ro,r,ro,jO,r")
13439 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o,r,<di>,K,<di>,o")))
13440 (clobber (reg:CC FLAGS_REG))]
13441 "ix86_binary_operator_ok (<CODE>, <DWI>mode, operands, TARGET_APX_NDD)"
13443 "&& reload_completed"
13444 [(const_int:DWIH 0)]
13446 /* This insn may disappear completely when operands[2] == const0_rtx
13447 and operands[0] == operands[1], which requires a NOTE_INSN_DELETED. */
13448 bool emit_insn_deleted_note_p = false;
13450 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
13452 if (operands[2] == const0_rtx)
13454 if (!rtx_equal_p (operands[0], operands[1]))
13455 emit_move_insn (operands[0], operands[1]);
13457 emit_insn_deleted_note_p = true;
13459 else if (operands[2] == constm1_rtx)
13462 emit_move_insn (operands[0], constm1_rtx);
13464 ix86_expand_unary_operator (NOT, <MODE>mode, &operands[0],
13468 ix86_expand_binary_operator (<CODE>, <MODE>mode, &operands[0],
13471 if (operands[5] == const0_rtx)
13473 if (!rtx_equal_p (operands[3], operands[4]))
13474 emit_move_insn (operands[3], operands[4]);
13475 else if (emit_insn_deleted_note_p)
13476 emit_note (NOTE_INSN_DELETED);
13478 else if (operands[5] == constm1_rtx)
13481 emit_move_insn (operands[3], constm1_rtx);
13483 ix86_expand_unary_operator (NOT, <MODE>mode, &operands[3],
13487 ix86_expand_binary_operator (<CODE>, <MODE>mode, &operands[3],
13492 [(set_attr "isa" "*,*,apx_ndd,apx_ndd,apx_ndd,apx_ndd_64,apx_ndd")])
13494 (define_insn "*<code><mode>_1<nf_name>"
13495 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r<nf_mem_constraint>,r,r,r,r,?k")
13497 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,0,rm,rjM,r,k")
13498 (match_operand:SWI248 2 "<general_operand>" "r,<i>,<m>,r,<i>,<m>,k")))]
13499 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands, TARGET_APX_NDD)
13502 <nf_prefix><logic>{<imodesuffix>}\t{%2, %0|%0, %2}
13503 <nf_prefix><logic>{<imodesuffix>}\t{%2, %0|%0, %2}
13504 <nf_prefix><logic>{<imodesuffix>}\t{%2, %0|%0, %2}
13505 <nf_prefix><logic>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
13506 <nf_prefix><logic>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
13507 <nf_prefix><logic>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
13509 [(set_attr "isa" "*,*,*,apx_ndd,apx_ndd,apx_ndd,<kmov_isa>")
13510 (set_attr "type" "alu,alu, alu, alu, alu, alu, msklog")
13511 (set_attr "has_nf" "1")
13512 (set_attr "mode" "<MODE>")])
13514 (define_insn_and_split "*notxor<mode>_1"
13515 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,r,r,?k")
13518 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,rm,r,k")
13519 (match_operand:SWI248 2 "<general_operand>" "r<i>,<m>,r<i>,<m>,k"))))
13520 (clobber (reg:CC FLAGS_REG))]
13521 "ix86_binary_operator_ok (XOR, <MODE>mode, operands, TARGET_APX_NDD)"
13523 "&& reload_completed"
13525 [(set (match_dup 0)
13526 (xor:SWI248 (match_dup 1) (match_dup 2)))
13527 (clobber (reg:CC FLAGS_REG))])
13529 (not:SWI248 (match_dup 0)))]
13531 if (MASK_REG_P (operands[0]))
13533 emit_insn (gen_kxnor<mode> (operands[0], operands[1], operands[2]));
13537 [(set_attr "isa" "*,*,apx_ndd,apx_ndd,<kmov_isa>")
13538 (set_attr "type" "alu, alu, alu, alu, msklog")
13539 (set_attr "mode" "<MODE>")])
13541 (define_insn_and_split "*iordi_1_bts"
13542 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13544 (match_operand:DI 1 "nonimmediate_operand" "%0")
13545 (match_operand:DI 2 "const_int_operand" "n")))
13546 (clobber (reg:CC FLAGS_REG))]
13547 "TARGET_64BIT && TARGET_USE_BT
13548 && ix86_binary_operator_ok (IOR, DImode, operands)
13549 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
13551 "&& reload_completed"
13552 [(parallel [(set (zero_extract:DI (match_dup 0)
13556 (clobber (reg:CC FLAGS_REG))])]
13557 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
13558 [(set_attr "type" "alu1")
13559 (set_attr "prefix_0f" "1")
13560 (set_attr "znver1_decode" "double")
13561 (set_attr "mode" "DI")])
13563 (define_insn_and_split "*xordi_1_btc"
13564 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13566 (match_operand:DI 1 "nonimmediate_operand" "%0")
13567 (match_operand:DI 2 "const_int_operand" "n")))
13568 (clobber (reg:CC FLAGS_REG))]
13569 "TARGET_64BIT && TARGET_USE_BT
13570 && ix86_binary_operator_ok (XOR, DImode, operands)
13571 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
13573 "&& reload_completed"
13574 [(parallel [(set (zero_extract:DI (match_dup 0)
13577 (not:DI (zero_extract:DI (match_dup 0)
13580 (clobber (reg:CC FLAGS_REG))])]
13581 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
13582 [(set_attr "type" "alu1")
13583 (set_attr "prefix_0f" "1")
13584 (set_attr "znver1_decode" "double")
13585 (set_attr "mode" "DI")])
13587 ;; Optimize a ^ ((a ^ b) & mask) to (~mask & a) | (b & mask)
13588 (define_insn_and_split "*xor2andn"
13589 [(set (match_operand:SWI248 0 "register_operand")
13593 (match_operand:SWI248 1 "nonimmediate_operand")
13594 (match_operand:SWI248 2 "nonimmediate_operand"))
13595 (match_operand:SWI248 3 "nonimmediate_operand"))
13597 (clobber (reg:CC FLAGS_REG))]
13598 "TARGET_BMI && ix86_pre_reload_split ()"
13601 [(parallel [(set (match_dup 4)
13606 (clobber (reg:CC FLAGS_REG))])
13607 (parallel [(set (match_dup 5)
13611 (clobber (reg:CC FLAGS_REG))])
13612 (parallel [(set (match_dup 0)
13616 (clobber (reg:CC FLAGS_REG))])]
13618 operands[1] = force_reg (<MODE>mode, operands[1]);
13619 operands[3] = force_reg (<MODE>mode, operands[3]);
13620 operands[4] = gen_reg_rtx (<MODE>mode);
13621 operands[5] = gen_reg_rtx (<MODE>mode);
13624 (define_insn "*<code>qi_1_zext<mode><nf_name>"
13625 [(set (match_operand:SWI248x 0 "register_operand" "=r,r")
13626 (zero_extend:SWI248x
13627 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%rm,r")
13628 (match_operand:QI 2 "x86_64_general_operand" "rn,m"))))]
13629 "TARGET_APX_NDD && <nf_condition>
13630 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13632 <nf_prefix><logic>{b}\t{%2, %1, %b0|%b0, %1, %2}
13633 <nf_prefix><logic>{b}\t{%2, %1, %b0|%b0, %1, %2}"
13634 [(set_attr "type" "alu")
13635 (set_attr "has_nf" "1")
13636 (set_attr "mode" "QI")])
13638 (define_insn "*<code>hi_1_zext<mode><nf_name>"
13639 [(set (match_operand:SWI48x 0 "register_operand" "=r,r")
13640 (zero_extend:SWI48x
13641 (any_or:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,r")
13642 (match_operand:HI 2 "x86_64_general_operand" "rn,m"))))]
13643 "TARGET_APX_NDD && <nf_condition>
13644 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13646 <nf_prefix><logic>{w}\t{%2, %1, %w0|%w0, %1, %2}
13647 <nf_prefix><logic>{w}\t{%2, %1, %w0|%w0, %1, %2}"
13648 [(set_attr "type" "alu")
13649 (set_attr "has_nf" "1")
13650 (set_attr "mode" "HI")])
13652 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
13653 (define_insn "*<code>si_1_zext"
13654 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
13656 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0,rm,rjM,r")
13657 (match_operand:SI 2 "x86_64_general_operand" "rBMe,r,e,BM"))))
13658 (clobber (reg:CC FLAGS_REG))]
13660 && ix86_binary_operator_ok (<CODE>, SImode, operands, TARGET_APX_NDD)"
13662 <logic>{l}\t{%2, %k0|%k0, %2}
13663 <logic>{l}\t{%2, %1, %k0|%k0, %1, %2}
13664 <logic>{l}\t{%2, %1, %k0|%k0, %1, %2}
13665 <logic>{l}\t{%2, %1, %k0|%k0, %1, %2}"
13666 [(set_attr "type" "alu")
13667 (set_attr "isa" "*,apx_ndd,apx_ndd,apx_ndd")
13668 (set_attr "mode" "SI")])
13670 (define_insn "*<code>si_1_zext_imm"
13671 [(set (match_operand:DI 0 "register_operand" "=r,r")
13673 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0,rm"))
13674 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z,Z")))
13675 (clobber (reg:CC FLAGS_REG))]
13677 && ix86_binary_operator_ok (<CODE>, SImode, operands, TARGET_APX_NDD)"
13679 <logic>{l}\t{%2, %k0|%k0, %2}
13680 <logic>{l}\t{%2, %1, %k0|%k0, %1, %2}"
13681 [(set_attr "type" "alu")
13682 (set_attr "isa" "*,apx_ndd")
13683 (set_attr "mode" "SI")])
13685 (define_insn "*<code>qi_1<nf_name>"
13686 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r,r,?k")
13687 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,rm,r,k")
13688 (match_operand:QI 2 "general_operand" "qn,m,rn,rn,m,k")))]
13689 "ix86_binary_operator_ok (<CODE>, QImode, operands, TARGET_APX_NDD)
13692 <nf_prefix><logic>{b}\t{%2, %0|%0, %2}
13693 <nf_prefix><logic>{b}\t{%2, %0|%0, %2}
13694 <nf_prefix><logic>{l}\t{%k2, %k0|%k0, %k2}
13695 <nf_prefix><logic>{b}\t{%2, %1, %0|%0, %1, %2}
13696 <nf_prefix><logic>{b}\t{%2, %1, %0|%0, %1, %2}
13698 [(set_attr "isa" "*,*,*,apx_ndd,apx_ndd,avx512f")
13699 (set_attr "type" "alu,alu,alu,alu,alu,msklog")
13700 (set_attr "has_nf" "1")
13702 (cond [(eq_attr "alternative" "2")
13703 (const_string "SI")
13704 (and (eq_attr "alternative" "5")
13705 (match_test "!TARGET_AVX512DQ"))
13706 (const_string "HI")
13708 (const_string "QI")))
13709 ;; Potential partial reg stall on alternative 2.
13710 (set (attr "preferred_for_speed")
13711 (cond [(eq_attr "alternative" "2")
13712 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
13713 (symbol_ref "true")))])
13715 (define_insn_and_split "*notxorqi_1"
13716 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r,r,?k")
13718 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,rm,r,k")
13719 (match_operand:QI 2 "general_operand" "qn,m,rn,rn,m,k"))))
13720 (clobber (reg:CC FLAGS_REG))]
13721 "ix86_binary_operator_ok (XOR, QImode, operands, TARGET_APX_NDD)"
13723 "&& reload_completed"
13725 [(set (match_dup 0)
13726 (xor:QI (match_dup 1) (match_dup 2)))
13727 (clobber (reg:CC FLAGS_REG))])
13729 (not:QI (match_dup 0)))]
13731 if (mask_reg_operand (operands[0], QImode))
13733 emit_insn (gen_kxnorqi (operands[0], operands[1], operands[2]));
13737 [(set_attr "isa" "*,*,*,apx_ndd,apx_ndd,avx512f")
13738 (set_attr "type" "alu,alu,alu,alu,alu,msklog")
13740 (cond [(eq_attr "alternative" "2")
13741 (const_string "SI")
13742 (and (eq_attr "alternative" "5")
13743 (match_test "!TARGET_AVX512DQ"))
13744 (const_string "HI")
13746 (const_string "QI")))
13747 ;; Potential partial reg stall on alternative 2.
13748 (set (attr "preferred_for_speed")
13749 (cond [(eq_attr "alternative" "2")
13750 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
13751 (symbol_ref "true")))])
13753 ;; convert (sign_extend:WIDE (any_logic:NARROW (memory, immediate)))
13754 ;; to (any_logic:WIDE (sign_extend (memory)), (sign_extend (immediate))).
13755 ;; This eliminates sign extension after logic operation.
13758 [(set (match_operand:SWI248 0 "register_operand")
13759 (sign_extend:SWI248
13760 (any_logic:QI (match_operand:QI 1 "memory_operand")
13761 (match_operand:QI 2 "const_int_operand"))))]
13763 [(set (match_dup 3) (sign_extend:SWI248 (match_dup 1)))
13764 (set (match_dup 0) (any_logic:SWI248 (match_dup 3) (match_dup 2)))]
13765 "operands[3] = gen_reg_rtx (<MODE>mode);")
13768 [(set (match_operand:SWI48 0 "register_operand")
13770 (any_logic:HI (match_operand:HI 1 "memory_operand")
13771 (match_operand:HI 2 "const_int_operand"))))]
13773 [(set (match_dup 3) (sign_extend:SWI48 (match_dup 1)))
13774 (set (match_dup 0) (any_logic:SWI48 (match_dup 3) (match_dup 2)))]
13775 "operands[3] = gen_reg_rtx (<MODE>mode);")
13778 [(set (match_operand:DI 0 "register_operand")
13780 (any_logic:SI (match_operand:SI 1 "memory_operand")
13781 (match_operand:SI 2 "const_int_operand"))))]
13783 [(set (match_dup 3) (sign_extend:DI (match_dup 1)))
13784 (set (match_dup 0) (any_logic:DI (match_dup 3) (match_dup 2)))]
13785 "operands[3] = gen_reg_rtx (DImode);")
13787 (define_insn "*<code><mode>_2"
13788 [(set (reg FLAGS_REG)
13789 (compare (any_or:SWI
13790 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,rm,r")
13791 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,r<i>,<m>"))
13793 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r")
13794 (any_or:SWI (match_dup 1) (match_dup 2)))]
13795 "ix86_match_ccmode (insn, CCNOmode)
13796 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands, TARGET_APX_NDD)"
13798 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
13799 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
13800 <logic>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
13801 <logic>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
13802 [(set_attr "type" "alu")
13803 (set_attr "isa" "*,*,apx_ndd,apx_ndd")
13804 (set_attr "mode" "<MODE>")])
13806 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
13807 ;; ??? Special case for immediate operand is missing - it is tricky.
13808 (define_insn "*<code>si_2_zext"
13809 [(set (reg FLAGS_REG)
13810 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0,rm,r")
13811 (match_operand:SI 2 "x86_64_general_operand" "rBMe,re,BM"))
13813 (set (match_operand:DI 0 "register_operand" "=r,r,r")
13814 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
13815 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
13816 && ix86_binary_operator_ok (<CODE>, SImode, operands, TARGET_APX_NDD)"
13818 <logic>{l}\t{%2, %k0|%k0, %2}
13819 <logic>{l}\t{%2, %1, %k0|%k0, %1, %2}
13820 <logic>{l}\t{%2, %1, %k0|%k0, %1, %2}"
13821 [(set_attr "type" "alu")
13822 (set_attr "isa" "*,apx_ndd,apx_ndd")
13823 (set_attr "mode" "SI")])
13825 (define_insn "*<code>si_2_zext_imm"
13826 [(set (reg FLAGS_REG)
13827 (compare (any_or:SI
13828 (match_operand:SI 1 "nonimmediate_operand" "%0,rm")
13829 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z,Z"))
13831 (set (match_operand:DI 0 "register_operand" "=r,r")
13832 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13833 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
13834 && ix86_binary_operator_ok (<CODE>, SImode, operands, TARGET_APX_NDD)"
13836 <logic>{l}\t{%2, %k0|%k0, %2}
13837 <logic>{l}\t{%2, %1, %k0|%k0, %1, %2}"
13838 [(set_attr "type" "alu")
13839 (set_attr "isa" "*,apx_ndd")
13840 (set_attr "mode" "SI")])
13842 (define_insn "*<code><mode>_3"
13843 [(set (reg FLAGS_REG)
13844 (compare (any_or:SWI
13845 (match_operand:SWI 1 "nonimmediate_operand" "%0")
13846 (match_operand:SWI 2 "<general_operand>" "<g>"))
13848 (clobber (match_scratch:SWI 0 "=<r>"))]
13849 "ix86_match_ccmode (insn, CCNOmode)
13850 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13851 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
13852 [(set_attr "type" "alu")
13853 (set_attr "mode" "<MODE>")])
13855 ;; Convert wide OR instructions with immediate operand to shorter QImode
13856 ;; equivalents when possible.
13857 ;; Don't do the splitting with memory operands, since it introduces risk
13858 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
13859 ;; for size, but that can (should?) be handled by generic code instead.
13860 ;; Don't do the splitting for APX NDD as NDD does not support *h registers.
13862 [(set (match_operand:SWI248 0 "QIreg_operand")
13863 (any_or:SWI248 (match_operand:SWI248 1 "register_operand")
13864 (match_operand:SWI248 2 "const_int_operand")))
13865 (clobber (reg:CC FLAGS_REG))]
13867 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13868 && !(INTVAL (operands[2]) & ~(255 << 8))
13869 && !(TARGET_APX_NDD && REGNO (operands[0]) != REGNO (operands[1]))"
13871 [(set (zero_extract:HI (match_dup 0)
13877 (zero_extract:HI (match_dup 1)
13881 (clobber (reg:CC FLAGS_REG))])]
13883 /* Handle the case where INTVAL (operands[2]) == 0. */
13884 if (operands[2] == const0_rtx)
13886 if (!rtx_equal_p (operands[0], operands[1]))
13887 emit_move_insn (operands[0], operands[1]);
13889 emit_note (NOTE_INSN_DELETED);
13892 operands[0] = gen_lowpart (HImode, operands[0]);
13893 operands[1] = gen_lowpart (HImode, operands[1]);
13894 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
13897 ;; Since OR can be encoded with sign extended immediate, this is only
13898 ;; profitable when 7th bit is set.
13900 [(set (match_operand:SWI248 0 "any_QIreg_operand")
13901 (any_or:SWI248 (match_operand:SWI248 1 "general_operand")
13902 (match_operand:SWI248 2 "const_int_operand")))
13903 (clobber (reg:CC FLAGS_REG))]
13905 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13906 && !(INTVAL (operands[2]) & ~255)
13907 && (INTVAL (operands[2]) & 128)
13908 && !(TARGET_APX_NDD
13909 && !rtx_equal_p (operands[0], operands[1]))"
13910 [(parallel [(set (strict_low_part (match_dup 0))
13911 (any_or:QI (match_dup 1)
13913 (clobber (reg:CC FLAGS_REG))])]
13915 operands[0] = gen_lowpart (QImode, operands[0]);
13916 operands[1] = gen_lowpart (QImode, operands[1]);
13917 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
13920 (define_expand "xorqi_ext_1_cc"
13922 [(set (reg:CCNO FLAGS_REG)
13926 (zero_extract:HI (match_operand:HI 1 "register_operand")
13929 (match_operand:QI 2 "const_int_operand"))
13931 (set (zero_extract:HI (match_operand:HI 0 "register_operand")
13937 (zero_extract:HI (match_dup 1)
13940 (match_dup 2)) 0))])])
13942 ;; Peephole2 rega = 0; rega op= regb into rega = regb.
13944 [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
13946 (clobber (reg:CC FLAGS_REG))])
13947 (parallel [(set (match_dup 0)
13948 (any_or_plus:SWI (match_dup 0)
13949 (match_operand:SWI 1 "<general_operand>")))
13950 (clobber (reg:CC FLAGS_REG))])]
13951 "!reg_mentioned_p (operands[0], operands[1])"
13952 [(set (match_dup 0) (match_dup 1))])
13954 ;; Peephole2 dead instruction in rega = 0; rega op= rega.
13956 [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
13958 (clobber (reg:CC FLAGS_REG))])
13959 (parallel [(set (match_dup 0)
13960 (any_or_plus:SWI (match_dup 0) (match_dup 0)))
13961 (clobber (reg:CC FLAGS_REG))])]
13963 [(parallel [(set (match_dup 0) (const_int 0))
13964 (clobber (reg:CC FLAGS_REG))])])
13966 ;; Split DST = (HI<<32)|LO early to minimize register usage.
13967 (define_insn_and_split "*concat<mode><dwi>3_1"
13968 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
13970 (ashift:<DWI> (match_operand:<DWI> 1 "register_operand" "r,r")
13971 (match_operand:QI 2 "const_int_operand"))
13973 (match_operand:DWIH 3 "nonimmediate_operand" "r,m"))))]
13974 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT"
13976 "&& reload_completed"
13979 split_double_concat (<DWI>mode, operands[0], operands[3],
13980 gen_lowpart (<MODE>mode, operands[1]));
13984 (define_insn_and_split "*concat<mode><dwi>3_2"
13985 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
13988 (match_operand:DWIH 1 "nonimmediate_operand" "r,m"))
13989 (ashift:<DWI> (match_operand:<DWI> 2 "register_operand" "r,r")
13990 (match_operand:QI 3 "const_int_operand"))))]
13991 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13993 "&& reload_completed"
13996 split_double_concat (<DWI>mode, operands[0], operands[1],
13997 gen_lowpart (<MODE>mode, operands[2]));
14001 (define_insn_and_split "*concat<mode><dwi>3_3"
14002 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,r,&r,x")
14006 (match_operand:DWIH 1 "nonimmediate_operand" "r,m,r,m,x"))
14007 (match_operand:QI 2 "const_int_operand"))
14009 (match_operand:DWIH 3 "nonimmediate_operand" "r,r,m,m,0"))))]
14010 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT"
14012 "&& reload_completed"
14015 if (SSE_REG_P (operands[0]))
14017 rtx tmp = gen_rtx_REG (V2DImode, REGNO (operands[0]));
14018 emit_insn (gen_vec_concatv2di (tmp, operands[3], operands[1]));
14021 split_double_concat (<DWI>mode, operands[0], operands[3], operands[1]);
14024 [(set_attr "isa" "*,*,*,x64,x64")])
14026 (define_insn_and_split "*concat<mode><dwi>3_4"
14027 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,r,&r")
14030 (match_operand:DWIH 1 "nonimmediate_operand" "r,m,r,m"))
14033 (match_operand:DWIH 2 "nonimmediate_operand" "r,r,m,m"))
14034 (match_operand:QI 3 "const_int_operand"))))]
14035 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
14037 "&& reload_completed"
14040 split_double_concat (<DWI>mode, operands[0], operands[1], operands[2]);
14043 [(set_attr "isa" "*,*,*,x64")])
14045 (define_insn_and_split "*concat<half><mode>3_5"
14046 [(set (match_operand:DWI 0 "nonimmediate_operand" "=r,o,o")
14048 (ashift:DWI (match_operand:DWI 1 "register_operand" "r,r,r")
14049 (match_operand:QI 2 "const_int_operand"))
14050 (match_operand:DWI 3 "const_scalar_int_operand" "n,n,Wd")))]
14051 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT / 2
14052 && (<MODE>mode == DImode
14053 ? CONST_INT_P (operands[3])
14054 && (UINTVAL (operands[3]) & ~GET_MODE_MASK (SImode)) == 0
14055 : CONST_INT_P (operands[3])
14056 ? INTVAL (operands[3]) >= 0
14057 : CONST_WIDE_INT_NUNITS (operands[3]) == 2
14058 && CONST_WIDE_INT_ELT (operands[3], 1) == 0)
14059 && !(CONST_INT_P (operands[3])
14060 ? ix86_endbr_immediate_operand (operands[3], VOIDmode)
14061 : ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[3],
14065 "&& reload_completed"
14068 rtx op3 = simplify_subreg (<HALF>mode, operands[3], <MODE>mode, 0);
14069 split_double_concat (<MODE>mode, operands[0], op3,
14070 gen_lowpart (<HALF>mode, operands[1]));
14073 [(set_attr "isa" "*,nox64,x64")])
14075 (define_insn_and_split "*concat<mode><dwi>3_6"
14076 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,o,r")
14080 (match_operand:DWIH 1 "nonimmediate_operand" "r,r,r,m"))
14081 (match_operand:QI 2 "const_int_operand"))
14082 (match_operand:<DWI> 3 "const_scalar_int_operand" "n,n,Wd,n")))]
14083 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT
14084 && (<DWI>mode == DImode
14085 ? CONST_INT_P (operands[3])
14086 && (UINTVAL (operands[3]) & ~GET_MODE_MASK (SImode)) == 0
14087 : CONST_INT_P (operands[3])
14088 ? INTVAL (operands[3]) >= 0
14089 : CONST_WIDE_INT_NUNITS (operands[3]) == 2
14090 && CONST_WIDE_INT_ELT (operands[3], 1) == 0)
14091 && !(CONST_INT_P (operands[3])
14092 ? ix86_endbr_immediate_operand (operands[3], VOIDmode)
14093 : ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[3],
14097 "&& reload_completed"
14100 rtx op3 = simplify_subreg (<MODE>mode, operands[3], <DWI>mode, 0);
14101 split_double_concat (<DWI>mode, operands[0], op3, operands[1]);
14104 [(set_attr "isa" "*,nox64,x64,*")])
14106 (define_insn_and_split "*concat<mode><dwi>3_7"
14107 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,o,r")
14110 (match_operand:DWIH 1 "nonimmediate_operand" "r,r,r,m"))
14111 (match_operand:<DWI> 2 "const_scalar_int_operand" "n,n,Wd,n")))]
14112 "<DWI>mode == DImode
14113 ? CONST_INT_P (operands[2])
14114 && (UINTVAL (operands[2]) & GET_MODE_MASK (SImode)) == 0
14115 && !ix86_endbr_immediate_operand (operands[2], VOIDmode)
14116 : CONST_WIDE_INT_P (operands[2])
14117 && CONST_WIDE_INT_NUNITS (operands[2]) == 2
14118 && CONST_WIDE_INT_ELT (operands[2], 0) == 0
14119 && !ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[2],
14123 "&& reload_completed"
14127 if (<DWI>mode == DImode)
14128 op2 = gen_int_mode (INTVAL (operands[2]) >> 32, <MODE>mode);
14130 op2 = gen_int_mode (CONST_WIDE_INT_ELT (operands[2], 1), <MODE>mode);
14131 split_double_concat (<DWI>mode, operands[0], operands[1], op2);
14134 [(set_attr "isa" "*,nox64,x64,*")])
14136 ;; Negation instructions
14138 (define_expand "neg<mode>2"
14139 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
14140 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
14143 ix86_expand_unary_operator (NEG, <MODE>mode, operands, TARGET_APX_NDD);
14147 (define_insn_and_split "*neg<dwi>2_doubleword"
14148 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,&r")
14149 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0,ro")))
14150 (clobber (reg:CC FLAGS_REG))]
14151 "ix86_unary_operator_ok (NEG, <DWI>mode, operands, TARGET_APX_NDD)"
14153 "&& reload_completed"
14155 [(set (reg:CCC FLAGS_REG)
14156 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
14157 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
14159 [(set (match_dup 2)
14160 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
14163 (clobber (reg:CC FLAGS_REG))])
14165 [(set (match_dup 2)
14166 (neg:DWIH (match_dup 2)))
14167 (clobber (reg:CC FLAGS_REG))])]
14168 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);"
14169 [(set_attr "isa" "*,apx_ndd")])
14182 [(set (match_operand:SWI48 0 "general_reg_operand")
14183 (match_operand:SWI48 1 "nonimmediate_gr_operand"))
14185 [(set (reg:CCC FLAGS_REG)
14186 (unspec:CCC [(match_operand:SWI48 2 "general_reg_operand")
14187 (const_int 0)] UNSPEC_CC_NE))
14188 (set (match_dup 2) (neg:SWI48 (match_dup 2)))])
14190 [(set (match_dup 0)
14191 (plus:SWI48 (plus:SWI48
14192 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
14195 (clobber (reg:CC FLAGS_REG))])
14197 [(set (match_dup 0)
14198 (neg:SWI48 (match_dup 0)))
14199 (clobber (reg:CC FLAGS_REG))])]
14200 "REGNO (operands[0]) != REGNO (operands[2])
14201 && !reg_mentioned_p (operands[0], operands[1])
14202 && !reg_mentioned_p (operands[2], operands[1])"
14204 [(set (reg:CCC FLAGS_REG)
14205 (unspec:CCC [(match_dup 2) (const_int 0)] UNSPEC_CC_NE))
14206 (set (match_dup 2) (neg:SWI48 (match_dup 2)))])
14208 [(set (match_dup 0)
14209 (minus:SWI48 (minus:SWI48
14211 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0)))
14213 (clobber (reg:CC FLAGS_REG))])]
14214 "ix86_expand_clear (operands[0]);")
14223 ;; sbbl %edx, %edx // *x86_mov<mode>cc_0_m1
14227 [(set (match_operand:SWI48 0 "general_reg_operand") (const_int 0))
14228 (clobber (reg:CC FLAGS_REG))])
14230 [(set (reg:CCC FLAGS_REG)
14231 (unspec:CCC [(match_operand:SWI48 1 "general_reg_operand")
14232 (const_int 0)] UNSPEC_CC_NE))
14233 (set (match_dup 1) (neg:SWI48 (match_dup 1)))])
14235 [(set (match_dup 0)
14236 (plus:SWI48 (plus:SWI48
14237 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
14240 (clobber (reg:CC FLAGS_REG))])
14242 [(set (match_dup 0)
14243 (neg:SWI48 (match_dup 0)))
14244 (clobber (reg:CC FLAGS_REG))])]
14245 "REGNO (operands[0]) != REGNO (operands[1])"
14247 [(set (reg:CCC FLAGS_REG)
14248 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
14249 (set (match_dup 1) (neg:SWI48 (match_dup 1)))])
14251 [(set (match_dup 0)
14252 (if_then_else:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
14255 (clobber (reg:CC FLAGS_REG))])])
14257 (define_insn "*neg<mode>_1<nf_name>"
14258 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,r")
14259 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0,rm")))]
14260 "ix86_unary_operator_ok (NEG, <MODE>mode, operands, TARGET_APX_NDD)
14263 <nf_prefix>neg{<imodesuffix>}\t%0
14264 <nf_prefix>neg{<imodesuffix>}\t{%1, %0|%0, %1}"
14265 [(set_attr "type" "negnot")
14266 (set_attr "isa" "*,apx_ndd")
14267 (set_attr "has_nf" "1")
14268 (set_attr "mode" "<MODE>")])
14270 (define_insn "*negqi_1_zext<mode><nf_name>"
14271 [(set (match_operand:SWI248x 0 "register_operand" "=r")
14272 (zero_extend:SWI248x
14273 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "rm"))))]
14274 "TARGET_APX_NDD && <nf_condition>"
14275 "<nf_prefix>neg{b}\t{%b1, %b0|%b0, %b1}"
14276 [(set_attr "type" "negnot")
14277 (set_attr "has_nf" "1")
14278 (set_attr "mode" "QI")])
14280 (define_insn "*neghi_1_zext<mode><nf_name>"
14281 [(set (match_operand:SWI48x 0 "register_operand" "=r")
14282 (zero_extend:SWI48x
14283 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))]
14284 "TARGET_APX_NDD && <nf_condition>"
14285 "<nf_prefix>neg{w}\t{%w1, %w0|%w0, %w1}"
14286 [(set_attr "type" "negnot")
14287 (set_attr "has_nf" "1")
14288 (set_attr "mode" "HI")])
14290 (define_insn "*negsi_1_zext"
14291 [(set (match_operand:DI 0 "register_operand" "=r,r")
14293 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm"))))
14294 (clobber (reg:CC FLAGS_REG))]
14296 && ix86_unary_operator_ok (NEG, SImode, operands, TARGET_APX_NDD)"
14299 neg{l}\t{%k1, %k0|%k0, %k1}"
14300 [(set_attr "type" "negnot")
14301 (set_attr "isa" "*,apx_ndd")
14302 (set_attr "mode" "SI")])
14304 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
14305 (define_insn_and_split "*neg<mode>_1_slp"
14306 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
14307 (neg:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")))
14308 (clobber (reg:CC FLAGS_REG))]
14309 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
14311 neg{<imodesuffix>}\t%0
14313 "&& reload_completed
14314 && !(rtx_equal_p (operands[0], operands[1]))"
14315 [(set (strict_low_part (match_dup 0)) (match_dup 1))
14317 [(set (strict_low_part (match_dup 0))
14318 (neg:SWI12 (match_dup 0)))
14319 (clobber (reg:CC FLAGS_REG))])]
14321 [(set_attr "type" "negnot")
14322 (set_attr "mode" "<MODE>")])
14324 (define_insn "*neg<mode>_2"
14325 [(set (reg FLAGS_REG)
14327 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0,rm"))
14329 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,r")
14330 (neg:SWI (match_dup 1)))]
14331 "ix86_match_ccmode (insn, CCGOCmode)
14332 && ix86_unary_operator_ok (NEG, <MODE>mode, operands, TARGET_APX_NDD)"
14334 neg{<imodesuffix>}\t%0
14335 neg{<imodesuffix>}\t{%1, %0|%0, %1}"
14336 [(set_attr "type" "negnot")
14337 (set_attr "isa" "*,apx_ndd")
14338 (set_attr "mode" "<MODE>")])
14340 (define_insn "*negsi_2_zext"
14341 [(set (reg FLAGS_REG)
14343 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm"))
14345 (set (match_operand:DI 0 "register_operand" "=r,r")
14347 (neg:SI (match_dup 1))))]
14348 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
14349 && ix86_unary_operator_ok (NEG, SImode, operands, TARGET_APX_NDD)"
14352 neg{l}\t{%1, %k0|%k0, %1}"
14353 [(set_attr "type" "negnot")
14354 (set_attr "isa" "*,apx_ndd")
14355 (set_attr "mode" "SI")])
14357 (define_insn "*neg<mode>_ccc_1"
14358 [(set (reg:CCC FLAGS_REG)
14360 [(match_operand:SWI 1 "nonimmediate_operand" "0,rm")
14361 (const_int 0)] UNSPEC_CC_NE))
14362 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,r")
14363 (neg:SWI (match_dup 1)))]
14366 neg{<imodesuffix>}\t%0
14367 neg{<imodesuffix>}\t{%1, %0|%0, %1}"
14368 [(set_attr "type" "negnot")
14369 (set_attr "isa" "*,apx_ndd")
14370 (set_attr "mode" "<MODE>")])
14372 (define_insn "*neg<mode>_ccc_2"
14373 [(set (reg:CCC FLAGS_REG)
14375 [(match_operand:SWI 1 "nonimmediate_operand" "0,rm")
14376 (const_int 0)] UNSPEC_CC_NE))
14377 (clobber (match_scratch:SWI 0 "=<r>,r"))]
14380 neg{<imodesuffix>}\t%0
14381 neg{<imodesuffix>}\t{%1, %0|%0, %1}"
14382 [(set_attr "type" "negnot")
14383 (set_attr "isa" "*,apx_ndd")
14384 (set_attr "mode" "<MODE>")])
14386 (define_expand "x86_neg<mode>_ccc"
14388 [(set (reg:CCC FLAGS_REG)
14389 (unspec:CCC [(match_operand:SWI48 1 "register_operand")
14390 (const_int 0)] UNSPEC_CC_NE))
14391 (set (match_operand:SWI48 0 "register_operand")
14392 (neg:SWI48 (match_dup 1)))])])
14394 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
14395 (define_insn_and_split "*negqi_ext<mode>_1"
14396 [(set (zero_extract:SWI248
14397 (match_operand 0 "int248_register_operand" "+Q,&Q")
14403 (match_operator:SWI248 2 "extract_operator"
14404 [(match_operand 1 "int248_register_operand" "0,!Q")
14406 (const_int 8)]) 0)) 0))
14407 (clobber (reg:CC FLAGS_REG))]
14413 && !(rtx_equal_p (operands[0], operands[1]))"
14414 [(set (zero_extract:SWI248
14415 (match_dup 0) (const_int 8) (const_int 8))
14416 (zero_extract:SWI248
14417 (match_dup 1) (const_int 8) (const_int 8)))
14419 [(set (zero_extract:SWI248
14420 (match_dup 0) (const_int 8) (const_int 8))
14425 [(match_dup 0) (const_int 8) (const_int 8)]) 0)) 0))
14426 (clobber (reg:CC FLAGS_REG))])]
14428 [(set_attr "type" "negnot")
14429 (set_attr "mode" "QI")])
14431 ;; Negate with jump on overflow.
14432 (define_expand "negv<mode>3"
14433 [(parallel [(set (reg:CCO FLAGS_REG)
14435 [(match_operand:SWI 1 "register_operand")
14436 (match_dup 3)] UNSPEC_CC_NE))
14437 (set (match_operand:SWI 0 "register_operand")
14438 (neg:SWI (match_dup 1)))])
14439 (set (pc) (if_then_else
14440 (eq (reg:CCO FLAGS_REG) (const_int 0))
14441 (label_ref (match_operand 2))
14446 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
14450 (define_insn "*negv<mode>3"
14451 [(set (reg:CCO FLAGS_REG)
14452 (unspec:CCO [(match_operand:SWI 1 "nonimmediate_operand" "0")
14453 (match_operand:SWI 2 "const_int_operand")]
14455 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
14456 (neg:SWI (match_dup 1)))]
14457 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
14458 && mode_signbit_p (<MODE>mode, operands[2])"
14459 "neg{<imodesuffix>}\t%0"
14460 [(set_attr "type" "negnot")
14461 (set_attr "mode" "<MODE>")])
14463 ;; Optimize *negsi_1 followed by *cmpsi_ccno_1 (PR target/91384)
14465 [(set (match_operand:SWI 0 "general_reg_operand")
14466 (match_operand:SWI 1 "general_reg_operand"))
14467 (parallel [(set (match_dup 0) (neg:SWI (match_dup 0)))
14468 (clobber (reg:CC FLAGS_REG))])
14469 (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))]
14471 [(set (match_dup 0) (match_dup 1))
14472 (parallel [(set (reg:CCZ FLAGS_REG)
14473 (compare:CCZ (neg:SWI (match_dup 0)) (const_int 0)))
14474 (set (match_dup 0) (neg:SWI (match_dup 0)))])])
14476 ;; Special expand pattern to handle integer mode abs
14478 (define_expand "abs<mode>2"
14480 [(set (match_operand:SDWIM 0 "register_operand")
14482 (match_operand:SDWIM 1 "general_operand")))
14483 (clobber (reg:CC FLAGS_REG))])]
14485 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)"
14487 if (TARGET_EXPAND_ABS)
14489 machine_mode mode = <MODE>mode;
14490 operands[1] = force_reg (mode, operands[1]);
14492 /* Generate rtx abs using:
14493 abs (x) = (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)) */
14495 rtx shift_amount = gen_int_mode (GET_MODE_PRECISION (mode) - 1, QImode);
14496 rtx shift_dst = expand_simple_binop (mode, ASHIFTRT, operands[1],
14497 shift_amount, NULL_RTX,
14499 rtx xor_dst = expand_simple_binop (mode, XOR, shift_dst, operands[1],
14500 operands[0], 0, OPTAB_DIRECT);
14501 rtx minus_dst = expand_simple_binop (mode, MINUS, xor_dst, shift_dst,
14502 operands[0], 0, OPTAB_DIRECT);
14503 if (!rtx_equal_p (minus_dst, operands[0]))
14504 emit_move_insn (operands[0], minus_dst);
14509 (define_insn_and_split "*abs<dwi>2_doubleword"
14510 [(set (match_operand:<DWI> 0 "register_operand")
14512 (match_operand:<DWI> 1 "general_operand")))
14513 (clobber (reg:CC FLAGS_REG))]
14515 && ix86_pre_reload_split ()"
14519 [(set (reg:CCC FLAGS_REG)
14520 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
14521 (set (match_dup 2) (neg:DWIH (match_dup 1)))])
14523 [(set (match_dup 5)
14524 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
14527 (clobber (reg:CC FLAGS_REG))])
14529 [(set (reg:CCGOC FLAGS_REG)
14531 (neg:DWIH (match_dup 5))
14534 (neg:DWIH (match_dup 5)))])
14537 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
14542 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
14546 operands[1] = force_reg (<DWI>mode, operands[1]);
14547 operands[2] = gen_reg_rtx (<DWI>mode);
14549 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
14552 (define_insn_and_split "*nabs<dwi>2_doubleword"
14553 [(set (match_operand:<DWI> 0 "register_operand")
14556 (match_operand:<DWI> 1 "general_operand"))))
14557 (clobber (reg:CC FLAGS_REG))]
14559 && ix86_pre_reload_split ()"
14563 [(set (reg:CCC FLAGS_REG)
14564 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
14565 (set (match_dup 2) (neg:DWIH (match_dup 1)))])
14567 [(set (match_dup 5)
14568 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
14571 (clobber (reg:CC FLAGS_REG))])
14573 [(set (reg:CCGOC FLAGS_REG)
14575 (neg:DWIH (match_dup 5))
14578 (neg:DWIH (match_dup 5)))])
14581 (lt (reg:CCGOC FLAGS_REG) (const_int 0))
14586 (lt (reg:CCGOC FLAGS_REG) (const_int 0))
14590 operands[1] = force_reg (<DWI>mode, operands[1]);
14591 operands[2] = gen_reg_rtx (<DWI>mode);
14593 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
14596 (define_insn_and_split "*abs<mode>2_1"
14597 [(set (match_operand:SWI 0 "register_operand")
14599 (match_operand:SWI 1 "general_operand")))
14600 (clobber (reg:CC FLAGS_REG))]
14602 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
14603 && ix86_pre_reload_split ()"
14607 [(set (reg:CCGOC FLAGS_REG)
14609 (neg:SWI (match_dup 1))
14612 (neg:SWI (match_dup 1)))])
14615 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
14619 operands[1] = force_reg (<MODE>mode, operands[1]);
14620 operands[2] = gen_reg_rtx (<MODE>mode);
14623 (define_insn_and_split "*nabs<mode>2_1"
14624 [(set (match_operand:SWI 0 "register_operand")
14627 (match_operand:SWI 1 "general_operand"))))
14628 (clobber (reg:CC FLAGS_REG))]
14630 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
14631 && ix86_pre_reload_split ()"
14635 [(set (reg:CCGOC FLAGS_REG)
14637 (neg:SWI (match_dup 1))
14640 (neg:SWI (match_dup 1)))])
14643 (lt (reg:CCGOC FLAGS_REG) (const_int 0))
14647 operands[1] = force_reg (<MODE>mode, operands[1]);
14648 operands[2] = gen_reg_rtx (<MODE>mode);
14651 (define_expand "<code>tf2"
14652 [(set (match_operand:TF 0 "register_operand")
14653 (absneg:TF (match_operand:TF 1 "register_operand")))]
14655 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
14657 (define_insn_and_split "*<code>tf2_1"
14658 [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
14660 (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m")))
14661 (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))]
14664 "&& reload_completed"
14665 [(set (match_dup 0)
14666 (<absneg_op>:TF (match_dup 1) (match_dup 2)))]
14670 if (MEM_P (operands[1]))
14671 std::swap (operands[1], operands[2]);
14675 if (operands_match_p (operands[0], operands[2]))
14676 std::swap (operands[1], operands[2]);
14679 [(set_attr "isa" "noavx,noavx,avx,avx")])
14681 (define_insn_and_split "*nabstf2_1"
14682 [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
14685 (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m"))))
14686 (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))]
14689 "&& reload_completed"
14690 [(set (match_dup 0)
14691 (ior:TF (match_dup 1) (match_dup 2)))]
14695 if (MEM_P (operands[1]))
14696 std::swap (operands[1], operands[2]);
14700 if (operands_match_p (operands[0], operands[2]))
14701 std::swap (operands[1], operands[2]);
14704 [(set_attr "isa" "noavx,noavx,avx,avx")])
14706 (define_expand "<code>hf2"
14707 [(set (match_operand:HF 0 "register_operand")
14708 (absneg:HF (match_operand:HF 1 "register_operand")))]
14709 "TARGET_AVX512FP16"
14710 "ix86_expand_fp_absneg_operator (<CODE>, HFmode, operands); DONE;")
14712 (define_expand "<code><mode>2"
14713 [(set (match_operand:X87MODEF 0 "register_operand")
14714 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
14715 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14716 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
14718 ;; Changing of sign for FP values is doable using integer unit too.
14719 (define_insn "*<code><mode>2_i387_1"
14720 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
14722 (match_operand:X87MODEF 1 "register_operand" "0,0")))
14723 (clobber (reg:CC FLAGS_REG))]
14724 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14728 [(set (match_operand:X87MODEF 0 "fp_register_operand")
14729 (absneg:X87MODEF (match_operand:X87MODEF 1 "fp_register_operand")))
14730 (clobber (reg:CC FLAGS_REG))]
14731 "TARGET_80387 && reload_completed"
14732 [(set (match_dup 0) (absneg:X87MODEF (match_dup 1)))])
14735 [(set (match_operand:X87MODEF 0 "general_reg_operand")
14736 (absneg:X87MODEF (match_operand:X87MODEF 1 "general_reg_operand")))
14737 (clobber (reg:CC FLAGS_REG))]
14738 "TARGET_80387 && reload_completed"
14740 "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
14742 (define_insn_and_split "*<code>hf2_1"
14743 [(set (match_operand:HF 0 "register_operand" "=Yv")
14745 (match_operand:HF 1 "register_operand" "Yv")))
14746 (use (match_operand:V8HF 2 "vector_operand" "Yvm"))
14747 (clobber (reg:CC FLAGS_REG))]
14748 "TARGET_AVX512FP16"
14750 "&& reload_completed"
14751 [(set (match_dup 0)
14752 (<absneg_op>:V8HF (match_dup 1) (match_dup 2)))]
14754 operands[0] = lowpart_subreg (V8HFmode, operands[0], HFmode);
14755 operands[1] = lowpart_subreg (V8HFmode, operands[1], HFmode);
14758 (define_insn "*<code><mode>2_1"
14759 [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv,f,!r")
14761 (match_operand:MODEF 1 "register_operand" "0,x,Yv,0,0")))
14762 (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm,X,X"))
14763 (clobber (reg:CC FLAGS_REG))]
14764 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14766 [(set_attr "isa" "noavx,noavx,avx,*,*")
14767 (set (attr "enabled")
14769 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
14771 (eq_attr "alternative" "3,4")
14772 (symbol_ref "TARGET_MIX_SSE_I387")
14773 (const_string "*"))
14775 (eq_attr "alternative" "3,4")
14776 (symbol_ref "true")
14777 (symbol_ref "false"))))])
14780 [(set (match_operand:MODEF 0 "sse_reg_operand")
14782 (match_operand:MODEF 1 "sse_reg_operand")))
14783 (use (match_operand:<ssevecmodef> 2 "vector_operand"))
14784 (clobber (reg:CC FLAGS_REG))]
14785 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14786 && reload_completed"
14787 [(set (match_dup 0)
14788 (<absneg_op>:<ssevecmodef> (match_dup 1) (match_dup 2)))]
14790 machine_mode mode = <MODE>mode;
14791 machine_mode vmode = <ssevecmodef>mode;
14793 operands[0] = lowpart_subreg (vmode, operands[0], mode);
14794 operands[1] = lowpart_subreg (vmode, operands[1], mode);
14796 if (!TARGET_AVX && operands_match_p (operands[0], operands[2]))
14797 std::swap (operands[1], operands[2]);
14801 [(set (match_operand:MODEF 0 "fp_register_operand")
14802 (absneg:MODEF (match_operand:MODEF 1 "fp_register_operand")))
14803 (use (match_operand 2))
14804 (clobber (reg:CC FLAGS_REG))]
14805 "TARGET_80387 && reload_completed"
14806 [(set (match_dup 0) (absneg:MODEF (match_dup 1)))])
14809 [(set (match_operand:MODEF 0 "general_reg_operand")
14810 (absneg:MODEF (match_operand:MODEF 1 "general_reg_operand")))
14811 (use (match_operand 2))
14812 (clobber (reg:CC FLAGS_REG))]
14813 "TARGET_80387 && reload_completed"
14815 "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
14817 (define_insn_and_split "*nabs<mode>2_1"
14818 [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv")
14821 (match_operand:MODEF 1 "register_operand" "0,x,Yv"))))
14822 (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm"))]
14823 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
14825 "&& reload_completed"
14826 [(set (match_dup 0)
14827 (ior:<ssevecmodef> (match_dup 1) (match_dup 2)))]
14829 machine_mode mode = <MODE>mode;
14830 machine_mode vmode = <ssevecmodef>mode;
14832 operands[0] = lowpart_subreg (vmode, operands[0], mode);
14833 operands[1] = lowpart_subreg (vmode, operands[1], mode);
14835 if (!TARGET_AVX && operands_match_p (operands[0], operands[2]))
14836 std::swap (operands[1], operands[2]);
14838 [(set_attr "isa" "noavx,noavx,avx")])
14840 ;; Conditionalize these after reload. If they match before reload, we
14841 ;; lose the clobber and ability to use integer instructions.
14843 (define_insn "*<code><mode>2_i387"
14844 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
14845 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
14846 "TARGET_80387 && reload_completed"
14847 "<absneg_mnemonic>"
14848 [(set_attr "type" "fsgn")
14849 (set_attr "mode" "<MODE>")])
14851 ;; Copysign instructions
14853 (define_expand "copysign<mode>3"
14854 [(match_operand:SSEMODEF 0 "register_operand")
14855 (match_operand:SSEMODEF 1 "nonmemory_operand")
14856 (match_operand:SSEMODEF 2 "register_operand")]
14857 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14858 || (TARGET_SSE && (<MODE>mode == TFmode))
14859 || (TARGET_AVX512FP16 && (<MODE>mode ==HFmode))"
14860 "ix86_expand_copysign (operands); DONE;")
14862 (define_expand "xorsign<mode>3"
14863 [(match_operand:MODEFH 0 "register_operand")
14864 (match_operand:MODEFH 1 "register_operand")
14865 (match_operand:MODEFH 2 "register_operand")]
14866 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14867 || <MODE>mode == HFmode"
14869 if (rtx_equal_p (operands[1], operands[2]))
14870 emit_insn (gen_abs<mode>2 (operands[0], operands[1]));
14872 ix86_expand_xorsign (operands);
14876 ;; One complement instructions
14878 (define_expand "one_cmpl<mode>2"
14879 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
14880 (not:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
14883 ix86_expand_unary_operator (NOT, <MODE>mode, operands, TARGET_APX_NDD);
14887 (define_insn_and_split "*one_cmpl<dwi>2_doubleword"
14888 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,&r")
14889 (not:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0,ro")))]
14890 "ix86_unary_operator_ok (NOT, <DWI>mode, operands, TARGET_APX_NDD)"
14892 "&& reload_completed"
14893 [(set (match_dup 0)
14894 (not:DWIH (match_dup 1)))
14896 (not:DWIH (match_dup 3)))]
14897 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);"
14898 [(set_attr "isa" "*,apx_ndd")])
14900 (define_insn "*one_cmpl<mode>2_1"
14901 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,?k")
14902 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0,rm,k")))]
14903 "ix86_unary_operator_ok (NOT, <MODE>mode, operands, TARGET_APX_NDD)"
14905 not{<imodesuffix>}\t%0
14906 not{<imodesuffix>}\t{%1, %0|%0, %1}
14908 [(set_attr "isa" "*,apx_ndd,<kmov_isa>")
14909 (set_attr "type" "negnot,negnot,msklog")
14910 (set_attr "mode" "<MODE>")])
14912 (define_insn "*one_cmplqi2_1_zext<mode>"
14913 [(set (match_operand:SWI248x 0 "register_operand" "=r")
14914 (zero_extend:SWI248x
14915 (not:QI (match_operand:QI 1 "nonimmediate_operand" "rm"))))]
14917 "not{b}\t{%1, %b0|%b0, %1}"
14918 [(set_attr "type" "negnot")
14919 (set_attr "mode" "QI")])
14921 (define_insn "*one_cmplhi2_1_zext<mode>"
14922 [(set (match_operand:SWI48x 0 "register_operand" "=r")
14923 (zero_extend:SWI48x
14924 (not:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))]
14926 "not{w}\t{%1, %w0|%w0, %1}"
14927 [(set_attr "type" "negnot")
14928 (set_attr "mode" "HI")])
14930 (define_insn "*one_cmplsi2_1_zext"
14931 [(set (match_operand:DI 0 "register_operand" "=r,r,?k")
14933 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm,k"))))]
14935 && ix86_unary_operator_ok (NOT, SImode, operands, TARGET_APX_NDD)"
14938 not{l}\t{%1, %k0|%k0, %1}
14940 [(set_attr "isa" "x64,apx_ndd,avx512bw")
14941 (set_attr "type" "negnot,negnot,msklog")
14942 (set_attr "mode" "SI,SI,SI")])
14944 (define_insn "*one_cmplqi2_1"
14945 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r,?k")
14946 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,rm,k")))]
14947 "ix86_unary_operator_ok (NOT, QImode, operands, TARGET_APX_NDD)"
14951 not{b}\t{%1, %0|%0, %1}
14953 [(set_attr "isa" "*,*,apx_ndd,avx512f")
14954 (set_attr "type" "negnot,negnot,negnot,msklog")
14956 (cond [(eq_attr "alternative" "1")
14957 (const_string "SI")
14958 (and (eq_attr "alternative" "3")
14959 (match_test "!TARGET_AVX512DQ"))
14960 (const_string "HI")
14962 (const_string "QI")))
14963 ;; Potential partial reg stall on alternative 1.
14964 (set (attr "preferred_for_speed")
14965 (cond [(eq_attr "alternative" "1")
14966 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
14967 (symbol_ref "true")))])
14969 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
14970 (define_insn_and_split "*one_cmpl<mode>_1_slp"
14971 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
14972 (not:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")))]
14973 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
14975 not{<imodesuffix>}\t%0
14977 "&& reload_completed
14978 && !(rtx_equal_p (operands[0], operands[1]))"
14979 [(set (strict_low_part (match_dup 0)) (match_dup 1))
14980 (set (strict_low_part (match_dup 0))
14981 (not:SWI12 (match_dup 0)))]
14983 [(set_attr "type" "negnot")
14984 (set_attr "mode" "<MODE>")])
14986 (define_insn "*one_cmpl<mode>2_2"
14987 [(set (reg FLAGS_REG)
14988 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0,rm"))
14990 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,r")
14991 (not:SWI (match_dup 1)))]
14992 "ix86_match_ccmode (insn, CCNOmode)
14993 && ix86_unary_operator_ok (NOT, <MODE>mode, operands, TARGET_APX_NDD)"
14995 [(set_attr "type" "alu1")
14996 (set_attr "isa" "*,apx_ndd")
14997 (set_attr "mode" "<MODE>")])
15000 [(set (match_operand 0 "flags_reg_operand")
15001 (match_operator 2 "compare_operator"
15002 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
15004 (set (match_operand:SWI 1 "nonimmediate_operand")
15005 (not:SWI (match_dup 3)))]
15006 "ix86_match_ccmode (insn, CCNOmode)"
15007 [(parallel [(set (match_dup 0)
15008 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
15011 (xor:SWI (match_dup 3) (const_int -1)))])])
15013 (define_insn "*one_cmplsi2_2_zext"
15014 [(set (reg FLAGS_REG)
15015 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm"))
15017 (set (match_operand:DI 0 "register_operand" "=r,r")
15018 (zero_extend:DI (not:SI (match_dup 1))))]
15019 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
15020 && ix86_unary_operator_ok (NOT, SImode, operands, TARGET_APX_NDD)"
15022 [(set_attr "type" "alu1")
15023 (set_attr "isa" "*,apx_ndd")
15024 (set_attr "mode" "SI")])
15027 [(set (match_operand 0 "flags_reg_operand")
15028 (match_operator 2 "compare_operator"
15029 [(not:SI (match_operand:SI 3 "nonimmediate_operand"))
15031 (set (match_operand:DI 1 "register_operand")
15032 (zero_extend:DI (not:SI (match_dup 3))))]
15033 "ix86_match_ccmode (insn, CCNOmode)"
15034 [(parallel [(set (match_dup 0)
15035 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
15038 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
15040 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
15041 (define_insn_and_split "*one_cmplqi_ext<mode>_1"
15042 [(set (zero_extract:SWI248
15043 (match_operand 0 "int248_register_operand" "+Q,&Q")
15049 (match_operator:SWI248 2 "extract_operator"
15050 [(match_operand 1 "int248_register_operand" "0,!Q")
15052 (const_int 8)]) 0)) 0))]
15058 && !(rtx_equal_p (operands[0], operands[1]))"
15059 [(set (zero_extract:SWI248
15060 (match_dup 0) (const_int 8) (const_int 8))
15061 (zero_extract:SWI248
15062 (match_dup 1) (const_int 8) (const_int 8)))
15063 (set (zero_extract:SWI248
15064 (match_dup 0) (const_int 8) (const_int 8))
15069 [(match_dup 0) (const_int 8) (const_int 8)]) 0)) 0))]
15071 [(set_attr "type" "negnot")
15072 (set_attr "mode" "QI")])
15074 ;; Shift instructions
15076 ;; DImode shifts are implemented using the i386 "shift double" opcode,
15077 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
15078 ;; is variable, then the count is in %cl and the "imm" operand is dropped
15079 ;; from the assembler input.
15081 ;; This instruction shifts the target reg/mem as usual, but instead of
15082 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
15083 ;; is a left shift double, bits are taken from the high order bits of
15084 ;; reg, else if the insn is a shift right double, bits are taken from the
15085 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
15086 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
15088 ;; Since sh[lr]d does not change the `reg' operand, that is done
15089 ;; separately, making all shifts emit pairs of shift double and normal
15090 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
15091 ;; support a 63 bit shift, each shift where the count is in a reg expands
15092 ;; to a pair of shifts, a branch, a shift by 32 and a label.
15094 ;; If the shift count is a constant, we need never emit more than one
15095 ;; shift pair, instead using moves and sign extension for counts greater
15098 (define_expand "ashl<mode>3"
15099 [(set (match_operand:SDWIM 0 "<shift_operand>")
15100 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
15101 (match_operand:QI 2 "nonmemory_operand")))]
15104 ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands, TARGET_APX_NDD);
15108 (define_insn_and_split "*ashl<dwi>3_doubleword_mask"
15109 [(set (match_operand:<DWI> 0 "register_operand")
15111 (match_operand:<DWI> 1 "register_operand")
15114 (match_operand 2 "int248_register_operand" "c")
15115 (match_operand 3 "const_int_operand")) 0)))
15116 (clobber (reg:CC FLAGS_REG))]
15117 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
15118 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
15119 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
15120 && ix86_pre_reload_split ()"
15124 [(set (match_dup 6)
15125 (ior:DWIH (ashift:DWIH (match_dup 6)
15126 (and:QI (match_dup 2) (match_dup 8)))
15128 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
15129 (minus:QI (match_dup 9)
15130 (and:QI (match_dup 2) (match_dup 8)))) 0)))
15131 (clobber (reg:CC FLAGS_REG))])
15133 [(set (match_dup 4)
15134 (ashift:DWIH (match_dup 5) (match_dup 2)))
15135 (clobber (reg:CC FLAGS_REG))])]
15137 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
15139 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
15140 operands[2] = gen_lowpart (QImode, operands[2]);
15141 emit_insn (gen_ashl<dwi>3_doubleword (operands[0], operands[1],
15146 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
15148 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
15149 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
15151 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
15152 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
15155 xops[0] = gen_reg_rtx (GET_MODE (operands[2]));
15156 xops[1] = operands[2];
15157 xops[2] = GEN_INT (INTVAL (operands[3])
15158 & ((<MODE_SIZE> * BITS_PER_UNIT) - 1));
15159 ix86_expand_binary_operator (AND, GET_MODE (operands[2]), xops);
15160 operands[2] = xops[0];
15163 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
15164 operands[2] = gen_lowpart (QImode, operands[2]);
15166 if (!rtx_equal_p (operands[6], operands[7]))
15167 emit_move_insn (operands[6], operands[7]);
15170 (define_insn_and_split "*ashl<dwi>3_doubleword_mask_1"
15171 [(set (match_operand:<DWI> 0 "register_operand")
15173 (match_operand:<DWI> 1 "register_operand")
15175 (match_operand:QI 2 "register_operand" "c")
15176 (match_operand:QI 3 "const_int_operand"))))
15177 (clobber (reg:CC FLAGS_REG))]
15178 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
15179 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
15180 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
15181 && ix86_pre_reload_split ()"
15185 [(set (match_dup 6)
15186 (ior:DWIH (ashift:DWIH (match_dup 6)
15187 (and:QI (match_dup 2) (match_dup 8)))
15189 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
15190 (minus:QI (match_dup 9)
15191 (and:QI (match_dup 2) (match_dup 8)))) 0)))
15192 (clobber (reg:CC FLAGS_REG))])
15194 [(set (match_dup 4)
15195 (ashift:DWIH (match_dup 5) (match_dup 2)))
15196 (clobber (reg:CC FLAGS_REG))])]
15198 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
15200 emit_insn (gen_ashl<dwi>3_doubleword (operands[0], operands[1],
15205 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
15207 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
15208 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
15210 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
15211 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
15213 rtx tem = gen_reg_rtx (QImode);
15214 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
15218 if (!rtx_equal_p (operands[6], operands[7]))
15219 emit_move_insn (operands[6], operands[7]);
15222 (define_insn "ashl<mode>3_doubleword"
15223 [(set (match_operand:DWI 0 "register_operand" "=&r,&r")
15224 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0Wc,r")
15225 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
15226 (clobber (reg:CC FLAGS_REG))]
15229 [(set_attr "type" "multi")
15230 (set_attr "isa" "*,apx_ndd")])
15233 [(set (match_operand:DWI 0 "register_operand")
15234 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
15235 (match_operand:QI 2 "nonmemory_operand")))
15236 (clobber (reg:CC FLAGS_REG))]
15237 "epilogue_completed"
15241 && !rtx_equal_p (operands[0], operands[1])
15242 && REG_P (operands[1]))
15243 ix86_split_ashl_ndd (operands, NULL_RTX);
15245 ix86_split_ashl (operands, NULL_RTX, <MODE>mode);
15249 ;; By default we don't ask for a scratch register, because when DWImode
15250 ;; values are manipulated, registers are already at a premium. But if
15251 ;; we have one handy, we won't turn it away.
15254 [(match_scratch:DWIH 3 "r")
15255 (parallel [(set (match_operand:<DWI> 0 "register_operand")
15257 (match_operand:<DWI> 1 "nonmemory_operand")
15258 (match_operand:QI 2 "nonmemory_operand")))
15259 (clobber (reg:CC FLAGS_REG))])
15265 && !rtx_equal_p (operands[0], operands[1])
15266 && (REG_P (operands[1])))
15267 ix86_split_ashl_ndd (operands, operands[3]);
15269 ix86_split_ashl (operands, operands[3], <DWI>mode);
15273 (define_insn_and_split "*ashl<dwi>3_doubleword_highpart"
15274 [(set (match_operand:<DWI> 0 "register_operand" "=r")
15276 (any_extend:<DWI> (match_operand:DWIH 1 "nonimmediate_operand" "rm"))
15277 (match_operand:QI 2 "const_int_operand")))
15278 (clobber (reg:CC FLAGS_REG))]
15279 "INTVAL (operands[2]) >= <MODE_SIZE> * BITS_PER_UNIT
15280 && INTVAL (operands[2]) < <MODE_SIZE> * BITS_PER_UNIT * 2"
15282 "&& reload_completed"
15285 split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[3]);
15286 int bits = INTVAL (operands[2]) - (<MODE_SIZE> * BITS_PER_UNIT);
15287 bool op_equal_p = rtx_equal_p (operands[3], operands[1]);
15291 emit_move_insn (operands[3], operands[1]);
15295 if (!op_equal_p && !TARGET_APX_NDD)
15296 emit_move_insn (operands[3], operands[1]);
15297 rtx op_tmp = TARGET_APX_NDD ? operands[1] : operands[3];
15298 emit_insn (gen_ashl<mode>3 (operands[3], op_tmp, GEN_INT (bits)));
15300 ix86_expand_clear (operands[0]);
15304 (define_insn "x86_64_shld<nf_name>"
15305 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
15306 (ior:DI (ashift:DI (match_dup 0)
15307 (and:QI (match_operand:QI 2 "nonmemory_operand" "Jc")
15312 (match_operand:DI 1 "register_operand" "r"))
15313 (minus:QI (const_int 64)
15314 (and:QI (match_dup 2) (const_int 63)))) 0)))]
15315 "TARGET_64BIT && <nf_condition>"
15316 "<nf_prefix>shld{q}\t{%2, %1, %0|%0, %1, %2}"
15317 [(set_attr "type" "ishift")
15318 (set_attr "prefix_0f" "1")
15319 (set_attr "has_nf" "1")
15320 (set_attr "mode" "DI")
15321 (set_attr "athlon_decode" "vector")
15322 (set_attr "amdfam10_decode" "vector")
15323 (set_attr "bdver1_decode" "vector")])
15325 (define_insn "x86_64_shld_ndd<nf_name>"
15326 [(set (match_operand:DI 0 "register_operand" "=r")
15327 (ior:DI (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "rm")
15328 (and:QI (match_operand:QI 3 "nonmemory_operand" "Jc")
15333 (match_operand:DI 2 "register_operand" "r"))
15334 (minus:QI (const_int 64)
15335 (and:QI (match_dup 3) (const_int 63)))) 0)))]
15336 "TARGET_APX_NDD && <nf_condition>"
15337 "<nf_prefix>shld{q}\t{%3, %2, %1, %0|%0, %1, %2, %3}"
15338 [(set_attr "type" "ishift")
15339 (set_attr "has_nf" "1")
15340 (set_attr "mode" "DI")])
15342 (define_insn "x86_64_shld_1<nf_name>"
15343 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
15344 (ior:DI (ashift:DI (match_dup 0)
15345 (match_operand:QI 2 "const_0_to_63_operand"))
15349 (match_operand:DI 1 "register_operand" "r"))
15350 (match_operand:QI 3 "const_0_to_255_operand")) 0)))]
15352 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])
15354 "<nf_prefix>shld{q}\t{%2, %1, %0|%0, %1, %2}"
15355 [(set_attr "type" "ishift")
15356 (set_attr "prefix_0f" "1")
15357 (set_attr "has_nf" "1")
15358 (set_attr "mode" "DI")
15359 (set_attr "length_immediate" "1")
15360 (set_attr "athlon_decode" "vector")
15361 (set_attr "amdfam10_decode" "vector")
15362 (set_attr "bdver1_decode" "vector")])
15364 (define_insn "x86_64_shld_ndd_1<nf_name>"
15365 [(set (match_operand:DI 0 "register_operand" "=r")
15366 (ior:DI (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "rm")
15367 (match_operand:QI 3 "const_0_to_63_operand"))
15371 (match_operand:DI 2 "register_operand" "r"))
15372 (match_operand:QI 4 "const_0_to_255_operand")) 0)))]
15374 && INTVAL (operands[4]) == 64 - INTVAL (operands[3])
15376 "<nf_prefix>shld{q}\t{%3, %2, %1, %0|%0, %1, %2, %3}"
15377 [(set_attr "type" "ishift")
15378 (set_attr "has_nf" "1")
15379 (set_attr "mode" "DI")
15380 (set_attr "length_immediate" "1")])
15382 (define_insn_and_split "*x86_64_shld_shrd_1_nozext_nf"
15383 [(set (match_operand:DI 0 "nonimmediate_operand")
15384 (ior:DI (ashift:DI (match_operand:DI 4 "nonimmediate_operand")
15385 (match_operand:QI 2 "const_0_to_63_operand"))
15387 (match_operand:DI 1 "nonimmediate_operand")
15388 (match_operand:QI 3 "const_0_to_63_operand"))))]
15389 "TARGET_64BIT && TARGET_APX_NF
15390 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])
15391 && ix86_pre_reload_split ()"
15396 if (rtx_equal_p (operands[4], operands[0]))
15398 operands[1] = force_reg (DImode, operands[1]);
15399 emit_insn (gen_x86_64_shld_1_nf (operands[0], operands[1],
15400 operands[2], operands[3]));
15402 else if (rtx_equal_p (operands[1], operands[0]))
15404 operands[4] = force_reg (DImode, operands[4]);
15405 emit_insn (gen_x86_64_shrd_1_nf (operands[0], operands[4],
15406 operands[3], operands[2]));
15408 else if (TARGET_APX_NDD)
15410 rtx tmp = gen_reg_rtx (DImode);
15411 if (MEM_P (operands[4]))
15413 operands[1] = force_reg (DImode, operands[1]);
15414 emit_insn (gen_x86_64_shld_ndd_1_nf (tmp, operands[4], operands[1],
15415 operands[2], operands[3]));
15417 else if (MEM_P (operands[1]))
15418 emit_insn (gen_x86_64_shrd_ndd_1_nf (tmp, operands[1], operands[4],
15419 operands[3], operands[2]));
15421 emit_insn (gen_x86_64_shld_ndd_1_nf (tmp, operands[4], operands[1],
15422 operands[2], operands[3]));
15423 emit_move_insn (operands[0], tmp);
15427 operands[1] = force_reg (DImode, operands[1]);
15428 rtx tmp = gen_reg_rtx (DImode);
15429 emit_move_insn (tmp, operands[4]);
15430 emit_insn (gen_x86_64_shld_1_nf (tmp, operands[1],
15431 operands[2], operands[3]));
15432 emit_move_insn (operands[0], tmp);
15437 (define_insn_and_split "*x86_64_shld_shrd_1_nozext"
15438 [(set (match_operand:DI 0 "nonimmediate_operand")
15439 (ior:DI (ashift:DI (match_operand:DI 4 "nonimmediate_operand")
15440 (match_operand:QI 2 "const_0_to_63_operand"))
15442 (match_operand:DI 1 "nonimmediate_operand")
15443 (match_operand:QI 3 "const_0_to_63_operand"))))
15444 (clobber (reg:CC FLAGS_REG))]
15446 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])
15447 && ix86_pre_reload_split ()"
15452 if (rtx_equal_p (operands[4], operands[0]))
15454 operands[1] = force_reg (DImode, operands[1]);
15455 emit_insn (gen_x86_64_shld_1 (operands[0], operands[1], operands[2], operands[3]));
15457 else if (rtx_equal_p (operands[1], operands[0]))
15459 operands[4] = force_reg (DImode, operands[4]);
15460 emit_insn (gen_x86_64_shrd_1 (operands[0], operands[4], operands[3], operands[2]));
15462 else if (TARGET_APX_NDD)
15464 rtx tmp = gen_reg_rtx (DImode);
15465 if (MEM_P (operands[4]))
15467 operands[1] = force_reg (DImode, operands[1]);
15468 emit_insn (gen_x86_64_shld_ndd_1 (tmp, operands[4], operands[1],
15469 operands[2], operands[3]));
15471 else if (MEM_P (operands[1]))
15472 emit_insn (gen_x86_64_shrd_ndd_1 (tmp, operands[1], operands[4],
15473 operands[3], operands[2]));
15475 emit_insn (gen_x86_64_shld_ndd_1 (tmp, operands[4], operands[1],
15476 operands[2], operands[3]));
15477 emit_move_insn (operands[0], tmp);
15481 operands[1] = force_reg (DImode, operands[1]);
15482 rtx tmp = gen_reg_rtx (DImode);
15483 emit_move_insn (tmp, operands[4]);
15484 emit_insn (gen_x86_64_shld_1 (tmp, operands[1], operands[2], operands[3]));
15485 emit_move_insn (operands[0], tmp);
15489 [(set_attr "has_nf" "1")])
15491 (define_insn_and_split "*x86_64_shld_2"
15492 [(set (match_operand:DI 0 "nonimmediate_operand")
15493 (ior:DI (ashift:DI (match_dup 0)
15494 (match_operand:QI 2 "nonmemory_operand"))
15495 (lshiftrt:DI (match_operand:DI 1 "register_operand")
15496 (minus:QI (const_int 64) (match_dup 2)))))
15497 (clobber (reg:CC FLAGS_REG))]
15498 "TARGET_64BIT && ix86_pre_reload_split ()"
15501 [(parallel [(set (match_dup 0)
15502 (ior:DI (ashift:DI (match_dup 0)
15503 (and:QI (match_dup 2) (const_int 63)))
15506 (zero_extend:TI (match_dup 1))
15507 (minus:QI (const_int 64)
15508 (and:QI (match_dup 2)
15509 (const_int 63)))) 0)))
15510 (clobber (reg:CC FLAGS_REG))])])
15512 (define_insn_and_split "*x86_64_shld_ndd_2"
15513 [(set (match_operand:DI 0 "nonimmediate_operand")
15514 (ior:DI (ashift:DI (match_operand:DI 1 "nonimmediate_operand")
15515 (match_operand:QI 3 "nonmemory_operand"))
15516 (lshiftrt:DI (match_operand:DI 2 "register_operand")
15517 (minus:QI (const_int 64) (match_dup 3)))))
15518 (clobber (reg:CC FLAGS_REG))]
15520 && ix86_pre_reload_split ()"
15523 [(parallel [(set (match_dup 4)
15524 (ior:DI (ashift:DI (match_dup 1)
15525 (and:QI (match_dup 3) (const_int 63)))
15528 (zero_extend:TI (match_dup 2))
15529 (minus:QI (const_int 64)
15530 (and:QI (match_dup 3)
15531 (const_int 63)))) 0)))
15532 (clobber (reg:CC FLAGS_REG))
15533 (set (match_dup 0) (match_dup 4))])]
15535 operands[4] = gen_reg_rtx (DImode);
15536 emit_move_insn (operands[4], operands[0]);
15539 (define_insn "x86_shld<nf_name>"
15540 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
15541 (ior:SI (ashift:SI (match_dup 0)
15542 (and:QI (match_operand:QI 2 "nonmemory_operand" "Ic")
15547 (match_operand:SI 1 "register_operand" "r"))
15548 (minus:QI (const_int 32)
15549 (and:QI (match_dup 2) (const_int 31)))) 0)))]
15551 "<nf_prefix>shld{l}\t{%2, %1, %0|%0, %1, %2}"
15552 [(set_attr "type" "ishift")
15553 (set_attr "prefix_0f" "1")
15554 (set_attr "has_nf" "1")
15555 (set_attr "mode" "SI")
15556 (set_attr "pent_pair" "np")
15557 (set_attr "athlon_decode" "vector")
15558 (set_attr "amdfam10_decode" "vector")
15559 (set_attr "bdver1_decode" "vector")])
15561 (define_insn "x86_shld_ndd<nf_name>"
15562 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
15563 (ior:SI (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
15564 (and:QI (match_operand:QI 3 "nonmemory_operand" "Ic")
15569 (match_operand:SI 2 "register_operand" "r"))
15570 (minus:QI (const_int 32)
15571 (and:QI (match_dup 3) (const_int 31)))) 0)))]
15572 "TARGET_APX_NDD && <nf_condition>"
15573 "<nf_prefix>shld{l}\t{%3, %2, %1, %0|%0, %1, %2, %3}"
15574 [(set_attr "type" "ishift")
15575 (set_attr "has_nf" "1")
15576 (set_attr "mode" "SI")])
15579 (define_insn "x86_shld_1<nf_name>"
15580 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
15581 (ior:SI (ashift:SI (match_dup 0)
15582 (match_operand:QI 2 "const_0_to_31_operand"))
15586 (match_operand:SI 1 "register_operand" "r"))
15587 (match_operand:QI 3 "const_0_to_63_operand")) 0)))]
15588 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])
15590 "<nf_prefix>shld{l}\t{%2, %1, %0|%0, %1, %2}"
15591 [(set_attr "type" "ishift")
15592 (set_attr "prefix_0f" "1")
15593 (set_attr "length_immediate" "1")
15594 (set_attr "has_nf" "1")
15595 (set_attr "mode" "SI")
15596 (set_attr "pent_pair" "np")
15597 (set_attr "athlon_decode" "vector")
15598 (set_attr "amdfam10_decode" "vector")
15599 (set_attr "bdver1_decode" "vector")])
15601 (define_insn "x86_shld_ndd_1<nf_name>"
15602 [(set (match_operand:SI 0 "register_operand" "=r")
15603 (ior:SI (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
15604 (match_operand:QI 3 "const_0_to_31_operand"))
15608 (match_operand:SI 2 "register_operand" "r"))
15609 (match_operand:QI 4 "const_0_to_63_operand")) 0)))]
15611 && INTVAL (operands[4]) == 32 - INTVAL (operands[3])
15613 "<nf_prefix>shld{l}\t{%3, %2, %1, %0|%0, %1, %2, %3}"
15614 [(set_attr "type" "ishift")
15615 (set_attr "length_immediate" "1")
15616 (set_attr "has_nf" "1")
15617 (set_attr "mode" "SI")])
15619 (define_insn_and_split "*x86_shld_shrd_1_nozext_nf"
15620 [(set (match_operand:SI 0 "nonimmediate_operand")
15621 (ior:SI (ashift:SI (match_operand:SI 4 "nonimmediate_operand")
15622 (match_operand:QI 2 "const_0_to_31_operand"))
15624 (match_operand:SI 1 "nonimmediate_operand")
15625 (match_operand:QI 3 "const_0_to_31_operand"))))]
15627 && INTVAL (operands[3]) == 32 - INTVAL (operands[2])
15628 && ix86_pre_reload_split ()"
15633 if (rtx_equal_p (operands[4], operands[0]))
15635 operands[1] = force_reg (SImode, operands[1]);
15636 emit_insn (gen_x86_shld_1_nf (operands[0], operands[1],
15637 operands[2], operands[3]));
15639 else if (rtx_equal_p (operands[1], operands[0]))
15641 operands[4] = force_reg (SImode, operands[4]);
15642 emit_insn (gen_x86_shrd_1_nf (operands[0], operands[4],
15643 operands[3], operands[2]));
15645 else if (TARGET_APX_NDD)
15647 rtx tmp = gen_reg_rtx (SImode);
15648 if (MEM_P (operands[4]))
15650 operands[1] = force_reg (SImode, operands[1]);
15651 emit_insn (gen_x86_shld_ndd_1_nf (tmp, operands[4], operands[1],
15652 operands[2], operands[3]));
15654 else if (MEM_P (operands[1]))
15655 emit_insn (gen_x86_shrd_ndd_1_nf (tmp, operands[1], operands[4],
15656 operands[3], operands[2]));
15658 emit_insn (gen_x86_shld_ndd_1_nf (tmp, operands[4], operands[1],
15659 operands[2], operands[3]));
15660 emit_move_insn (operands[0], tmp);
15664 operands[1] = force_reg (SImode, operands[1]);
15665 rtx tmp = gen_reg_rtx (SImode);
15666 emit_move_insn (tmp, operands[4]);
15667 emit_insn (gen_x86_shld_1_nf (tmp, operands[1], operands[2],
15669 emit_move_insn (operands[0], tmp);
15674 (define_insn_and_split "*x86_shld_shrd_1_nozext"
15675 [(set (match_operand:SI 0 "nonimmediate_operand")
15676 (ior:SI (ashift:SI (match_operand:SI 4 "nonimmediate_operand")
15677 (match_operand:QI 2 "const_0_to_31_operand"))
15679 (match_operand:SI 1 "nonimmediate_operand")
15680 (match_operand:QI 3 "const_0_to_31_operand"))))
15681 (clobber (reg:CC FLAGS_REG))]
15682 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])
15683 && ix86_pre_reload_split ()"
15688 if (rtx_equal_p (operands[4], operands[0]))
15690 operands[1] = force_reg (SImode, operands[1]);
15691 emit_insn (gen_x86_shld_1 (operands[0], operands[1], operands[2], operands[3]));
15693 else if (rtx_equal_p (operands[1], operands[0]))
15695 operands[4] = force_reg (SImode, operands[4]);
15696 emit_insn (gen_x86_shrd_1 (operands[0], operands[4], operands[3], operands[2]));
15698 else if (TARGET_APX_NDD)
15700 rtx tmp = gen_reg_rtx (SImode);
15701 if (MEM_P (operands[4]))
15703 operands[1] = force_reg (SImode, operands[1]);
15704 emit_insn (gen_x86_shld_ndd_1 (tmp, operands[4], operands[1],
15705 operands[2], operands[3]));
15707 else if (MEM_P (operands[1]))
15708 emit_insn (gen_x86_shrd_ndd_1 (tmp, operands[1], operands[4],
15709 operands[3], operands[2]));
15711 emit_insn (gen_x86_shld_ndd_1 (tmp, operands[4], operands[1],
15712 operands[2], operands[3]));
15713 emit_move_insn (operands[0], tmp);
15717 operands[1] = force_reg (SImode, operands[1]);
15718 rtx tmp = gen_reg_rtx (SImode);
15719 emit_move_insn (tmp, operands[4]);
15720 emit_insn (gen_x86_shld_1 (tmp, operands[1], operands[2], operands[3]));
15721 emit_move_insn (operands[0], tmp);
15725 [(set_attr "has_nf" "1")])
15727 (define_insn_and_split "*x86_shld_2"
15728 [(set (match_operand:SI 0 "nonimmediate_operand")
15729 (ior:SI (ashift:SI (match_dup 0)
15730 (match_operand:QI 2 "nonmemory_operand"))
15731 (lshiftrt:SI (match_operand:SI 1 "register_operand")
15732 (minus:QI (const_int 32) (match_dup 2)))))
15733 (clobber (reg:CC FLAGS_REG))]
15734 "TARGET_64BIT && ix86_pre_reload_split ()"
15737 [(parallel [(set (match_dup 0)
15738 (ior:SI (ashift:SI (match_dup 0)
15739 (and:QI (match_dup 2) (const_int 31)))
15742 (zero_extend:DI (match_dup 1))
15743 (minus:QI (const_int 32)
15744 (and:QI (match_dup 2)
15745 (const_int 31)))) 0)))
15746 (clobber (reg:CC FLAGS_REG))])])
15748 (define_insn_and_split "*x86_shld_ndd_2"
15749 [(set (match_operand:SI 0 "nonimmediate_operand")
15750 (ior:SI (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
15751 (match_operand:QI 3 "nonmemory_operand"))
15752 (lshiftrt:SI (match_operand:SI 2 "register_operand")
15753 (minus:QI (const_int 32) (match_dup 3)))))
15754 (clobber (reg:CC FLAGS_REG))]
15756 && ix86_pre_reload_split ()"
15759 [(parallel [(set (match_dup 4)
15760 (ior:SI (ashift:SI (match_dup 1)
15761 (and:QI (match_dup 3) (const_int 31)))
15764 (zero_extend:DI (match_dup 2))
15765 (minus:QI (const_int 32)
15766 (and:QI (match_dup 3)
15767 (const_int 31)))) 0)))
15768 (clobber (reg:CC FLAGS_REG))
15769 (set (match_dup 0) (match_dup 4))])]
15771 operands[4] = gen_reg_rtx (SImode);
15772 emit_move_insn (operands[4], operands[0]);
15775 (define_expand "@x86_shift<mode>_adj_1"
15776 [(set (reg:CCZ FLAGS_REG)
15777 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
15780 (set (match_operand:SWI48 0 "register_operand")
15781 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
15782 (match_operand:SWI48 1 "register_operand")
15785 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
15786 (match_operand:SWI48 3 "register_operand")
15789 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
15791 (define_expand "@x86_shift<mode>_adj_2"
15792 [(use (match_operand:SWI48 0 "register_operand"))
15793 (use (match_operand:SWI48 1 "register_operand"))
15794 (use (match_operand:QI 2 "register_operand"))]
15797 rtx_code_label *label = gen_label_rtx ();
15800 emit_insn (gen_testqi_ccz_1 (operands[2],
15801 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
15803 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
15804 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
15805 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
15806 gen_rtx_LABEL_REF (VOIDmode, label),
15808 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
15809 JUMP_LABEL (tmp) = label;
15811 emit_move_insn (operands[0], operands[1]);
15812 ix86_expand_clear (operands[1]);
15814 emit_label (label);
15815 LABEL_NUSES (label) = 1;
15820 ;; Avoid useless masking of count operand.
15821 (define_insn_and_split "*ashl<mode>3_mask"
15822 [(set (match_operand:SWI48 0 "nonimmediate_operand")
15824 (match_operand:SWI48 1 "nonimmediate_operand")
15827 (match_operand 2 "int248_register_operand" "c,r")
15828 (match_operand 3 "const_int_operand")) 0)))
15829 (clobber (reg:CC FLAGS_REG))]
15830 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
15831 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15832 == GET_MODE_BITSIZE (<MODE>mode)-1
15833 && ix86_pre_reload_split ()"
15837 [(set (match_dup 0)
15838 (ashift:SWI48 (match_dup 1)
15840 (clobber (reg:CC FLAGS_REG))])]
15842 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
15843 operands[2] = gen_lowpart (QImode, operands[2]);
15845 [(set_attr "isa" "*,bmi2")])
15847 (define_insn_and_split "*ashl<mode>3_mask_1"
15848 [(set (match_operand:SWI48 0 "nonimmediate_operand")
15850 (match_operand:SWI48 1 "nonimmediate_operand")
15852 (match_operand:QI 2 "register_operand" "c,r")
15853 (match_operand:QI 3 "const_int_operand"))))
15854 (clobber (reg:CC FLAGS_REG))]
15855 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
15856 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15857 == GET_MODE_BITSIZE (<MODE>mode)-1
15858 && ix86_pre_reload_split ()"
15862 [(set (match_dup 0)
15863 (ashift:SWI48 (match_dup 1)
15865 (clobber (reg:CC FLAGS_REG))])]
15867 [(set_attr "isa" "*,bmi2")])
15869 (define_insn "*bmi2_ashl<mode>3_1"
15870 [(set (match_operand:SWI48 0 "register_operand" "=r")
15871 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
15872 (match_operand:SWI48 2 "register_operand" "r")))]
15874 "shlx\t{%2, %1, %0|%0, %1, %2}"
15875 [(set_attr "type" "ishiftx")
15876 (set_attr "mode" "<MODE>")])
15878 (define_insn "*ashl<mode>3_1<nf_name>"
15879 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,?k,r")
15880 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm,k,rm")
15881 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r,<KS>,c<S>")))]
15882 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands, TARGET_APX_NDD)
15885 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
15886 switch (get_attr_type (insn))
15889 if (TARGET_APX_NDD && <nf_applied>)
15890 return "%{nf%} sal{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}";
15899 gcc_assert (operands[2] == const1_rtx);
15900 gcc_assert (rtx_equal_p (operands[0], operands[1]));
15901 return "<nf_prefix>add{<imodesuffix>}\t%0, %0";
15904 if (operands[2] == const1_rtx
15905 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
15906 /* For NDD form instructions related to TARGET_SHIFT1, the $1
15907 immediate do not need to be omitted as assembler will map it
15908 to use shorter encoding. */
15909 && !use_ndd && !<nf_applied>)
15910 return "sal{<imodesuffix>}\t%0";
15912 return use_ndd ? "<nf_prefix>sal{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
15913 : "<nf_prefix>sal{<imodesuffix>}\t{%2, %0|%0, %2}";
15916 [(set_attr "isa" "*,*,bmi2,avx512bw,apx_ndd")
15918 (cond [(eq_attr "alternative" "1")
15919 (const_string "lea")
15920 (eq_attr "alternative" "2")
15921 (const_string "ishiftx")
15922 (eq_attr "alternative" "4")
15923 (const_string "ishift")
15924 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
15925 (match_operand 0 "register_operand"))
15926 (match_operand 2 "const1_operand"))
15927 (const_string "alu")
15928 (eq_attr "alternative" "3")
15929 (const_string "msklog")
15931 (const_string "ishift")))
15932 (set (attr "length_immediate")
15934 (ior (eq_attr "type" "alu")
15935 (and (eq_attr "type" "ishift")
15936 (and (match_operand 2 "const1_operand")
15937 (ior (match_test "TARGET_SHIFT1")
15938 (match_test "optimize_function_for_size_p (cfun)")))))
15940 (const_string "*")))
15941 (set_attr "has_nf" "1")
15942 (set_attr "mode" "<MODE>")])
15944 ;; Convert shift to the shiftx pattern to avoid flags dependency.
15945 ;; For NF/NDD doesn't support shift count as r, it just support c<S>,
15946 ;; and it has no flag.
15948 [(set (match_operand:SWI48 0 "register_operand")
15949 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
15950 (match_operand:QI 2 "register_operand")))]
15951 "TARGET_BMI2 && reload_completed"
15952 [(set (match_dup 0)
15953 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
15954 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
15957 [(set (match_operand:SWI48 0 "register_operand")
15958 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
15959 (match_operand:QI 2 "register_operand")))
15960 (clobber (reg:CC FLAGS_REG))]
15961 "TARGET_BMI2 && reload_completed"
15962 [(set (match_dup 0)
15963 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
15964 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
15966 (define_insn "*bmi2_ashlsi3_1_zext"
15967 [(set (match_operand:DI 0 "register_operand" "=r")
15969 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
15970 (match_operand:SI 2 "register_operand" "r"))))]
15971 "TARGET_64BIT && TARGET_BMI2"
15972 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
15973 [(set_attr "type" "ishiftx")
15974 (set_attr "mode" "SI")])
15976 (define_insn "*ashlqi3_1_zext<mode><nf_name>"
15977 [(set (match_operand:SWI248x 0 "register_operand" "=r")
15978 (zero_extend:SWI248x
15979 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "rm")
15980 (match_operand:QI 2 "nonmemory_operand" "cI"))))]
15981 "TARGET_APX_NDD && <nf_condition>"
15982 "<nf_prefix>sal{b}\t{%2, %1, %b0|%b0, %1, %2}"
15983 [(set_attr "type" "ishiftx")
15984 (set_attr "has_nf" "1")
15985 (set_attr "mode" "QI")])
15987 (define_insn "*ashlhi3_1_zext<mode><nf_name>"
15988 [(set (match_operand:SWI48x 0 "register_operand" "=r")
15989 (zero_extend:SWI48x
15990 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "rm")
15991 (match_operand:QI 2 "nonmemory_operand" "cI"))))]
15992 "TARGET_APX_NDD && <nf_condition>"
15993 "<nf_prefix>sal{w}\t{%2, %1, %w0|%w0, %1, %2}"
15994 [(set_attr "type" "ishiftx")
15995 (set_attr "has_nf" "1")
15996 (set_attr "mode" "HI")])
15998 (define_insn "*ashlsi3_1_zext"
15999 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
16001 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm,rm")
16002 (match_operand:QI 2 "nonmemory_operand" "cI,M,r,cI"))))
16003 (clobber (reg:CC FLAGS_REG))]
16005 && ix86_binary_operator_ok (ASHIFT, SImode, operands, TARGET_APX_NDD)"
16007 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
16008 switch (get_attr_type (insn))
16015 gcc_assert (operands[2] == const1_rtx);
16016 return "add{l}\t%k0, %k0";
16019 if (operands[2] == const1_rtx
16020 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
16022 return "sal{l}\t%k0";
16024 return use_ndd ? "sal{l}\t{%2, %1, %k0|%k0, %1, %2}"
16025 : "sal{l}\t{%2, %k0|%k0, %2}";
16028 [(set_attr "isa" "*,*,bmi2,apx_ndd")
16030 (cond [(eq_attr "alternative" "1")
16031 (const_string "lea")
16032 (eq_attr "alternative" "2")
16033 (const_string "ishiftx")
16034 (eq_attr "alternative" "3")
16035 (const_string "ishift")
16036 (and (match_test "TARGET_DOUBLE_WITH_ADD")
16037 (match_operand 2 "const1_operand"))
16038 (const_string "alu")
16040 (const_string "ishift")))
16041 (set (attr "length_immediate")
16043 (ior (eq_attr "type" "alu")
16044 (and (eq_attr "type" "ishift")
16045 (and (match_operand 2 "const1_operand")
16046 (ior (match_test "TARGET_SHIFT1")
16047 (match_test "optimize_function_for_size_p (cfun)")))))
16049 (const_string "*")))
16050 (set_attr "mode" "SI")])
16052 ;; Convert shift to the shiftx pattern to avoid flags dependency.
16054 [(set (match_operand:DI 0 "register_operand")
16056 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
16057 (match_operand:QI 2 "register_operand"))))
16058 (clobber (reg:CC FLAGS_REG))]
16059 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
16060 [(set (match_dup 0)
16061 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
16062 "operands[2] = gen_lowpart (SImode, operands[2]);")
16064 (define_insn "*ashlhi3_1<nf_name>"
16065 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp,?k,r")
16066 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l,k,rm")
16067 (match_operand:QI 2 "nonmemory_operand" "cI,M,Ww,cI")))]
16068 "ix86_binary_operator_ok (ASHIFT, HImode, operands, TARGET_APX_NDD)
16071 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
16072 switch (get_attr_type (insn))
16075 if (TARGET_APX_NDD && <nf_applied>)
16076 return "%{nf%} sal{w}\t{%2, %1, %0|%0, %1, %2}";
16084 gcc_assert (operands[2] == const1_rtx);
16085 return "<nf_prefix>add{w}\t%0, %0";
16088 if (operands[2] == const1_rtx
16089 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
16090 && !use_ndd && !<nf_applied>)
16091 return "sal{w}\t%0";
16093 return use_ndd ? "<nf_prefix>sal{w}\t{%2, %1, %0|%0, %1, %2}"
16094 : "<nf_prefix>sal{w}\t{%2, %0|%0, %2}";
16097 [(set_attr "isa" "*,*,avx512f,apx_ndd")
16099 (cond [(eq_attr "alternative" "1")
16100 (const_string "lea")
16101 (eq_attr "alternative" "2")
16102 (const_string "msklog")
16103 (eq_attr "alternative" "3")
16104 (const_string "ishift")
16105 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
16106 (match_operand 0 "register_operand"))
16107 (match_operand 2 "const1_operand"))
16108 (const_string "alu")
16110 (const_string "ishift")))
16111 (set (attr "length_immediate")
16113 (ior (eq_attr "type" "alu")
16114 (and (eq_attr "type" "ishift")
16115 (and (match_operand 2 "const1_operand")
16116 (ior (match_test "TARGET_SHIFT1")
16117 (match_test "optimize_function_for_size_p (cfun)")))))
16119 (const_string "*")))
16120 (set_attr "has_nf" "1")
16121 (set_attr "mode" "HI,SI,HI,HI")])
16123 (define_insn "*ashlqi3_1<nf_name>"
16124 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp,?k,r")
16125 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l,k,rm")
16126 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M,Wb,cI")))]
16127 "ix86_binary_operator_ok (ASHIFT, QImode, operands, TARGET_APX_NDD)
16130 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
16131 switch (get_attr_type (insn))
16134 if (TARGET_APX_NDD && <nf_applied>)
16135 return "%{nf%} sal{b}\t{%2, %1, %0|%0, %1, %2}";
16143 gcc_assert (operands[2] == const1_rtx);
16144 if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
16145 return "<nf_prefix>add{l}\t%k0, %k0";
16147 return "<nf_prefix>add{b}\t%0, %0";
16150 if (operands[2] == const1_rtx
16151 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
16152 && !use_ndd && !<nf_applied>)
16154 if (get_attr_mode (insn) == MODE_SI)
16155 return "sal{l}\t%k0";
16157 return "sal{b}\t%0";
16161 if (get_attr_mode (insn) == MODE_SI)
16162 return "<nf_prefix>sal{l}\t{%2, %k0|%k0, %2}";
16164 return use_ndd ? "<nf_prefix>sal{b}\t{%2, %1, %0|%0, %1, %2}"
16165 : "<nf_prefix>sal{b}\t{%2, %0|%0, %2}";
16169 [(set_attr "isa" "*,*,*,avx512dq,apx_ndd")
16171 (cond [(eq_attr "alternative" "2")
16172 (const_string "lea")
16173 (eq_attr "alternative" "3")
16174 (const_string "msklog")
16175 (eq_attr "alternative" "4")
16176 (const_string "ishift")
16177 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
16178 (match_operand 0 "register_operand"))
16179 (match_operand 2 "const1_operand"))
16180 (const_string "alu")
16182 (const_string "ishift")))
16183 (set (attr "length_immediate")
16185 (ior (eq_attr "type" "alu")
16186 (and (eq_attr "type" "ishift")
16187 (and (match_operand 2 "const1_operand")
16188 (ior (match_test "TARGET_SHIFT1")
16189 (match_test "optimize_function_for_size_p (cfun)")))))
16191 (const_string "*")))
16192 (set_attr "has_nf" "1")
16193 (set_attr "mode" "QI,SI,SI,QI,QI")
16194 ;; Potential partial reg stall on alternative 1.
16195 (set (attr "preferred_for_speed")
16196 (cond [(eq_attr "alternative" "1,4")
16197 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
16198 (symbol_ref "true")))])
16200 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
16201 (define_insn_and_split "*ashl<mode>3_1_slp"
16202 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
16203 (ashift:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
16204 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
16205 (clobber (reg:CC FLAGS_REG))]
16206 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
16208 if (which_alternative)
16211 switch (get_attr_type (insn))
16214 gcc_assert (operands[2] == const1_rtx);
16215 return "add{<imodesuffix>}\t%0, %0";
16218 if (operands[2] == const1_rtx
16219 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
16220 return "sal{<imodesuffix>}\t%0";
16222 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
16225 "&& reload_completed
16226 && !(rtx_equal_p (operands[0], operands[1]))"
16227 [(set (strict_low_part (match_dup 0)) (match_dup 1))
16229 [(set (strict_low_part (match_dup 0))
16230 (ashift:SWI12 (match_dup 0) (match_dup 2)))
16231 (clobber (reg:CC FLAGS_REG))])]
16233 [(set (attr "type")
16234 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
16235 (match_operand 2 "const1_operand"))
16236 (const_string "alu")
16238 (const_string "ishift")))
16239 (set (attr "length_immediate")
16241 (ior (eq_attr "type" "alu")
16242 (and (eq_attr "type" "ishift")
16243 (and (match_operand 2 "const1_operand")
16244 (ior (match_test "TARGET_SHIFT1")
16245 (match_test "optimize_function_for_size_p (cfun)")))))
16247 (const_string "*")))
16248 (set_attr "mode" "<MODE>")])
16250 ;; Convert ashift to the lea pattern to avoid flags dependency.
16252 [(set (match_operand:SWI 0 "general_reg_operand")
16253 (ashift:SWI (match_operand:SWI 1 "index_reg_operand")
16254 (match_operand 2 "const_0_to_3_operand")))
16255 (clobber (reg:CC FLAGS_REG))]
16257 && REGNO (operands[0]) != REGNO (operands[1])"
16258 [(set (match_dup 0)
16259 (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
16261 if (<MODE>mode != <LEAMODE>mode)
16263 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
16264 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
16266 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
16270 [(set (match_operand:SWI 0 "general_reg_operand")
16271 (ashift:SWI (match_operand:SWI 1 "index_reg_operand")
16272 (match_operand 2 "const_0_to_3_operand")))]
16274 && REGNO (operands[0]) != REGNO (operands[1])
16275 && !TARGET_APX_NDD"
16276 [(set (match_dup 0)
16277 (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
16279 if (<MODE>mode != <LEAMODE>mode)
16281 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
16282 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
16284 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
16287 ;; Convert ashift to the lea pattern to avoid flags dependency.
16289 [(set (match_operand:DI 0 "general_reg_operand")
16291 (ashift:SI (match_operand:SI 1 "index_reg_operand")
16292 (match_operand 2 "const_0_to_3_operand"))))
16293 (clobber (reg:CC FLAGS_REG))]
16294 "TARGET_64BIT && reload_completed
16295 && REGNO (operands[0]) != REGNO (operands[1])"
16296 [(set (match_dup 0)
16297 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
16299 operands[1] = gen_lowpart (SImode, operands[1]);
16300 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
16303 ;; This pattern can't accept a variable shift count, since shifts by
16304 ;; zero don't affect the flags. We assume that shifts by constant
16305 ;; zero are optimized away.
16306 (define_insn "*ashl<mode>3_cmp"
16307 [(set (reg FLAGS_REG)
16309 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0,rm")
16310 (match_operand:QI 2 "<shift_immediate_operand>" "<S>,<S>"))
16312 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,r")
16313 (ashift:SWI (match_dup 1) (match_dup 2)))]
16314 "(optimize_function_for_size_p (cfun)
16315 || !TARGET_PARTIAL_FLAG_REG_STALL
16316 || (operands[2] == const1_rtx
16318 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
16319 && ix86_match_ccmode (insn, CCGOCmode)
16320 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands, TARGET_APX_NDD)"
16322 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
16323 switch (get_attr_type (insn))
16326 gcc_assert (operands[2] == const1_rtx);
16327 return "add{<imodesuffix>}\t%0, %0";
16330 if (operands[2] == const1_rtx
16331 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
16333 return "sal{<imodesuffix>}\t%0";
16335 return use_ndd ? "sal{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
16336 : "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
16339 [(set_attr "isa" "*,apx_ndd")
16341 (cond [(eq_attr "alternative" "1")
16342 (const_string "ishift")
16343 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
16344 (match_operand 0 "register_operand"))
16345 (match_operand 2 "const1_operand"))
16346 (const_string "alu")
16348 (const_string "ishift")))
16349 (set (attr "length_immediate")
16351 (ior (eq_attr "type" "alu")
16352 (and (eq_attr "type" "ishift")
16353 (and (match_operand 2 "const1_operand")
16354 (ior (match_test "TARGET_SHIFT1")
16355 (match_test "optimize_function_for_size_p (cfun)")))))
16357 (const_string "*")))
16358 (set_attr "mode" "<MODE>")])
16360 (define_insn "*ashlsi3_cmp_zext"
16361 [(set (reg FLAGS_REG)
16363 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
16364 (match_operand:QI 2 "const_1_to_31_operand"))
16366 (set (match_operand:DI 0 "register_operand" "=r,r")
16367 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
16369 && (optimize_function_for_size_p (cfun)
16370 || !TARGET_PARTIAL_FLAG_REG_STALL
16371 || (operands[2] == const1_rtx
16373 || TARGET_DOUBLE_WITH_ADD)))
16374 && ix86_match_ccmode (insn, CCGOCmode)
16375 && ix86_binary_operator_ok (ASHIFT, SImode, operands, TARGET_APX_NDD)"
16377 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
16378 switch (get_attr_type (insn))
16381 gcc_assert (operands[2] == const1_rtx);
16382 return "add{l}\t%k0, %k0";
16385 if (operands[2] == const1_rtx
16386 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
16388 return "sal{l}\t%k0";
16390 return use_ndd ? "sal{l}\t{%2, %1, %k0|%k0, %1, %2}"
16391 : "sal{l}\t{%2, %k0|%k0, %2}";
16394 [(set_attr "isa" "*,apx_ndd")
16396 (cond [(eq_attr "alternative" "1")
16397 (const_string "ishift")
16398 (and (match_test "TARGET_DOUBLE_WITH_ADD")
16399 (match_operand 2 "const1_operand"))
16400 (const_string "alu")
16402 (const_string "ishift")))
16403 (set (attr "length_immediate")
16405 (ior (eq_attr "type" "alu")
16406 (and (eq_attr "type" "ishift")
16407 (and (match_operand 2 "const1_operand")
16408 (ior (match_test "TARGET_SHIFT1")
16409 (match_test "optimize_function_for_size_p (cfun)")))))
16411 (const_string "*")))
16412 (set_attr "mode" "SI")])
16414 (define_insn "*ashl<mode>3_cconly"
16415 [(set (reg FLAGS_REG)
16417 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0,rm")
16418 (match_operand:QI 2 "<shift_immediate_operand>" "<S>,<S>"))
16420 (clobber (match_scratch:SWI 0 "=<r>,r"))]
16421 "(optimize_function_for_size_p (cfun)
16422 || !TARGET_PARTIAL_FLAG_REG_STALL
16423 || (operands[2] == const1_rtx
16425 || TARGET_DOUBLE_WITH_ADD)))
16426 && ix86_match_ccmode (insn, CCGOCmode)"
16428 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
16429 switch (get_attr_type (insn))
16432 gcc_assert (operands[2] == const1_rtx);
16433 return "add{<imodesuffix>}\t%0, %0";
16436 if (operands[2] == const1_rtx
16437 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
16439 return "sal{<imodesuffix>}\t%0";
16441 return use_ndd ? "sal{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
16442 : "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
16445 [(set_attr "isa" "*,apx_ndd")
16447 (cond [(eq_attr "alternative" "1")
16448 (const_string "ishift")
16449 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
16450 (match_operand 0 "register_operand"))
16451 (match_operand 2 "const1_operand"))
16452 (const_string "alu")
16454 (const_string "ishift")))
16455 (set (attr "length_immediate")
16457 (ior (eq_attr "type" "alu")
16458 (and (eq_attr "type" "ishift")
16459 (and (match_operand 2 "const1_operand")
16460 (ior (match_test "TARGET_SHIFT1")
16461 (match_test "optimize_function_for_size_p (cfun)")))))
16463 (const_string "*")))
16464 (set_attr "mode" "<MODE>")])
16466 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
16467 (define_insn_and_split "*ashlqi_ext<mode>_1"
16468 [(set (zero_extract:SWI248
16469 (match_operand 0 "int248_register_operand" "+Q,&Q")
16475 (match_operator:SWI248 3 "extract_operator"
16476 [(match_operand 1 "int248_register_operand" "0,!Q")
16479 (match_operand:QI 2 "nonmemory_operand" "cI,cI")) 0))
16480 (clobber (reg:CC FLAGS_REG))]
16483 if (which_alternative)
16486 switch (get_attr_type (insn))
16489 gcc_assert (operands[2] == const1_rtx);
16490 return "add{b}\t%h0, %h0";
16493 if (operands[2] == const1_rtx
16494 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
16495 return "sal{b}\t%h0";
16497 return "sal{b}\t{%2, %h0|%h0, %2}";
16501 && !(rtx_equal_p (operands[0], operands[1]))"
16502 [(set (zero_extract:SWI248
16503 (match_dup 0) (const_int 8) (const_int 8))
16504 (zero_extract:SWI248
16505 (match_dup 1) (const_int 8) (const_int 8)))
16507 [(set (zero_extract:SWI248
16508 (match_dup 0) (const_int 8) (const_int 8))
16513 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
16515 (clobber (reg:CC FLAGS_REG))])]
16517 [(set (attr "type")
16518 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
16519 (match_operand 2 "const1_operand"))
16520 (const_string "alu")
16522 (const_string "ishift")))
16523 (set (attr "length_immediate")
16525 (ior (eq_attr "type" "alu")
16526 (and (eq_attr "type" "ishift")
16527 (and (match_operand 2 "const1_operand")
16528 (ior (match_test "TARGET_SHIFT1")
16529 (match_test "optimize_function_for_size_p (cfun)")))))
16531 (const_string "*")))
16532 (set_attr "mode" "QI")])
16534 ;; See comment above `ashl<mode>3' about how this works.
16536 (define_expand "<insn><mode>3"
16537 [(set (match_operand:SDWIM 0 "<shift_operand>")
16538 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
16539 (match_operand:QI 2 "nonmemory_operand")))]
16542 ix86_expand_binary_operator (<CODE>, <MODE>mode, operands, TARGET_APX_NDD);
16546 ;; Avoid useless masking of count operand.
16547 (define_insn_and_split "*<insn><mode>3_mask"
16548 [(set (match_operand:SWI48 0 "nonimmediate_operand")
16550 (match_operand:SWI48 1 "nonimmediate_operand")
16553 (match_operand 2 "int248_register_operand" "c,r")
16554 (match_operand 3 "const_int_operand")) 0)))
16555 (clobber (reg:CC FLAGS_REG))]
16556 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
16557 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16558 == GET_MODE_BITSIZE (<MODE>mode)-1
16559 && ix86_pre_reload_split ()"
16563 [(set (match_dup 0)
16564 (any_shiftrt:SWI48 (match_dup 1)
16566 (clobber (reg:CC FLAGS_REG))])]
16568 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
16569 operands[2] = gen_lowpart (QImode, operands[2]);
16571 [(set_attr "isa" "*,bmi2")])
16573 (define_insn_and_split "*<insn><mode>3_mask_1"
16574 [(set (match_operand:SWI48 0 "nonimmediate_operand")
16576 (match_operand:SWI48 1 "nonimmediate_operand")
16578 (match_operand:QI 2 "register_operand" "c,r")
16579 (match_operand:QI 3 "const_int_operand"))))
16580 (clobber (reg:CC FLAGS_REG))]
16581 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
16582 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16583 == GET_MODE_BITSIZE (<MODE>mode)-1
16584 && ix86_pre_reload_split ()"
16588 [(set (match_dup 0)
16589 (any_shiftrt:SWI48 (match_dup 1)
16591 (clobber (reg:CC FLAGS_REG))])]
16593 [(set_attr "isa" "*,bmi2")])
16595 (define_insn_and_split "*<insn><dwi>3_doubleword_mask"
16596 [(set (match_operand:<DWI> 0 "register_operand")
16598 (match_operand:<DWI> 1 "register_operand")
16601 (match_operand 2 "int248_register_operand" "c")
16602 (match_operand 3 "const_int_operand")) 0)))
16603 (clobber (reg:CC FLAGS_REG))]
16604 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
16605 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
16606 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
16607 && ix86_pre_reload_split ()"
16611 [(set (match_dup 4)
16612 (ior:DWIH (lshiftrt:DWIH (match_dup 4)
16613 (and:QI (match_dup 2) (match_dup 8)))
16615 (ashift:<DWI> (zero_extend:<DWI> (match_dup 7))
16616 (minus:QI (match_dup 9)
16617 (and:QI (match_dup 2) (match_dup 8)))) 0)))
16618 (clobber (reg:CC FLAGS_REG))])
16620 [(set (match_dup 6)
16621 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
16622 (clobber (reg:CC FLAGS_REG))])]
16624 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
16626 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
16627 operands[2] = gen_lowpart (QImode, operands[2]);
16628 emit_insn (gen_<insn><dwi>3_doubleword (operands[0], operands[1],
16633 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
16635 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
16636 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
16638 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
16639 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
16642 xops[0] = gen_reg_rtx (GET_MODE (operands[2]));
16643 xops[1] = operands[2];
16644 xops[2] = GEN_INT (INTVAL (operands[3])
16645 & ((<MODE_SIZE> * BITS_PER_UNIT) - 1));
16646 ix86_expand_binary_operator (AND, GET_MODE (operands[2]), xops);
16647 operands[2] = xops[0];
16650 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
16651 operands[2] = gen_lowpart (QImode, operands[2]);
16653 if (!rtx_equal_p (operands[4], operands[5]))
16654 emit_move_insn (operands[4], operands[5]);
16657 (define_insn_and_split "*<insn><dwi>3_doubleword_mask_1"
16658 [(set (match_operand:<DWI> 0 "register_operand")
16660 (match_operand:<DWI> 1 "register_operand")
16662 (match_operand:QI 2 "register_operand" "c")
16663 (match_operand:QI 3 "const_int_operand"))))
16664 (clobber (reg:CC FLAGS_REG))]
16665 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
16666 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
16667 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
16668 && ix86_pre_reload_split ()"
16672 [(set (match_dup 4)
16673 (ior:DWIH (lshiftrt:DWIH (match_dup 4)
16674 (and:QI (match_dup 2) (match_dup 8)))
16676 (ashift:<DWI> (zero_extend:<DWI> (match_dup 7))
16677 (minus:QI (match_dup 9)
16678 (and:QI (match_dup 2) (match_dup 8)))) 0)))
16679 (clobber (reg:CC FLAGS_REG))])
16681 [(set (match_dup 6)
16682 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
16683 (clobber (reg:CC FLAGS_REG))])]
16685 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
16687 emit_insn (gen_<insn><dwi>3_doubleword (operands[0], operands[1],
16692 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
16694 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
16695 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
16697 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
16698 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
16700 rtx tem = gen_reg_rtx (QImode);
16701 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
16705 if (!rtx_equal_p (operands[4], operands[5]))
16706 emit_move_insn (operands[4], operands[5]);
16709 (define_insn_and_split "<insn><mode>3_doubleword"
16710 [(set (match_operand:DWI 0 "register_operand" "=&r,&r")
16711 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0,r")
16712 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
16713 (clobber (reg:CC FLAGS_REG))]
16716 "epilogue_completed"
16720 && !rtx_equal_p (operands[0], operands[1]))
16721 ix86_split_rshift_ndd (<CODE>, operands, NULL_RTX);
16723 ix86_split_<insn> (operands, NULL_RTX, <MODE>mode);
16726 [(set_attr "type" "multi")
16727 (set_attr "isa" "*,apx_ndd")])
16729 ;; By default we don't ask for a scratch register, because when DWImode
16730 ;; values are manipulated, registers are already at a premium. But if
16731 ;; we have one handy, we won't turn it away.
16734 [(match_scratch:DWIH 3 "r")
16735 (parallel [(set (match_operand:<DWI> 0 "register_operand")
16737 (match_operand:<DWI> 1 "register_operand")
16738 (match_operand:QI 2 "nonmemory_operand")))
16739 (clobber (reg:CC FLAGS_REG))])
16745 && !rtx_equal_p (operands[0], operands[1]))
16746 ix86_split_rshift_ndd (<CODE>, operands, operands[3]);
16748 ix86_split_<insn> (operands, operands[3], <DWI>mode);
16752 ;; Split truncations of double word right shifts into x86_shrd_1.
16753 (define_insn_and_split "<insn><dwi>3_doubleword_lowpart_nf"
16754 [(set (match_operand:DWIH 0 "register_operand" "=&r")
16756 (any_shiftrt:<DWI> (match_operand:<DWI> 1 "register_operand" "r")
16757 (match_operand:QI 2 "const_int_operand")) 0))]
16758 "TARGET_APX_NF && UINTVAL (operands[2]) < <MODE_SIZE> * BITS_PER_UNIT"
16760 "&& reload_completed"
16761 [(set (match_dup 0)
16762 (ior:DWIH (lshiftrt:DWIH (match_dup 0) (match_dup 2))
16764 (ashift:<DWI> (zero_extend:<DWI> (match_dup 3))
16765 (match_dup 4)) 0)))]
16767 split_double_mode (<DWI>mode, &operands[1], 1, &operands[1], &operands[3]);
16768 operands[4] = GEN_INT ((<MODE_SIZE> * BITS_PER_UNIT) - INTVAL (operands[2]));
16769 if (!rtx_equal_p (operands[0], operands[1]))
16770 emit_move_insn (operands[0], operands[1]);
16773 (define_insn_and_split "<insn><dwi>3_doubleword_lowpart"
16774 [(set (match_operand:DWIH 0 "register_operand" "=&r")
16776 (any_shiftrt:<DWI> (match_operand:<DWI> 1 "register_operand" "r")
16777 (match_operand:QI 2 "const_int_operand")) 0))
16778 (clobber (reg:CC FLAGS_REG))]
16779 "UINTVAL (operands[2]) < <MODE_SIZE> * BITS_PER_UNIT"
16781 "&& reload_completed"
16783 [(set (match_dup 0)
16784 (ior:DWIH (lshiftrt:DWIH (match_dup 0) (match_dup 2))
16786 (ashift:<DWI> (zero_extend:<DWI> (match_dup 3))
16787 (match_dup 4)) 0)))
16788 (clobber (reg:CC FLAGS_REG))])]
16790 split_double_mode (<DWI>mode, &operands[1], 1, &operands[1], &operands[3]);
16791 operands[4] = GEN_INT ((<MODE_SIZE> * BITS_PER_UNIT) - INTVAL (operands[2]));
16792 if (!rtx_equal_p (operands[0], operands[1]))
16793 emit_move_insn (operands[0], operands[1]);
16795 [(set_attr "has_nf" "1")])
16797 (define_insn "x86_64_shrd<nf_name>"
16798 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
16799 (ior:DI (lshiftrt:DI (match_dup 0)
16800 (and:QI (match_operand:QI 2 "nonmemory_operand" "Jc")
16805 (match_operand:DI 1 "register_operand" "r"))
16806 (minus:QI (const_int 64)
16807 (and:QI (match_dup 2) (const_int 63)))) 0)))]
16808 "TARGET_64BIT && <nf_condition>"
16809 "<nf_prefix>shrd{q}\t{%2, %1, %0|%0, %1, %2}"
16810 [(set_attr "type" "ishift")
16811 (set_attr "prefix_0f" "1")
16812 (set_attr "has_nf" "1")
16813 (set_attr "mode" "DI")
16814 (set_attr "athlon_decode" "vector")
16815 (set_attr "amdfam10_decode" "vector")
16816 (set_attr "bdver1_decode" "vector")])
16818 (define_insn "x86_64_shrd_ndd<nf_name>"
16819 [(set (match_operand:DI 0 "register_operand" "=r")
16820 (ior:DI (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "rm")
16821 (and:QI (match_operand:QI 3 "nonmemory_operand" "Jc")
16826 (match_operand:DI 2 "register_operand" "r"))
16827 (minus:QI (const_int 64)
16828 (and:QI (match_dup 3) (const_int 63)))) 0)))]
16829 "TARGET_APX_NDD && <nf_condition>"
16830 "<nf_prefix>shrd{q}\t{%3, %2, %1, %0|%0, %1, %2, %3}"
16831 [(set_attr "type" "ishift")
16832 (set_attr "has_nf" "1")
16833 (set_attr "mode" "DI")])
16835 (define_insn "x86_64_shrd_1<nf_name>"
16836 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
16837 (ior:DI (lshiftrt:DI (match_dup 0)
16838 (match_operand:QI 2 "const_0_to_63_operand"))
16842 (match_operand:DI 1 "register_operand" "r"))
16843 (match_operand:QI 3 "const_0_to_255_operand")) 0)))]
16845 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])
16847 "<nf_prefix>shrd{q}\t{%2, %1, %0|%0, %1, %2}"
16848 [(set_attr "type" "ishift")
16849 (set_attr "prefix_0f" "1")
16850 (set_attr "length_immediate" "1")
16851 (set_attr "has_nf" "1")
16852 (set_attr "mode" "DI")
16853 (set_attr "athlon_decode" "vector")
16854 (set_attr "amdfam10_decode" "vector")
16855 (set_attr "bdver1_decode" "vector")])
16857 (define_insn "x86_64_shrd_ndd_1<nf_name>"
16858 [(set (match_operand:DI 0 "register_operand" "=r")
16859 (ior:DI (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "rm")
16860 (match_operand:QI 3 "const_0_to_63_operand"))
16864 (match_operand:DI 2 "register_operand" "r"))
16865 (match_operand:QI 4 "const_0_to_255_operand")) 0)))]
16867 && INTVAL (operands[4]) == 64 - INTVAL (operands[3])
16869 "<nf_prefix>shrd{q}\t{%3, %2, %1, %0|%0, %1, %2, %3}"
16870 [(set_attr "type" "ishift")
16871 (set_attr "length_immediate" "1")
16872 (set_attr "has_nf" "1")
16873 (set_attr "mode" "DI")])
16875 (define_insn_and_split "*x86_64_shrd_shld_1_nozext_nf"
16876 [(set (match_operand:DI 0 "nonimmediate_operand")
16877 (ior:DI (lshiftrt:DI (match_operand:DI 4 "nonimmediate_operand")
16878 (match_operand:QI 2 "const_0_to_63_operand"))
16880 (match_operand:DI 1 "nonimmediate_operand")
16881 (match_operand:QI 3 "const_0_to_63_operand"))))]
16882 "TARGET_64BIT && TARGET_APX_NF
16883 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])
16884 && ix86_pre_reload_split ()"
16889 if (rtx_equal_p (operands[4], operands[0]))
16891 operands[1] = force_reg (DImode, operands[1]);
16892 emit_insn (gen_x86_64_shrd_1_nf (operands[0], operands[1],
16893 operands[2], operands[3]));
16895 else if (rtx_equal_p (operands[1], operands[0]))
16897 operands[4] = force_reg (DImode, operands[4]);
16898 emit_insn (gen_x86_64_shld_1_nf (operands[0], operands[4],
16899 operands[3], operands[2]));
16901 else if (TARGET_APX_NDD)
16903 rtx tmp = gen_reg_rtx (DImode);
16904 if (MEM_P (operands[4]))
16906 operands[1] = force_reg (DImode, operands[1]);
16907 emit_insn (gen_x86_64_shrd_ndd_1_nf (tmp, operands[4], operands[1],
16908 operands[2], operands[3]));
16910 else if (MEM_P (operands[1]))
16911 emit_insn (gen_x86_64_shld_ndd_1_nf (tmp, operands[1], operands[4],
16912 operands[3], operands[2]));
16914 emit_insn (gen_x86_64_shrd_ndd_1_nf (tmp, operands[4], operands[1],
16915 operands[2], operands[3]));
16916 emit_move_insn (operands[0], tmp);
16920 operands[1] = force_reg (DImode, operands[1]);
16921 rtx tmp = gen_reg_rtx (DImode);
16922 emit_move_insn (tmp, operands[4]);
16923 emit_insn (gen_x86_64_shrd_1_nf (tmp, operands[1],
16924 operands[2], operands[3]));
16925 emit_move_insn (operands[0], tmp);
16930 (define_insn_and_split "*x86_64_shrd_shld_1_nozext"
16931 [(set (match_operand:DI 0 "nonimmediate_operand")
16932 (ior:DI (lshiftrt:DI (match_operand:DI 4 "nonimmediate_operand")
16933 (match_operand:QI 2 "const_0_to_63_operand"))
16935 (match_operand:DI 1 "nonimmediate_operand")
16936 (match_operand:QI 3 "const_0_to_63_operand"))))
16937 (clobber (reg:CC FLAGS_REG))]
16939 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])
16940 && ix86_pre_reload_split ()"
16945 if (rtx_equal_p (operands[4], operands[0]))
16947 operands[1] = force_reg (DImode, operands[1]);
16948 emit_insn (gen_x86_64_shrd_1 (operands[0], operands[1], operands[2], operands[3]));
16950 else if (rtx_equal_p (operands[1], operands[0]))
16952 operands[4] = force_reg (DImode, operands[4]);
16953 emit_insn (gen_x86_64_shld_1 (operands[0], operands[4], operands[3], operands[2]));
16955 else if (TARGET_APX_NDD)
16957 rtx tmp = gen_reg_rtx (DImode);
16958 if (MEM_P (operands[4]))
16960 operands[1] = force_reg (DImode, operands[1]);
16961 emit_insn (gen_x86_64_shrd_ndd_1 (tmp, operands[4], operands[1],
16962 operands[2], operands[3]));
16964 else if (MEM_P (operands[1]))
16965 emit_insn (gen_x86_64_shld_ndd_1 (tmp, operands[1], operands[4],
16966 operands[3], operands[2]));
16968 emit_insn (gen_x86_64_shrd_ndd_1 (tmp, operands[4], operands[1],
16969 operands[2], operands[3]));
16970 emit_move_insn (operands[0], tmp);
16974 operands[1] = force_reg (DImode, operands[1]);
16975 rtx tmp = gen_reg_rtx (DImode);
16976 emit_move_insn (tmp, operands[4]);
16977 emit_insn (gen_x86_64_shrd_1 (tmp, operands[1], operands[2], operands[3]));
16978 emit_move_insn (operands[0], tmp);
16982 [(set_attr "has_nf" "1")])
16984 (define_insn_and_split "*x86_64_shrd_2"
16985 [(set (match_operand:DI 0 "nonimmediate_operand")
16986 (ior:DI (lshiftrt:DI (match_dup 0)
16987 (match_operand:QI 2 "nonmemory_operand"))
16988 (ashift:DI (match_operand:DI 1 "register_operand")
16989 (minus:QI (const_int 64) (match_dup 2)))))
16990 (clobber (reg:CC FLAGS_REG))]
16991 "TARGET_64BIT && ix86_pre_reload_split ()"
16994 [(parallel [(set (match_dup 0)
16995 (ior:DI (lshiftrt:DI (match_dup 0)
16996 (and:QI (match_dup 2) (const_int 63)))
16999 (zero_extend:TI (match_dup 1))
17000 (minus:QI (const_int 64)
17001 (and:QI (match_dup 2)
17002 (const_int 63)))) 0)))
17003 (clobber (reg:CC FLAGS_REG))])])
17005 (define_insn_and_split "*x86_64_shrd_ndd_2"
17006 [(set (match_operand:DI 0 "nonimmediate_operand")
17007 (ior:DI (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand")
17008 (match_operand:QI 3 "nonmemory_operand"))
17009 (ashift:DI (match_operand:DI 2 "register_operand")
17010 (minus:QI (const_int 64) (match_dup 2)))))
17011 (clobber (reg:CC FLAGS_REG))]
17013 && ix86_pre_reload_split ()"
17016 [(parallel [(set (match_dup 4)
17017 (ior:DI (lshiftrt:DI (match_dup 1)
17018 (and:QI (match_dup 3) (const_int 63)))
17021 (zero_extend:TI (match_dup 2))
17022 (minus:QI (const_int 64)
17023 (and:QI (match_dup 3)
17024 (const_int 63)))) 0)))
17025 (clobber (reg:CC FLAGS_REG))
17026 (set (match_dup 0) (match_dup 4))])]
17028 operands[4] = gen_reg_rtx (DImode);
17029 emit_move_insn (operands[4], operands[0]);
17032 (define_insn "x86_shrd<nf_name>"
17033 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
17034 (ior:SI (lshiftrt:SI (match_dup 0)
17035 (and:QI (match_operand:QI 2 "nonmemory_operand" "Ic")
17040 (match_operand:SI 1 "register_operand" "r"))
17041 (minus:QI (const_int 32)
17042 (and:QI (match_dup 2) (const_int 31)))) 0)))]
17044 "<nf_prefix>shrd{l}\t{%2, %1, %0|%0, %1, %2}"
17045 [(set_attr "type" "ishift")
17046 (set_attr "prefix_0f" "1")
17047 (set_attr "has_nf" "1")
17048 (set_attr "mode" "SI")
17049 (set_attr "pent_pair" "np")
17050 (set_attr "athlon_decode" "vector")
17051 (set_attr "amdfam10_decode" "vector")
17052 (set_attr "bdver1_decode" "vector")])
17054 (define_insn "x86_shrd_ndd<nf_name>"
17055 [(set (match_operand:SI 0 "register_operand" "=r")
17056 (ior:SI (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
17057 (and:QI (match_operand:QI 3 "nonmemory_operand" "Ic")
17062 (match_operand:SI 2 "register_operand" "r"))
17063 (minus:QI (const_int 32)
17064 (and:QI (match_dup 3) (const_int 31)))) 0)))]
17065 "TARGET_APX_NDD && <nf_condition>"
17066 "<nf_prefix>shrd{l}\t{%3, %2, %1, %0|%0, %1, %2, %3}"
17067 [(set_attr "type" "ishift")
17068 (set_attr "has_nf" "1")
17069 (set_attr "mode" "SI")])
17071 (define_insn "x86_shrd_1<nf_name>"
17072 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
17073 (ior:SI (lshiftrt:SI (match_dup 0)
17074 (match_operand:QI 2 "const_0_to_31_operand"))
17078 (match_operand:SI 1 "register_operand" "r"))
17079 (match_operand:QI 3 "const_0_to_63_operand")) 0)))]
17080 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])
17082 "<nf_prefix>shrd{l}\t{%2, %1, %0|%0, %1, %2}"
17083 [(set_attr "type" "ishift")
17084 (set_attr "prefix_0f" "1")
17085 (set_attr "length_immediate" "1")
17086 (set_attr "has_nf" "1")
17087 (set_attr "mode" "SI")
17088 (set_attr "pent_pair" "np")
17089 (set_attr "athlon_decode" "vector")
17090 (set_attr "amdfam10_decode" "vector")
17091 (set_attr "bdver1_decode" "vector")])
17093 (define_insn "x86_shrd_ndd_1<nf_name>"
17094 [(set (match_operand:SI 0 "register_operand" "=r")
17095 (ior:SI (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
17096 (match_operand:QI 3 "const_0_to_31_operand"))
17100 (match_operand:SI 2 "register_operand" "r"))
17101 (match_operand:QI 4 "const_0_to_63_operand")) 0)))]
17103 && (INTVAL (operands[4]) == 32 - INTVAL (operands[3]))
17105 "<nf_prefix>shrd{l}\t{%3, %2, %1, %0|%0, %1, %2, %3}"
17106 [(set_attr "type" "ishift")
17107 (set_attr "length_immediate" "1")
17108 (set_attr "has_nf" "1")
17109 (set_attr "mode" "SI")])
17111 (define_insn_and_split "*x86_shrd_shld_1_nozext_nf"
17112 [(set (match_operand:SI 0 "nonimmediate_operand")
17113 (ior:SI (lshiftrt:SI (match_operand:SI 4 "nonimmediate_operand")
17114 (match_operand:QI 2 "const_0_to_31_operand"))
17116 (match_operand:SI 1 "nonimmediate_operand")
17117 (match_operand:QI 3 "const_0_to_31_operand"))))]
17119 && INTVAL (operands[3]) == 32 - INTVAL (operands[2])
17120 && ix86_pre_reload_split ()"
17125 if (rtx_equal_p (operands[4], operands[0]))
17127 operands[1] = force_reg (SImode, operands[1]);
17128 emit_insn (gen_x86_shrd_1_nf (operands[0], operands[1],
17129 operands[2], operands[3]));
17131 else if (rtx_equal_p (operands[1], operands[0]))
17133 operands[4] = force_reg (SImode, operands[4]);
17134 emit_insn (gen_x86_shld_1_nf (operands[0], operands[4],
17135 operands[3], operands[2]));
17137 else if (TARGET_APX_NDD)
17139 rtx tmp = gen_reg_rtx (SImode);
17140 if (MEM_P (operands[4]))
17142 operands[1] = force_reg (SImode, operands[1]);
17143 emit_insn (gen_x86_shrd_ndd_1_nf (tmp, operands[4], operands[1],
17144 operands[2], operands[3]));
17146 else if (MEM_P (operands[1]))
17147 emit_insn (gen_x86_shld_ndd_1_nf (tmp, operands[1], operands[4],
17148 operands[3], operands[2]));
17150 emit_insn (gen_x86_shrd_ndd_1_nf (tmp, operands[4], operands[1],
17151 operands[2], operands[3]));
17152 emit_move_insn (operands[0], tmp);
17156 operands[1] = force_reg (SImode, operands[1]);
17157 rtx tmp = gen_reg_rtx (SImode);
17158 emit_move_insn (tmp, operands[4]);
17159 emit_insn (gen_x86_shrd_1_nf (tmp, operands[1], operands[2],
17161 emit_move_insn (operands[0], tmp);
17166 (define_insn_and_split "*x86_shrd_shld_1_nozext"
17167 [(set (match_operand:SI 0 "nonimmediate_operand")
17168 (ior:SI (lshiftrt:SI (match_operand:SI 4 "nonimmediate_operand")
17169 (match_operand:QI 2 "const_0_to_31_operand"))
17171 (match_operand:SI 1 "nonimmediate_operand")
17172 (match_operand:QI 3 "const_0_to_31_operand"))))
17173 (clobber (reg:CC FLAGS_REG))]
17174 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])
17175 && ix86_pre_reload_split ()"
17180 if (rtx_equal_p (operands[4], operands[0]))
17182 operands[1] = force_reg (SImode, operands[1]);
17183 emit_insn (gen_x86_shrd_1 (operands[0], operands[1], operands[2], operands[3]));
17185 else if (rtx_equal_p (operands[1], operands[0]))
17187 operands[4] = force_reg (SImode, operands[4]);
17188 emit_insn (gen_x86_shld_1 (operands[0], operands[4], operands[3], operands[2]));
17190 else if (TARGET_APX_NDD)
17192 rtx tmp = gen_reg_rtx (SImode);
17193 if (MEM_P (operands[4]))
17195 operands[1] = force_reg (SImode, operands[1]);
17196 emit_insn (gen_x86_shrd_ndd_1 (tmp, operands[4], operands[1],
17197 operands[2], operands[3]));
17199 else if (MEM_P (operands[1]))
17200 emit_insn (gen_x86_shld_ndd_1 (tmp, operands[1], operands[4],
17201 operands[3], operands[2]));
17203 emit_insn (gen_x86_shrd_ndd_1 (tmp, operands[4], operands[1],
17204 operands[2], operands[3]));
17205 emit_move_insn (operands[0], tmp);
17209 operands[1] = force_reg (SImode, operands[1]);
17210 rtx tmp = gen_reg_rtx (SImode);
17211 emit_move_insn (tmp, operands[4]);
17212 emit_insn (gen_x86_shrd_1 (tmp, operands[1], operands[2], operands[3]));
17213 emit_move_insn (operands[0], tmp);
17217 [(set_attr "has_nf" "1")])
17219 (define_insn_and_split "*x86_shrd_2"
17220 [(set (match_operand:SI 0 "nonimmediate_operand")
17221 (ior:SI (lshiftrt:SI (match_dup 0)
17222 (match_operand:QI 2 "nonmemory_operand"))
17223 (ashift:SI (match_operand:SI 1 "register_operand")
17224 (minus:QI (const_int 32) (match_dup 2)))))
17225 (clobber (reg:CC FLAGS_REG))]
17226 "TARGET_64BIT && ix86_pre_reload_split ()"
17229 [(parallel [(set (match_dup 0)
17230 (ior:SI (lshiftrt:SI (match_dup 0)
17231 (and:QI (match_dup 2) (const_int 31)))
17234 (zero_extend:DI (match_dup 1))
17235 (minus:QI (const_int 32)
17236 (and:QI (match_dup 2)
17237 (const_int 31)))) 0)))
17238 (clobber (reg:CC FLAGS_REG))])])
17240 (define_insn_and_split "*x86_shrd_ndd_2"
17241 [(set (match_operand:SI 0 "nonimmediate_operand")
17242 (ior:SI (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
17243 (match_operand:QI 3 "nonmemory_operand"))
17244 (ashift:SI (match_operand:SI 2 "register_operand")
17245 (minus:QI (const_int 32) (match_dup 3)))))
17246 (clobber (reg:CC FLAGS_REG))]
17248 && ix86_pre_reload_split ()"
17251 [(parallel [(set (match_dup 4)
17252 (ior:SI (lshiftrt:SI (match_dup 1)
17253 (and:QI (match_dup 3) (const_int 31)))
17256 (zero_extend:DI (match_dup 2))
17257 (minus:QI (const_int 32)
17258 (and:QI (match_dup 3)
17259 (const_int 31)))) 0)))
17260 (clobber (reg:CC FLAGS_REG))
17261 (set (match_dup 0) (match_dup 4))])]
17263 operands[4] = gen_reg_rtx (SImode);
17264 emit_move_insn (operands[4], operands[0]);
17267 ;; Base name for insn mnemonic.
17268 (define_mode_attr cvt_mnemonic
17269 [(SI "{cltd|cdq}") (DI "{cqto|cqo}")])
17271 (define_insn "ashr<mode>3_cvt<nf_name>"
17272 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=*d,rm,r")
17274 (match_operand:SWI48 1 "nonimmediate_operand" "*a,0,rm")
17275 (match_operand:QI 2 "const_int_operand")))]
17276 "INTVAL (operands[2]) == GET_MODE_BITSIZE (<MODE>mode)-1
17277 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
17278 && ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands, TARGET_APX_NDD)
17282 <nf_prefix>sar{<imodesuffix>}\t{%2, %0|%0, %2}
17283 <nf_prefix>sar{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
17284 [(set_attr "isa" "*,*,apx_ndd")
17285 (set_attr "type" "imovx,ishift,ishift")
17286 (set_attr "prefix_0f" "0,*,*")
17287 (set_attr "length_immediate" "0,*,*")
17288 (set_attr "modrm" "0,1,1")
17289 (set_attr "has_nf" "1")
17290 (set_attr "mode" "<MODE>")])
17292 (define_insn "*ashrsi3_cvt_zext"
17293 [(set (match_operand:DI 0 "register_operand" "=*d,r,r")
17295 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0,rm")
17296 (match_operand:QI 2 "const_int_operand"))))
17297 (clobber (reg:CC FLAGS_REG))]
17298 "TARGET_64BIT && INTVAL (operands[2]) == 31
17299 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
17300 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands, TARGET_APX_NDD)"
17303 sar{l}\t{%2, %k0|%k0, %2}
17304 sar{l}\t{%2, %1, %k0|%k0, %1, %2}"
17305 [(set_attr "isa" "*,*,apx_ndd")
17306 (set_attr "type" "imovx,ishift,ishift")
17307 (set_attr "prefix_0f" "0,*,*")
17308 (set_attr "length_immediate" "0,*,*")
17309 (set_attr "modrm" "0,1,1")
17310 (set_attr "mode" "SI")])
17312 (define_expand "@x86_shift<mode>_adj_3"
17313 [(use (match_operand:SWI48 0 "register_operand"))
17314 (use (match_operand:SWI48 1 "register_operand"))
17315 (use (match_operand:QI 2 "register_operand"))]
17318 rtx_code_label *label = gen_label_rtx ();
17321 emit_insn (gen_testqi_ccz_1 (operands[2],
17322 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
17324 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
17325 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
17326 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
17327 gen_rtx_LABEL_REF (VOIDmode, label),
17329 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
17330 JUMP_LABEL (tmp) = label;
17332 emit_move_insn (operands[0], operands[1]);
17333 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
17334 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
17335 emit_label (label);
17336 LABEL_NUSES (label) = 1;
17341 (define_insn "*bmi2_<insn><mode>3_1"
17342 [(set (match_operand:SWI48 0 "register_operand" "=r")
17343 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
17344 (match_operand:SWI48 2 "register_operand" "r")))]
17346 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
17347 [(set_attr "type" "ishiftx")
17348 (set_attr "mode" "<MODE>")])
17350 (define_insn "*ashr<mode>3_1<nf_name>"
17351 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
17353 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm,rm")
17354 (match_operand:QI 2 "nonmemory_operand" "c<S>,r,c<S>")))]
17355 "ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands, TARGET_APX_NDD)
17358 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
17359 switch (get_attr_type (insn))
17365 if (operands[2] == const1_rtx
17366 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
17367 && !use_ndd && !<nf_applied>)
17368 return "sar{<imodesuffix>}\t%0";
17370 return use_ndd ? "<nf_prefix>sar{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
17371 : "<nf_prefix>sar{<imodesuffix>}\t{%2, %0|%0, %2}";
17374 [(set_attr "isa" "*,bmi2,apx_ndd")
17375 (set_attr "type" "ishift,ishiftx,ishift")
17376 (set (attr "length_immediate")
17378 (and (match_operand 2 "const1_operand")
17379 (ior (match_test "TARGET_SHIFT1")
17380 (match_test "optimize_function_for_size_p (cfun)")))
17382 (const_string "*")))
17383 (set_attr "has_nf" "1")
17384 (set_attr "mode" "<MODE>")])
17386 ;; Specialization of *lshr<mode>3_1 below, extracting the SImode
17387 ;; highpart of a DI to be extracted, but allowing it to be clobbered.
17388 (define_insn_and_split "*highpartdisi2"
17389 [(set (subreg:DI (match_operand:SI 0 "register_operand" "=r,x,?k,r") 0)
17390 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0,k,rm")
17392 (clobber (reg:CC FLAGS_REG))]
17395 "&& reload_completed"
17397 [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 32)))
17398 (clobber (reg:CC FLAGS_REG))])]
17400 if (SSE_REG_P (operands[0]))
17402 rtx tmp = gen_rtx_REG (V4SImode, REGNO (operands[0]));
17403 emit_insn (gen_sse_shufps_v4si (tmp, tmp, tmp,
17404 const1_rtx, const1_rtx,
17405 GEN_INT (5), GEN_INT (5)));
17408 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
17410 [(set_attr "isa" "*,*,*,apx_ndd")])
17412 (define_insn "*lshr<mode>3_1<nf_name>"
17413 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,?k,r")
17415 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm,k,rm")
17416 (match_operand:QI 2 "nonmemory_operand" "c<S>,r,<KS>,c<S>")))]
17417 "ix86_binary_operator_ok (LSHIFTRT, <MODE>mode, operands, TARGET_APX_NDD)
17420 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
17421 switch (get_attr_type (insn))
17428 if (operands[2] == const1_rtx
17429 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
17430 && !use_ndd && !<nf_applied>)
17431 return "shr{<imodesuffix>}\t%0";
17433 return use_ndd ? "<nf_prefix>shr{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
17434 : "<nf_prefix>shr{<imodesuffix>}\t{%2, %0|%0, %2}";
17437 [(set_attr "isa" "*,bmi2,avx512bw,apx_ndd")
17438 (set_attr "type" "ishift,ishiftx,msklog,ishift")
17439 (set (attr "length_immediate")
17441 (and (and (match_operand 2 "const1_operand")
17442 (eq_attr "alternative" "0"))
17443 (ior (match_test "TARGET_SHIFT1")
17444 (match_test "optimize_function_for_size_p (cfun)")))
17446 (const_string "*")))
17447 (set_attr "has_nf" "1")
17448 (set_attr "mode" "<MODE>")])
17450 ;; Convert shift to the shiftx pattern to avoid flags dependency.
17451 ;; For NF/NDD doesn't support shift count as r, it just support c<S>,
17452 ;; and it has no flag.
17454 [(set (match_operand:SWI48 0 "register_operand")
17455 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17456 (match_operand:QI 2 "register_operand")))]
17457 "TARGET_BMI2 && reload_completed"
17458 [(set (match_dup 0)
17459 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
17460 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
17463 [(set (match_operand:SWI48 0 "register_operand")
17464 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17465 (match_operand:QI 2 "register_operand")))
17466 (clobber (reg:CC FLAGS_REG))]
17467 "TARGET_BMI2 && reload_completed"
17468 [(set (match_dup 0)
17469 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
17470 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
17472 (define_insn "*bmi2_<insn>si3_1_zext"
17473 [(set (match_operand:DI 0 "register_operand" "=r")
17475 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
17476 (match_operand:SI 2 "register_operand" "r"))))]
17477 "TARGET_64BIT && TARGET_BMI2"
17478 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
17479 [(set_attr "type" "ishiftx")
17480 (set_attr "mode" "SI")])
17482 (define_insn "*<insn>qi3_1_zext<mode><nf_name>"
17483 [(set (match_operand:SWI248x 0 "register_operand" "=r")
17484 (zero_extend:SWI248x
17485 (any_shiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "rm")
17486 (match_operand:QI 2 "nonmemory_operand" "cI"))))]
17487 "TARGET_APX_NDD && <nf_condition>"
17488 "<nf_prefix><shift>{b}\t{%2, %1, %b0|%b0, %1, %2}"
17489 [(set_attr "type" "ishift")
17490 (set_attr "has_nf" "1")
17491 (set_attr "mode" "QI")])
17493 (define_insn "*<insn>hi3_1_zext<mode><nf_name>"
17494 [(set (match_operand:SWI48x 0 "register_operand" "=r")
17495 (zero_extend:SWI48x
17496 (any_shiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "rm")
17497 (match_operand:QI 2 "nonmemory_operand" "cI"))))]
17498 "TARGET_APX_NDD && <nf_condition>"
17499 "<nf_prefix><shift>{w}\t{%2, %1, %w0|%w0, %1, %2}"
17500 [(set_attr "type" "ishift")
17501 (set_attr "has_nf" "1")
17502 (set_attr "mode" "HI")])
17504 (define_insn "*<insn>si3_1_zext"
17505 [(set (match_operand:DI 0 "register_operand" "=r,r,r,?k")
17507 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm,rm,k")
17508 (match_operand:QI 2 "nonmemory_operand" "cI,r,cI,I"))))
17509 (clobber (reg:CC FLAGS_REG))]
17511 && ix86_binary_operator_ok (<CODE>, SImode, operands, TARGET_APX_NDD)"
17513 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
17514 switch (get_attr_type (insn))
17522 if (operands[2] == const1_rtx
17523 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
17525 return "<shift>{l}\t%k0";
17527 return use_ndd ? "<shift>{l}\t{%2, %1, %k0|%k0, %1, %2}"
17528 : "<shift>{l}\t{%2, %k0|%k0, %2}";
17531 [(set_attr "isa" "*,bmi2,apx_ndd,avx512bw")
17532 (set_attr "type" "ishift,ishiftx,ishift,msklog")
17533 (set (attr "length_immediate")
17535 (and (match_operand 2 "const1_operand")
17536 (ior (match_test "TARGET_SHIFT1")
17537 (match_test "optimize_function_for_size_p (cfun)")))
17539 (const_string "*")))
17540 (set_attr "mode" "SI")
17541 (set (attr "enabled")
17543 (eq_attr "alternative" "3")
17544 (symbol_ref "<CODE> == LSHIFTRT && TARGET_AVX512BW")
17545 (const_string "*")))])
17547 ;; Convert shift to the shiftx pattern to avoid flags dependency.
17549 [(set (match_operand:DI 0 "register_operand")
17551 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
17552 (match_operand:QI 2 "register_operand"))))
17553 (clobber (reg:CC FLAGS_REG))]
17554 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
17555 [(set (match_dup 0)
17556 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
17557 "operands[2] = gen_lowpart (SImode, operands[2]);")
17559 (define_insn "*ashr<mode>3_1<nf_name>"
17560 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m, r")
17562 (match_operand:SWI12 1 "nonimmediate_operand" "0, rm")
17563 (match_operand:QI 2 "nonmemory_operand" "c<S>, c<S>")))]
17564 "ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands, TARGET_APX_NDD)
17567 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
17568 if (operands[2] == const1_rtx
17569 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
17570 && !use_ndd && !<nf_applied>)
17571 return "sar{<imodesuffix>}\t%0";
17573 return use_ndd ? "<nf_prefix>sar{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
17574 : "<nf_prefix>sar{<imodesuffix>}\t{%2, %0|%0, %2}";
17576 [(set_attr "isa" "*, apx_ndd")
17577 (set_attr "type" "ishift")
17578 (set (attr "length_immediate")
17580 (and (match_operand 2 "const1_operand")
17581 (ior (match_test "TARGET_SHIFT1")
17582 (match_test "optimize_function_for_size_p (cfun)")))
17584 (const_string "*")))
17585 (set_attr "has_nf" "1")
17586 (set_attr "mode" "<MODE>")])
17588 (define_insn "*lshrqi3_1<nf_name>"
17589 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,?k,r")
17591 (match_operand:QI 1 "nonimmediate_operand" "0, k, rm")
17592 (match_operand:QI 2 "nonmemory_operand" "cI,Wb,cI")))]
17593 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands, TARGET_APX_NDD)
17596 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
17597 switch (get_attr_type (insn))
17600 if (operands[2] == const1_rtx
17601 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
17602 && !use_ndd && !<nf_applied>)
17603 return "shr{b}\t%0";
17605 return use_ndd ? "<nf_prefix>shr{b}\t{%2, %1, %0|%0, %1, %2}"
17606 : "<nf_prefix>shr{b}\t{%2, %0|%0, %2}";
17610 gcc_unreachable ();
17613 [(set_attr "isa" "*,avx512dq,apx_ndd")
17614 (set_attr "type" "ishift,msklog,ishift")
17615 (set (attr "length_immediate")
17617 (and (and (match_operand 2 "const1_operand")
17618 (eq_attr "alternative" "0"))
17619 (ior (match_test "TARGET_SHIFT1")
17620 (match_test "optimize_function_for_size_p (cfun)")))
17622 (const_string "*")))
17623 (set_attr "has_nf" "1")
17624 (set_attr "mode" "QI")])
17626 (define_insn "*lshrhi3_1<nf_name>"
17627 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm, ?k, r")
17629 (match_operand:HI 1 "nonimmediate_operand" "0, k, rm")
17630 (match_operand:QI 2 "nonmemory_operand" "cI, Ww, cI")))]
17631 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands, TARGET_APX_NDD)
17634 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
17635 switch (get_attr_type (insn))
17638 if (operands[2] == const1_rtx
17639 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
17640 && !use_ndd && !<nf_applied>)
17641 return "shr{w}\t%0";
17643 return use_ndd ? "<nf_prefix>shr{w}\t{%2, %1, %0|%0, %1, %2}"
17644 : "<nf_prefix>shr{w}\t{%2, %0|%0, %2}";
17648 gcc_unreachable ();
17651 [(set_attr "isa" "*, avx512f, apx_ndd")
17652 (set_attr "type" "ishift,msklog,ishift")
17653 (set (attr "length_immediate")
17655 (and (and (match_operand 2 "const1_operand")
17656 (eq_attr "alternative" "0"))
17657 (ior (match_test "TARGET_SHIFT1")
17658 (match_test "optimize_function_for_size_p (cfun)")))
17660 (const_string "*")))
17661 (set_attr "has_nf" "1")
17662 (set_attr "mode" "HI")])
17664 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
17665 (define_insn_and_split "*<insn><mode>3_1_slp"
17666 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
17667 (any_shiftrt:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
17668 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
17669 (clobber (reg:CC FLAGS_REG))]
17670 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
17672 if (which_alternative)
17675 if (operands[2] == const1_rtx
17676 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
17677 return "<shift>{<imodesuffix>}\t%0";
17679 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
17681 "&& reload_completed
17682 && !(rtx_equal_p (operands[0], operands[1]))"
17683 [(set (strict_low_part (match_dup 0)) (match_dup 1))
17685 [(set (strict_low_part (match_dup 0))
17686 (any_shiftrt:SWI12 (match_dup 0) (match_dup 2)))
17687 (clobber (reg:CC FLAGS_REG))])]
17689 [(set_attr "type" "ishift")
17690 (set (attr "length_immediate")
17692 (and (match_operand 2 "const1_operand")
17693 (ior (match_test "TARGET_SHIFT1")
17694 (match_test "optimize_function_for_size_p (cfun)")))
17696 (const_string "*")))
17697 (set_attr "mode" "<MODE>")])
17699 ;; This pattern can't accept a variable shift count, since shifts by
17700 ;; zero don't affect the flags. We assume that shifts by constant
17701 ;; zero are optimized away.
17702 (define_insn "*<insn><mode>3_cmp"
17703 [(set (reg FLAGS_REG)
17706 (match_operand:SWI 1 "nonimmediate_operand" "0,rm")
17707 (match_operand:QI 2 "<shift_immediate_operand>" "<S>,<S>"))
17709 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,r")
17710 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
17711 "(optimize_function_for_size_p (cfun)
17712 || !TARGET_PARTIAL_FLAG_REG_STALL
17713 || (operands[2] == const1_rtx
17715 && ix86_match_ccmode (insn, CCGOCmode)
17716 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands, TARGET_APX_NDD)"
17718 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
17719 if (operands[2] == const1_rtx
17720 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
17722 return "<shift>{<imodesuffix>}\t%0";
17724 return use_ndd ? "<shift>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
17725 : "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
17727 [(set_attr "isa" "*,apx_ndd")
17728 (set_attr "type" "ishift")
17729 (set (attr "length_immediate")
17731 (and (match_operand 2 "const1_operand")
17732 (ior (match_test "TARGET_SHIFT1")
17733 (match_test "optimize_function_for_size_p (cfun)")))
17735 (const_string "*")))
17736 (set_attr "mode" "<MODE>")])
17738 (define_insn "*<insn>si3_cmp_zext"
17739 [(set (reg FLAGS_REG)
17741 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
17742 (match_operand:QI 2 "const_1_to_31_operand"))
17744 (set (match_operand:DI 0 "register_operand" "=r,r")
17745 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
17747 && (optimize_function_for_size_p (cfun)
17748 || !TARGET_PARTIAL_FLAG_REG_STALL
17749 || (operands[2] == const1_rtx
17751 && ix86_match_ccmode (insn, CCGOCmode)
17752 && ix86_binary_operator_ok (<CODE>, SImode, operands, TARGET_APX_NDD)"
17754 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
17755 if (operands[2] == const1_rtx
17756 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
17758 return "<shift>{l}\t%k0";
17760 return use_ndd ? "<shift>{l}\t{%2, %1, %k0|%k0, %1, %2}"
17761 : "<shift>{l}\t{%2, %k0|%k0, %2}";
17763 [(set_attr "isa" "*,apx_ndd")
17764 (set_attr "type" "ishift")
17765 (set (attr "length_immediate")
17767 (and (match_operand 2 "const1_operand")
17768 (ior (match_test "TARGET_SHIFT1")
17769 (match_test "optimize_function_for_size_p (cfun)")))
17771 (const_string "*")))
17772 (set_attr "mode" "SI")])
17774 (define_insn "*<insn><mode>3_cconly"
17775 [(set (reg FLAGS_REG)
17778 (match_operand:SWI 1 "nonimmediate_operand" "0,rm")
17779 (match_operand:QI 2 "<shift_immediate_operand>" "<S>,<S>"))
17781 (clobber (match_scratch:SWI 0 "=<r>,r"))]
17782 "(optimize_function_for_size_p (cfun)
17783 || !TARGET_PARTIAL_FLAG_REG_STALL
17784 || (operands[2] == const1_rtx
17786 && ix86_match_ccmode (insn, CCGOCmode)"
17788 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
17789 if (operands[2] == const1_rtx
17790 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
17792 return "<shift>{<imodesuffix>}\t%0";
17795 ? "<shift>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
17796 : "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
17798 [(set_attr "isa" "*,apx_ndd")
17799 (set_attr "type" "ishift")
17800 (set (attr "length_immediate")
17802 (and (match_operand 2 "const1_operand")
17803 (ior (match_test "TARGET_SHIFT1")
17804 (match_test "optimize_function_for_size_p (cfun)")))
17806 (const_string "*")))
17807 (set_attr "mode" "<MODE>")])
17809 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
17810 (define_insn_and_split "*<insn>qi_ext<mode>_1"
17811 [(set (zero_extract:SWI248
17812 (match_operand 0 "int248_register_operand" "+Q,&Q")
17818 (match_operator:SWI248 3 "extract_operator"
17819 [(match_operand 1 "int248_register_operand" "0,!Q")
17822 (match_operand:QI 2 "nonmemory_operand" "cI,cI")) 0))
17823 (clobber (reg:CC FLAGS_REG))]
17826 if (which_alternative)
17829 if (operands[2] == const1_rtx
17830 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
17831 return "<shift>{b}\t%h0";
17833 return "<shift>{b}\t{%2, %h0|%h0, %2}";
17836 && !(rtx_equal_p (operands[0], operands[1]))"
17837 [(set (zero_extract:SWI248
17838 (match_dup 0) (const_int 8) (const_int 8))
17839 (zero_extract:SWI248
17840 (match_dup 1) (const_int 8) (const_int 8)))
17842 [(set (zero_extract:SWI248
17843 (match_dup 0) (const_int 8) (const_int 8))
17848 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
17850 (clobber (reg:CC FLAGS_REG))])]
17852 [(set_attr "type" "ishift")
17853 (set (attr "length_immediate")
17855 (and (match_operand 2 "const1_operand")
17856 (ior (match_test "TARGET_SHIFT1")
17857 (match_test "optimize_function_for_size_p (cfun)")))
17859 (const_string "*")))
17860 (set_attr "mode" "QI")])
17862 (define_insn_and_split "*extend<dwi>2_doubleword_highpart"
17863 [(set (match_operand:<DWI> 0 "register_operand" "=r")
17865 (ashift:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")
17866 (match_operand:QI 2 "const_int_operand"))
17867 (match_operand:QI 3 "const_int_operand")))
17868 (clobber (reg:CC FLAGS_REG))]
17869 "INTVAL (operands[2]) == INTVAL (operands[3])
17870 && UINTVAL (operands[2]) < <MODE_SIZE> * BITS_PER_UNIT"
17872 "&& reload_completed"
17873 [(parallel [(set (match_dup 4)
17874 (ashift:DWIH (match_dup 4) (match_dup 2)))
17875 (clobber (reg:CC FLAGS_REG))])
17876 (parallel [(set (match_dup 4)
17877 (ashiftrt:DWIH (match_dup 4) (match_dup 2)))
17878 (clobber (reg:CC FLAGS_REG))])]
17879 "split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[4]);")
17881 (define_insn_and_split "*extendv2di2_highpart_stv"
17882 [(set (match_operand:V2DI 0 "register_operand" "=v")
17884 (ashift:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "vm")
17885 (match_operand:QI 2 "const_int_operand"))
17886 (match_operand:QI 3 "const_int_operand")))]
17887 "!TARGET_64BIT && TARGET_STV && TARGET_AVX512VL
17888 && INTVAL (operands[2]) == INTVAL (operands[3])
17889 && UINTVAL (operands[2]) < 32"
17891 "&& reload_completed"
17892 [(set (match_dup 0)
17893 (ashift:V2DI (match_dup 1) (match_dup 2)))
17895 (ashiftrt:V2DI (match_dup 0) (match_dup 2)))])
17897 ;; Without AVX512VL, split this instruction before reload.
17898 (define_insn_and_split "*extendv2di2_highpart_stv_noavx512vl"
17899 [(set (match_operand:V2DI 0 "register_operand" "=v")
17901 (ashift:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "vm")
17902 (match_operand:QI 2 "const_int_operand"))
17903 (match_operand:QI 3 "const_int_operand")))]
17905 && INTVAL (operands[2]) == INTVAL (operands[3])
17906 && UINTVAL (operands[2]) < 32
17907 && ix86_pre_reload_split ()"
17910 [(set (match_dup 4)
17911 (ashift:V2DI (match_dup 1) (match_dup 2)))
17913 (ashiftrt:V2DI (match_dup 4) (match_dup 2)))]
17917 rtx op0 = operands[0];
17918 rtx op2 = operands[2];
17919 rtx tmp1 = gen_reg_rtx (V4SImode);
17920 rtx tmp2 = gen_reg_rtx (V4SImode);
17921 rtx tmp3 = gen_reg_rtx (V4SImode);
17922 rtx tmp4 = gen_reg_rtx (V4SImode);
17923 emit_move_insn (tmp1, lowpart_subreg (V4SImode, operands[1], V2DImode));
17924 emit_insn (gen_ashlv4si3 (tmp2, tmp1, op2));
17925 emit_insn (gen_ashrv4si3 (tmp3, tmp2, op2));
17926 vec_perm_builder sel (4, 4, 1);
17927 sel.quick_grow (4);
17932 vec_perm_indices indices(sel, 2, 4);
17933 bool ok = targetm.vectorize.vec_perm_const (V4SImode, V4SImode, tmp4,
17934 tmp1, tmp3, indices);
17936 emit_move_insn (op0, lowpart_subreg (V2DImode, tmp4, V4SImode));
17940 operands[4] = gen_reg_rtx (V2DImode);
17943 ;; Rotate instructions
17945 (define_expand "<insn>ti3"
17946 [(set (match_operand:TI 0 "register_operand")
17947 (any_rotate:TI (match_operand:TI 1 "register_operand")
17948 (match_operand:QI 2 "nonmemory_operand")))]
17951 if (const_1_to_63_operand (operands[2], VOIDmode))
17952 emit_insn (gen_ix86_<insn>ti3_doubleword
17953 (operands[0], operands[1], operands[2]));
17954 else if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 64)
17956 operands[1] = force_reg (TImode, operands[1]);
17957 emit_insn (gen_<insn>64ti2_doubleword (operands[0], operands[1]));
17961 rtx amount = force_reg (QImode, operands[2]);
17962 rtx src_lo = gen_lowpart (DImode, operands[1]);
17963 rtx src_hi = gen_highpart (DImode, operands[1]);
17964 rtx tmp_lo = gen_reg_rtx (DImode);
17965 rtx tmp_hi = gen_reg_rtx (DImode);
17966 emit_move_insn (tmp_lo, src_lo);
17967 emit_move_insn (tmp_hi, src_hi);
17968 rtx (*shiftd) (rtx, rtx, rtx)
17969 = (<CODE> == ROTATE) ? gen_x86_64_shld : gen_x86_64_shrd;
17970 emit_insn (shiftd (tmp_lo, src_hi, amount));
17971 emit_insn (shiftd (tmp_hi, src_lo, amount));
17972 rtx dst_lo = gen_lowpart (DImode, operands[0]);
17973 rtx dst_hi = gen_highpart (DImode, operands[0]);
17974 emit_move_insn (dst_lo, tmp_lo);
17975 emit_move_insn (dst_hi, tmp_hi);
17976 emit_insn (gen_x86_shiftdi_adj_1 (dst_lo, dst_hi, amount, tmp_lo));
17981 (define_expand "<insn>di3"
17982 [(set (match_operand:DI 0 "shiftdi_operand")
17983 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
17984 (match_operand:QI 2 "nonmemory_operand")))]
17988 ix86_expand_binary_operator (<CODE>, DImode, operands, TARGET_APX_NDD);
17989 else if (const_1_to_31_operand (operands[2], VOIDmode))
17990 emit_insn (gen_ix86_<insn>di3_doubleword
17991 (operands[0], operands[1], operands[2]));
17992 else if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 32)
17994 operands[1] = force_reg (DImode, operands[1]);
17995 emit_insn (gen_<insn>32di2_doubleword (operands[0], operands[1]));
18003 (define_expand "<insn><mode>3"
18004 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
18005 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
18006 (match_operand:QI 2 "nonmemory_operand")))]
18009 ix86_expand_binary_operator (<CODE>, <MODE>mode, operands, TARGET_APX_NDD);
18013 ;; Avoid useless masking of count operand.
18014 (define_insn_and_split "*<insn><mode>3_mask"
18015 [(set (match_operand:SWI 0 "nonimmediate_operand")
18017 (match_operand:SWI 1 "nonimmediate_operand")
18020 (match_operand 2 "int248_register_operand" "c")
18021 (match_operand 3 "const_int_operand")) 0)))
18022 (clobber (reg:CC FLAGS_REG))]
18023 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
18024 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
18025 == GET_MODE_BITSIZE (<MODE>mode)-1
18026 && ix86_pre_reload_split ()"
18030 [(set (match_dup 0)
18031 (any_rotate:SWI (match_dup 1)
18033 (clobber (reg:CC FLAGS_REG))])]
18035 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
18036 operands[2] = gen_lowpart (QImode, operands[2]);
18040 [(set (match_operand:SWI 0 "register_operand")
18042 (match_operand:SWI 1 "const_int_operand")
18045 (match_operand 2 "int248_register_operand")
18046 (match_operand 3 "const_int_operand")) 0)))]
18047 "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode) - 1))
18048 == GET_MODE_BITSIZE (<MODE>mode) - 1"
18049 [(set (match_dup 4) (match_dup 1))
18051 (any_rotate:SWI (match_dup 4)
18052 (subreg:QI (match_dup 2) 0)))]
18053 "operands[4] = gen_reg_rtx (<MODE>mode);")
18055 (define_insn_and_split "*<insn><mode>3_mask_1"
18056 [(set (match_operand:SWI 0 "nonimmediate_operand")
18058 (match_operand:SWI 1 "nonimmediate_operand")
18060 (match_operand:QI 2 "register_operand" "c")
18061 (match_operand:QI 3 "const_int_operand"))))
18062 (clobber (reg:CC FLAGS_REG))]
18063 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
18064 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
18065 == GET_MODE_BITSIZE (<MODE>mode)-1
18066 && ix86_pre_reload_split ()"
18070 [(set (match_dup 0)
18071 (any_rotate:SWI (match_dup 1)
18073 (clobber (reg:CC FLAGS_REG))])])
18076 [(set (match_operand:SWI 0 "register_operand")
18078 (match_operand:SWI 1 "const_int_operand")
18080 (match_operand:QI 2 "register_operand")
18081 (match_operand:QI 3 "const_int_operand"))))]
18082 "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode) - 1))
18083 == GET_MODE_BITSIZE (<MODE>mode) - 1"
18084 [(set (match_dup 4) (match_dup 1))
18086 (any_rotate:SWI (match_dup 4) (match_dup 2)))]
18087 "operands[4] = gen_reg_rtx (<MODE>mode);")
18089 ;; Implement rotation using two double-precision
18090 ;; shift instructions and a scratch register.
18092 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
18093 [(set (match_operand:<DWI> 0 "register_operand" "=r")
18094 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
18095 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
18096 (clobber (reg:CC FLAGS_REG))
18097 (clobber (match_scratch:DWIH 3 "=&r"))]
18101 [(set (match_dup 3) (match_dup 4))
18103 [(set (match_dup 4)
18104 (ior:DWIH (ashift:DWIH (match_dup 4)
18105 (and:QI (match_dup 2) (match_dup 6)))
18107 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
18108 (minus:QI (match_dup 7)
18109 (and:QI (match_dup 2)
18110 (match_dup 6)))) 0)))
18111 (clobber (reg:CC FLAGS_REG))])
18113 [(set (match_dup 5)
18114 (ior:DWIH (ashift:DWIH (match_dup 5)
18115 (and:QI (match_dup 2) (match_dup 6)))
18117 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 3))
18118 (minus:QI (match_dup 7)
18119 (and:QI (match_dup 2)
18120 (match_dup 6)))) 0)))
18121 (clobber (reg:CC FLAGS_REG))])]
18123 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
18124 operands[7] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
18126 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
18129 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
18130 [(set (match_operand:<DWI> 0 "register_operand" "=r")
18131 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
18132 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
18133 (clobber (reg:CC FLAGS_REG))
18134 (clobber (match_scratch:DWIH 3 "=&r"))]
18138 [(set (match_dup 3) (match_dup 4))
18140 [(set (match_dup 4)
18141 (ior:DWIH (lshiftrt:DWIH (match_dup 4)
18142 (and:QI (match_dup 2) (match_dup 6)))
18144 (ashift:<DWI> (zero_extend:<DWI> (match_dup 5))
18145 (minus:QI (match_dup 7)
18146 (and:QI (match_dup 2)
18147 (match_dup 6)))) 0)))
18148 (clobber (reg:CC FLAGS_REG))])
18150 [(set (match_dup 5)
18151 (ior:DWIH (lshiftrt:DWIH (match_dup 5)
18152 (and:QI (match_dup 2) (match_dup 6)))
18154 (ashift:<DWI> (zero_extend:<DWI> (match_dup 3))
18155 (minus:QI (match_dup 7)
18156 (and:QI (match_dup 2)
18157 (match_dup 6)))) 0)))
18158 (clobber (reg:CC FLAGS_REG))])]
18160 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
18161 operands[7] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
18163 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
18166 (define_insn_and_split "<insn>32di2_doubleword"
18167 [(set (match_operand:DI 0 "register_operand" "=r,r")
18168 (any_rotate:DI (match_operand:DI 1 "register_operand" "0,r")
18172 "&& reload_completed"
18173 [(set (match_dup 0) (match_dup 3))
18174 (set (match_dup 2) (match_dup 1))]
18176 split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);
18177 if (rtx_equal_p (operands[0], operands[1]))
18179 emit_insn (gen_swapsi (operands[0], operands[2]));
18184 (define_insn_and_split "<insn>64ti2_doubleword"
18185 [(set (match_operand:TI 0 "register_operand" "=r,r")
18186 (any_rotate:TI (match_operand:TI 1 "register_operand" "0,r")
18190 "&& reload_completed"
18191 [(set (match_dup 0) (match_dup 3))
18192 (set (match_dup 2) (match_dup 1))]
18194 split_double_mode (TImode, &operands[0], 2, &operands[0], &operands[2]);
18195 if (rtx_equal_p (operands[0], operands[1]))
18197 emit_insn (gen_swapdi (operands[0], operands[2]));
18202 (define_mode_attr rorx_immediate_operand
18203 [(SI "const_0_to_31_operand")
18204 (DI "const_0_to_63_operand")])
18206 (define_insn "*bmi2_rorx<mode>3_1"
18207 [(set (match_operand:SWI48 0 "register_operand" "=r")
18209 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18210 (match_operand:QI 2 "<rorx_immediate_operand>" "<S>")))]
18211 "TARGET_BMI2 && !optimize_function_for_size_p (cfun)"
18212 "rorx\t{%2, %1, %0|%0, %1, %2}"
18213 [(set_attr "type" "rotatex")
18214 (set_attr "mode" "<MODE>")])
18216 (define_insn "*<insn><mode>3_1<nf_name>"
18217 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
18219 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm,rm")
18220 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>,c<S>")))]
18221 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands, TARGET_APX_NDD)
18224 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
18225 switch (get_attr_type (insn))
18228 if (TARGET_APX_NDD && <nf_applied>)
18229 return "%{nf%} <rotate>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}";
18234 if (operands[2] == const1_rtx
18235 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
18236 && !use_ndd && !<nf_applied>)
18237 return "<rotate>{<imodesuffix>}\t%0";
18239 return use_ndd ? "<nf_prefix><rotate>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
18240 : "<nf_prefix><rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
18243 [(set_attr "isa" "*,bmi2,apx_ndd")
18244 (set_attr "type" "rotate,rotatex,rotate")
18245 (set (attr "preferred_for_size")
18246 (cond [(eq_attr "alternative" "0")
18247 (symbol_ref "true")]
18248 (symbol_ref "false")))
18249 (set (attr "length_immediate")
18251 (and (eq_attr "type" "rotate")
18252 (and (match_operand 2 "const1_operand")
18253 (ior (match_test "TARGET_SHIFT1")
18254 (match_test "optimize_function_for_size_p (cfun)"))))
18256 (const_string "*")))
18257 (set_attr "has_nf" "1")
18258 (set_attr "mode" "<MODE>")])
18260 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
18262 [(set (match_operand:SWI48 0 "register_operand")
18263 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
18264 (match_operand:QI 2 "const_int_operand")))
18265 (clobber (reg:CC FLAGS_REG))]
18266 "TARGET_BMI2 && reload_completed && !optimize_function_for_size_p (cfun)"
18267 [(set (match_dup 0)
18268 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
18270 int bitsize = GET_MODE_BITSIZE (<MODE>mode);
18272 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
18276 [(set (match_operand:SWI48 0 "register_operand")
18277 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
18278 (match_operand:QI 2 "const_int_operand")))]
18279 "TARGET_BMI2 && reload_completed && !optimize_function_for_size_p (cfun)
18280 && !TARGET_APX_NDD"
18281 [(set (match_dup 0)
18282 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
18284 int bitsize = GET_MODE_BITSIZE (<MODE>mode);
18286 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
18290 [(set (match_operand:SWI48 0 "register_operand")
18291 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
18292 (match_operand:QI 2 "const_int_operand")))
18293 (clobber (reg:CC FLAGS_REG))]
18294 "TARGET_BMI2 && reload_completed && !optimize_function_for_size_p (cfun)"
18295 [(set (match_dup 0)
18296 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
18298 (define_insn "*bmi2_rorxsi3_1_zext"
18299 [(set (match_operand:DI 0 "register_operand" "=r")
18301 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
18302 (match_operand:QI 2 "const_0_to_31_operand"))))]
18303 "TARGET_64BIT && TARGET_BMI2 && !optimize_function_for_size_p (cfun)"
18304 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
18305 [(set_attr "type" "rotatex")
18306 (set_attr "mode" "SI")])
18308 (define_insn "*<insn>qi3_1_zext<mode><nf_name>"
18309 [(set (match_operand:SWI248x 0 "register_operand" "=r")
18310 (zero_extend:SWI248x
18311 (any_rotate:QI (match_operand:QI 1 "nonimmediate_operand" "rm")
18312 (match_operand:QI 2 "nonmemory_operand" "cI"))))]
18313 "TARGET_APX_NDD && <nf_condition>"
18314 "<nf_prefix><rotate>{b}\t{%2, %1, %b0|%b0, %1, %2}"
18315 [(set_attr "type" "rotate")
18316 (set_attr "has_nf" "1")
18317 (set_attr "mode" "QI")])
18319 (define_insn "*<insn>hi3_1_zext<mode><nf_name>"
18320 [(set (match_operand:SWI48x 0 "register_operand" "=r")
18321 (zero_extend:SWI48x
18322 (any_rotate:HI (match_operand:HI 1 "nonimmediate_operand" "rm")
18323 (match_operand:QI 2 "nonmemory_operand" "cI"))))]
18324 "TARGET_APX_NDD && <nf_condition>"
18325 "<nf_prefix><rotate>{w}\t{%2, %1, %w0|%w0, %1, %2}"
18326 [(set_attr "type" "rotate")
18327 (set_attr "has_nf" "1")
18328 (set_attr "mode" "HI")])
18330 (define_insn "*<insn>si3_1_zext"
18331 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
18333 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm,rm")
18334 (match_operand:QI 2 "nonmemory_operand" "cI,I,cI"))))
18335 (clobber (reg:CC FLAGS_REG))]
18336 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
18338 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
18339 switch (get_attr_type (insn))
18345 if (operands[2] == const1_rtx
18346 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
18348 return "<rotate>{l}\t%k0";
18350 return use_ndd ? "<rotate>{l}\t{%2, %1, %k0|%k0, %1, %2}"
18351 : "<rotate>{l}\t{%2, %k0|%k0, %2}";
18354 [(set_attr "isa" "*,bmi2,apx_ndd")
18355 (set_attr "type" "rotate,rotatex,rotate")
18356 (set (attr "preferred_for_size")
18357 (cond [(eq_attr "alternative" "0")
18358 (symbol_ref "true")]
18359 (symbol_ref "false")))
18360 (set (attr "length_immediate")
18362 (and (eq_attr "type" "rotate")
18363 (and (match_operand 2 "const1_operand")
18364 (ior (match_test "TARGET_SHIFT1")
18365 (match_test "optimize_function_for_size_p (cfun)"))))
18367 (const_string "*")))
18368 (set_attr "mode" "SI")])
18370 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
18372 [(set (match_operand:DI 0 "register_operand")
18374 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
18375 (match_operand:QI 2 "const_int_operand"))))
18376 (clobber (reg:CC FLAGS_REG))]
18377 "TARGET_64BIT && TARGET_BMI2 && reload_completed
18378 && !optimize_function_for_size_p (cfun)"
18379 [(set (match_dup 0)
18380 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
18382 int bitsize = GET_MODE_BITSIZE (SImode);
18384 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
18388 [(set (match_operand:DI 0 "register_operand")
18390 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
18391 (match_operand:QI 2 "const_int_operand"))))
18392 (clobber (reg:CC FLAGS_REG))]
18393 "TARGET_64BIT && TARGET_BMI2 && reload_completed
18394 && !optimize_function_for_size_p (cfun)"
18395 [(set (match_dup 0)
18396 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
18398 (define_insn "*<insn><mode>3_1<nf_name>"
18399 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m,r")
18400 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0,rm")
18401 (match_operand:QI 2 "nonmemory_operand" "c<S>,c<S>")))]
18402 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands, TARGET_APX_NDD)
18405 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
18406 if (operands[2] == const1_rtx
18407 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
18408 && !use_ndd && !<nf_applied>)
18409 return "<rotate>{<imodesuffix>}\t%0";
18412 ? "<nf_prefix><rotate>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
18413 : "<nf_prefix><rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
18415 [(set_attr "isa" "*,apx_ndd")
18416 (set_attr "type" "rotate")
18417 (set (attr "length_immediate")
18419 (and (match_operand 2 "const1_operand")
18420 (ior (match_test "TARGET_SHIFT1")
18421 (match_test "optimize_function_for_size_p (cfun)")))
18423 (const_string "*")))
18424 (set_attr "has_nf" "1")
18425 (set_attr "mode" "<MODE>")])
18427 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
18428 (define_insn_and_split "*<insn><mode>3_1_slp"
18429 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
18430 (any_rotate:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
18431 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
18432 (clobber (reg:CC FLAGS_REG))]
18433 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
18435 if (which_alternative)
18438 if (operands[2] == const1_rtx
18439 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
18440 return "<rotate>{<imodesuffix>}\t%0";
18442 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
18444 "&& reload_completed
18445 && !(rtx_equal_p (operands[0], operands[1]))"
18446 [(set (strict_low_part (match_dup 0)) (match_dup 1))
18448 [(set (strict_low_part (match_dup 0))
18449 (any_rotate:SWI12 (match_dup 0) (match_dup 2)))
18450 (clobber (reg:CC FLAGS_REG))])]
18452 [(set_attr "type" "rotate")
18453 (set (attr "length_immediate")
18455 (and (match_operand 2 "const1_operand")
18456 (ior (match_test "TARGET_SHIFT1")
18457 (match_test "optimize_function_for_size_p (cfun)")))
18459 (const_string "*")))
18460 (set_attr "mode" "<MODE>")])
18463 [(set (match_operand:HI 0 "QIreg_operand")
18464 (any_rotate:HI (match_dup 0) (const_int 8)))
18465 (clobber (reg:CC FLAGS_REG))]
18467 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
18468 [(set (match_dup 0) (bswap:HI (match_dup 0)))])
18470 ;; Rotations through carry flag
18471 (define_insn "rcrsi2"
18472 [(set (match_operand:SI 0 "register_operand" "=r,r")
18474 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
18476 (ashift:SI (ltu:SI (reg:CCC FLAGS_REG) (const_int 0))
18478 (clobber (reg:CC FLAGS_REG))]
18482 rcr{l}\t{%1, %0|%0, %1}"
18483 [(set_attr "isa" "*,apx_ndd")
18484 (set_attr "type" "ishift1")
18485 (set_attr "memory" "none")
18486 (set_attr "length_immediate" "0")
18487 (set_attr "mode" "SI")])
18489 (define_insn "rcrdi2"
18490 [(set (match_operand:DI 0 "register_operand" "=r,r")
18492 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,rm")
18494 (ashift:DI (ltu:DI (reg:CCC FLAGS_REG) (const_int 0))
18496 (clobber (reg:CC FLAGS_REG))]
18500 rcr{q}\t{%1, %0|%0, %1}"
18501 [(set_attr "isa" "*,apx_ndd")
18502 (set_attr "type" "ishift1")
18503 (set_attr "length_immediate" "0")
18504 (set_attr "mode" "DI")])
18506 ;; Versions of sar and shr that set the carry flag.
18507 (define_insn "<insn><mode>3_carry"
18508 [(set (reg:CCC FLAGS_REG)
18509 (unspec:CCC [(and:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
18511 (const_int 0)] UNSPEC_CC_NE))
18512 (set (match_operand:SWI48 0 "register_operand" "=r,r")
18513 (any_shiftrt:SWI48 (match_dup 1) (const_int 1)))]
18516 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
18517 if ((TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
18519 return "<shift>{<imodesuffix>}\t%0";
18520 return use_ndd ? "<shift>{<imodesuffix>}\t{$1, %1, %0|%0, %1, 1}"
18521 : "<shift>{<imodesuffix>}\t{$1, %0|%0, 1}";
18523 [(set_attr "isa" "*, apx_ndd")
18524 (set_attr "type" "ishift1")
18525 (set (attr "length_immediate")
18527 (ior (match_test "TARGET_SHIFT1")
18528 (match_test "optimize_function_for_size_p (cfun)"))
18530 (const_string "*")))
18531 (set_attr "mode" "<MODE>")])
18533 ;; Bit set / bit test instructions
18535 ;; %%% bts, btr, btc
18537 ;; These instructions are *slow* when applied to memory.
18539 (define_code_attr btsc [(ior "bts") (xor "btc")])
18541 (define_insn "*<btsc><mode>"
18542 [(set (match_operand:SWI48 0 "register_operand" "=r")
18544 (ashift:SWI48 (const_int 1)
18545 (match_operand:QI 2 "register_operand" "r"))
18546 (match_operand:SWI48 1 "register_operand" "0")))
18547 (clobber (reg:CC FLAGS_REG))]
18549 "<btsc>{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
18550 [(set_attr "type" "alu1")
18551 (set_attr "prefix_0f" "1")
18552 (set_attr "znver1_decode" "double")
18553 (set_attr "mode" "<MODE>")])
18555 ;; Avoid useless masking of count operand.
18556 (define_insn_and_split "*<btsc><mode>_mask"
18557 [(set (match_operand:SWI48 0 "register_operand")
18563 (match_operand 1 "int248_register_operand")
18564 (match_operand 2 "const_int_operand")) 0))
18565 (match_operand:SWI48 3 "register_operand")))
18566 (clobber (reg:CC FLAGS_REG))]
18568 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
18569 == GET_MODE_BITSIZE (<MODE>mode)-1
18570 && ix86_pre_reload_split ()"
18574 [(set (match_dup 0)
18576 (ashift:SWI48 (const_int 1)
18579 (clobber (reg:CC FLAGS_REG))])]
18581 operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
18582 operands[1] = gen_lowpart (QImode, operands[1]);
18585 (define_insn_and_split "*<btsc><mode>_mask_1"
18586 [(set (match_operand:SWI48 0 "register_operand")
18591 (match_operand:QI 1 "register_operand")
18592 (match_operand:QI 2 "const_int_operand")))
18593 (match_operand:SWI48 3 "register_operand")))
18594 (clobber (reg:CC FLAGS_REG))]
18596 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
18597 == GET_MODE_BITSIZE (<MODE>mode)-1
18598 && ix86_pre_reload_split ()"
18602 [(set (match_dup 0)
18604 (ashift:SWI48 (const_int 1)
18607 (clobber (reg:CC FLAGS_REG))])])
18609 (define_insn "*btr<mode>"
18610 [(set (match_operand:SWI48 0 "register_operand" "=r")
18612 (rotate:SWI48 (const_int -2)
18613 (match_operand:QI 2 "register_operand" "r"))
18614 (match_operand:SWI48 1 "register_operand" "0")))
18615 (clobber (reg:CC FLAGS_REG))]
18617 "btr{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
18618 [(set_attr "type" "alu1")
18619 (set_attr "prefix_0f" "1")
18620 (set_attr "znver1_decode" "double")
18621 (set_attr "mode" "<MODE>")])
18623 ;; Avoid useless masking of count operand.
18624 (define_insn_and_split "*btr<mode>_mask"
18625 [(set (match_operand:SWI48 0 "register_operand")
18631 (match_operand 1 "int248_register_operand")
18632 (match_operand 2 "const_int_operand")) 0))
18633 (match_operand:SWI48 3 "register_operand")))
18634 (clobber (reg:CC FLAGS_REG))]
18636 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
18637 == GET_MODE_BITSIZE (<MODE>mode)-1
18638 && ix86_pre_reload_split ()"
18642 [(set (match_dup 0)
18644 (rotate:SWI48 (const_int -2)
18647 (clobber (reg:CC FLAGS_REG))])]
18649 operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
18650 operands[1] = gen_lowpart (QImode, operands[1]);
18653 (define_insn_and_split "*btr<mode>_mask_1"
18654 [(set (match_operand:SWI48 0 "register_operand")
18659 (match_operand:QI 1 "register_operand")
18660 (match_operand:QI 2 "const_int_operand")))
18661 (match_operand:SWI48 3 "register_operand")))
18662 (clobber (reg:CC FLAGS_REG))]
18664 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
18665 == GET_MODE_BITSIZE (<MODE>mode)-1
18666 && ix86_pre_reload_split ()"
18670 [(set (match_dup 0)
18672 (rotate:SWI48 (const_int -2)
18675 (clobber (reg:CC FLAGS_REG))])])
18677 (define_insn_and_split "*btr<mode>_1"
18678 [(set (match_operand:SWI12 0 "register_operand")
18681 (rotate:SI (const_int -2)
18682 (match_operand:QI 2 "register_operand")) 0)
18683 (match_operand:SWI12 1 "nonimmediate_operand")))
18684 (clobber (reg:CC FLAGS_REG))]
18685 "TARGET_USE_BT && ix86_pre_reload_split ()"
18689 [(set (match_dup 0)
18690 (and:SI (rotate:SI (const_int -2) (match_dup 2))
18692 (clobber (reg:CC FLAGS_REG))])]
18694 operands[0] = lowpart_subreg (SImode, operands[0], <MODE>mode);
18695 operands[1] = force_reg (<MODE>mode, operands[1]);
18696 operands[1] = lowpart_subreg (SImode, operands[1], <MODE>mode);
18699 (define_insn_and_split "*btr<mode>_2"
18700 [(set (zero_extract:HI
18701 (match_operand:SWI12 0 "nonimmediate_operand")
18703 (match_operand:QI 1 "register_operand"))
18705 (clobber (reg:CC FLAGS_REG))]
18706 "TARGET_USE_BT && ix86_pre_reload_split ()"
18708 "&& MEM_P (operands[0])"
18709 [(set (match_dup 2) (match_dup 0))
18711 [(set (match_dup 3)
18712 (and:SI (rotate:SI (const_int -2) (match_dup 1))
18714 (clobber (reg:CC FLAGS_REG))])
18715 (set (match_dup 0) (match_dup 5))]
18717 operands[2] = gen_reg_rtx (<MODE>mode);
18718 operands[5] = gen_reg_rtx (<MODE>mode);
18719 operands[3] = lowpart_subreg (SImode, operands[5], <MODE>mode);
18720 operands[4] = lowpart_subreg (SImode, operands[2], <MODE>mode);
18724 [(set (zero_extract:HI
18725 (match_operand:SWI12 0 "register_operand")
18727 (match_operand:QI 1 "register_operand"))
18729 (clobber (reg:CC FLAGS_REG))]
18730 "TARGET_USE_BT && ix86_pre_reload_split ()"
18732 [(set (match_dup 0)
18733 (and:SI (rotate:SI (const_int -2) (match_dup 1))
18735 (clobber (reg:CC FLAGS_REG))])]
18737 operands[2] = lowpart_subreg (SImode, operands[0], <MODE>mode);
18738 operands[0] = lowpart_subreg (SImode, operands[0], <MODE>mode);
18741 ;; These instructions are never faster than the corresponding
18742 ;; and/ior/xor operations when using immediate operand, so with
18743 ;; 32-bit there's no point. But in 64-bit, we can't hold the
18744 ;; relevant immediates within the instruction itself, so operating
18745 ;; on bits in the high 32-bits of a register becomes easier.
18747 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
18748 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
18749 ;; negdf respectively, so they can never be disabled entirely.
18751 (define_insn "*btsq_imm"
18752 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
18754 (match_operand:QI 1 "const_0_to_63_operand"))
18756 (clobber (reg:CC FLAGS_REG))]
18757 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
18758 "bts{q}\t{%1, %0|%0, %1}"
18759 [(set_attr "type" "alu1")
18760 (set_attr "prefix_0f" "1")
18761 (set_attr "znver1_decode" "double")
18762 (set_attr "mode" "DI")])
18764 (define_insn "*btrq_imm"
18765 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
18767 (match_operand:QI 1 "const_0_to_63_operand"))
18769 (clobber (reg:CC FLAGS_REG))]
18770 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
18771 "btr{q}\t{%1, %0|%0, %1}"
18772 [(set_attr "type" "alu1")
18773 (set_attr "prefix_0f" "1")
18774 (set_attr "znver1_decode" "double")
18775 (set_attr "mode" "DI")])
18777 (define_insn "*btcq_imm"
18778 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
18780 (match_operand:QI 1 "const_0_to_63_operand"))
18781 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
18782 (clobber (reg:CC FLAGS_REG))]
18783 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
18784 "btc{q}\t{%1, %0|%0, %1}"
18785 [(set_attr "type" "alu1")
18786 (set_attr "prefix_0f" "1")
18787 (set_attr "znver1_decode" "double")
18788 (set_attr "mode" "DI")])
18790 ;; Allow Nocona to avoid these instructions if a register is available.
18793 [(match_scratch:DI 2 "r")
18794 (parallel [(set (zero_extract:DI
18795 (match_operand:DI 0 "nonimmediate_operand")
18797 (match_operand:QI 1 "const_0_to_63_operand"))
18799 (clobber (reg:CC FLAGS_REG))])]
18800 "TARGET_64BIT && !TARGET_USE_BT"
18801 [(parallel [(set (match_dup 0)
18802 (ior:DI (match_dup 0) (match_dup 3)))
18803 (clobber (reg:CC FLAGS_REG))])]
18805 int i = INTVAL (operands[1]);
18807 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
18809 if (!x86_64_immediate_operand (operands[3], DImode))
18811 emit_move_insn (operands[2], operands[3]);
18812 operands[3] = operands[2];
18817 [(match_scratch:DI 2 "r")
18818 (parallel [(set (zero_extract:DI
18819 (match_operand:DI 0 "nonimmediate_operand")
18821 (match_operand:QI 1 "const_0_to_63_operand"))
18823 (clobber (reg:CC FLAGS_REG))])]
18824 "TARGET_64BIT && !TARGET_USE_BT"
18825 [(parallel [(set (match_dup 0)
18826 (and:DI (match_dup 0) (match_dup 3)))
18827 (clobber (reg:CC FLAGS_REG))])]
18829 int i = INTVAL (operands[1]);
18831 operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
18833 if (!x86_64_immediate_operand (operands[3], DImode))
18835 emit_move_insn (operands[2], operands[3]);
18836 operands[3] = operands[2];
18841 [(match_scratch:DI 2 "r")
18842 (parallel [(set (zero_extract:DI
18843 (match_operand:DI 0 "nonimmediate_operand")
18845 (match_operand:QI 1 "const_0_to_63_operand"))
18846 (not:DI (zero_extract:DI
18847 (match_dup 0) (const_int 1) (match_dup 1))))
18848 (clobber (reg:CC FLAGS_REG))])]
18849 "TARGET_64BIT && !TARGET_USE_BT"
18850 [(parallel [(set (match_dup 0)
18851 (xor:DI (match_dup 0) (match_dup 3)))
18852 (clobber (reg:CC FLAGS_REG))])]
18854 int i = INTVAL (operands[1]);
18856 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
18858 if (!x86_64_immediate_operand (operands[3], DImode))
18860 emit_move_insn (operands[2], operands[3]);
18861 operands[3] = operands[2];
18867 (define_insn "*bt<mode>"
18868 [(set (reg:CCC FLAGS_REG)
18870 (zero_extract:SWI48
18871 (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
18873 (match_operand:QI 1 "nonmemory_operand" "q<S>,<S>"))
18877 switch (get_attr_mode (insn))
18880 return "bt{l}\t{%k1, %k0|%k0, %k1}";
18883 return "bt{q}\t{%q1, %0|%0, %q1}";
18886 gcc_unreachable ();
18889 [(set_attr "type" "alu1")
18890 (set_attr "prefix_0f" "1")
18893 (and (match_test "CONST_INT_P (operands[1])")
18894 (match_test "INTVAL (operands[1]) < 32"))
18895 (const_string "SI")
18896 (const_string "<MODE>")))])
18898 (define_insn_and_split "*bt<SWI48:mode>_mask"
18899 [(set (reg:CCC FLAGS_REG)
18901 (zero_extract:SWI48
18902 (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
18906 (match_operand:SWI248 1 "register_operand")
18907 (match_operand 2 "const_int_operand")) 0))
18910 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<SWI48:MODE>mode)-1))
18911 == GET_MODE_BITSIZE (<SWI48:MODE>mode)-1
18912 && ix86_pre_reload_split ()"
18915 [(set (reg:CCC FLAGS_REG)
18917 (zero_extract:SWI48 (match_dup 0) (const_int 1) (match_dup 1))
18919 "operands[1] = gen_lowpart (QImode, operands[1]);")
18921 (define_insn_and_split "*jcc_bt<mode>"
18923 (if_then_else (match_operator 0 "bt_comparison_operator"
18924 [(zero_extract:SWI48
18925 (match_operand:SWI48 1 "nonimmediate_operand")
18927 (match_operand:QI 2 "nonmemory_operand"))
18929 (label_ref (match_operand 3))
18931 (clobber (reg:CC FLAGS_REG))]
18932 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
18933 && (CONST_INT_P (operands[2])
18934 ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
18935 && INTVAL (operands[2])
18936 >= (optimize_function_for_size_p (cfun) ? 8 : 32))
18937 : !memory_operand (operands[1], <MODE>mode))
18938 && ix86_pre_reload_split ()"
18941 [(set (reg:CCC FLAGS_REG)
18943 (zero_extract:SWI48
18949 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
18950 (label_ref (match_dup 3))
18953 operands[0] = shallow_copy_rtx (operands[0]);
18954 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
18957 ;; Avoid useless masking of bit offset operand.
18958 (define_insn_and_split "*jcc_bt<mode>_mask"
18960 (if_then_else (match_operator 0 "bt_comparison_operator"
18961 [(zero_extract:SWI48
18962 (match_operand:SWI48 1 "register_operand")
18965 (match_operand:QI 2 "register_operand")
18966 (match_operand 3 "const_int_operand")))
18968 (label_ref (match_operand 4))
18970 (clobber (reg:CC FLAGS_REG))]
18971 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
18972 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
18973 == GET_MODE_BITSIZE (<MODE>mode)-1
18974 && ix86_pre_reload_split ()"
18977 [(set (reg:CCC FLAGS_REG)
18979 (zero_extract:SWI48
18985 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
18986 (label_ref (match_dup 4))
18989 operands[0] = shallow_copy_rtx (operands[0]);
18990 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
18993 ;; Avoid useless masking of bit offset operand.
18994 (define_insn_and_split "*jcc_bt<SWI48:mode>_mask_1"
18996 (if_then_else (match_operator 0 "bt_comparison_operator"
18997 [(zero_extract:SWI48
18998 (match_operand:SWI48 1 "register_operand")
19002 (match_operand:SWI248 2 "register_operand")
19003 (match_operand 3 "const_int_operand")) 0))
19005 (label_ref (match_operand 4))
19007 (clobber (reg:CC FLAGS_REG))]
19008 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
19009 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<SWI48:MODE>mode)-1))
19010 == GET_MODE_BITSIZE (<SWI48:MODE>mode)-1
19011 && ix86_pre_reload_split ()"
19014 [(set (reg:CCC FLAGS_REG)
19016 (zero_extract:SWI48
19022 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
19023 (label_ref (match_dup 4))
19026 operands[0] = shallow_copy_rtx (operands[0]);
19027 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
19028 operands[2] = gen_lowpart (QImode, operands[2]);
19031 ;; Help combine recognize bt followed by cmov
19033 [(set (match_operand:SWI248 0 "register_operand")
19034 (if_then_else:SWI248
19035 (match_operator 5 "bt_comparison_operator"
19036 [(zero_extract:SWI48
19037 (match_operand:SWI48 1 "register_operand")
19039 (match_operand:QI 2 "register_operand"))
19041 (match_operand:SWI248 3 "nonimmediate_operand")
19042 (match_operand:SWI248 4 "nonimmediate_operand")))]
19043 "TARGET_USE_BT && TARGET_CMOVE
19044 && !(MEM_P (operands[3]) && MEM_P (operands[4]))
19045 && ix86_pre_reload_split ()"
19046 [(set (reg:CCC FLAGS_REG)
19048 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
19051 (if_then_else:SWI248 (eq (reg:CCC FLAGS_REG) (const_int 0))
19055 if (GET_CODE (operands[5]) == EQ)
19056 std::swap (operands[3], operands[4]);
19059 ;; Help combine recognize bt followed by setc
19060 (define_insn_and_split "*bt<mode>_setcqi"
19061 [(set (subreg:SWI48 (match_operand:QI 0 "register_operand") 0)
19062 (zero_extract:SWI48
19063 (match_operand:SWI48 1 "register_operand")
19065 (match_operand:QI 2 "register_operand")))
19066 (clobber (reg:CC FLAGS_REG))]
19067 "TARGET_USE_BT && ix86_pre_reload_split ()"
19070 [(set (reg:CCC FLAGS_REG)
19072 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
19075 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))])
19077 ;; Help combine recognize bt followed by setnc
19078 (define_insn_and_split "*bt<mode>_setncqi"
19079 [(set (match_operand:QI 0 "register_operand")
19083 (lshiftrt:SWI48 (match_operand:SWI48 1 "register_operand")
19084 (match_operand:QI 2 "register_operand")) 0))
19086 (clobber (reg:CC FLAGS_REG))]
19087 "TARGET_USE_BT && ix86_pre_reload_split ()"
19090 [(set (reg:CCC FLAGS_REG)
19092 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
19095 (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))])
19097 (define_insn_and_split "*bt<mode>_setnc<mode>"
19098 [(set (match_operand:SWI48 0 "register_operand")
19101 (lshiftrt:SWI48 (match_operand:SWI48 1 "register_operand")
19102 (match_operand:QI 2 "register_operand")))
19104 (clobber (reg:CC FLAGS_REG))]
19105 "TARGET_USE_BT && ix86_pre_reload_split ()"
19108 [(set (reg:CCC FLAGS_REG)
19110 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
19113 (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))
19114 (set (match_dup 0) (zero_extend:SWI48 (match_dup 3)))]
19115 "operands[3] = gen_reg_rtx (QImode);")
19117 ;; Help combine recognize bt followed by setnc (PR target/110588)
19118 (define_insn_and_split "*bt<mode>_setncqi_2"
19119 [(set (match_operand:QI 0 "register_operand")
19121 (zero_extract:SWI48
19122 (match_operand:SWI48 1 "register_operand")
19124 (match_operand:QI 2 "register_operand"))
19126 (clobber (reg:CC FLAGS_REG))]
19127 "TARGET_USE_BT && ix86_pre_reload_split ()"
19130 [(set (reg:CCC FLAGS_REG)
19132 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
19135 (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))])
19137 ;; Help combine recognize bt followed by setc
19138 (define_insn_and_split "*bt<mode>_setc<mode>_mask"
19139 [(set (match_operand:SWI48 0 "register_operand")
19140 (zero_extract:SWI48
19141 (match_operand:SWI48 1 "register_operand")
19145 (match_operand:SWI48 2 "register_operand")
19146 (match_operand 3 "const_int_operand")) 0)))
19147 (clobber (reg:CC FLAGS_REG))]
19149 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
19150 == GET_MODE_BITSIZE (<MODE>mode)-1
19151 && ix86_pre_reload_split ()"
19154 [(set (reg:CCC FLAGS_REG)
19156 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
19159 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))
19160 (set (match_dup 0) (zero_extend:SWI48 (match_dup 3)))]
19162 operands[2] = gen_lowpart (QImode, operands[2]);
19163 operands[3] = gen_reg_rtx (QImode);
19166 ;; Store-flag instructions.
19169 [(set (match_operand:QI 0 "nonimmediate_operand")
19170 (match_operator:QI 1 "add_comparison_operator"
19171 [(not:SWI (match_operand:SWI 2 "register_operand"))
19172 (match_operand:SWI 3 "nonimmediate_operand")]))]
19174 [(set (reg:CCC FLAGS_REG)
19176 (plus:SWI (match_dup 2) (match_dup 3))
19179 (match_op_dup 1 [(reg:CCC FLAGS_REG) (const_int 0)]))])
19182 [(set (match_operand:QI 0 "nonimmediate_operand")
19183 (match_operator:QI 1 "shr_comparison_operator"
19184 [(match_operand:DI 2 "register_operand")
19185 (match_operand 3 "const_int_operand")]))]
19187 && IN_RANGE (exact_log2 (UINTVAL (operands[3]) + 1), 32, 63)"
19188 [(set (reg:CCZ FLAGS_REG)
19190 (lshiftrt:DI (match_dup 2) (match_dup 4))
19193 (match_op_dup 1 [(reg:CCZ FLAGS_REG) (const_int 0)]))]
19195 enum rtx_code new_code;
19197 operands[1] = shallow_copy_rtx (operands[1]);
19198 switch (GET_CODE (operands[1]))
19200 case GTU: new_code = NE; break;
19201 case LEU: new_code = EQ; break;
19202 default: gcc_unreachable ();
19204 PUT_CODE (operands[1], new_code);
19206 operands[4] = GEN_INT (exact_log2 (UINTVAL (operands[3]) + 1));
19209 ;; For all sCOND expanders, also expand the compare or test insn that
19210 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
19212 (define_insn "*setcc_<mode>_zu"
19213 [(set (match_operand:SWI248 0 "register_operand" "=r")
19214 (match_operator:SWI248 1 "ix86_comparison_operator"
19215 [(reg FLAGS_REG) (const_int 0)]))]
19218 [(set_attr "type" "setcc")])
19220 (define_insn_and_split "*setcc_di_1"
19221 [(set (match_operand:DI 0 "register_operand" "=q")
19222 (match_operator:DI 1 "ix86_comparison_operator"
19223 [(reg FLAGS_REG) (const_int 0)]))]
19224 "!TARGET_APX_ZU && TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
19226 "&& reload_completed"
19227 [(set (match_dup 2) (match_dup 1))
19228 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
19230 operands[1] = shallow_copy_rtx (operands[1]);
19231 PUT_MODE (operands[1], QImode);
19232 operands[2] = gen_lowpart (QImode, operands[0]);
19235 (define_insn_and_split "*setcc_<mode>_1_and"
19236 [(set (match_operand:SWI24 0 "register_operand" "=q")
19237 (match_operator:SWI24 1 "ix86_comparison_operator"
19238 [(reg FLAGS_REG) (const_int 0)]))
19239 (clobber (reg:CC FLAGS_REG))]
19240 "!TARGET_PARTIAL_REG_STALL
19241 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
19243 "&& reload_completed"
19244 [(set (match_dup 2) (match_dup 1))
19245 (parallel [(set (match_dup 0) (zero_extend:SWI24 (match_dup 2)))
19246 (clobber (reg:CC FLAGS_REG))])]
19248 operands[1] = shallow_copy_rtx (operands[1]);
19249 PUT_MODE (operands[1], QImode);
19250 operands[2] = gen_lowpart (QImode, operands[0]);
19253 (define_insn_and_split "*setcc_<mode>_1_movzbl"
19254 [(set (match_operand:SWI24 0 "register_operand" "=q")
19255 (match_operator:SWI24 1 "ix86_comparison_operator"
19256 [(reg FLAGS_REG) (const_int 0)]))]
19257 "!TARGET_APX_ZU && !TARGET_PARTIAL_REG_STALL
19258 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
19260 "&& reload_completed"
19261 [(set (match_dup 2) (match_dup 1))
19262 (set (match_dup 0) (zero_extend:SWI24 (match_dup 2)))]
19264 operands[1] = shallow_copy_rtx (operands[1]);
19265 PUT_MODE (operands[1], QImode);
19266 operands[2] = gen_lowpart (QImode, operands[0]);
19269 (define_insn "*setcc_qi"
19270 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
19271 (match_operator:QI 1 "ix86_comparison_operator"
19272 [(reg FLAGS_REG) (const_int 0)]))]
19275 [(set_attr "type" "setcc")
19276 (set_attr "mode" "QI")])
19278 (define_insn "*setcc_qi_slp"
19279 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+q"))
19280 (match_operator:QI 1 "ix86_comparison_operator"
19281 [(reg FLAGS_REG) (const_int 0)]))]
19284 [(set_attr "type" "setcc")
19285 (set_attr "mode" "QI")])
19287 (define_expand "setcc_si_slp"
19288 [(set (match_operand:SI 0 "register_operand")
19290 [(match_operand:QI 1)
19291 (match_operand:SI 2 "register_operand")] UNSPEC_SETCC_SI_SLP))])
19293 (define_insn_and_split "*setcc_si_slp"
19294 [(set (match_operand:SI 0 "register_operand" "=q")
19296 [(match_operator:QI 1 "ix86_comparison_operator"
19297 [(reg FLAGS_REG) (const_int 0)])
19298 (match_operand:SI 2 "register_operand" "0")] UNSPEC_SETCC_SI_SLP))]
19299 "ix86_pre_reload_split ()"
19302 [(set (match_dup 0) (match_dup 2))
19303 (set (strict_low_part (match_dup 3)) (match_dup 1))]
19305 operands[3] = gen_lowpart (QImode, operands[0]);
19308 ;; In general it is not safe to assume too much about CCmode registers,
19309 ;; so simplify-rtx stops when it sees a second one. Under certain
19310 ;; conditions this is safe on x86, so help combine not create
19317 [(set (match_operand:QI 0 "nonimmediate_operand")
19318 (ne:QI (match_operator 1 "ix86_comparison_operator"
19319 [(reg FLAGS_REG) (const_int 0)])
19322 [(set (match_dup 0) (match_dup 1))]
19324 operands[1] = shallow_copy_rtx (operands[1]);
19325 PUT_MODE (operands[1], QImode);
19329 [(set (strict_low_part (match_operand:QI 0 "register_operand"))
19330 (ne:QI (match_operator 1 "ix86_comparison_operator"
19331 [(reg FLAGS_REG) (const_int 0)])
19334 [(set (match_dup 0) (match_dup 1))]
19336 operands[1] = shallow_copy_rtx (operands[1]);
19337 PUT_MODE (operands[1], QImode);
19341 [(set (match_operand:QI 0 "nonimmediate_operand")
19342 (eq:QI (match_operator 1 "ix86_comparison_operator"
19343 [(reg FLAGS_REG) (const_int 0)])
19346 [(set (match_dup 0) (match_dup 1))]
19348 operands[1] = shallow_copy_rtx (operands[1]);
19349 PUT_MODE (operands[1], QImode);
19350 PUT_CODE (operands[1],
19351 ix86_reverse_condition (GET_CODE (operands[1]),
19352 GET_MODE (XEXP (operands[1], 0))));
19354 /* Make sure that (a) the CCmode we have for the flags is strong
19355 enough for the reversed compare or (b) we have a valid FP compare. */
19356 if (! ix86_comparison_operator (operands[1], VOIDmode))
19361 [(set (strict_low_part (match_operand:QI 0 "register_operand"))
19362 (eq:QI (match_operator 1 "ix86_comparison_operator"
19363 [(reg FLAGS_REG) (const_int 0)])
19366 [(set (match_dup 0) (match_dup 1))]
19368 operands[1] = shallow_copy_rtx (operands[1]);
19369 PUT_MODE (operands[1], QImode);
19370 PUT_CODE (operands[1],
19371 ix86_reverse_condition (GET_CODE (operands[1]),
19372 GET_MODE (XEXP (operands[1], 0))));
19374 /* Make sure that (a) the CCmode we have for the flags is strong
19375 enough for the reversed compare or (b) we have a valid FP compare. */
19376 if (! ix86_comparison_operator (operands[1], VOIDmode))
19380 ;; Eliminate redundant compare between set{z,nz} and j{z,nz}:
19381 ;; setz %al; test %al,%al; jz <...> -> setz %al; jnz <...> and
19382 ;; setnz %al, test %al,%al; jz <...> -> setnz %al; jz <...>.
19384 [(set (match_operand:QI 0 "nonimmediate_operand")
19385 (match_operator:QI 1 "bt_comparison_operator"
19386 [(reg:CCZ FLAGS_REG) (const_int 0)]))
19387 (set (reg:CCZ FLAGS_REG)
19388 (compare:CCZ (match_dup 0) (const_int 0)))
19390 (if_then_else (match_operator 2 "bt_comparison_operator"
19391 [(reg:CCZ FLAGS_REG) (const_int 0)])
19394 "peep2_regno_dead_p (3, FLAGS_REG)"
19395 [(set (match_dup 0)
19396 (match_op_dup 1 [(reg:CCZ FLAGS_REG) (const_int 0)]))
19398 (if_then_else (match_dup 2)
19402 if (GET_CODE (operands[1]) == EQ)
19404 operands[2] = shallow_copy_rtx (operands[2]);
19405 PUT_CODE (operands[2], reverse_condition (GET_CODE (operands[2])));
19409 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
19410 ;; subsequent logical operations are used to imitate conditional moves.
19411 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
19414 (define_insn "setcc_<mode>_sse"
19415 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
19416 (match_operator:MODEF 3 "sse_comparison_operator"
19417 [(match_operand:MODEF 1 "register_operand" "0,x")
19418 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xjm")]))]
19419 "SSE_FLOAT_MODE_P (<MODE>mode)"
19421 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
19422 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
19423 [(set_attr "isa" "noavx,avx")
19424 (set_attr "addr" "*,gpr16")
19425 (set_attr "type" "ssecmp")
19426 (set_attr "length_immediate" "1")
19427 (set_attr "prefix" "orig,vex")
19428 (set_attr "mode" "<MODE>")])
19430 (define_insn "setcc_hf_mask"
19431 [(set (match_operand:QI 0 "register_operand" "=k")
19433 [(match_operand:HF 1 "register_operand" "v")
19434 (match_operand:HF 2 "nonimmediate_operand" "vm")
19435 (match_operand:SI 3 "const_0_to_31_operand")]
19437 "TARGET_AVX512FP16"
19438 "vcmpsh\t{%3, %2, %1, %0|%0, %1, %2, %3}"
19439 [(set_attr "type" "ssecmp")
19440 (set_attr "prefix" "evex")
19441 (set_attr "mode" "HF")])
19444 ;; Basic conditional jump instructions.
19449 (match_operator 1 "add_comparison_operator"
19450 [(not:SWI (match_operand:SWI 2 "register_operand"))
19451 (match_operand:SWI 3 "nonimmediate_operand")])
19452 (label_ref (match_operand 0))
19455 [(set (reg:CCC FLAGS_REG)
19457 (plus:SWI (match_dup 2) (match_dup 3))
19460 (if_then_else (match_op_dup 1 [(reg:CCC FLAGS_REG) (const_int 0)])
19461 (label_ref (match_operand 0))
19467 (match_operator 1 "shr_comparison_operator"
19468 [(match_operand:DI 2 "register_operand")
19469 (match_operand 3 "const_int_operand")])
19470 (label_ref (match_operand 0))
19473 && IN_RANGE (exact_log2 (UINTVAL (operands[3]) + 1), 32, 63)"
19474 [(set (reg:CCZ FLAGS_REG)
19476 (lshiftrt:DI (match_dup 2) (match_dup 4))
19479 (if_then_else (match_op_dup 1 [(reg:CCZ FLAGS_REG) (const_int 0)])
19480 (label_ref (match_operand 0))
19483 enum rtx_code new_code;
19485 operands[1] = shallow_copy_rtx (operands[1]);
19486 switch (GET_CODE (operands[1]))
19488 case GTU: new_code = NE; break;
19489 case LEU: new_code = EQ; break;
19490 default: gcc_unreachable ();
19492 PUT_CODE (operands[1], new_code);
19494 operands[4] = GEN_INT (exact_log2 (UINTVAL (operands[3]) + 1));
19497 ;; We ignore the overflow flag for signed branch instructions.
19499 (define_insn "*jcc"
19501 (if_then_else (match_operator 1 "ix86_comparison_operator"
19502 [(reg FLAGS_REG) (const_int 0)])
19503 (label_ref (match_operand 0))
19507 [(set_attr "type" "ibr")
19508 (set_attr "modrm" "0")
19509 (set (attr "length")
19511 (and (ge (minus (match_dup 0) (pc))
19513 (lt (minus (match_dup 0) (pc))
19518 ;; In general it is not safe to assume too much about CCmode registers,
19519 ;; so simplify-rtx stops when it sees a second one. Under certain
19520 ;; conditions this is safe on x86, so help combine not create
19528 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
19529 [(reg FLAGS_REG) (const_int 0)])
19531 (label_ref (match_operand 1))
19535 (if_then_else (match_dup 0)
19536 (label_ref (match_dup 1))
19539 operands[0] = shallow_copy_rtx (operands[0]);
19540 PUT_MODE (operands[0], VOIDmode);
19545 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
19546 [(reg FLAGS_REG) (const_int 0)])
19548 (label_ref (match_operand 1))
19552 (if_then_else (match_dup 0)
19553 (label_ref (match_dup 1))
19556 operands[0] = shallow_copy_rtx (operands[0]);
19557 PUT_MODE (operands[0], VOIDmode);
19558 PUT_CODE (operands[0],
19559 ix86_reverse_condition (GET_CODE (operands[0]),
19560 GET_MODE (XEXP (operands[0], 0))));
19562 /* Make sure that (a) the CCmode we have for the flags is strong
19563 enough for the reversed compare or (b) we have a valid FP compare. */
19564 if (! ix86_comparison_operator (operands[0], VOIDmode))
19568 ;; Unconditional and other jump instructions
19570 (define_insn "jump"
19572 (label_ref (match_operand 0)))]
19575 [(set_attr "type" "ibr")
19576 (set_attr "modrm" "0")
19577 (set (attr "length")
19579 (and (ge (minus (match_dup 0) (pc))
19581 (lt (minus (match_dup 0) (pc))
19586 (define_expand "indirect_jump"
19587 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
19590 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
19591 operands[0] = convert_memory_address (word_mode, operands[0]);
19592 cfun->machine->has_local_indirect_jump = true;
19595 (define_insn "*indirect_jump"
19596 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
19598 "* return ix86_output_indirect_jmp (operands[0]);"
19599 [(set (attr "type")
19600 (if_then_else (match_test "(cfun->machine->indirect_branch_type
19601 != indirect_branch_keep)")
19602 (const_string "multi")
19603 (const_string "ibr")))
19604 (set_attr "length_immediate" "0")])
19606 (define_expand "tablejump"
19607 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
19608 (use (label_ref (match_operand 1)))])]
19611 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
19612 relative. Convert the relative address to an absolute address. */
19616 enum rtx_code code;
19618 /* We can't use @GOTOFF for text labels on VxWorks;
19619 see gotoff_operand. */
19620 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
19624 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
19626 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
19630 op1 = pic_offset_table_rtx;
19635 op0 = pic_offset_table_rtx;
19639 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
19643 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
19644 operands[0] = convert_memory_address (word_mode, operands[0]);
19645 cfun->machine->has_local_indirect_jump = true;
19648 (define_insn "*tablejump_1"
19649 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
19650 (use (label_ref (match_operand 1)))]
19652 "* return ix86_output_indirect_jmp (operands[0]);"
19653 [(set (attr "type")
19654 (if_then_else (match_test "(cfun->machine->indirect_branch_type
19655 != indirect_branch_keep)")
19656 (const_string "multi")
19657 (const_string "ibr")))
19658 (set_attr "length_immediate" "0")])
19660 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
19663 [(set (match_operand 4 "flags_reg_operand") (match_operand 0))
19664 (set (match_operand:QI 1 "register_operand")
19665 (match_operator:QI 2 "ix86_comparison_operator"
19666 [(reg FLAGS_REG) (const_int 0)]))
19667 (set (match_operand 3 "any_QIreg_operand")
19668 (zero_extend (match_dup 1)))]
19669 "(peep2_reg_dead_p (3, operands[1])
19670 || operands_match_p (operands[1], operands[3]))
19671 && ! reg_overlap_mentioned_p (operands[3], operands[0])
19672 && peep2_regno_dead_p (0, FLAGS_REG)"
19673 [(set (match_dup 4) (match_dup 0))
19674 (set (strict_low_part (match_dup 5))
19677 operands[5] = gen_lowpart (QImode, operands[3]);
19678 ix86_expand_clear (operands[3]);
19682 [(parallel [(set (match_operand 5 "flags_reg_operand") (match_operand 0))
19683 (match_operand 4)])
19684 (set (match_operand:QI 1 "register_operand")
19685 (match_operator:QI 2 "ix86_comparison_operator"
19686 [(reg FLAGS_REG) (const_int 0)]))
19687 (set (match_operand 3 "any_QIreg_operand")
19688 (zero_extend (match_dup 1)))]
19689 "(peep2_reg_dead_p (3, operands[1])
19690 || operands_match_p (operands[1], operands[3]))
19691 && ! reg_overlap_mentioned_p (operands[3], operands[0])
19692 && ! reg_overlap_mentioned_p (operands[3], operands[4])
19693 && ! reg_set_p (operands[3], operands[4])
19694 && peep2_regno_dead_p (0, FLAGS_REG)"
19695 [(parallel [(set (match_dup 5) (match_dup 0))
19697 (set (strict_low_part (match_dup 6))
19700 operands[6] = gen_lowpart (QImode, operands[3]);
19701 ix86_expand_clear (operands[3]);
19705 [(set (match_operand 6 "flags_reg_operand") (match_operand 0))
19706 (parallel [(set (match_operand 7 "flags_reg_operand") (match_operand 1))
19707 (match_operand 5)])
19708 (set (match_operand:QI 2 "register_operand")
19709 (match_operator:QI 3 "ix86_comparison_operator"
19710 [(reg FLAGS_REG) (const_int 0)]))
19711 (set (match_operand 4 "any_QIreg_operand")
19712 (zero_extend (match_dup 2)))]
19713 "(peep2_reg_dead_p (4, operands[2])
19714 || operands_match_p (operands[2], operands[4]))
19715 && ! reg_overlap_mentioned_p (operands[4], operands[0])
19716 && ! reg_overlap_mentioned_p (operands[4], operands[1])
19717 && ! reg_overlap_mentioned_p (operands[4], operands[5])
19718 && ! reg_set_p (operands[4], operands[5])
19719 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
19720 && peep2_regno_dead_p (0, FLAGS_REG)"
19721 [(set (match_dup 6) (match_dup 0))
19722 (parallel [(set (match_dup 7) (match_dup 1))
19724 (set (strict_low_part (match_dup 8))
19727 operands[8] = gen_lowpart (QImode, operands[4]);
19728 ix86_expand_clear (operands[4]);
19731 ;; Similar, but match zero extend with andsi3.
19734 [(set (match_operand 4 "flags_reg_operand") (match_operand 0))
19735 (set (match_operand:QI 1 "register_operand")
19736 (match_operator:QI 2 "ix86_comparison_operator"
19737 [(reg FLAGS_REG) (const_int 0)]))
19738 (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
19739 (and:SI (match_dup 3) (const_int 255)))
19740 (clobber (reg:CC FLAGS_REG))])]
19741 "REGNO (operands[1]) == REGNO (operands[3])
19742 && ! reg_overlap_mentioned_p (operands[3], operands[0])
19743 && peep2_regno_dead_p (0, FLAGS_REG)"
19744 [(set (match_dup 4) (match_dup 0))
19745 (set (strict_low_part (match_dup 5))
19748 operands[5] = gen_lowpart (QImode, operands[3]);
19749 ix86_expand_clear (operands[3]);
19753 [(parallel [(set (match_operand 5 "flags_reg_operand") (match_operand 0))
19754 (match_operand 4)])
19755 (set (match_operand:QI 1 "register_operand")
19756 (match_operator:QI 2 "ix86_comparison_operator"
19757 [(reg FLAGS_REG) (const_int 0)]))
19758 (parallel [(set (match_operand 3 "any_QIreg_operand")
19759 (zero_extend (match_dup 1)))
19760 (clobber (reg:CC FLAGS_REG))])]
19761 "(peep2_reg_dead_p (3, operands[1])
19762 || operands_match_p (operands[1], operands[3]))
19763 && ! reg_overlap_mentioned_p (operands[3], operands[0])
19764 && ! reg_overlap_mentioned_p (operands[3], operands[4])
19765 && ! reg_set_p (operands[3], operands[4])
19766 && peep2_regno_dead_p (0, FLAGS_REG)"
19767 [(parallel [(set (match_dup 5) (match_dup 0))
19769 (set (strict_low_part (match_dup 6))
19772 operands[6] = gen_lowpart (QImode, operands[3]);
19773 ix86_expand_clear (operands[3]);
19777 [(set (match_operand 6 "flags_reg_operand") (match_operand 0))
19778 (parallel [(set (match_operand 7 "flags_reg_operand") (match_operand 1))
19779 (match_operand 5)])
19780 (set (match_operand:QI 2 "register_operand")
19781 (match_operator:QI 3 "ix86_comparison_operator"
19782 [(reg FLAGS_REG) (const_int 0)]))
19783 (parallel [(set (match_operand 4 "any_QIreg_operand")
19784 (zero_extend (match_dup 2)))
19785 (clobber (reg:CC FLAGS_REG))])]
19786 "(peep2_reg_dead_p (4, operands[2])
19787 || operands_match_p (operands[2], operands[4]))
19788 && ! reg_overlap_mentioned_p (operands[4], operands[0])
19789 && ! reg_overlap_mentioned_p (operands[4], operands[1])
19790 && ! reg_overlap_mentioned_p (operands[4], operands[5])
19791 && ! reg_set_p (operands[4], operands[5])
19792 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
19793 && peep2_regno_dead_p (0, FLAGS_REG)"
19794 [(set (match_dup 6) (match_dup 0))
19795 (parallel [(set (match_dup 7) (match_dup 1))
19797 (set (strict_low_part (match_dup 8))
19800 operands[8] = gen_lowpart (QImode, operands[4]);
19801 ix86_expand_clear (operands[4]);
19805 [(set (match_operand 4 "flags_reg_operand") (match_operand 0))
19806 (set (strict_low_part (match_operand:QI 5 "register_operand"))
19807 (match_operator:QI 6 "ix86_comparison_operator"
19808 [(reg FLAGS_REG) (const_int 0)]))
19809 (set (match_operand:QI 1 "register_operand")
19810 (match_operator:QI 2 "ix86_comparison_operator"
19811 [(reg FLAGS_REG) (const_int 0)]))
19812 (set (match_operand 3 "any_QIreg_operand")
19813 (zero_extend (match_dup 1)))]
19814 "(peep2_reg_dead_p (4, operands[1])
19815 || operands_match_p (operands[1], operands[3]))
19816 && ! reg_overlap_mentioned_p (operands[3], operands[0])
19817 && ! reg_overlap_mentioned_p (operands[3], operands[5])
19818 && ! reg_overlap_mentioned_p (operands[1], operands[5])
19819 && peep2_regno_dead_p (0, FLAGS_REG)"
19820 [(set (match_dup 4) (match_dup 0))
19821 (set (strict_low_part (match_dup 5))
19823 (set (strict_low_part (match_dup 7))
19826 operands[7] = gen_lowpart (QImode, operands[3]);
19827 ix86_expand_clear (operands[3]);
19830 ;; Call instructions.
19832 ;; The predicates normally associated with named expanders are not properly
19833 ;; checked for calls. This is a bug in the generic code, but it isn't that
19834 ;; easy to fix. Ignore it for now and be prepared to fix things up.
19836 ;; P6 processors will jump to the address after the decrement when %esp
19837 ;; is used as a call operand, so they will execute return address as a code.
19838 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
19840 ;; Register constraint for call instruction.
19841 (define_mode_attr c [(SI "l") (DI "r")])
19843 ;; Call subroutine returning no value.
19845 (define_expand "call"
19846 [(call (match_operand:QI 0)
19848 (use (match_operand 2))]
19851 ix86_expand_call (NULL, operands[0], operands[1],
19852 operands[2], NULL, false);
19856 (define_expand "sibcall"
19857 [(call (match_operand:QI 0)
19859 (use (match_operand 2))]
19862 ix86_expand_call (NULL, operands[0], operands[1],
19863 operands[2], NULL, true);
19867 (define_insn "*call"
19868 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
19869 (match_operand 1))]
19870 "!SIBLING_CALL_P (insn)"
19871 "* return ix86_output_call_insn (insn, operands[0]);"
19872 [(set_attr "type" "call")])
19874 ;; This covers both call and sibcall since only GOT slot is allowed.
19875 (define_insn "*call_got_x32"
19876 [(call (mem:QI (zero_extend:DI
19877 (match_operand:SI 0 "GOT_memory_operand" "Bg")))
19878 (match_operand 1))]
19881 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
19882 return ix86_output_call_insn (insn, fnaddr);
19884 [(set_attr "type" "call")])
19886 ;; Since sibcall never returns, we can only use call-clobbered register
19888 (define_insn "*sibcall_GOT_32"
19891 (match_operand:SI 0 "register_no_elim_operand" "U")
19892 (match_operand:SI 1 "GOT32_symbol_operand"))))
19893 (match_operand 2))]
19896 && !TARGET_INDIRECT_BRANCH_REGISTER
19897 && SIBLING_CALL_P (insn)"
19899 rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
19900 fnaddr = gen_const_mem (SImode, fnaddr);
19901 return ix86_output_call_insn (insn, fnaddr);
19903 [(set_attr "type" "call")])
19905 (define_insn "*sibcall"
19906 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
19907 (match_operand 1))]
19908 "SIBLING_CALL_P (insn)"
19909 "* return ix86_output_call_insn (insn, operands[0]);"
19910 [(set_attr "type" "call")])
19912 (define_insn "*sibcall_memory"
19913 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
19915 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
19916 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
19917 "* return ix86_output_call_insn (insn, operands[0]);"
19918 [(set_attr "type" "call")])
19921 [(set (match_operand:W 0 "register_operand")
19922 (match_operand:W 1 "memory_operand"))
19923 (call (mem:QI (match_dup 0))
19924 (match_operand 3))]
19926 && !TARGET_INDIRECT_BRANCH_REGISTER
19927 && SIBLING_CALL_P (peep2_next_insn (1))
19928 && !reg_mentioned_p (operands[0],
19929 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
19930 [(parallel [(call (mem:QI (match_dup 1))
19932 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
19935 [(set (match_operand:W 0 "register_operand")
19936 (match_operand:W 1 "memory_operand"))
19937 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
19938 (call (mem:QI (match_dup 0))
19939 (match_operand 3))]
19941 && !TARGET_INDIRECT_BRANCH_REGISTER
19942 && SIBLING_CALL_P (peep2_next_insn (2))
19943 && !reg_mentioned_p (operands[0],
19944 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
19945 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
19946 (parallel [(call (mem:QI (match_dup 1))
19948 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
19950 (define_expand "call_pop"
19951 [(parallel [(call (match_operand:QI 0)
19952 (match_operand:SI 1))
19953 (set (reg:SI SP_REG)
19954 (plus:SI (reg:SI SP_REG)
19955 (match_operand:SI 3)))])]
19958 ix86_expand_call (NULL, operands[0], operands[1],
19959 operands[2], operands[3], false);
19963 (define_insn "*call_pop"
19964 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz"))
19966 (set (reg:SI SP_REG)
19967 (plus:SI (reg:SI SP_REG)
19968 (match_operand:SI 2 "immediate_operand" "i")))]
19969 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
19970 "* return ix86_output_call_insn (insn, operands[0]);"
19971 [(set_attr "type" "call")])
19973 (define_insn "*sibcall_pop"
19974 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
19976 (set (reg:SI SP_REG)
19977 (plus:SI (reg:SI SP_REG)
19978 (match_operand:SI 2 "immediate_operand" "i")))]
19979 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
19980 "* return ix86_output_call_insn (insn, operands[0]);"
19981 [(set_attr "type" "call")])
19983 (define_insn "*sibcall_pop_memory"
19984 [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs"))
19986 (set (reg:SI SP_REG)
19987 (plus:SI (reg:SI SP_REG)
19988 (match_operand:SI 2 "immediate_operand" "i")))
19989 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
19991 "* return ix86_output_call_insn (insn, operands[0]);"
19992 [(set_attr "type" "call")])
19995 [(set (match_operand:SI 0 "register_operand")
19996 (match_operand:SI 1 "memory_operand"))
19997 (parallel [(call (mem:QI (match_dup 0))
19999 (set (reg:SI SP_REG)
20000 (plus:SI (reg:SI SP_REG)
20001 (match_operand:SI 4 "immediate_operand")))])]
20002 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
20003 && !reg_mentioned_p (operands[0],
20004 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
20005 [(parallel [(call (mem:QI (match_dup 1))
20007 (set (reg:SI SP_REG)
20008 (plus:SI (reg:SI SP_REG)
20010 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
20013 [(set (match_operand:SI 0 "register_operand")
20014 (match_operand:SI 1 "memory_operand"))
20015 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
20016 (parallel [(call (mem:QI (match_dup 0))
20018 (set (reg:SI SP_REG)
20019 (plus:SI (reg:SI SP_REG)
20020 (match_operand:SI 4 "immediate_operand")))])]
20021 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
20022 && !reg_mentioned_p (operands[0],
20023 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
20024 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
20025 (parallel [(call (mem:QI (match_dup 1))
20027 (set (reg:SI SP_REG)
20028 (plus:SI (reg:SI SP_REG)
20030 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
20032 ;; Combining simple memory jump instruction
20035 [(set (match_operand:W 0 "register_operand")
20036 (match_operand:W 1 "memory_operand"))
20037 (set (pc) (match_dup 0))]
20039 && !TARGET_INDIRECT_BRANCH_REGISTER
20040 && peep2_reg_dead_p (2, operands[0])"
20041 [(set (pc) (match_dup 1))])
20043 ;; Call subroutine, returning value in operand 0
20045 (define_expand "call_value"
20046 [(set (match_operand 0)
20047 (call (match_operand:QI 1)
20048 (match_operand 2)))
20049 (use (match_operand 3))]
20052 ix86_expand_call (operands[0], operands[1], operands[2],
20053 operands[3], NULL, false);
20057 (define_expand "sibcall_value"
20058 [(set (match_operand 0)
20059 (call (match_operand:QI 1)
20060 (match_operand 2)))
20061 (use (match_operand 3))]
20064 ix86_expand_call (operands[0], operands[1], operands[2],
20065 operands[3], NULL, true);
20069 (define_insn "*call_value"
20070 [(set (match_operand 0)
20071 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
20072 (match_operand 2)))]
20073 "!SIBLING_CALL_P (insn)"
20074 "* return ix86_output_call_insn (insn, operands[1]);"
20075 [(set_attr "type" "callv")])
20077 ;; This covers both call and sibcall since only GOT slot is allowed.
20078 (define_insn "*call_value_got_x32"
20079 [(set (match_operand 0)
20082 (match_operand:SI 1 "GOT_memory_operand" "Bg")))
20083 (match_operand 2)))]
20086 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
20087 return ix86_output_call_insn (insn, fnaddr);
20089 [(set_attr "type" "callv")])
20091 ;; Since sibcall never returns, we can only use call-clobbered register
20093 (define_insn "*sibcall_value_GOT_32"
20094 [(set (match_operand 0)
20097 (match_operand:SI 1 "register_no_elim_operand" "U")
20098 (match_operand:SI 2 "GOT32_symbol_operand"))))
20099 (match_operand 3)))]
20102 && !TARGET_INDIRECT_BRANCH_REGISTER
20103 && SIBLING_CALL_P (insn)"
20105 rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
20106 fnaddr = gen_const_mem (SImode, fnaddr);
20107 return ix86_output_call_insn (insn, fnaddr);
20109 [(set_attr "type" "callv")])
20111 (define_insn "*sibcall_value"
20112 [(set (match_operand 0)
20113 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
20114 (match_operand 2)))]
20115 "SIBLING_CALL_P (insn)"
20116 "* return ix86_output_call_insn (insn, operands[1]);"
20117 [(set_attr "type" "callv")])
20119 (define_insn "*sibcall_value_memory"
20120 [(set (match_operand 0)
20121 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
20122 (match_operand 2)))
20123 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
20124 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
20125 "* return ix86_output_call_insn (insn, operands[1]);"
20126 [(set_attr "type" "callv")])
20129 [(set (match_operand:W 0 "register_operand")
20130 (match_operand:W 1 "memory_operand"))
20131 (set (match_operand 2)
20132 (call (mem:QI (match_dup 0))
20133 (match_operand 3)))]
20135 && !TARGET_INDIRECT_BRANCH_REGISTER
20136 && SIBLING_CALL_P (peep2_next_insn (1))
20137 && !reg_mentioned_p (operands[0],
20138 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
20139 [(parallel [(set (match_dup 2)
20140 (call (mem:QI (match_dup 1))
20142 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
20145 [(set (match_operand:W 0 "register_operand")
20146 (match_operand:W 1 "memory_operand"))
20147 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
20148 (set (match_operand 2)
20149 (call (mem:QI (match_dup 0))
20150 (match_operand 3)))]
20152 && !TARGET_INDIRECT_BRANCH_REGISTER
20153 && SIBLING_CALL_P (peep2_next_insn (2))
20154 && !reg_mentioned_p (operands[0],
20155 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
20156 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
20157 (parallel [(set (match_dup 2)
20158 (call (mem:QI (match_dup 1))
20160 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
20162 (define_expand "call_value_pop"
20163 [(parallel [(set (match_operand 0)
20164 (call (match_operand:QI 1)
20165 (match_operand:SI 2)))
20166 (set (reg:SI SP_REG)
20167 (plus:SI (reg:SI SP_REG)
20168 (match_operand:SI 4)))])]
20171 ix86_expand_call (operands[0], operands[1], operands[2],
20172 operands[3], operands[4], false);
20176 (define_insn "*call_value_pop"
20177 [(set (match_operand 0)
20178 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz"))
20179 (match_operand 2)))
20180 (set (reg:SI SP_REG)
20181 (plus:SI (reg:SI SP_REG)
20182 (match_operand:SI 3 "immediate_operand" "i")))]
20183 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
20184 "* return ix86_output_call_insn (insn, operands[1]);"
20185 [(set_attr "type" "callv")])
20187 (define_insn "*sibcall_value_pop"
20188 [(set (match_operand 0)
20189 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
20190 (match_operand 2)))
20191 (set (reg:SI SP_REG)
20192 (plus:SI (reg:SI SP_REG)
20193 (match_operand:SI 3 "immediate_operand" "i")))]
20194 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
20195 "* return ix86_output_call_insn (insn, operands[1]);"
20196 [(set_attr "type" "callv")])
20198 (define_insn "*sibcall_value_pop_memory"
20199 [(set (match_operand 0)
20200 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
20201 (match_operand 2)))
20202 (set (reg:SI SP_REG)
20203 (plus:SI (reg:SI SP_REG)
20204 (match_operand:SI 3 "immediate_operand" "i")))
20205 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
20207 "* return ix86_output_call_insn (insn, operands[1]);"
20208 [(set_attr "type" "callv")])
20211 [(set (match_operand:SI 0 "register_operand")
20212 (match_operand:SI 1 "memory_operand"))
20213 (parallel [(set (match_operand 2)
20214 (call (mem:QI (match_dup 0))
20215 (match_operand 3)))
20216 (set (reg:SI SP_REG)
20217 (plus:SI (reg:SI SP_REG)
20218 (match_operand:SI 4 "immediate_operand")))])]
20219 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
20220 && !reg_mentioned_p (operands[0],
20221 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
20222 [(parallel [(set (match_dup 2)
20223 (call (mem:QI (match_dup 1))
20225 (set (reg:SI SP_REG)
20226 (plus:SI (reg:SI SP_REG)
20228 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
20231 [(set (match_operand:SI 0 "register_operand")
20232 (match_operand:SI 1 "memory_operand"))
20233 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
20234 (parallel [(set (match_operand 2)
20235 (call (mem:QI (match_dup 0))
20236 (match_operand 3)))
20237 (set (reg:SI SP_REG)
20238 (plus:SI (reg:SI SP_REG)
20239 (match_operand:SI 4 "immediate_operand")))])]
20240 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
20241 && !reg_mentioned_p (operands[0],
20242 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
20243 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
20244 (parallel [(set (match_dup 2)
20245 (call (mem:QI (match_dup 1))
20247 (set (reg:SI SP_REG)
20248 (plus:SI (reg:SI SP_REG)
20250 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
20252 ;; Call subroutine returning any type.
20254 (define_expand "untyped_call"
20255 [(parallel [(call (match_operand 0)
20258 (match_operand 2)])]
20263 /* In order to give reg-stack an easier job in validating two
20264 coprocessor registers as containing a possible return value,
20265 simply pretend the untyped call returns a complex long double
20268 We can't use SSE_REGPARM_MAX here since callee is unprototyped
20269 and should have the default ABI. */
20271 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
20272 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
20273 operands[0], const0_rtx,
20274 GEN_INT ((TARGET_64BIT
20275 ? (ix86_abi == SYSV_ABI
20276 ? X86_64_SSE_REGPARM_MAX
20277 : X86_64_MS_SSE_REGPARM_MAX)
20278 : X86_32_SSE_REGPARM_MAX)
20282 for (i = 0; i < XVECLEN (operands[2], 0); i++)
20284 rtx set = XVECEXP (operands[2], 0, i);
20285 emit_move_insn (SET_DEST (set), SET_SRC (set));
20288 /* The optimizer does not know that the call sets the function value
20289 registers we stored in the result block. We avoid problems by
20290 claiming that all hard registers are used and clobbered at this
20292 emit_insn (gen_blockage ());
20297 ;; Prologue and epilogue instructions
20299 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
20300 ;; all of memory. This blocks insns from being moved across this point.
20302 (define_insn "blockage"
20303 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
20306 [(set_attr "length" "0")])
20308 ;; Do not schedule instructions accessing memory across this point.
20310 (define_expand "memory_blockage"
20311 [(set (match_dup 0)
20312 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
20315 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
20316 MEM_VOLATILE_P (operands[0]) = 1;
20319 (define_insn "*memory_blockage"
20320 [(set (match_operand:BLK 0)
20321 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
20324 [(set_attr "length" "0")])
20326 ;; As USE insns aren't meaningful after reload, this is used instead
20327 ;; to prevent deleting instructions setting registers for PIC code
20328 (define_insn "prologue_use"
20329 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
20332 [(set_attr "length" "0")])
20334 ;; Insn emitted into the body of a function to return from a function.
20335 ;; This is only done if the function's epilogue is known to be simple.
20336 ;; See comments for ix86_can_use_return_insn_p in i386.cc.
20338 (define_expand "return"
20340 "ix86_can_use_return_insn_p ()"
20342 if (crtl->args.pops_args)
20344 rtx popc = GEN_INT (crtl->args.pops_args);
20345 emit_jump_insn (gen_simple_return_pop_internal (popc));
20350 ;; We need to disable this for TARGET_SEH, as otherwise
20351 ;; shrink-wrapped prologue gets enabled too. This might exceed
20352 ;; the maximum size of prologue in unwind information.
20353 ;; Also disallow shrink-wrapping if using stack slot to pass the
20354 ;; static chain pointer - the first instruction has to be pushl %esi
20355 ;; and it can't be moved around, as we use alternate entry points
20357 ;; Also disallow for ms_hook_prologue functions which have frame
20358 ;; pointer set up in function label which is correctly handled in
20359 ;; ix86_expand_{prologue|epligoue}() only.
20361 (define_expand "simple_return"
20363 "!TARGET_SEH && !ix86_static_chain_on_stack && !ix86_function_ms_hook_prologue (cfun->decl)"
20365 if (crtl->args.pops_args)
20367 rtx popc = GEN_INT (crtl->args.pops_args);
20368 emit_jump_insn (gen_simple_return_pop_internal (popc));
20373 (define_insn "simple_return_internal"
20376 "* return ix86_output_function_return (false);"
20377 [(set_attr "length" "1")
20378 (set_attr "atom_unit" "jeu")
20379 (set_attr "length_immediate" "0")
20380 (set_attr "modrm" "0")])
20382 (define_insn "interrupt_return"
20384 (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
20387 return TARGET_64BIT ? (TARGET_UINTR ? "uiret" : "iretq") : "iret";
20390 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
20391 ;; instruction Athlon and K8 have.
20393 (define_insn "simple_return_internal_long"
20395 (unspec [(const_int 0)] UNSPEC_REP)]
20397 "* return ix86_output_function_return (true);"
20398 [(set_attr "length" "2")
20399 (set_attr "atom_unit" "jeu")
20400 (set_attr "length_immediate" "0")
20401 (set_attr "prefix_rep" "1")
20402 (set_attr "modrm" "0")])
20404 (define_insn_and_split "simple_return_pop_internal"
20406 (use (match_operand:SI 0 "const_int_operand"))]
20409 "&& cfun->machine->function_return_type != indirect_branch_keep"
20411 "ix86_split_simple_return_pop_internal (operands[0]); DONE;"
20412 [(set_attr "length" "3")
20413 (set_attr "atom_unit" "jeu")
20414 (set_attr "length_immediate" "2")
20415 (set_attr "modrm" "0")])
20417 (define_expand "simple_return_indirect_internal"
20420 (use (match_operand 0 "register_operand"))])])
20422 (define_insn "*simple_return_indirect_internal<mode>"
20424 (use (match_operand:W 0 "register_operand" "r"))]
20426 "* return ix86_output_indirect_function_return (operands[0]);"
20427 [(set (attr "type")
20428 (if_then_else (match_test "(cfun->machine->indirect_branch_type
20429 != indirect_branch_keep)")
20430 (const_string "multi")
20431 (const_string "ibr")))
20432 (set_attr "length_immediate" "0")])
20438 [(set_attr "length" "1")
20439 (set_attr "length_immediate" "0")
20440 (set_attr "modrm" "0")])
20442 ;; Generate nops. Operand 0 is the number of nops, up to 8.
20443 (define_insn "nops"
20444 [(unspec_volatile [(match_operand 0 "const_int_operand")]
20448 int num = INTVAL (operands[0]);
20450 gcc_assert (IN_RANGE (num, 1, 8));
20453 fputs ("\tnop\n", asm_out_file);
20457 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
20458 (set_attr "length_immediate" "0")
20459 (set_attr "modrm" "0")])
20461 ;; Pad to 1 << op0 byte boundary, max skip in op1. Used to avoid
20462 ;; branch prediction penalty for the third jump in a 16-byte
20464 ;; Also it's used to align tight loops which can be fix into 1 cacheline.
20465 ;; It can help code prefetch and reduce DSB miss.
20467 (define_insn "max_skip_align"
20468 [(unspec_volatile [(match_operand 0) (match_operand 1)] UNSPECV_ALIGN)]
20471 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
20472 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, (int)INTVAL (operands[0]), (int)INTVAL (operands[1]));
20474 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
20475 The align insn is used to avoid 3 jump instructions in the row to improve
20476 branch prediction and the benefits hardly outweigh the cost of extra 8
20477 nops on the average inserted by full alignment pseudo operation. */
20481 [(set_attr "length" "16")])
20483 (define_expand "prologue"
20486 "ix86_expand_prologue (); DONE;")
20488 (define_expand "set_got"
20490 [(set (match_operand:SI 0 "register_operand")
20491 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
20492 (clobber (reg:CC FLAGS_REG))])]
20495 if (flag_pic && !TARGET_VXWORKS_RTP)
20496 ix86_pc_thunk_call_expanded = true;
20499 (define_insn "*set_got"
20500 [(set (match_operand:SI 0 "register_operand" "=r")
20501 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
20502 (clobber (reg:CC FLAGS_REG))]
20504 "* return output_set_got (operands[0], NULL_RTX);"
20505 [(set_attr "type" "multi")
20506 (set_attr "length" "12")])
20508 (define_expand "set_got_labelled"
20510 [(set (match_operand:SI 0 "register_operand")
20511 (unspec:SI [(label_ref (match_operand 1))]
20513 (clobber (reg:CC FLAGS_REG))])]
20516 if (flag_pic && !TARGET_VXWORKS_RTP)
20517 ix86_pc_thunk_call_expanded = true;
20520 (define_insn "*set_got_labelled"
20521 [(set (match_operand:SI 0 "register_operand" "=r")
20522 (unspec:SI [(label_ref (match_operand 1))]
20524 (clobber (reg:CC FLAGS_REG))]
20526 "* return output_set_got (operands[0], operands[1]);"
20527 [(set_attr "type" "multi")
20528 (set_attr "length" "12")])
20530 (define_insn "set_got_rex64"
20531 [(set (match_operand:DI 0 "register_operand" "=r")
20532 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
20534 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
20535 [(set_attr "type" "lea")
20536 (set_attr "length_address" "4")
20537 (set_attr "mode" "DI")])
20539 (define_insn "set_rip_rex64"
20540 [(set (match_operand:DI 0 "register_operand" "=r")
20541 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
20543 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
20544 [(set_attr "type" "lea")
20545 (set_attr "length_address" "4")
20546 (set_attr "mode" "DI")])
20548 (define_insn "set_got_offset_rex64"
20549 [(set (match_operand:DI 0 "register_operand" "=r")
20551 [(label_ref (match_operand 1))]
20552 UNSPEC_SET_GOT_OFFSET))]
20554 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
20555 [(set_attr "type" "imov")
20556 (set_attr "length_immediate" "0")
20557 (set_attr "length_address" "8")
20558 (set_attr "mode" "DI")])
20560 (define_expand "epilogue"
20563 "ix86_expand_epilogue (1); DONE;")
20565 (define_expand "sibcall_epilogue"
20568 "ix86_expand_epilogue (0); DONE;")
20570 (define_expand "eh_return"
20571 [(use (match_operand 0 "register_operand"))]
20574 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
20576 /* Tricky bit: we write the address of the handler to which we will
20577 be returning into someone else's stack frame, one word below the
20578 stack address we wish to restore. */
20579 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
20580 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
20581 /* Return address is always in word_mode. */
20582 tmp = gen_rtx_MEM (word_mode, tmp);
20583 if (GET_MODE (ra) != word_mode)
20584 ra = convert_to_mode (word_mode, ra, 1);
20585 emit_move_insn (tmp, ra);
20587 emit_jump_insn (gen_eh_return_internal ());
20592 (define_insn_and_split "eh_return_internal"
20596 "epilogue_completed"
20598 "ix86_expand_epilogue (2); DONE;")
20600 (define_expand "@leave_<mode>"
20602 [(set (reg:W SP_REG) (plus:W (reg:W BP_REG) (match_dup 0)))
20603 (set (reg:W BP_REG) (mem:W (reg:W BP_REG)))
20604 (clobber (mem:BLK (scratch)))])]
20606 "operands[0] = GEN_INT (<MODE_SIZE>);")
20608 (define_insn "*leave"
20609 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
20610 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
20611 (clobber (mem:BLK (scratch)))]
20614 [(set_attr "type" "leave")])
20616 (define_insn "*leave_rex64"
20617 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
20618 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
20619 (clobber (mem:BLK (scratch)))]
20622 [(set_attr "type" "leave")])
20624 ;; Handle -fsplit-stack.
20626 (define_expand "split_stack_prologue"
20630 ix86_expand_split_stack_prologue ();
20634 ;; In order to support the call/return predictor, we use a return
20635 ;; instruction which the middle-end doesn't see.
20636 (define_insn "split_stack_return"
20637 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
20638 UNSPECV_SPLIT_STACK_RETURN)]
20641 if (operands[0] == const0_rtx)
20646 [(set_attr "atom_unit" "jeu")
20647 (set_attr "modrm" "0")
20648 (set (attr "length")
20649 (if_then_else (match_operand:SI 0 "const0_operand")
20652 (set (attr "length_immediate")
20653 (if_then_else (match_operand:SI 0 "const0_operand")
20657 ;; If there are operand 0 bytes available on the stack, jump to
20660 (define_expand "split_stack_space_check"
20661 [(set (pc) (if_then_else
20662 (ltu (minus (reg SP_REG)
20663 (match_operand 0 "register_operand"))
20665 (label_ref (match_operand 1))
20669 rtx reg = gen_reg_rtx (Pmode);
20671 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, operands[0]));
20673 operands[2] = ix86_split_stack_guard ();
20674 ix86_expand_branch (GEU, reg, operands[2], operands[1]);
20679 ;; Bit manipulation instructions.
20681 (define_expand "ffs<mode>2"
20682 [(set (match_dup 2) (const_int -1))
20683 (parallel [(set (match_dup 3) (match_dup 4))
20684 (set (match_operand:SWI48 0 "register_operand")
20686 (match_operand:SWI48 1 "nonimmediate_operand")))])
20687 (set (match_dup 0) (if_then_else:SWI48
20688 (eq (match_dup 3) (const_int 0))
20691 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
20692 (clobber (reg:CC FLAGS_REG))])]
20695 machine_mode flags_mode;
20697 if (<MODE>mode == SImode && !TARGET_CMOVE)
20699 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
20703 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
20705 operands[2] = gen_reg_rtx (<MODE>mode);
20706 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
20707 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
20710 (define_insn_and_split "ffssi2_no_cmove"
20711 [(set (match_operand:SI 0 "register_operand" "=r")
20712 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
20713 (clobber (match_scratch:SI 2 "=&q"))
20714 (clobber (reg:CC FLAGS_REG))]
20717 "&& reload_completed"
20718 [(parallel [(set (match_dup 4) (match_dup 5))
20719 (set (match_dup 0) (ctz:SI (match_dup 1)))])
20720 (set (strict_low_part (match_dup 3))
20721 (eq:QI (match_dup 4) (const_int 0)))
20722 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
20723 (clobber (reg:CC FLAGS_REG))])
20724 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
20725 (clobber (reg:CC FLAGS_REG))])
20726 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
20727 (clobber (reg:CC FLAGS_REG))])]
20729 machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
20731 operands[3] = gen_lowpart (QImode, operands[2]);
20732 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
20733 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
20735 ix86_expand_clear (operands[2]);
20738 (define_insn_and_split "*tzcnt<mode>_1"
20739 [(set (reg:CCC FLAGS_REG)
20740 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
20742 (set (match_operand:SWI48 0 "register_operand" "=r")
20743 (ctz:SWI48 (match_dup 1)))]
20745 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
20746 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
20747 && optimize_function_for_speed_p (cfun)
20748 && !reg_mentioned_p (operands[0], operands[1])"
20750 [(set (reg:CCC FLAGS_REG)
20751 (compare:CCC (match_dup 1) (const_int 0)))
20753 (ctz:SWI48 (match_dup 1)))
20754 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
20755 "ix86_expand_clear (operands[0]);"
20756 [(set_attr "type" "alu1")
20757 (set_attr "prefix_0f" "1")
20758 (set_attr "prefix_rep" "1")
20759 (set_attr "btver2_decode" "double")
20760 (set_attr "mode" "<MODE>")])
20762 ; False dependency happens when destination is only updated by tzcnt,
20763 ; lzcnt or popcnt. There is no false dependency when destination is
20764 ; also used in source.
20765 (define_insn "*tzcnt<mode>_1_falsedep"
20766 [(set (reg:CCC FLAGS_REG)
20767 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
20769 (set (match_operand:SWI48 0 "register_operand" "=r")
20770 (ctz:SWI48 (match_dup 1)))
20771 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
20772 UNSPEC_INSN_FALSE_DEP)]
20774 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
20775 [(set_attr "type" "alu1")
20776 (set_attr "prefix_0f" "1")
20777 (set_attr "prefix_rep" "1")
20778 (set_attr "btver2_decode" "double")
20779 (set_attr "mode" "<MODE>")])
20781 (define_insn "*bsf<mode>_1"
20782 [(set (reg:CCZ FLAGS_REG)
20783 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
20785 (set (match_operand:SWI48 0 "register_operand" "=r")
20786 (ctz:SWI48 (match_dup 1)))]
20788 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
20789 [(set_attr "type" "alu1")
20790 (set_attr "prefix_0f" "1")
20791 (set_attr "btver2_decode" "double")
20792 (set_attr "znver1_decode" "vector")
20793 (set_attr "mode" "<MODE>")])
20795 (define_insn_and_split "ctz<mode>2"
20796 [(set (match_operand:SWI48 0 "register_operand" "=r")
20798 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
20799 (clobber (reg:CC FLAGS_REG))]
20803 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
20804 else if (optimize_function_for_size_p (cfun))
20806 else if (TARGET_CPU_P (GENERIC))
20807 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
20808 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
20810 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
20812 "(TARGET_BMI || TARGET_CPU_P (GENERIC))
20813 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
20814 && optimize_function_for_speed_p (cfun)
20815 && !reg_mentioned_p (operands[0], operands[1])"
20817 [(set (match_dup 0)
20818 (ctz:SWI48 (match_dup 1)))
20819 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
20820 (clobber (reg:CC FLAGS_REG))])]
20821 "ix86_expand_clear (operands[0]);"
20822 [(set_attr "type" "alu1")
20823 (set_attr "prefix_0f" "1")
20824 (set (attr "prefix_rep")
20826 (ior (match_test "TARGET_BMI")
20827 (and (not (match_test "optimize_function_for_size_p (cfun)"))
20828 (match_test "TARGET_CPU_P (GENERIC)")))
20830 (const_string "0")))
20831 (set_attr "mode" "<MODE>")])
20833 ; False dependency happens when destination is only updated by tzcnt,
20834 ; lzcnt or popcnt. There is no false dependency when destination is
20835 ; also used in source.
20836 (define_insn "*ctz<mode>2_falsedep"
20837 [(set (match_operand:SWI48 0 "register_operand" "=r")
20839 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
20840 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
20841 UNSPEC_INSN_FALSE_DEP)
20842 (clobber (reg:CC FLAGS_REG))]
20846 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
20847 else if (TARGET_CPU_P (GENERIC))
20848 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
20849 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
20851 gcc_unreachable ();
20853 [(set_attr "type" "alu1")
20854 (set_attr "prefix_0f" "1")
20855 (set_attr "prefix_rep" "1")
20856 (set_attr "mode" "<MODE>")])
20858 (define_insn_and_split "*ctzsi2_zext"
20859 [(set (match_operand:DI 0 "register_operand" "=r")
20863 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
20865 (clobber (reg:CC FLAGS_REG))]
20866 "TARGET_BMI && TARGET_64BIT"
20867 "tzcnt{l}\t{%1, %k0|%k0, %1}"
20868 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
20869 && optimize_function_for_speed_p (cfun)
20870 && !reg_mentioned_p (operands[0], operands[1])"
20872 [(set (match_dup 0)
20873 (and:DI (subreg:DI (ctz:SI (match_dup 1)) 0) (const_int 63)))
20874 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
20875 (clobber (reg:CC FLAGS_REG))])]
20876 "ix86_expand_clear (operands[0]);"
20877 [(set_attr "type" "alu1")
20878 (set_attr "prefix_0f" "1")
20879 (set_attr "prefix_rep" "1")
20880 (set_attr "mode" "SI")])
20882 ; False dependency happens when destination is only updated by tzcnt,
20883 ; lzcnt or popcnt. There is no false dependency when destination is
20884 ; also used in source.
20885 (define_insn "*ctzsi2_zext_falsedep"
20886 [(set (match_operand:DI 0 "register_operand" "=r")
20890 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
20892 (unspec [(match_operand:DI 2 "register_operand" "0")]
20893 UNSPEC_INSN_FALSE_DEP)
20894 (clobber (reg:CC FLAGS_REG))]
20895 "TARGET_BMI && TARGET_64BIT"
20896 "tzcnt{l}\t{%1, %k0|%k0, %1}"
20897 [(set_attr "type" "alu1")
20898 (set_attr "prefix_0f" "1")
20899 (set_attr "prefix_rep" "1")
20900 (set_attr "mode" "SI")])
20902 (define_insn_and_split "*ctzsidi2_<s>ext"
20903 [(set (match_operand:DI 0 "register_operand" "=r")
20906 (match_operand:SI 1 "nonimmediate_operand" "rm"))))
20907 (clobber (reg:CC FLAGS_REG))]
20911 return "tzcnt{l}\t{%1, %k0|%k0, %1}";
20912 else if (TARGET_CPU_P (GENERIC)
20913 && !optimize_function_for_size_p (cfun))
20914 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
20915 return "rep%; bsf{l}\t{%1, %k0|%k0, %1}";
20916 return "bsf{l}\t{%1, %k0|%k0, %1}";
20918 "(TARGET_BMI || TARGET_CPU_P (GENERIC))
20919 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
20920 && optimize_function_for_speed_p (cfun)
20921 && !reg_mentioned_p (operands[0], operands[1])"
20923 [(set (match_dup 0)
20924 (any_extend:DI (ctz:SI (match_dup 1))))
20925 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
20926 (clobber (reg:CC FLAGS_REG))])]
20927 "ix86_expand_clear (operands[0]);"
20928 [(set_attr "type" "alu1")
20929 (set_attr "prefix_0f" "1")
20930 (set (attr "prefix_rep")
20932 (ior (match_test "TARGET_BMI")
20933 (and (not (match_test "optimize_function_for_size_p (cfun)"))
20934 (match_test "TARGET_CPU_P (GENERIC)")))
20936 (const_string "0")))
20937 (set_attr "mode" "SI")])
20939 (define_insn "*ctzsidi2_<s>ext_falsedep"
20940 [(set (match_operand:DI 0 "register_operand" "=r")
20943 (match_operand:SI 1 "nonimmediate_operand" "rm"))))
20944 (unspec [(match_operand:DI 2 "register_operand" "0")]
20945 UNSPEC_INSN_FALSE_DEP)
20946 (clobber (reg:CC FLAGS_REG))]
20950 return "tzcnt{l}\t{%1, %k0|%k0, %1}";
20951 else if (TARGET_CPU_P (GENERIC))
20952 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
20953 return "rep%; bsf{l}\t{%1, %k0|%k0, %1}";
20955 gcc_unreachable ();
20957 [(set_attr "type" "alu1")
20958 (set_attr "prefix_0f" "1")
20959 (set_attr "prefix_rep" "1")
20960 (set_attr "mode" "SI")])
20962 (define_insn "bsr_rex64"
20963 [(set (reg:CCZ FLAGS_REG)
20964 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
20966 (set (match_operand:DI 0 "register_operand" "=r")
20967 (minus:DI (const_int 63)
20968 (clz:DI (match_dup 1))))]
20970 "bsr{q}\t{%1, %0|%0, %1}"
20971 [(set_attr "type" "alu1")
20972 (set_attr "prefix_0f" "1")
20973 (set_attr "znver1_decode" "vector")
20974 (set_attr "mode" "DI")])
20976 (define_insn "bsr_rex64_1"
20977 [(set (match_operand:DI 0 "register_operand" "=r")
20978 (minus:DI (const_int 63)
20979 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
20980 (clobber (reg:CC FLAGS_REG))]
20981 "!TARGET_LZCNT && TARGET_64BIT"
20982 "bsr{q}\t{%1, %0|%0, %1}"
20983 [(set_attr "type" "alu1")
20984 (set_attr "prefix_0f" "1")
20985 (set_attr "znver1_decode" "vector")
20986 (set_attr "mode" "DI")])
20988 (define_insn "bsr_rex64_1_zext"
20989 [(set (match_operand:DI 0 "register_operand" "=r")
20991 (minus:SI (const_int 63)
20993 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
20995 (clobber (reg:CC FLAGS_REG))]
20996 "!TARGET_LZCNT && TARGET_64BIT"
20997 "bsr{q}\t{%1, %0|%0, %1}"
20998 [(set_attr "type" "alu1")
20999 (set_attr "prefix_0f" "1")
21000 (set_attr "znver1_decode" "vector")
21001 (set_attr "mode" "DI")])
21004 [(set (reg:CCZ FLAGS_REG)
21005 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
21007 (set (match_operand:SI 0 "register_operand" "=r")
21008 (minus:SI (const_int 31)
21009 (clz:SI (match_dup 1))))]
21011 "bsr{l}\t{%1, %0|%0, %1}"
21012 [(set_attr "type" "alu1")
21013 (set_attr "prefix_0f" "1")
21014 (set_attr "znver1_decode" "vector")
21015 (set_attr "mode" "SI")])
21017 (define_insn "bsr_1"
21018 [(set (match_operand:SI 0 "register_operand" "=r")
21019 (minus:SI (const_int 31)
21020 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
21021 (clobber (reg:CC FLAGS_REG))]
21023 "bsr{l}\t{%1, %0|%0, %1}"
21024 [(set_attr "type" "alu1")
21025 (set_attr "prefix_0f" "1")
21026 (set_attr "znver1_decode" "vector")
21027 (set_attr "mode" "SI")])
21029 (define_insn "bsr_zext_1"
21030 [(set (match_operand:DI 0 "register_operand" "=r")
21034 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))))
21035 (clobber (reg:CC FLAGS_REG))]
21036 "!TARGET_LZCNT && TARGET_64BIT"
21037 "bsr{l}\t{%1, %k0|%k0, %1}"
21038 [(set_attr "type" "alu1")
21039 (set_attr "prefix_0f" "1")
21040 (set_attr "znver1_decode" "vector")
21041 (set_attr "mode" "SI")])
21043 ; As bsr is undefined behavior on zero and for other input
21044 ; values it is in range 0 to 63, we can optimize away sign-extends.
21045 (define_insn_and_split "*bsr_rex64_2"
21046 [(set (match_operand:DI 0 "register_operand")
21051 (subreg:SI (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
21054 (clobber (reg:CC FLAGS_REG))]
21055 "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
21058 [(parallel [(set (reg:CCZ FLAGS_REG)
21059 (compare:CCZ (match_dup 1) (const_int 0)))
21061 (minus:DI (const_int 63) (clz:DI (match_dup 1))))])
21062 (parallel [(set (match_dup 0)
21063 (zero_extend:DI (xor:SI (match_dup 3) (const_int 63))))
21064 (clobber (reg:CC FLAGS_REG))])]
21066 operands[2] = gen_reg_rtx (DImode);
21067 operands[3] = lowpart_subreg (SImode, operands[2], DImode);
21070 (define_insn_and_split "*bsr_2"
21071 [(set (match_operand:DI 0 "register_operand")
21076 (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
21078 (clobber (reg:CC FLAGS_REG))]
21079 "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
21082 [(parallel [(set (reg:CCZ FLAGS_REG)
21083 (compare:CCZ (match_dup 1) (const_int 0)))
21085 (minus:SI (const_int 31) (clz:SI (match_dup 1))))])
21086 (parallel [(set (match_dup 0)
21087 (zero_extend:DI (xor:SI (match_dup 2) (const_int 31))))
21088 (clobber (reg:CC FLAGS_REG))])]
21089 "operands[2] = gen_reg_rtx (SImode);")
21091 ; Splitters to optimize 64 - __builtin_clzl (x) or 32 - __builtin_clz (x).
21092 ; Again, as for !TARGET_LZCNT CLZ is UB at zero, CLZ is guaranteed to be
21093 ; in [0, 63] or [0, 31] range.
21095 [(set (match_operand:SI 0 "register_operand")
21097 (match_operand:SI 2 "const_int_operand")
21099 (minus:SI (const_int 63)
21101 (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
21104 "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
21105 [(set (match_dup 3)
21106 (minus:DI (const_int 63) (clz:DI (match_dup 1))))
21108 (plus:SI (match_dup 5) (match_dup 4)))]
21110 operands[3] = gen_reg_rtx (DImode);
21111 operands[5] = lowpart_subreg (SImode, operands[3], DImode);
21112 if (INTVAL (operands[2]) == 63)
21114 emit_insn (gen_bsr_rex64_1_zext (operands[3], operands[1]));
21115 emit_move_insn (operands[0], operands[5]);
21118 operands[4] = gen_int_mode (UINTVAL (operands[2]) - 63, SImode);
21122 [(set (match_operand:SI 0 "register_operand")
21124 (match_operand:SI 2 "const_int_operand")
21126 (minus:SI (const_int 31)
21127 (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
21129 "!TARGET_LZCNT && ix86_pre_reload_split ()"
21130 [(set (match_dup 3)
21131 (minus:SI (const_int 31) (clz:SI (match_dup 1))))
21133 (plus:SI (match_dup 3) (match_dup 4)))]
21135 if (INTVAL (operands[2]) == 31)
21137 emit_insn (gen_bsr_1 (operands[0], operands[1]));
21140 operands[3] = gen_reg_rtx (SImode);
21141 operands[4] = gen_int_mode (UINTVAL (operands[2]) - 31, SImode);
21145 [(set (match_operand:DI 0 "register_operand")
21147 (match_operand:DI 2 "const_int_operand")
21150 (minus:SI (const_int 63)
21152 (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
21157 && ix86_pre_reload_split ()
21158 && ((unsigned HOST_WIDE_INT)
21159 trunc_int_for_mode (UINTVAL (operands[2]) - 63, SImode)
21160 == UINTVAL (operands[2]) - 63)"
21161 [(set (match_dup 3)
21162 (minus:DI (const_int 63) (clz:DI (match_dup 1))))
21164 (plus:DI (match_dup 3) (match_dup 4)))]
21166 if (INTVAL (operands[2]) == 63)
21168 emit_insn (gen_bsr_rex64_1 (operands[0], operands[1]));
21171 operands[3] = gen_reg_rtx (DImode);
21172 operands[4] = GEN_INT (UINTVAL (operands[2]) - 63);
21176 [(set (match_operand:DI 0 "register_operand")
21178 (match_operand:DI 2 "const_int_operand")
21181 (minus:SI (const_int 31)
21182 (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
21183 (const_int 31)))))]
21186 && ix86_pre_reload_split ()
21187 && ((unsigned HOST_WIDE_INT)
21188 trunc_int_for_mode (UINTVAL (operands[2]) - 31, SImode)
21189 == UINTVAL (operands[2]) - 31)"
21190 [(set (match_dup 3)
21191 (zero_extend:DI (minus:SI (const_int 31) (clz:SI (match_dup 1)))))
21193 (plus:DI (match_dup 3) (match_dup 4)))]
21195 if (INTVAL (operands[2]) == 31)
21197 emit_insn (gen_bsr_zext_1 (operands[0], operands[1]));
21200 operands[3] = gen_reg_rtx (DImode);
21201 operands[4] = GEN_INT (UINTVAL (operands[2]) - 31);
21204 (define_expand "clz<mode>2"
21206 [(set (reg:CCZ FLAGS_REG)
21207 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
21209 (set (match_dup 3) (minus:SWI48
21211 (clz:SWI48 (match_dup 1))))])
21213 [(set (match_operand:SWI48 0 "register_operand")
21214 (xor:SWI48 (match_dup 3) (match_dup 2)))
21215 (clobber (reg:CC FLAGS_REG))])]
21220 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
21223 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
21224 operands[3] = gen_reg_rtx (<MODE>mode);
21227 (define_insn_and_split "clz<mode>2_lzcnt_nf"
21228 [(set (match_operand:SWI48 0 "register_operand" "=r")
21230 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
21231 "TARGET_APX_NF && TARGET_LZCNT"
21232 "%{nf%} lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
21233 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
21234 && optimize_function_for_speed_p (cfun)
21235 && !reg_mentioned_p (operands[0], operands[1])"
21237 [(set (match_dup 0)
21238 (clz:SWI48 (match_dup 1)))
21239 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
21240 "ix86_expand_clear (operands[0]);"
21241 [(set_attr "prefix_rep" "1")
21242 (set_attr "type" "bitmanip")
21243 (set_attr "mode" "<MODE>")])
21245 (define_insn_and_split "clz<mode>2_lzcnt"
21246 [(set (match_operand:SWI48 0 "register_operand" "=r")
21248 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
21249 (clobber (reg:CC FLAGS_REG))]
21251 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
21252 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
21253 && optimize_function_for_speed_p (cfun)
21254 && !reg_mentioned_p (operands[0], operands[1])"
21256 [(set (match_dup 0)
21257 (clz:SWI48 (match_dup 1)))
21258 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
21259 (clobber (reg:CC FLAGS_REG))])]
21260 "ix86_expand_clear (operands[0]);"
21261 [(set_attr "prefix_rep" "1")
21262 (set_attr "type" "bitmanip")
21263 (set_attr "has_nf" "1")
21264 (set_attr "mode" "<MODE>")])
21266 ; False dependency happens when destination is only updated by tzcnt,
21267 ; lzcnt or popcnt. There is no false dependency when destination is
21268 ; also used in source.
21269 (define_insn "*clz<mode>2_lzcnt_falsedep_nf"
21270 [(set (match_operand:SWI48 0 "register_operand" "=r")
21272 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
21273 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
21274 UNSPEC_INSN_FALSE_DEP)]
21275 "TARGET_APX_NF && TARGET_LZCNT"
21276 "%{nf%} lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
21277 [(set_attr "prefix_rep" "1")
21278 (set_attr "type" "bitmanip")
21279 (set_attr "mode" "<MODE>")])
21281 (define_insn "*clz<mode>2_lzcnt_falsedep"
21282 [(set (match_operand:SWI48 0 "register_operand" "=r")
21284 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
21285 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
21286 UNSPEC_INSN_FALSE_DEP)
21287 (clobber (reg:CC FLAGS_REG))]
21289 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
21290 [(set_attr "prefix_rep" "1")
21291 (set_attr "type" "bitmanip")
21292 (set_attr "has_nf" "1")
21293 (set_attr "mode" "<MODE>")])
21295 (define_insn_and_split "*clzsi2_lzcnt_zext"
21296 [(set (match_operand:DI 0 "register_operand" "=r")
21300 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
21302 (clobber (reg:CC FLAGS_REG))]
21303 "TARGET_LZCNT && TARGET_64BIT"
21304 "lzcnt{l}\t{%1, %k0|%k0, %1}"
21305 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
21306 && optimize_function_for_speed_p (cfun)
21307 && !reg_mentioned_p (operands[0], operands[1])"
21309 [(set (match_dup 0)
21310 (and:DI (subreg:DI (clz:SI (match_dup 1)) 0) (const_int 63)))
21311 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
21312 (clobber (reg:CC FLAGS_REG))])]
21313 "ix86_expand_clear (operands[0]);"
21314 [(set_attr "prefix_rep" "1")
21315 (set_attr "type" "bitmanip")
21316 (set_attr "mode" "SI")])
21318 ; False dependency happens when destination is only updated by tzcnt,
21319 ; lzcnt or popcnt. There is no false dependency when destination is
21320 ; also used in source.
21321 (define_insn "*clzsi2_lzcnt_zext_falsedep"
21322 [(set (match_operand:DI 0 "register_operand" "=r")
21326 (match_operand:SWI48 1 "nonimmediate_operand" "rm")) 0)
21328 (unspec [(match_operand:DI 2 "register_operand" "0")]
21329 UNSPEC_INSN_FALSE_DEP)
21330 (clobber (reg:CC FLAGS_REG))]
21332 "lzcnt{l}\t{%1, %k0|%k0, %1}"
21333 [(set_attr "prefix_rep" "1")
21334 (set_attr "type" "bitmanip")
21335 (set_attr "mode" "SI")])
21337 (define_insn_and_split "*clzsi2_lzcnt_zext_2"
21338 [(set (match_operand:DI 0 "register_operand" "=r")
21340 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
21341 (clobber (reg:CC FLAGS_REG))]
21342 "TARGET_LZCNT && TARGET_64BIT"
21343 "lzcnt{l}\t{%1, %k0|%k0, %1}"
21344 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
21345 && optimize_function_for_speed_p (cfun)
21346 && !reg_mentioned_p (operands[0], operands[1])"
21348 [(set (match_dup 0)
21349 (zero_extend:DI (clz:SI (match_dup 1))))
21350 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
21351 (clobber (reg:CC FLAGS_REG))])]
21352 "ix86_expand_clear (operands[0]);"
21353 [(set_attr "prefix_rep" "1")
21354 (set_attr "type" "bitmanip")
21355 (set_attr "mode" "SI")])
21357 ; False dependency happens when destination is only updated by tzcnt,
21358 ; lzcnt or popcnt. There is no false dependency when destination is
21359 ; also used in source.
21360 (define_insn "*clzsi2_lzcnt_zext_2_falsedep"
21361 [(set (match_operand:DI 0 "register_operand" "=r")
21363 (clz:SI (match_operand:SWI48 1 "nonimmediate_operand" "rm"))))
21364 (unspec [(match_operand:DI 2 "register_operand" "0")]
21365 UNSPEC_INSN_FALSE_DEP)
21366 (clobber (reg:CC FLAGS_REG))]
21368 "lzcnt{l}\t{%1, %k0|%k0, %1}"
21369 [(set_attr "prefix_rep" "1")
21370 (set_attr "type" "bitmanip")
21371 (set_attr "mode" "SI")])
21373 (define_int_iterator LT_ZCNT
21374 [(UNSPEC_TZCNT "TARGET_BMI")
21375 (UNSPEC_LZCNT "TARGET_LZCNT")])
21377 (define_int_attr lt_zcnt
21378 [(UNSPEC_TZCNT "tzcnt")
21379 (UNSPEC_LZCNT "lzcnt")])
21381 (define_int_attr lt_zcnt_type
21382 [(UNSPEC_TZCNT "alu1")
21383 (UNSPEC_LZCNT "bitmanip")])
21385 ;; Version of lzcnt/tzcnt that is expanded from intrinsics. This version
21386 ;; provides operand size as output when source operand is zero.
21388 (define_insn_and_split "<lt_zcnt>_<mode>_nf"
21389 [(set (match_operand:SWI48 0 "register_operand" "=r")
21391 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))]
21393 "%{nf%} <lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
21394 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
21395 && optimize_function_for_speed_p (cfun)
21396 && !reg_mentioned_p (operands[0], operands[1])"
21398 [(set (match_dup 0)
21399 (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
21400 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
21401 "ix86_expand_clear (operands[0]);"
21402 [(set_attr "type" "<lt_zcnt_type>")
21403 (set_attr "prefix_0f" "1")
21404 (set_attr "prefix_rep" "1")
21405 (set_attr "mode" "<MODE>")])
21407 (define_insn_and_split "<lt_zcnt>_<mode>"
21408 [(set (match_operand:SWI48 0 "register_operand" "=r")
21410 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
21411 (clobber (reg:CC FLAGS_REG))]
21413 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
21414 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
21415 && optimize_function_for_speed_p (cfun)
21416 && !reg_mentioned_p (operands[0], operands[1])"
21418 [(set (match_dup 0)
21419 (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
21420 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
21421 (clobber (reg:CC FLAGS_REG))])]
21422 "ix86_expand_clear (operands[0]);"
21423 [(set_attr "type" "<lt_zcnt_type>")
21424 (set_attr "prefix_0f" "1")
21425 (set_attr "prefix_rep" "1")
21426 (set_attr "has_nf" "1")
21427 (set_attr "mode" "<MODE>")])
21429 ; False dependency happens when destination is only updated by tzcnt,
21430 ; lzcnt or popcnt. There is no false dependency when destination is
21431 ; also used in source.
21432 (define_insn "*<lt_zcnt>_<mode>_falsedep_nf"
21433 [(set (match_operand:SWI48 0 "register_operand" "=r")
21435 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
21436 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
21437 UNSPEC_INSN_FALSE_DEP)]
21439 "%{nf%} <lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
21440 [(set_attr "type" "<lt_zcnt_type>")
21441 (set_attr "prefix_0f" "1")
21442 (set_attr "prefix_rep" "1")
21443 (set_attr "mode" "<MODE>")])
21445 (define_insn "*<lt_zcnt>_<mode>_falsedep"
21446 [(set (match_operand:SWI48 0 "register_operand" "=r")
21448 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
21449 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
21450 UNSPEC_INSN_FALSE_DEP)
21451 (clobber (reg:CC FLAGS_REG))]
21453 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
21454 [(set_attr "type" "<lt_zcnt_type>")
21455 (set_attr "prefix_0f" "1")
21456 (set_attr "prefix_rep" "1")
21457 (set_attr "has_nf" "1")
21458 (set_attr "mode" "<MODE>")])
21460 (define_insn "<lt_zcnt>_hi<nf_name>"
21461 [(set (match_operand:HI 0 "register_operand" "=r")
21463 [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT))]
21465 "<nf_prefix><lt_zcnt>{w}\t{%1, %0|%0, %1}"
21466 [(set_attr "type" "<lt_zcnt_type>")
21467 (set_attr "prefix_0f" "1")
21468 (set_attr "prefix_rep" "1")
21469 (set_attr "has_nf" "1")
21470 (set_attr "mode" "HI")])
21472 ;; BMI instructions.
21474 (define_insn "bmi_bextr_<mode>"
21475 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
21476 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
21477 (match_operand:SWI48 2 "register_operand" "r,r")]
21479 (clobber (reg:CC FLAGS_REG))]
21481 "bextr\t{%2, %1, %0|%0, %1, %2}"
21482 [(set_attr "type" "bitmanip")
21483 (set_attr "btver2_decode" "direct, double")
21484 (set_attr "mode" "<MODE>")])
21486 (define_insn "*bmi_bextr_<mode>_ccz"
21487 [(set (reg:CCZ FLAGS_REG)
21489 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
21490 (match_operand:SWI48 2 "register_operand" "r,r")]
21493 (clobber (match_scratch:SWI48 0 "=r,r"))]
21495 "bextr\t{%2, %1, %0|%0, %1, %2}"
21496 [(set_attr "type" "bitmanip")
21497 (set_attr "btver2_decode" "direct, double")
21498 (set_attr "mode" "<MODE>")])
21500 (define_insn "*bmi_blsi_<mode>"
21501 [(set (match_operand:SWI48 0 "register_operand" "=r")
21504 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
21506 (clobber (reg:CC FLAGS_REG))]
21508 "blsi\t{%1, %0|%0, %1}"
21509 [(set_attr "type" "bitmanip")
21510 (set_attr "btver2_decode" "double")
21511 (set_attr "mode" "<MODE>")])
21513 (define_insn "*bmi_blsi_<mode>_cmp"
21514 [(set (reg FLAGS_REG)
21517 (neg:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
21520 (set (match_operand:SWI48 0 "register_operand" "=r")
21521 (and:SWI48 (neg:SWI48 (match_dup 1)) (match_dup 1)))]
21522 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
21523 "blsi\t{%1, %0|%0, %1}"
21524 [(set_attr "type" "bitmanip")
21525 (set_attr "btver2_decode" "double")
21526 (set_attr "mode" "<MODE>")])
21528 (define_insn "*bmi_blsi_<mode>_ccno"
21529 [(set (reg FLAGS_REG)
21532 (neg:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
21535 (clobber (match_scratch:SWI48 0 "=r"))]
21536 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
21537 "blsi\t{%1, %0|%0, %1}"
21538 [(set_attr "type" "bitmanip")
21539 (set_attr "btver2_decode" "double")
21540 (set_attr "mode" "<MODE>")])
21542 (define_insn "*bmi_blsmsk_<mode>"
21543 [(set (match_operand:SWI48 0 "register_operand" "=r")
21546 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
21549 (clobber (reg:CC FLAGS_REG))]
21551 "blsmsk\t{%1, %0|%0, %1}"
21552 [(set_attr "type" "bitmanip")
21553 (set_attr "btver2_decode" "double")
21554 (set_attr "mode" "<MODE>")])
21556 (define_insn "*bmi_blsr_<mode>"
21557 [(set (match_operand:SWI48 0 "register_operand" "=r")
21560 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
21563 (clobber (reg:CC FLAGS_REG))]
21565 "blsr\t{%1, %0|%0, %1}"
21566 [(set_attr "type" "bitmanip")
21567 (set_attr "btver2_decode" "double")
21568 (set_attr "mode" "<MODE>")])
21570 (define_insn "*bmi_blsr_<mode>_cmp"
21571 [(set (reg:CCZ FLAGS_REG)
21575 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
21579 (set (match_operand:SWI48 0 "register_operand" "=r")
21586 "blsr\t{%1, %0|%0, %1}"
21587 [(set_attr "type" "bitmanip")
21588 (set_attr "btver2_decode" "double")
21589 (set_attr "mode" "<MODE>")])
21591 (define_insn "*bmi_blsr_<mode>_ccz"
21592 [(set (reg:CCZ FLAGS_REG)
21596 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
21600 (clobber (match_scratch:SWI48 0 "=r"))]
21602 "blsr\t{%1, %0|%0, %1}"
21603 [(set_attr "type" "bitmanip")
21604 (set_attr "btver2_decode" "double")
21605 (set_attr "mode" "<MODE>")])
21607 ;; BMI2 instructions.
21608 (define_expand "bmi2_bzhi_<mode>3"
21610 [(set (match_operand:SWI48 0 "register_operand")
21611 (if_then_else:SWI48
21612 (ne:QI (match_operand:QI 2 "register_operand")
21614 (zero_extract:SWI48
21615 (match_operand:SWI48 1 "nonimmediate_operand")
21616 (umin:QI (match_dup 2) (match_dup 3))
21619 (clobber (reg:CC FLAGS_REG))])]
21622 operands[2] = gen_lowpart (QImode, operands[2]);
21623 operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
21626 (define_insn "*bmi2_bzhi_<mode>3"
21627 [(set (match_operand:SWI48 0 "register_operand" "=r")
21628 (if_then_else:SWI48
21629 (ne:QI (match_operand:QI 2 "register_operand" "q")
21631 (zero_extract:SWI48
21632 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
21633 (umin:QI (match_dup 2)
21634 (match_operand:QI 3 "const_int_operand"))
21637 (clobber (reg:CC FLAGS_REG))]
21638 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
21639 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
21640 [(set_attr "type" "bitmanip")
21641 (set_attr "prefix" "vex")
21642 (set_attr "mode" "<MODE>")])
21644 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
21645 [(set (reg:CCZ FLAGS_REG)
21647 (if_then_else:SWI48
21648 (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0))
21649 (zero_extract:SWI48
21650 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
21651 (umin:QI (match_dup 2)
21652 (match_operand:QI 3 "const_int_operand"))
21656 (clobber (match_scratch:SWI48 0 "=r"))]
21657 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
21658 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
21659 [(set_attr "type" "bitmanip")
21660 (set_attr "prefix" "vex")
21661 (set_attr "mode" "<MODE>")])
21663 (define_insn "*bmi2_bzhi_<mode>3_2"
21664 [(set (match_operand:SWI48 0 "register_operand" "=r")
21667 (ashift:SWI48 (const_int 1)
21668 (match_operand:QI 2 "register_operand" "r"))
21670 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
21671 (clobber (reg:CC FLAGS_REG))]
21673 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
21674 [(set_attr "type" "bitmanip")
21675 (set_attr "prefix" "vex")
21676 (set_attr "mode" "<MODE>")])
21678 (define_insn "*bmi2_bzhi_<mode>3_3"
21679 [(set (match_operand:SWI48 0 "register_operand" "=r")
21682 (ashift:SWI48 (const_int -1)
21683 (match_operand:QI 2 "register_operand" "r")))
21684 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
21685 (clobber (reg:CC FLAGS_REG))]
21687 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
21688 [(set_attr "type" "bitmanip")
21689 (set_attr "prefix" "vex")
21690 (set_attr "mode" "<MODE>")])
21692 (define_insn "*bmi2_bzhi_zero_extendsidi_4"
21693 [(set (match_operand:DI 0 "register_operand" "=r")
21697 (ashift:SI (const_int 1)
21698 (match_operand:QI 2 "register_operand" "r"))
21700 (match_operand:SI 1 "nonimmediate_operand" "rm"))))
21701 (clobber (reg:CC FLAGS_REG))]
21702 "TARGET_64BIT && TARGET_BMI2"
21703 "bzhi\t{%q2, %q1, %q0|%q0, %q1, %q2}"
21704 [(set_attr "type" "bitmanip")
21705 (set_attr "prefix" "vex")
21706 (set_attr "mode" "DI")])
21708 (define_insn "*bmi2_bzhi_zero_extendsidi_5"
21709 [(set (match_operand:DI 0 "register_operand" "=r")
21713 (ashift:SI (const_int 1)
21714 (match_operand:QI 2 "register_operand" "r"))
21716 (match_operand:DI 1 "nonimmediate_operand" "rm")))
21717 (clobber (reg:CC FLAGS_REG))]
21718 "TARGET_64BIT && TARGET_BMI2"
21719 "bzhi\t{%q2, %q1, %q0|%q0, %q1, %q2}"
21720 [(set_attr "type" "bitmanip")
21721 (set_attr "prefix" "vex")
21722 (set_attr "mode" "DI")])
21724 (define_insn "bmi2_pdep_<mode>3"
21725 [(set (match_operand:SWI48 0 "register_operand" "=r")
21726 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
21727 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
21730 "pdep\t{%2, %1, %0|%0, %1, %2}"
21731 [(set_attr "type" "bitmanip")
21732 (set_attr "prefix" "vex")
21733 (set_attr "mode" "<MODE>")])
21735 (define_insn "bmi2_pext_<mode>3"
21736 [(set (match_operand:SWI48 0 "register_operand" "=r")
21737 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
21738 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
21741 "pext\t{%2, %1, %0|%0, %1, %2}"
21742 [(set_attr "type" "bitmanip")
21743 (set_attr "prefix" "vex")
21744 (set_attr "mode" "<MODE>")])
21746 ;; TBM instructions.
21747 (define_insn "@tbm_bextri_<mode>"
21748 [(set (match_operand:SWI48 0 "register_operand" "=r")
21749 (zero_extract:SWI48
21750 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
21751 (match_operand:QI 2 "const_0_to_255_operand")
21752 (match_operand:QI 3 "const_0_to_255_operand")))
21753 (clobber (reg:CC FLAGS_REG))]
21756 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
21757 return "bextr\t{%2, %1, %0|%0, %1, %2}";
21759 [(set_attr "type" "bitmanip")
21760 (set_attr "mode" "<MODE>")])
21762 (define_insn "*tbm_blcfill_<mode>"
21763 [(set (match_operand:SWI48 0 "register_operand" "=r")
21766 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
21769 (clobber (reg:CC FLAGS_REG))]
21771 "blcfill\t{%1, %0|%0, %1}"
21772 [(set_attr "type" "bitmanip")
21773 (set_attr "mode" "<MODE>")])
21775 (define_insn "*tbm_blci_<mode>"
21776 [(set (match_operand:SWI48 0 "register_operand" "=r")
21780 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
21783 (clobber (reg:CC FLAGS_REG))]
21785 "blci\t{%1, %0|%0, %1}"
21786 [(set_attr "type" "bitmanip")
21787 (set_attr "mode" "<MODE>")])
21789 (define_insn "*tbm_blcic_<mode>"
21790 [(set (match_operand:SWI48 0 "register_operand" "=r")
21793 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
21797 (clobber (reg:CC FLAGS_REG))]
21799 "blcic\t{%1, %0|%0, %1}"
21800 [(set_attr "type" "bitmanip")
21801 (set_attr "mode" "<MODE>")])
21803 (define_insn "*tbm_blcmsk_<mode>"
21804 [(set (match_operand:SWI48 0 "register_operand" "=r")
21807 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
21810 (clobber (reg:CC FLAGS_REG))]
21812 "blcmsk\t{%1, %0|%0, %1}"
21813 [(set_attr "type" "bitmanip")
21814 (set_attr "mode" "<MODE>")])
21816 (define_insn "*tbm_blcs_<mode>"
21817 [(set (match_operand:SWI48 0 "register_operand" "=r")
21820 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
21823 (clobber (reg:CC FLAGS_REG))]
21825 "blcs\t{%1, %0|%0, %1}"
21826 [(set_attr "type" "bitmanip")
21827 (set_attr "mode" "<MODE>")])
21829 (define_insn "*tbm_blsfill_<mode>"
21830 [(set (match_operand:SWI48 0 "register_operand" "=r")
21833 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
21836 (clobber (reg:CC FLAGS_REG))]
21838 "blsfill\t{%1, %0|%0, %1}"
21839 [(set_attr "type" "bitmanip")
21840 (set_attr "mode" "<MODE>")])
21842 (define_insn "*tbm_blsic_<mode>"
21843 [(set (match_operand:SWI48 0 "register_operand" "=r")
21846 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
21850 (clobber (reg:CC FLAGS_REG))]
21852 "blsic\t{%1, %0|%0, %1}"
21853 [(set_attr "type" "bitmanip")
21854 (set_attr "mode" "<MODE>")])
21856 (define_insn "*tbm_t1mskc_<mode>"
21857 [(set (match_operand:SWI48 0 "register_operand" "=r")
21860 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
21864 (clobber (reg:CC FLAGS_REG))]
21866 "t1mskc\t{%1, %0|%0, %1}"
21867 [(set_attr "type" "bitmanip")
21868 (set_attr "mode" "<MODE>")])
21870 (define_insn "*tbm_tzmsk_<mode>"
21871 [(set (match_operand:SWI48 0 "register_operand" "=r")
21874 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
21878 (clobber (reg:CC FLAGS_REG))]
21880 "tzmsk\t{%1, %0|%0, %1}"
21881 [(set_attr "type" "bitmanip")
21882 (set_attr "mode" "<MODE>")])
21884 (define_insn_and_split "popcount<mode>2_nf"
21885 [(set (match_operand:SWI48 0 "register_operand" "=r")
21887 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
21888 "TARGET_APX_NF && TARGET_POPCNT"
21891 return "%{nf%} popcnt\t{%1, %0|%0, %1}";
21893 return "%{nf%} popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
21896 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
21897 && optimize_function_for_speed_p (cfun)
21898 && !reg_mentioned_p (operands[0], operands[1])"
21900 [(set (match_dup 0)
21901 (popcount:SWI48 (match_dup 1)))
21902 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
21903 "ix86_expand_clear (operands[0]);"
21904 [(set_attr "prefix_rep" "1")
21905 (set_attr "type" "bitmanip")
21906 (set_attr "mode" "<MODE>")])
21908 (define_insn_and_split "popcount<mode>2"
21909 [(set (match_operand:SWI48 0 "register_operand" "=r")
21911 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
21912 (clobber (reg:CC FLAGS_REG))]
21916 return "popcnt\t{%1, %0|%0, %1}";
21918 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
21921 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
21922 && optimize_function_for_speed_p (cfun)
21923 && !reg_mentioned_p (operands[0], operands[1])"
21925 [(set (match_dup 0)
21926 (popcount:SWI48 (match_dup 1)))
21927 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
21928 (clobber (reg:CC FLAGS_REG))])]
21929 "ix86_expand_clear (operands[0]);"
21930 [(set_attr "prefix_rep" "1")
21931 (set_attr "type" "bitmanip")
21932 (set_attr "has_nf" "1")
21933 (set_attr "mode" "<MODE>")])
21935 ; False dependency happens when destination is only updated by tzcnt,
21936 ; lzcnt or popcnt. There is no false dependency when destination is
21937 ; also used in source.
21938 (define_insn "*popcount<mode>2_falsedep_nf"
21939 [(set (match_operand:SWI48 0 "register_operand" "=r")
21941 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
21942 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
21943 UNSPEC_INSN_FALSE_DEP)]
21944 "TARGET_APX_NF && TARGET_POPCNT"
21947 return "%{nf%} popcnt\t{%1, %0|%0, %1}";
21949 return "%{nf%} popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
21952 [(set_attr "prefix_rep" "1")
21953 (set_attr "type" "bitmanip")
21954 (set_attr "mode" "<MODE>")])
21956 (define_insn "*popcount<mode>2_falsedep"
21957 [(set (match_operand:SWI48 0 "register_operand" "=r")
21959 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
21960 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
21961 UNSPEC_INSN_FALSE_DEP)
21962 (clobber (reg:CC FLAGS_REG))]
21966 return "popcnt\t{%1, %0|%0, %1}";
21968 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
21971 [(set_attr "prefix_rep" "1")
21972 (set_attr "type" "bitmanip")
21973 (set_attr "has_nf" "1")
21974 (set_attr "mode" "<MODE>")])
21976 (define_insn_and_split "*popcountsi2_zext"
21977 [(set (match_operand:DI 0 "register_operand" "=r")
21981 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
21983 (clobber (reg:CC FLAGS_REG))]
21984 "TARGET_POPCNT && TARGET_64BIT"
21987 return "popcnt\t{%1, %k0|%k0, %1}";
21989 return "popcnt{l}\t{%1, %k0|%k0, %1}";
21992 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
21993 && optimize_function_for_speed_p (cfun)
21994 && !reg_mentioned_p (operands[0], operands[1])"
21996 [(set (match_dup 0)
21997 (and:DI (subreg:DI (popcount:SI (match_dup 1)) 0) (const_int 63)))
21998 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
21999 (clobber (reg:CC FLAGS_REG))])]
22000 "ix86_expand_clear (operands[0]);"
22001 [(set_attr "prefix_rep" "1")
22002 (set_attr "type" "bitmanip")
22003 (set_attr "mode" "SI")])
22005 ; False dependency happens when destination is only updated by tzcnt,
22006 ; lzcnt or popcnt. There is no false dependency when destination is
22007 ; also used in source.
22008 (define_insn "*popcountsi2_zext_falsedep"
22009 [(set (match_operand:DI 0 "register_operand" "=r")
22013 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
22015 (unspec [(match_operand:DI 2 "register_operand" "0")]
22016 UNSPEC_INSN_FALSE_DEP)
22017 (clobber (reg:CC FLAGS_REG))]
22018 "TARGET_POPCNT && TARGET_64BIT"
22021 return "popcnt\t{%1, %k0|%k0, %1}";
22023 return "popcnt{l}\t{%1, %k0|%k0, %1}";
22026 [(set_attr "prefix_rep" "1")
22027 (set_attr "type" "bitmanip")
22028 (set_attr "mode" "SI")])
22030 (define_insn_and_split "*popcountsi2_zext_2"
22031 [(set (match_operand:DI 0 "register_operand" "=r")
22033 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
22034 (clobber (reg:CC FLAGS_REG))]
22035 "TARGET_POPCNT && TARGET_64BIT"
22038 return "popcnt\t{%1, %k0|%k0, %1}";
22040 return "popcnt{l}\t{%1, %k0|%k0, %1}";
22043 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
22044 && optimize_function_for_speed_p (cfun)
22045 && !reg_mentioned_p (operands[0], operands[1])"
22047 [(set (match_dup 0)
22048 (zero_extend:DI (popcount:SI (match_dup 1))))
22049 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
22050 (clobber (reg:CC FLAGS_REG))])]
22051 "ix86_expand_clear (operands[0]);"
22052 [(set_attr "prefix_rep" "1")
22053 (set_attr "type" "bitmanip")
22054 (set_attr "mode" "SI")])
22056 ; False dependency happens when destination is only updated by tzcnt,
22057 ; lzcnt or popcnt. There is no false dependency when destination is
22058 ; also used in source.
22059 (define_insn "*popcountsi2_zext_2_falsedep"
22060 [(set (match_operand:DI 0 "register_operand" "=r")
22062 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
22063 (unspec [(match_operand:DI 2 "register_operand" "0")]
22064 UNSPEC_INSN_FALSE_DEP)
22065 (clobber (reg:CC FLAGS_REG))]
22066 "TARGET_POPCNT && TARGET_64BIT"
22069 return "popcnt\t{%1, %k0|%k0, %1}";
22071 return "popcnt{l}\t{%1, %k0|%k0, %1}";
22074 [(set_attr "prefix_rep" "1")
22075 (set_attr "type" "bitmanip")
22076 (set_attr "mode" "SI")])
22078 (define_insn_and_split "*popcounthi2_1"
22079 [(set (match_operand:SI 0 "register_operand")
22081 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
22082 (clobber (reg:CC FLAGS_REG))]
22084 && ix86_pre_reload_split ()"
22089 rtx tmp = gen_reg_rtx (HImode);
22091 emit_insn (gen_popcounthi2 (tmp, operands[1]));
22092 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
22096 (define_insn_and_split "*popcounthi2_2"
22097 [(set (match_operand:SI 0 "register_operand")
22099 (popcount:HI (match_operand:HI 1 "nonimmediate_operand"))))
22100 (clobber (reg:CC FLAGS_REG))]
22102 && ix86_pre_reload_split ()"
22107 rtx tmp = gen_reg_rtx (HImode);
22109 emit_insn (gen_popcounthi2 (tmp, operands[1]));
22110 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
22114 (define_insn "popcounthi2<nf_name>"
22115 [(set (match_operand:HI 0 "register_operand" "=r")
22117 (match_operand:HI 1 "nonimmediate_operand" "rm")))]
22118 "TARGET_POPCNT && <nf_condition>"
22121 return "<nf_prefix>popcnt\t{%1, %0|%0, %1}";
22123 return "<nf_prefix>popcnt{w}\t{%1, %0|%0, %1}";
22126 [(set_attr "prefix_rep" "1")
22127 (set_attr "type" "bitmanip")
22128 (set_attr "has_nf" "1")
22129 (set_attr "mode" "HI")])
22131 (define_expand "bswapdi2"
22132 [(set (match_operand:DI 0 "register_operand")
22133 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
22137 operands[1] = force_reg (DImode, operands[1]);
22140 (define_expand "bswapsi2"
22141 [(set (match_operand:SI 0 "register_operand")
22142 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
22147 operands[1] = force_reg (SImode, operands[1]);
22151 rtx x = gen_reg_rtx (SImode);
22153 emit_insn (gen_bswaphisi2_lowpart (x, operands[1]));
22154 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
22155 emit_insn (gen_bswaphisi2_lowpart (operands[0], x));
22161 (define_insn "*bswap<mode>2_movbe"
22162 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
22163 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
22165 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
22168 movbe{<imodesuffix>}\t{%1, %0|%0, %1}
22169 movbe{<imodesuffix>}\t{%1, %0|%0, %1}"
22170 [(set_attr "type" "bitmanip,imov,imov")
22171 (set_attr "modrm" "0,1,1")
22172 (set_attr "prefix_0f" "*,1,1")
22173 (set_attr "prefix_extra" "*,1,1")
22174 (set_attr "mode" "<MODE>")])
22176 (define_insn "*bswap<mode>2"
22177 [(set (match_operand:SWI48 0 "register_operand" "=r")
22178 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
22181 [(set_attr "type" "bitmanip")
22182 (set_attr "modrm" "0")
22183 (set_attr "mode" "<MODE>")])
22185 (define_expand "bswaphi2"
22186 [(set (match_operand:HI 0 "register_operand")
22187 (bswap:HI (match_operand:HI 1 "nonimmediate_operand")))]
22191 operands[1] = force_reg (HImode, operands[1]);
22194 (define_insn "*bswaphi2_movbe"
22195 [(set (match_operand:HI 0 "nonimmediate_operand" "=Q,r,m")
22196 (bswap:HI (match_operand:HI 1 "nonimmediate_operand" "0,m,r")))]
22198 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
22200 xchg{b}\t{%h0, %b0|%b0, %h0}
22201 movbe{w}\t{%1, %0|%0, %1}
22202 movbe{w}\t{%1, %0|%0, %1}"
22203 [(set_attr "type" "imov")
22204 (set_attr "modrm" "*,1,1")
22205 (set_attr "prefix_0f" "*,1,1")
22206 (set_attr "prefix_extra" "*,1,1")
22207 (set_attr "pent_pair" "np,*,*")
22208 (set_attr "athlon_decode" "vector,*,*")
22209 (set_attr "amdfam10_decode" "double,*,*")
22210 (set_attr "bdver1_decode" "double,*,*")
22211 (set_attr "mode" "QI,HI,HI")])
22213 (define_insn "*bswaphi2"
22214 [(set (match_operand:HI 0 "register_operand" "=Q")
22215 (bswap:HI (match_operand:HI 1 "register_operand" "0")))]
22217 "xchg{b}\t{%h0, %b0|%b0, %h0}"
22218 [(set_attr "type" "imov")
22219 (set_attr "pent_pair" "np")
22220 (set_attr "athlon_decode" "vector")
22221 (set_attr "amdfam10_decode" "double")
22222 (set_attr "bdver1_decode" "double")
22223 (set_attr "mode" "QI")])
22226 [(set (match_operand:HI 0 "general_reg_operand")
22227 (bswap:HI (match_dup 0)))]
22228 "!(TARGET_USE_XCHGB ||
22229 TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
22230 && peep2_regno_dead_p (0, FLAGS_REG)"
22231 [(parallel [(set (match_dup 0) (rotate:HI (match_dup 0) (const_int 8)))
22232 (clobber (reg:CC FLAGS_REG))])])
22234 (define_insn "bswaphisi2_lowpart"
22235 [(set (match_operand:SI 0 "register_operand" "=Q")
22236 (ior:SI (and:SI (match_operand:SI 1 "register_operand" "0")
22237 (const_int -65536))
22238 (lshiftrt:SI (bswap:SI (match_dup 1))
22241 "xchg{b}\t{%h0, %b0|%b0, %h0}"
22242 [(set_attr "type" "imov")
22243 (set_attr "pent_pair" "np")
22244 (set_attr "athlon_decode" "vector")
22245 (set_attr "amdfam10_decode" "double")
22246 (set_attr "bdver1_decode" "double")
22247 (set_attr "mode" "QI")])
22250 [(set (match_operand:SI 0 "general_reg_operand")
22251 (ior:SI (and:SI (match_dup 0)
22252 (const_int -65536))
22253 (lshiftrt:SI (bswap:SI (match_dup 0))
22255 "!(TARGET_USE_XCHGB ||
22256 TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
22257 && peep2_regno_dead_p (0, FLAGS_REG)"
22258 [(parallel [(set (strict_low_part (match_dup 0))
22259 (rotate:HI (match_dup 0) (const_int 8)))
22260 (clobber (reg:CC FLAGS_REG))])]
22261 "operands[0] = gen_lowpart (HImode, operands[0]);")
22263 ;; Variant of above peephole2 to improve register allocation.
22265 [(set (match_operand:SI 0 "general_reg_operand")
22266 (match_operand:SI 1 "register_operand"))
22268 (ior:SI (and:SI (match_dup 0)
22269 (const_int -65536))
22270 (lshiftrt:SI (bswap:SI (match_dup 0))
22272 (set (match_operand:SI 2 "general_reg_operand") (match_dup 0))]
22273 "!(TARGET_USE_XCHGB ||
22274 TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
22275 && peep2_regno_dead_p (0, FLAGS_REG)
22276 && peep2_reg_dead_p(3, operands[0])"
22278 [(set (strict_low_part (match_dup 3))
22279 (rotate:HI (match_dup 3) (const_int 8)))
22280 (clobber (reg:CC FLAGS_REG))])]
22282 if (!rtx_equal_p (operands[1], operands[2]))
22283 emit_move_insn (operands[2], operands[1]);
22284 operands[3] = gen_lowpart (HImode, operands[2]);
22287 (define_expand "paritydi2"
22288 [(set (match_operand:DI 0 "register_operand")
22289 (parity:DI (match_operand:DI 1 "register_operand")))]
22292 rtx scratch = gen_reg_rtx (QImode);
22293 rtx hipart1 = gen_reg_rtx (SImode);
22294 rtx lopart1 = gen_reg_rtx (SImode);
22295 rtx xor1 = gen_reg_rtx (SImode);
22296 rtx shift2 = gen_reg_rtx (SImode);
22297 rtx hipart2 = gen_reg_rtx (HImode);
22298 rtx lopart2 = gen_reg_rtx (HImode);
22299 rtx xor2 = gen_reg_rtx (HImode);
22303 rtx shift1 = gen_reg_rtx (DImode);
22304 emit_insn (gen_lshrdi3 (shift1, operands[1], GEN_INT (32)));
22305 emit_move_insn (hipart1, gen_lowpart (SImode, shift1));
22308 emit_move_insn (hipart1, gen_highpart (SImode, operands[1]));
22310 emit_move_insn (lopart1, gen_lowpart (SImode, operands[1]));
22311 emit_insn (gen_xorsi3 (xor1, hipart1, lopart1));
22313 emit_insn (gen_lshrsi3 (shift2, xor1, GEN_INT (16)));
22314 emit_move_insn (hipart2, gen_lowpart (HImode, shift2));
22315 emit_move_insn (lopart2, gen_lowpart (HImode, xor1));
22316 emit_insn (gen_xorhi3 (xor2, hipart2, lopart2));
22318 emit_insn (gen_parityhi2_cmp (xor2));
22320 ix86_expand_setcc (scratch, ORDERED,
22321 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
22324 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
22327 rtx tmp = gen_reg_rtx (SImode);
22329 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
22330 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
22335 (define_expand "paritysi2"
22336 [(set (match_operand:SI 0 "register_operand")
22337 (parity:SI (match_operand:SI 1 "register_operand")))]
22340 rtx scratch = gen_reg_rtx (QImode);
22341 rtx shift = gen_reg_rtx (SImode);
22342 rtx hipart = gen_reg_rtx (HImode);
22343 rtx lopart = gen_reg_rtx (HImode);
22344 rtx tmp = gen_reg_rtx (HImode);
22346 emit_insn (gen_lshrsi3 (shift, operands[1], GEN_INT (16)));
22347 emit_move_insn (hipart, gen_lowpart (HImode, shift));
22348 emit_move_insn (lopart, gen_lowpart (HImode, operands[1]));
22349 emit_insn (gen_xorhi3 (tmp, hipart, lopart));
22351 emit_insn (gen_parityhi2_cmp (tmp));
22353 ix86_expand_setcc (scratch, ORDERED,
22354 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
22356 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
22360 (define_expand "parityhi2"
22361 [(set (match_operand:HI 0 "register_operand")
22362 (parity:HI (match_operand:HI 1 "register_operand")))]
22365 rtx scratch = gen_reg_rtx (QImode);
22366 rtx tmp = gen_reg_rtx (HImode);
22368 emit_move_insn (tmp, operands[1]);
22369 emit_insn (gen_parityhi2_cmp (tmp));
22371 ix86_expand_setcc (scratch, ORDERED,
22372 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
22374 emit_insn (gen_zero_extendqihi2 (operands[0], scratch));
22378 (define_expand "parityqi2"
22379 [(set (match_operand:QI 0 "register_operand")
22380 (parity:QI (match_operand:QI 1 "register_operand")))]
22383 emit_insn (gen_parityqi2_cmp (operands[1]));
22385 ix86_expand_setcc (operands[0], ORDERED,
22386 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
22390 (define_insn "parityhi2_cmp"
22391 [(set (reg:CC FLAGS_REG)
22392 (unspec:CC [(match_operand:HI 0 "register_operand" "+Q")]
22394 (clobber (match_dup 0))]
22396 "xor{b}\t{%h0, %b0|%b0, %h0}"
22397 [(set_attr "length" "2")
22398 (set_attr "mode" "QI")])
22400 (define_insn "parityqi2_cmp"
22401 [(set (reg:CC FLAGS_REG)
22402 (unspec:CC [(match_operand:QI 0 "register_operand" "q")]
22406 [(set_attr "mode" "QI")])
22408 ;; Replace zero_extend:HI followed by parityhi2_cmp with parityqi2_cmp
22410 [(set (match_operand:HI 0 "register_operand")
22411 (zero_extend:HI (match_operand:QI 1 "general_reg_operand")))
22412 (parallel [(set (reg:CC FLAGS_REG)
22413 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
22414 (clobber (match_dup 0))])]
22416 [(set (reg:CC FLAGS_REG)
22417 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))])
22419 ;; Eliminate QImode popcount&1 using parity flag
22421 [(set (match_operand:SI 0 "register_operand")
22422 (zero_extend:SI (match_operand:QI 1 "general_reg_operand")))
22423 (parallel [(set (match_operand:SI 2 "register_operand")
22424 (popcount:SI (match_dup 0)))
22425 (clobber (reg:CC FLAGS_REG))])
22426 (set (reg:CCZ FLAGS_REG)
22427 (compare:CCZ (and:QI (match_operand:QI 3 "register_operand")
22430 (set (pc) (if_then_else (match_operator 4 "bt_comparison_operator"
22431 [(reg:CCZ FLAGS_REG)
22433 (label_ref (match_operand 5))
22435 "REGNO (operands[2]) == REGNO (operands[3])
22436 && peep2_reg_dead_p (3, operands[0])
22437 && peep2_reg_dead_p (3, operands[2])
22438 && peep2_regno_dead_p (4, FLAGS_REG)"
22439 [(set (reg:CC FLAGS_REG)
22440 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
22441 (set (pc) (if_then_else (match_op_dup 4 [(reg:CC FLAGS_REG)
22443 (label_ref (match_dup 5))
22446 operands[4] = shallow_copy_rtx (operands[4]);
22447 PUT_CODE (operands[4], GET_CODE (operands[4]) == EQ ? UNORDERED : ORDERED);
22450 ;; Eliminate HImode popcount&1 using parity flag
22452 [(match_scratch:HI 0 "Q")
22453 (parallel [(set (match_operand:HI 1 "register_operand")
22455 (match_operand:HI 2 "nonimmediate_operand")))
22456 (clobber (reg:CC FLAGS_REG))])
22457 (set (match_operand 3 "register_operand")
22458 (zero_extend (match_dup 1)))
22459 (set (reg:CCZ FLAGS_REG)
22460 (compare:CCZ (and:QI (match_operand:QI 4 "register_operand")
22463 (set (pc) (if_then_else (match_operator 5 "bt_comparison_operator"
22464 [(reg:CCZ FLAGS_REG)
22466 (label_ref (match_operand 6))
22468 "REGNO (operands[3]) == REGNO (operands[4])
22469 && peep2_reg_dead_p (3, operands[1])
22470 && peep2_reg_dead_p (3, operands[3])
22471 && peep2_regno_dead_p (4, FLAGS_REG)"
22472 [(set (match_dup 0) (match_dup 2))
22473 (parallel [(set (reg:CC FLAGS_REG)
22474 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
22475 (clobber (match_dup 0))])
22476 (set (pc) (if_then_else (match_op_dup 5 [(reg:CC FLAGS_REG)
22478 (label_ref (match_dup 6))
22481 operands[5] = shallow_copy_rtx (operands[5]);
22482 PUT_CODE (operands[5], GET_CODE (operands[5]) == EQ ? UNORDERED : ORDERED);
22485 ;; Eliminate HImode popcount&1 using parity flag (variant 2)
22487 [(match_scratch:HI 0 "Q")
22488 (parallel [(set (match_operand:HI 1 "register_operand")
22490 (match_operand:HI 2 "nonimmediate_operand")))
22491 (clobber (reg:CC FLAGS_REG))])
22492 (set (reg:CCZ FLAGS_REG)
22493 (compare:CCZ (and:QI (match_operand:QI 3 "register_operand")
22496 (set (pc) (if_then_else (match_operator 4 "bt_comparison_operator"
22497 [(reg:CCZ FLAGS_REG)
22499 (label_ref (match_operand 5))
22501 "REGNO (operands[1]) == REGNO (operands[3])
22502 && peep2_reg_dead_p (2, operands[1])
22503 && peep2_reg_dead_p (2, operands[3])
22504 && peep2_regno_dead_p (3, FLAGS_REG)"
22505 [(set (match_dup 0) (match_dup 2))
22506 (parallel [(set (reg:CC FLAGS_REG)
22507 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
22508 (clobber (match_dup 0))])
22509 (set (pc) (if_then_else (match_op_dup 4 [(reg:CC FLAGS_REG)
22511 (label_ref (match_dup 5))
22514 operands[4] = shallow_copy_rtx (operands[4]);
22515 PUT_CODE (operands[4], GET_CODE (operands[4]) == EQ ? UNORDERED : ORDERED);
22519 ;; Thread-local storage patterns for ELF.
22521 ;; Note that these code sequences must appear exactly as shown
22522 ;; in order to allow linker relaxation.
22524 (define_insn "*tls_global_dynamic_32_gnu"
22525 [(set (match_operand:SI 0 "register_operand" "=a")
22527 [(match_operand:SI 1 "register_operand" "Yb")
22528 (match_operand 2 "tls_symbolic_operand")
22529 (match_operand 3 "constant_call_address_operand" "Bz")
22532 (clobber (match_scratch:SI 4 "=d"))
22533 (clobber (match_scratch:SI 5 "=c"))
22534 (clobber (reg:CC FLAGS_REG))]
22535 "!TARGET_64BIT && TARGET_GNU_TLS"
22537 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
22539 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
22542 ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
22543 if (TARGET_SUN_TLS)
22544 #ifdef HAVE_AS_IX86_TLSGDPLT
22545 return "call\t%a2@tlsgdplt";
22547 return "call\t%p3@plt";
22549 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
22550 return "call\t%P3";
22551 return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
22553 [(set_attr "type" "multi")
22554 (set_attr "length" "12")])
22556 (define_expand "tls_global_dynamic_32"
22558 [(set (match_operand:SI 0 "register_operand")
22559 (unspec:SI [(match_operand:SI 2 "register_operand")
22560 (match_operand 1 "tls_symbolic_operand")
22561 (match_operand 3 "constant_call_address_operand")
22564 (clobber (scratch:SI))
22565 (clobber (scratch:SI))
22566 (clobber (reg:CC FLAGS_REG))])]
22568 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
22570 (define_insn "*tls_global_dynamic_64_<mode>"
22571 [(set (match_operand:P 0 "register_operand" "=a")
22573 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
22574 (match_operand 3)))
22575 (unspec:P [(match_operand 1 "tls_symbolic_operand")
22581 /* The .loc directive has effect for 'the immediately following assembly
22582 instruction'. So for a sequence:
22586 the 'immediately following assembly instruction' is insn1.
22587 We want to emit an insn prefix here, but if we use .byte (as shown in
22588 'ELF Handling For Thread-Local Storage'), a preceding .loc will point
22589 inside the insn sequence, rather than to the start. After relaxation
22590 of the sequence by the linker, the .loc might point inside an insn.
22591 Use data16 prefix instead, which doesn't have this problem. */
22592 fputs ("\tdata16", asm_out_file);
22594 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
22595 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
22596 fputs (ASM_SHORT "0x6666\n", asm_out_file);
22598 fputs (ASM_BYTE "0x66\n", asm_out_file);
22599 fputs ("\trex64\n", asm_out_file);
22600 if (TARGET_SUN_TLS)
22601 return "call\t%p2@plt";
22602 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
22603 return "call\t%P2";
22604 return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
22606 [(set_attr "type" "multi")
22607 (set (attr "length")
22608 (symbol_ref "TARGET_X32 ? 15 : 16"))])
22610 (define_insn "*tls_global_dynamic_64_largepic"
22611 [(set (match_operand:DI 0 "register_operand" "=a")
22613 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
22614 (match_operand:DI 3 "immediate_operand" "i")))
22615 (match_operand 4)))
22616 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
22619 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
22620 && GET_CODE (operands[3]) == CONST
22621 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
22622 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
22625 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
22626 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
22627 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
22628 return "call\t{*%%rax|rax}";
22630 [(set_attr "type" "multi")
22631 (set_attr "length" "22")])
22633 (define_expand "@tls_global_dynamic_64_<mode>"
22635 [(set (match_operand:P 0 "register_operand")
22637 (mem:QI (match_operand 2))
22639 (unspec:P [(match_operand 1 "tls_symbolic_operand")
22643 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
22645 (define_insn "*tls_local_dynamic_base_32_gnu"
22646 [(set (match_operand:SI 0 "register_operand" "=a")
22648 [(match_operand:SI 1 "register_operand" "Yb")
22649 (match_operand 2 "constant_call_address_operand" "Bz")
22651 UNSPEC_TLS_LD_BASE))
22652 (clobber (match_scratch:SI 3 "=d"))
22653 (clobber (match_scratch:SI 4 "=c"))
22654 (clobber (reg:CC FLAGS_REG))]
22655 "!TARGET_64BIT && TARGET_GNU_TLS"
22658 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
22659 if (TARGET_SUN_TLS)
22661 if (HAVE_AS_IX86_TLSLDMPLT)
22662 return "call\t%&@tlsldmplt";
22664 return "call\t%p2@plt";
22666 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
22667 return "call\t%P2";
22668 return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
22670 [(set_attr "type" "multi")
22671 (set_attr "length" "11")])
22673 (define_expand "tls_local_dynamic_base_32"
22675 [(set (match_operand:SI 0 "register_operand")
22677 [(match_operand:SI 1 "register_operand")
22678 (match_operand 2 "constant_call_address_operand")
22680 UNSPEC_TLS_LD_BASE))
22681 (clobber (scratch:SI))
22682 (clobber (scratch:SI))
22683 (clobber (reg:CC FLAGS_REG))])]
22685 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
22687 (define_insn "*tls_local_dynamic_base_64_<mode>"
22688 [(set (match_operand:P 0 "register_operand" "=a")
22690 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
22691 (match_operand 2)))
22692 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
22696 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
22697 if (TARGET_SUN_TLS)
22698 return "call\t%p1@plt";
22699 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
22700 return "call\t%P1";
22701 return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
22703 [(set_attr "type" "multi")
22704 (set_attr "length" "12")])
22706 (define_insn "*tls_local_dynamic_base_64_largepic"
22707 [(set (match_operand:DI 0 "register_operand" "=a")
22709 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
22710 (match_operand:DI 2 "immediate_operand" "i")))
22711 (match_operand 3)))
22712 (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
22713 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
22714 && GET_CODE (operands[2]) == CONST
22715 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
22716 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
22719 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
22720 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
22721 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
22722 return "call\t{*%%rax|rax}";
22724 [(set_attr "type" "multi")
22725 (set_attr "length" "22")])
22727 (define_expand "@tls_local_dynamic_base_64_<mode>"
22729 [(set (match_operand:P 0 "register_operand")
22731 (mem:QI (match_operand 1))
22733 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
22735 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
22737 ;; Local dynamic of a single variable is a lose. Show combine how
22738 ;; to convert that back to global dynamic.
22740 (define_insn_and_split "*tls_local_dynamic_32_once"
22741 [(set (match_operand:SI 0 "register_operand" "=a")
22743 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
22744 (match_operand 2 "constant_call_address_operand" "Bz")
22746 UNSPEC_TLS_LD_BASE)
22747 (const:SI (unspec:SI
22748 [(match_operand 3 "tls_symbolic_operand")]
22750 (clobber (match_scratch:SI 4 "=d"))
22751 (clobber (match_scratch:SI 5 "=c"))
22752 (clobber (reg:CC FLAGS_REG))]
22757 [(set (match_dup 0)
22758 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
22761 (clobber (match_dup 4))
22762 (clobber (match_dup 5))
22763 (clobber (reg:CC FLAGS_REG))])])
22765 ;; Load and add the thread base pointer from %<tp_seg>:0.
22766 (define_expand "get_thread_pointer<mode>"
22767 [(set (match_operand:PTR 0 "register_operand")
22768 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
22771 /* targetm is not visible in the scope of the condition. */
22772 if (!targetm.have_tls)
22773 error ("%<__builtin_thread_pointer%> is not supported on this target");
22776 (define_insn_and_split "*load_tp_<mode>"
22777 [(set (match_operand:PTR 0 "register_operand" "=r")
22778 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
22782 [(set (match_dup 0)
22785 addr_space_t as = DEFAULT_TLS_SEG_REG;
22787 operands[1] = gen_const_mem (<MODE>mode, const0_rtx);
22788 set_mem_addr_space (operands[1], as);
22791 (define_insn_and_split "*load_tp_x32_zext"
22792 [(set (match_operand:DI 0 "register_operand" "=r")
22794 (unspec:SI [(const_int 0)] UNSPEC_TP)))]
22798 [(set (match_dup 0)
22799 (zero_extend:DI (match_dup 1)))]
22801 addr_space_t as = DEFAULT_TLS_SEG_REG;
22803 operands[1] = gen_const_mem (SImode, const0_rtx);
22804 set_mem_addr_space (operands[1], as);
22807 (define_insn_and_split "*add_tp_<mode>"
22808 [(set (match_operand:PTR 0 "register_operand" "=r")
22810 (unspec:PTR [(const_int 0)] UNSPEC_TP)
22811 (match_operand:PTR 1 "register_operand" "0")))
22812 (clobber (reg:CC FLAGS_REG))]
22817 [(set (match_dup 0)
22818 (plus:PTR (match_dup 1) (match_dup 2)))
22819 (clobber (reg:CC FLAGS_REG))])]
22821 addr_space_t as = DEFAULT_TLS_SEG_REG;
22823 operands[2] = gen_const_mem (<MODE>mode, const0_rtx);
22824 set_mem_addr_space (operands[2], as);
22827 (define_insn_and_split "*add_tp_x32_zext"
22828 [(set (match_operand:DI 0 "register_operand" "=r")
22830 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
22831 (match_operand:SI 1 "register_operand" "0"))))
22832 (clobber (reg:CC FLAGS_REG))]
22837 [(set (match_dup 0)
22839 (plus:SI (match_dup 1) (match_dup 2))))
22840 (clobber (reg:CC FLAGS_REG))])]
22842 addr_space_t as = DEFAULT_TLS_SEG_REG;
22844 operands[2] = gen_const_mem (SImode, const0_rtx);
22845 set_mem_addr_space (operands[2], as);
22848 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
22849 ;; %rax as destination of the initial executable code sequence.
22850 (define_insn "tls_initial_exec_64_sun"
22851 [(set (match_operand:DI 0 "register_operand" "=a")
22853 [(match_operand 1 "tls_symbolic_operand")]
22854 UNSPEC_TLS_IE_SUN))
22855 (clobber (reg:CC FLAGS_REG))]
22856 "TARGET_64BIT && TARGET_SUN_TLS"
22859 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
22860 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
22862 [(set_attr "type" "multi")])
22864 ;; GNU2 TLS patterns can be split.
22866 (define_expand "tls_dynamic_gnu2_32"
22867 [(set (match_dup 3)
22868 (plus:SI (match_operand:SI 2 "register_operand")
22870 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
22873 [(set (match_operand:SI 0 "register_operand")
22874 (unspec:SI [(match_dup 1) (match_dup 3)
22875 (match_dup 2) (reg:SI SP_REG)]
22877 (clobber (reg:CC FLAGS_REG))])]
22878 "!TARGET_64BIT && TARGET_GNU2_TLS"
22880 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
22881 ix86_tls_descriptor_calls_expanded_in_cfun = true;
22884 (define_insn "*tls_dynamic_gnu2_lea_32"
22885 [(set (match_operand:SI 0 "register_operand" "=r")
22886 (plus:SI (match_operand:SI 1 "register_operand" "b")
22888 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
22889 UNSPEC_TLSDESC))))]
22890 "!TARGET_64BIT && TARGET_GNU2_TLS"
22891 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
22892 [(set_attr "type" "lea")
22893 (set_attr "mode" "SI")
22894 (set_attr "length" "6")
22895 (set_attr "length_address" "4")])
22897 (define_insn "*tls_dynamic_gnu2_call_32"
22898 [(set (match_operand:SI 0 "register_operand" "=a")
22899 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
22900 (match_operand:SI 2 "register_operand" "0")
22901 ;; we have to make sure %ebx still points to the GOT
22902 (match_operand:SI 3 "register_operand" "b")
22905 (clobber (reg:CC FLAGS_REG))]
22906 "!TARGET_64BIT && TARGET_GNU2_TLS"
22907 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
22908 [(set_attr "type" "call")
22909 (set_attr "length" "2")
22910 (set_attr "length_address" "0")])
22912 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
22913 [(set (match_operand:SI 0 "register_operand" "=&a")
22915 (unspec:SI [(match_operand 3 "tls_modbase_operand")
22916 (match_operand:SI 4)
22917 (match_operand:SI 2 "register_operand" "b")
22920 (const:SI (unspec:SI
22921 [(match_operand 1 "tls_symbolic_operand")]
22923 (clobber (reg:CC FLAGS_REG))]
22924 "!TARGET_64BIT && TARGET_GNU2_TLS"
22927 [(set (match_dup 0) (match_dup 5))]
22929 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
22930 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
22933 (define_expand "@tls_dynamic_gnu2_64_<mode>"
22934 [(set (match_dup 2)
22935 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")]
22938 [(set (match_operand:PTR 0 "register_operand")
22939 (unspec:PTR [(match_dup 1) (match_dup 2) (reg:PTR SP_REG)]
22941 (clobber (reg:CC FLAGS_REG))])]
22942 "TARGET_64BIT && TARGET_GNU2_TLS"
22944 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (ptr_mode) : operands[0];
22945 ix86_tls_descriptor_calls_expanded_in_cfun = true;
22948 (define_insn "*tls_dynamic_gnu2_lea_64_<mode>"
22949 [(set (match_operand:PTR 0 "register_operand" "=r")
22950 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")]
22952 "TARGET_64BIT && TARGET_GNU2_TLS"
22953 "lea%z0\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
22954 [(set_attr "type" "lea")
22955 (set_attr "mode" "<MODE>")
22956 (set_attr "length" "7")
22957 (set_attr "length_address" "4")])
22959 (define_insn "*tls_dynamic_gnu2_call_64_<mode>"
22960 [(set (match_operand:PTR 0 "register_operand" "=a")
22961 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")
22962 (match_operand:PTR 2 "register_operand" "0")
22965 (clobber (reg:CC FLAGS_REG))]
22966 "TARGET_64BIT && TARGET_GNU2_TLS"
22967 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
22968 [(set_attr "type" "call")
22969 (set_attr "length" "2")
22970 (set_attr "length_address" "0")])
22972 (define_insn_and_split "*tls_dynamic_gnu2_combine_64_<mode>"
22973 [(set (match_operand:PTR 0 "register_operand" "=&a")
22975 (unspec:PTR [(match_operand 2 "tls_modbase_operand")
22976 (match_operand:PTR 3)
22979 (const:PTR (unspec:PTR
22980 [(match_operand 1 "tls_symbolic_operand")]
22982 (clobber (reg:CC FLAGS_REG))]
22983 "TARGET_64BIT && TARGET_GNU2_TLS"
22986 [(set (match_dup 0) (match_dup 4))]
22988 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (ptr_mode) : operands[0];
22989 emit_insn (gen_tls_dynamic_gnu2_64 (ptr_mode, operands[4], operands[1]));
22993 [(match_operand 0 "tls_address_pattern")]
22994 "TARGET_TLS_DIRECT_SEG_REFS"
22996 "operands[0] = ix86_rewrite_tls_address (operands[0]);")
22999 ;; These patterns match the binary 387 instructions for addM3, subM3,
23000 ;; mulM3 and divM3. There are three patterns for each of DFmode and
23001 ;; SFmode. The first is the normal insn, the second the same insn but
23002 ;; with one operand a conversion, and the third the same insn but with
23003 ;; the other operand a conversion. The conversion may be SFmode or
23004 ;; SImode if the target mode DFmode, but only SImode if the target mode
23007 ;; Gcc is slightly more smart about handling normal two address instructions
23008 ;; so use special patterns for add and mull.
23010 (define_insn "*fop_xf_comm_i387"
23011 [(set (match_operand:XF 0 "register_operand" "=f")
23012 (match_operator:XF 3 "binary_fp_operator"
23013 [(match_operand:XF 1 "register_operand" "%0")
23014 (match_operand:XF 2 "register_operand" "f")]))]
23016 && COMMUTATIVE_ARITH_P (operands[3])"
23017 "* return output_387_binary_op (insn, operands);"
23018 [(set (attr "type")
23019 (if_then_else (match_operand:XF 3 "mult_operator")
23020 (const_string "fmul")
23021 (const_string "fop")))
23022 (set_attr "mode" "XF")])
23024 (define_insn "*fop_<mode>_comm"
23025 [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
23026 (match_operator:MODEF 3 "binary_fp_operator"
23027 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
23028 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
23029 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
23030 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
23031 && COMMUTATIVE_ARITH_P (operands[3])
23032 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
23033 "* return output_387_binary_op (insn, operands);"
23034 [(set (attr "type")
23035 (if_then_else (eq_attr "alternative" "1,2")
23036 (if_then_else (match_operand:MODEF 3 "mult_operator")
23037 (const_string "ssemul")
23038 (const_string "sseadd"))
23039 (if_then_else (match_operand:MODEF 3 "mult_operator")
23040 (const_string "fmul")
23041 (const_string "fop"))))
23042 (set_attr "isa" "*,noavx,avx")
23043 (set_attr "prefix" "orig,orig,vex")
23044 (set_attr "mode" "<MODE>")
23045 (set (attr "enabled")
23047 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
23049 (eq_attr "alternative" "0")
23050 (symbol_ref "TARGET_MIX_SSE_I387
23051 && X87_ENABLE_ARITH (<MODE>mode)")
23052 (const_string "*"))
23054 (eq_attr "alternative" "0")
23055 (symbol_ref "true")
23056 (symbol_ref "false"))))])
23058 (define_insn "*<insn>hf"
23059 [(set (match_operand:HF 0 "register_operand" "=v")
23060 (plusminusmultdiv:HF
23061 (match_operand:HF 1 "nonimmediate_operand" "<comm>v")
23062 (match_operand:HF 2 "nonimmediate_operand" "vm")))]
23064 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
23065 "v<insn>sh\t{%2, %1, %0|%0, %1, %2}"
23066 [(set_attr "prefix" "evex")
23067 (set_attr "mode" "HF")])
23069 (define_insn "*rcpsf2_sse"
23070 [(set (match_operand:SF 0 "register_operand" "=x,x,x,x")
23071 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m,ja")]
23073 "TARGET_SSE && TARGET_SSE_MATH"
23075 %vrcpss\t{%d1, %0|%0, %d1}
23076 %vrcpss\t{%d1, %0|%0, %d1}
23077 rcpss\t{%1, %d0|%d0, %1}
23078 vrcpss\t{%1, %d0|%d0, %1}"
23079 [(set_attr "isa" "*,*,noavx,avx")
23080 (set_attr "addr" "*,*,*,gpr16")
23081 (set_attr "type" "sse")
23082 (set_attr "atom_sse_attr" "rcp")
23083 (set_attr "btver2_sse_attr" "rcp")
23084 (set_attr "prefix" "maybe_vex")
23085 (set_attr "mode" "SF")
23086 (set_attr "avx_partial_xmm_update" "false,false,true,true")
23087 (set (attr "preferred_for_speed")
23088 (cond [(match_test "TARGET_AVX")
23089 (symbol_ref "true")
23090 (eq_attr "alternative" "1,2,3")
23091 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
23093 (symbol_ref "true")))])
23095 (define_insn "rcphf2"
23096 [(set (match_operand:HF 0 "register_operand" "=v,v")
23097 (unspec:HF [(match_operand:HF 1 "nonimmediate_operand" "v,m")]
23099 "TARGET_AVX512FP16"
23101 vrcpsh\t{%d1, %0|%0, %d1}
23102 vrcpsh\t{%1, %d0|%d0, %1}"
23103 [(set_attr "type" "sse")
23104 (set_attr "prefix" "evex")
23105 (set_attr "mode" "HF")
23106 (set_attr "avx_partial_xmm_update" "false,true")])
23108 (define_insn "*fop_xf_1_i387"
23109 [(set (match_operand:XF 0 "register_operand" "=f,f")
23110 (match_operator:XF 3 "binary_fp_operator"
23111 [(match_operand:XF 1 "register_operand" "0,f")
23112 (match_operand:XF 2 "register_operand" "f,0")]))]
23114 && !COMMUTATIVE_ARITH_P (operands[3])"
23115 "* return output_387_binary_op (insn, operands);"
23116 [(set (attr "type")
23117 (if_then_else (match_operand:XF 3 "div_operator")
23118 (const_string "fdiv")
23119 (const_string "fop")))
23120 (set_attr "mode" "XF")])
23122 (define_insn "*fop_<mode>_1"
23123 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
23124 (match_operator:MODEF 3 "binary_fp_operator"
23125 [(match_operand:MODEF 1
23126 "x87nonimm_ssenomem_operand" "0,fm,0,v")
23127 (match_operand:MODEF 2
23128 "nonimmediate_operand" "fm,0,xm,vm")]))]
23129 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
23130 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
23131 && !COMMUTATIVE_ARITH_P (operands[3])
23132 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
23133 "* return output_387_binary_op (insn, operands);"
23134 [(set (attr "type")
23135 (if_then_else (eq_attr "alternative" "2,3")
23136 (if_then_else (match_operand:MODEF 3 "div_operator")
23137 (const_string "ssediv")
23138 (const_string "sseadd"))
23139 (if_then_else (match_operand:MODEF 3 "div_operator")
23140 (const_string "fdiv")
23141 (const_string "fop"))))
23142 (set_attr "isa" "*,*,noavx,avx")
23143 (set_attr "prefix" "orig,orig,orig,vex")
23144 (set_attr "mode" "<MODE>")
23145 (set (attr "enabled")
23147 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
23149 (eq_attr "alternative" "0,1")
23150 (symbol_ref "TARGET_MIX_SSE_I387
23151 && X87_ENABLE_ARITH (<MODE>mode)")
23152 (const_string "*"))
23154 (eq_attr "alternative" "0,1")
23155 (symbol_ref "true")
23156 (symbol_ref "false"))))])
23158 (define_insn "*fop_<X87MODEF:mode>_2_i387"
23159 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
23160 (match_operator:X87MODEF 3 "binary_fp_operator"
23162 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
23163 (match_operand:X87MODEF 2 "register_operand" "0")]))]
23164 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
23165 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
23166 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
23167 || optimize_function_for_size_p (cfun))"
23168 "* return output_387_binary_op (insn, operands);"
23169 [(set (attr "type")
23170 (cond [(match_operand:X87MODEF 3 "mult_operator")
23171 (const_string "fmul")
23172 (match_operand:X87MODEF 3 "div_operator")
23173 (const_string "fdiv")
23175 (const_string "fop")))
23176 (set_attr "fp_int_src" "true")
23177 (set_attr "mode" "<SWI24:MODE>")])
23179 (define_insn "*fop_<X87MODEF:mode>_3_i387"
23180 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
23181 (match_operator:X87MODEF 3 "binary_fp_operator"
23182 [(match_operand:X87MODEF 1 "register_operand" "0")
23184 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
23185 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
23186 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
23187 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
23188 || optimize_function_for_size_p (cfun))"
23189 "* return output_387_binary_op (insn, operands);"
23190 [(set (attr "type")
23191 (cond [(match_operand:X87MODEF 3 "mult_operator")
23192 (const_string "fmul")
23193 (match_operand:X87MODEF 3 "div_operator")
23194 (const_string "fdiv")
23196 (const_string "fop")))
23197 (set_attr "fp_int_src" "true")
23198 (set_attr "mode" "<SWI24:MODE>")])
23200 (define_insn "*fop_xf_4_i387"
23201 [(set (match_operand:XF 0 "register_operand" "=f,f")
23202 (match_operator:XF 3 "binary_fp_operator"
23204 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
23205 (match_operand:XF 2 "register_operand" "0,f")]))]
23207 "* return output_387_binary_op (insn, operands);"
23208 [(set (attr "type")
23209 (cond [(match_operand:XF 3 "mult_operator")
23210 (const_string "fmul")
23211 (match_operand:XF 3 "div_operator")
23212 (const_string "fdiv")
23214 (const_string "fop")))
23215 (set_attr "mode" "<MODE>")])
23217 (define_insn "*fop_df_4_i387"
23218 [(set (match_operand:DF 0 "register_operand" "=f,f")
23219 (match_operator:DF 3 "binary_fp_operator"
23221 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
23222 (match_operand:DF 2 "register_operand" "0,f")]))]
23223 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
23224 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
23225 "* return output_387_binary_op (insn, operands);"
23226 [(set (attr "type")
23227 (cond [(match_operand:DF 3 "mult_operator")
23228 (const_string "fmul")
23229 (match_operand:DF 3 "div_operator")
23230 (const_string "fdiv")
23232 (const_string "fop")))
23233 (set_attr "mode" "SF")])
23235 (define_insn "*fop_xf_5_i387"
23236 [(set (match_operand:XF 0 "register_operand" "=f,f")
23237 (match_operator:XF 3 "binary_fp_operator"
23238 [(match_operand:XF 1 "register_operand" "0,f")
23240 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
23242 "* return output_387_binary_op (insn, operands);"
23243 [(set (attr "type")
23244 (cond [(match_operand:XF 3 "mult_operator")
23245 (const_string "fmul")
23246 (match_operand:XF 3 "div_operator")
23247 (const_string "fdiv")
23249 (const_string "fop")))
23250 (set_attr "mode" "<MODE>")])
23252 (define_insn "*fop_df_5_i387"
23253 [(set (match_operand:DF 0 "register_operand" "=f,f")
23254 (match_operator:DF 3 "binary_fp_operator"
23255 [(match_operand:DF 1 "register_operand" "0,f")
23257 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
23258 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
23259 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
23260 "* return output_387_binary_op (insn, operands);"
23261 [(set (attr "type")
23262 (cond [(match_operand:DF 3 "mult_operator")
23263 (const_string "fmul")
23264 (match_operand:DF 3 "div_operator")
23265 (const_string "fdiv")
23267 (const_string "fop")))
23268 (set_attr "mode" "SF")])
23270 (define_insn "*fop_xf_6_i387"
23271 [(set (match_operand:XF 0 "register_operand" "=f,f")
23272 (match_operator:XF 3 "binary_fp_operator"
23274 (match_operand:MODEF 1 "register_operand" "0,f"))
23276 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
23278 "* return output_387_binary_op (insn, operands);"
23279 [(set (attr "type")
23280 (cond [(match_operand:XF 3 "mult_operator")
23281 (const_string "fmul")
23282 (match_operand:XF 3 "div_operator")
23283 (const_string "fdiv")
23285 (const_string "fop")))
23286 (set_attr "mode" "<MODE>")])
23288 (define_insn "*fop_df_6_i387"
23289 [(set (match_operand:DF 0 "register_operand" "=f,f")
23290 (match_operator:DF 3 "binary_fp_operator"
23292 (match_operand:SF 1 "register_operand" "0,f"))
23294 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
23295 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
23296 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
23297 "* return output_387_binary_op (insn, operands);"
23298 [(set (attr "type")
23299 (cond [(match_operand:DF 3 "mult_operator")
23300 (const_string "fmul")
23301 (match_operand:DF 3 "div_operator")
23302 (const_string "fdiv")
23304 (const_string "fop")))
23305 (set_attr "mode" "SF")])
23307 ;; FPU special functions.
23309 ;; This pattern implements a no-op XFmode truncation for
23310 ;; all fancy i386 XFmode math functions.
23312 (define_insn "truncxf<mode>2_i387_noop_unspec"
23313 [(set (match_operand:MODEF 0 "nonimmediate_operand" "=mf")
23314 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
23315 UNSPEC_TRUNC_NOOP))]
23316 "TARGET_USE_FANCY_MATH_387"
23317 "* return output_387_reg_move (insn, operands);"
23318 [(set_attr "type" "fmov")
23319 (set_attr "mode" "<MODE>")])
23321 (define_insn "sqrtxf2"
23322 [(set (match_operand:XF 0 "register_operand" "=f")
23323 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
23324 "TARGET_USE_FANCY_MATH_387"
23326 [(set_attr "type" "fpspc")
23327 (set_attr "mode" "XF")
23328 (set_attr "athlon_decode" "direct")
23329 (set_attr "amdfam10_decode" "direct")
23330 (set_attr "bdver1_decode" "direct")])
23332 (define_insn "*rsqrtsf2_sse"
23333 [(set (match_operand:SF 0 "register_operand" "=x,x,x,x")
23334 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m,ja")]
23336 "TARGET_SSE && TARGET_SSE_MATH"
23338 %vrsqrtss\t{%d1, %0|%0, %d1}
23339 %vrsqrtss\t{%d1, %0|%0, %d1}
23340 rsqrtss\t{%1, %d0|%d0, %1}
23341 vrsqrtss\t{%1, %d0|%d0, %1}"
23342 [(set_attr "isa" "*,*,noavx,avx")
23343 (set_attr "addr" "*,*,*,gpr16")
23344 (set_attr "type" "sse")
23345 (set_attr "atom_sse_attr" "rcp")
23346 (set_attr "btver2_sse_attr" "rcp")
23347 (set_attr "prefix" "maybe_vex")
23348 (set_attr "mode" "SF")
23349 (set_attr "avx_partial_xmm_update" "false,false,true,true")
23350 (set (attr "preferred_for_speed")
23351 (cond [(match_test "TARGET_AVX")
23352 (symbol_ref "true")
23353 (eq_attr "alternative" "1,2,3")
23354 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
23356 (symbol_ref "true")))])
23358 (define_expand "rsqrtsf2"
23359 [(set (match_operand:SF 0 "register_operand")
23360 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
23362 "TARGET_SSE && TARGET_SSE_MATH"
23364 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
23368 (define_insn "rsqrthf2"
23369 [(set (match_operand:HF 0 "register_operand" "=v,v")
23370 (unspec:HF [(match_operand:HF 1 "nonimmediate_operand" "v,m")]
23372 "TARGET_AVX512FP16"
23374 vrsqrtsh\t{%d1, %0|%0, %d1}
23375 vrsqrtsh\t{%1, %d0|%d0, %1}"
23376 [(set_attr "type" "sse")
23377 (set_attr "prefix" "evex")
23378 (set_attr "avx_partial_xmm_update" "false,true")
23379 (set_attr "mode" "HF")])
23381 (define_insn "sqrthf2"
23382 [(set (match_operand:HF 0 "register_operand" "=v,v")
23384 (match_operand:HF 1 "nonimmediate_operand" "v,m")))]
23385 "TARGET_AVX512FP16"
23387 vsqrtsh\t{%d1, %0|%0, %d1}
23388 vsqrtsh\t{%1, %d0|%d0, %1}"
23389 [(set_attr "type" "sse")
23390 (set_attr "prefix" "evex")
23391 (set_attr "avx_partial_xmm_update" "false,true")
23392 (set_attr "mode" "HF")])
23394 (define_insn "*sqrt<mode>2_sse"
23395 [(set (match_operand:MODEF 0 "register_operand" "=v,v,v")
23397 (match_operand:MODEF 1 "nonimmediate_operand" "0,v,m")))]
23398 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
23400 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
23401 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
23402 %vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
23403 [(set_attr "type" "sse")
23404 (set_attr "atom_sse_attr" "sqrt")
23405 (set_attr "btver2_sse_attr" "sqrt")
23406 (set_attr "prefix" "maybe_vex")
23407 (set_attr "avx_partial_xmm_update" "false,false,true")
23408 (set_attr "mode" "<MODE>")
23409 (set (attr "preferred_for_speed")
23410 (cond [(match_test "TARGET_AVX")
23411 (symbol_ref "true")
23412 (eq_attr "alternative" "1,2")
23413 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
23415 (symbol_ref "true")))])
23417 (define_expand "sqrt<mode>2"
23418 [(set (match_operand:MODEF 0 "register_operand")
23420 (match_operand:MODEF 1 "nonimmediate_operand")))]
23421 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
23422 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
23424 if (<MODE>mode == SFmode
23425 && TARGET_SSE && TARGET_SSE_MATH
23426 && TARGET_RECIP_SQRT
23427 && !optimize_function_for_size_p (cfun)
23428 && flag_finite_math_only && !flag_trapping_math
23429 && flag_unsafe_math_optimizations)
23431 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
23435 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
23437 rtx op0 = gen_reg_rtx (XFmode);
23438 rtx op1 = gen_reg_rtx (XFmode);
23440 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
23441 emit_insn (gen_sqrtxf2 (op0, op1));
23442 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
23447 (define_expand "hypot<mode>3"
23448 [(use (match_operand:MODEF 0 "register_operand"))
23449 (use (match_operand:MODEF 1 "general_operand"))
23450 (use (match_operand:MODEF 2 "general_operand"))]
23451 "TARGET_USE_FANCY_MATH_387
23452 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
23453 || TARGET_MIX_SSE_I387)
23454 && flag_finite_math_only
23455 && flag_unsafe_math_optimizations"
23457 rtx op0 = gen_reg_rtx (XFmode);
23458 rtx op1 = gen_reg_rtx (XFmode);
23459 rtx op2 = gen_reg_rtx (XFmode);
23461 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
23462 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
23464 emit_insn (gen_mulxf3 (op1, op1, op1));
23465 emit_insn (gen_mulxf3 (op2, op2, op2));
23466 emit_insn (gen_addxf3 (op0, op2, op1));
23467 emit_insn (gen_sqrtxf2 (op0, op0));
23469 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
23473 (define_insn "x86_fnstsw_1"
23474 [(set (match_operand:HI 0 "register_operand" "=a")
23475 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
23478 [(set_attr "length" "2")
23479 (set_attr "mode" "SI")
23480 (set_attr "unit" "i387")])
23482 (define_insn "fpremxf4_i387"
23483 [(set (match_operand:XF 0 "register_operand" "=f")
23484 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
23485 (match_operand:XF 3 "register_operand" "1")]
23487 (set (match_operand:XF 1 "register_operand" "=f")
23488 (unspec:XF [(match_dup 2) (match_dup 3)]
23490 (set (reg:CCFP FPSR_REG)
23491 (unspec:CCFP [(match_dup 2) (match_dup 3)]
23493 "TARGET_USE_FANCY_MATH_387"
23495 [(set_attr "type" "fpspc")
23496 (set_attr "znver1_decode" "vector")
23497 (set_attr "mode" "XF")])
23499 (define_expand "fmodxf3"
23500 [(use (match_operand:XF 0 "register_operand"))
23501 (use (match_operand:XF 1 "general_operand"))
23502 (use (match_operand:XF 2 "general_operand"))]
23503 "TARGET_USE_FANCY_MATH_387"
23505 rtx_code_label *label = gen_label_rtx ();
23507 rtx op1 = gen_reg_rtx (XFmode);
23508 rtx op2 = gen_reg_rtx (XFmode);
23510 emit_move_insn (op2, operands[2]);
23511 emit_move_insn (op1, operands[1]);
23513 emit_label (label);
23514 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
23515 ix86_emit_fp_unordered_jump (label);
23516 LABEL_NUSES (label) = 1;
23518 emit_move_insn (operands[0], op1);
23522 (define_expand "fmod<mode>3"
23523 [(use (match_operand:MODEF 0 "register_operand"))
23524 (use (match_operand:MODEF 1 "general_operand"))
23525 (use (match_operand:MODEF 2 "general_operand"))]
23526 "TARGET_USE_FANCY_MATH_387"
23528 rtx (*gen_truncxf) (rtx, rtx);
23530 rtx_code_label *label = gen_label_rtx ();
23532 rtx op1 = gen_reg_rtx (XFmode);
23533 rtx op2 = gen_reg_rtx (XFmode);
23535 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
23536 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
23538 emit_label (label);
23539 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
23540 ix86_emit_fp_unordered_jump (label);
23541 LABEL_NUSES (label) = 1;
23543 /* Truncate the result properly for strict SSE math. */
23544 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
23545 && !TARGET_MIX_SSE_I387)
23546 gen_truncxf = gen_truncxf<mode>2;
23548 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
23550 emit_insn (gen_truncxf (operands[0], op1));
23554 (define_insn "fprem1xf4_i387"
23555 [(set (match_operand:XF 0 "register_operand" "=f")
23556 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
23557 (match_operand:XF 3 "register_operand" "1")]
23559 (set (match_operand:XF 1 "register_operand" "=f")
23560 (unspec:XF [(match_dup 2) (match_dup 3)]
23562 (set (reg:CCFP FPSR_REG)
23563 (unspec:CCFP [(match_dup 2) (match_dup 3)]
23565 "TARGET_USE_FANCY_MATH_387"
23567 [(set_attr "type" "fpspc")
23568 (set_attr "znver1_decode" "vector")
23569 (set_attr "mode" "XF")])
23571 (define_expand "remainderxf3"
23572 [(use (match_operand:XF 0 "register_operand"))
23573 (use (match_operand:XF 1 "general_operand"))
23574 (use (match_operand:XF 2 "general_operand"))]
23575 "TARGET_USE_FANCY_MATH_387"
23577 rtx_code_label *label = gen_label_rtx ();
23579 rtx op1 = gen_reg_rtx (XFmode);
23580 rtx op2 = gen_reg_rtx (XFmode);
23582 emit_move_insn (op2, operands[2]);
23583 emit_move_insn (op1, operands[1]);
23585 emit_label (label);
23586 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
23587 ix86_emit_fp_unordered_jump (label);
23588 LABEL_NUSES (label) = 1;
23590 emit_move_insn (operands[0], op1);
23594 (define_expand "remainder<mode>3"
23595 [(use (match_operand:MODEF 0 "register_operand"))
23596 (use (match_operand:MODEF 1 "general_operand"))
23597 (use (match_operand:MODEF 2 "general_operand"))]
23598 "TARGET_USE_FANCY_MATH_387"
23600 rtx (*gen_truncxf) (rtx, rtx);
23602 rtx_code_label *label = gen_label_rtx ();
23604 rtx op1 = gen_reg_rtx (XFmode);
23605 rtx op2 = gen_reg_rtx (XFmode);
23607 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
23608 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
23610 emit_label (label);
23612 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
23613 ix86_emit_fp_unordered_jump (label);
23614 LABEL_NUSES (label) = 1;
23616 /* Truncate the result properly for strict SSE math. */
23617 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
23618 && !TARGET_MIX_SSE_I387)
23619 gen_truncxf = gen_truncxf<mode>2;
23621 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
23623 emit_insn (gen_truncxf (operands[0], op1));
23627 (define_int_iterator SINCOS
23631 (define_int_attr sincos
23632 [(UNSPEC_SIN "sin")
23633 (UNSPEC_COS "cos")])
23635 (define_insn "<sincos>xf2"
23636 [(set (match_operand:XF 0 "register_operand" "=f")
23637 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
23639 "TARGET_USE_FANCY_MATH_387
23640 && flag_unsafe_math_optimizations"
23642 [(set_attr "type" "fpspc")
23643 (set_attr "znver1_decode" "vector")
23644 (set_attr "mode" "XF")])
23646 (define_expand "<sincos><mode>2"
23647 [(set (match_operand:MODEF 0 "register_operand")
23648 (unspec:MODEF [(match_operand:MODEF 1 "general_operand")]
23650 "TARGET_USE_FANCY_MATH_387
23651 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
23652 || TARGET_MIX_SSE_I387)
23653 && flag_unsafe_math_optimizations"
23655 rtx op0 = gen_reg_rtx (XFmode);
23656 rtx op1 = gen_reg_rtx (XFmode);
23658 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
23659 emit_insn (gen_<sincos>xf2 (op0, op1));
23660 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
23664 (define_insn "sincosxf3"
23665 [(set (match_operand:XF 0 "register_operand" "=f")
23666 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
23667 UNSPEC_SINCOS_COS))
23668 (set (match_operand:XF 1 "register_operand" "=f")
23669 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
23670 "TARGET_USE_FANCY_MATH_387
23671 && flag_unsafe_math_optimizations"
23673 [(set_attr "type" "fpspc")
23674 (set_attr "znver1_decode" "vector")
23675 (set_attr "mode" "XF")])
23677 (define_expand "sincos<mode>3"
23678 [(use (match_operand:MODEF 0 "register_operand"))
23679 (use (match_operand:MODEF 1 "register_operand"))
23680 (use (match_operand:MODEF 2 "general_operand"))]
23681 "TARGET_USE_FANCY_MATH_387
23682 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
23683 || TARGET_MIX_SSE_I387)
23684 && flag_unsafe_math_optimizations"
23686 rtx op0 = gen_reg_rtx (XFmode);
23687 rtx op1 = gen_reg_rtx (XFmode);
23688 rtx op2 = gen_reg_rtx (XFmode);
23690 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
23691 emit_insn (gen_sincosxf3 (op0, op1, op2));
23692 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
23693 emit_insn (gen_truncxf<mode>2 (operands[1], op1));
23697 (define_insn "fptanxf4_i387"
23698 [(set (match_operand:SF 0 "register_operand" "=f")
23699 (match_operand:SF 3 "const1_operand"))
23700 (set (match_operand:XF 1 "register_operand" "=f")
23701 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
23703 "TARGET_USE_FANCY_MATH_387
23704 && flag_unsafe_math_optimizations"
23706 [(set_attr "type" "fpspc")
23707 (set_attr "znver1_decode" "vector")
23708 (set_attr "mode" "XF")])
23710 (define_expand "tanxf2"
23711 [(use (match_operand:XF 0 "register_operand"))
23712 (use (match_operand:XF 1 "register_operand"))]
23713 "TARGET_USE_FANCY_MATH_387
23714 && flag_unsafe_math_optimizations"
23716 rtx one = gen_reg_rtx (SFmode);
23717 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1],
23718 CONST1_RTX (SFmode)));
23722 (define_expand "tan<mode>2"
23723 [(use (match_operand:MODEF 0 "register_operand"))
23724 (use (match_operand:MODEF 1 "general_operand"))]
23725 "TARGET_USE_FANCY_MATH_387
23726 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
23727 || TARGET_MIX_SSE_I387)
23728 && flag_unsafe_math_optimizations"
23730 rtx op0 = gen_reg_rtx (XFmode);
23731 rtx op1 = gen_reg_rtx (XFmode);
23733 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
23734 emit_insn (gen_tanxf2 (op0, op1));
23735 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
23739 (define_insn "atan2xf3"
23740 [(set (match_operand:XF 0 "register_operand" "=f")
23741 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
23742 (match_operand:XF 1 "register_operand" "f")]
23744 (clobber (match_scratch:XF 3 "=1"))]
23745 "TARGET_USE_FANCY_MATH_387
23746 && flag_unsafe_math_optimizations"
23748 [(set_attr "type" "fpspc")
23749 (set_attr "znver1_decode" "vector")
23750 (set_attr "mode" "XF")])
23752 (define_expand "atan2<mode>3"
23753 [(use (match_operand:MODEF 0 "register_operand"))
23754 (use (match_operand:MODEF 1 "general_operand"))
23755 (use (match_operand:MODEF 2 "general_operand"))]
23756 "TARGET_USE_FANCY_MATH_387
23757 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
23758 || TARGET_MIX_SSE_I387)
23759 && flag_unsafe_math_optimizations"
23761 rtx op0 = gen_reg_rtx (XFmode);
23762 rtx op1 = gen_reg_rtx (XFmode);
23763 rtx op2 = gen_reg_rtx (XFmode);
23765 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
23766 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
23768 emit_insn (gen_atan2xf3 (op0, op1, op2));
23769 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
23773 (define_expand "atanxf2"
23774 [(parallel [(set (match_operand:XF 0 "register_operand")
23775 (unspec:XF [(match_dup 2)
23776 (match_operand:XF 1 "register_operand")]
23778 (clobber (scratch:XF))])]
23779 "TARGET_USE_FANCY_MATH_387
23780 && flag_unsafe_math_optimizations"
23781 "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
23783 (define_expand "atan<mode>2"
23784 [(use (match_operand:MODEF 0 "register_operand"))
23785 (use (match_operand:MODEF 1 "general_operand"))]
23786 "TARGET_USE_FANCY_MATH_387
23787 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
23788 || TARGET_MIX_SSE_I387)
23789 && flag_unsafe_math_optimizations"
23791 rtx op0 = gen_reg_rtx (XFmode);
23792 rtx op1 = gen_reg_rtx (XFmode);
23794 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
23795 emit_insn (gen_atanxf2 (op0, op1));
23796 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
23800 (define_expand "asinxf2"
23801 [(set (match_dup 2)
23802 (mult:XF (match_operand:XF 1 "register_operand")
23804 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
23805 (set (match_dup 5) (sqrt:XF (match_dup 4)))
23806 (parallel [(set (match_operand:XF 0 "register_operand")
23807 (unspec:XF [(match_dup 5) (match_dup 1)]
23809 (clobber (scratch:XF))])]
23810 "TARGET_USE_FANCY_MATH_387
23811 && flag_unsafe_math_optimizations"
23815 for (i = 2; i < 6; i++)
23816 operands[i] = gen_reg_rtx (XFmode);
23818 emit_move_insn (operands[3], CONST1_RTX (XFmode));
23821 (define_expand "asin<mode>2"
23822 [(use (match_operand:MODEF 0 "register_operand"))
23823 (use (match_operand:MODEF 1 "general_operand"))]
23824 "TARGET_USE_FANCY_MATH_387
23825 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
23826 || TARGET_MIX_SSE_I387)
23827 && flag_unsafe_math_optimizations"
23829 rtx op0 = gen_reg_rtx (XFmode);
23830 rtx op1 = gen_reg_rtx (XFmode);
23832 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
23833 emit_insn (gen_asinxf2 (op0, op1));
23834 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
23838 (define_expand "acosxf2"
23839 [(set (match_dup 2)
23840 (mult:XF (match_operand:XF 1 "register_operand")
23842 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
23843 (set (match_dup 5) (sqrt:XF (match_dup 4)))
23844 (parallel [(set (match_operand:XF 0 "register_operand")
23845 (unspec:XF [(match_dup 1) (match_dup 5)]
23847 (clobber (scratch:XF))])]
23848 "TARGET_USE_FANCY_MATH_387
23849 && flag_unsafe_math_optimizations"
23853 for (i = 2; i < 6; i++)
23854 operands[i] = gen_reg_rtx (XFmode);
23856 emit_move_insn (operands[3], CONST1_RTX (XFmode));
23859 (define_expand "acos<mode>2"
23860 [(use (match_operand:MODEF 0 "register_operand"))
23861 (use (match_operand:MODEF 1 "general_operand"))]
23862 "TARGET_USE_FANCY_MATH_387
23863 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
23864 || TARGET_MIX_SSE_I387)
23865 && flag_unsafe_math_optimizations"
23867 rtx op0 = gen_reg_rtx (XFmode);
23868 rtx op1 = gen_reg_rtx (XFmode);
23870 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
23871 emit_insn (gen_acosxf2 (op0, op1));
23872 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
23876 (define_expand "sinhxf2"
23877 [(use (match_operand:XF 0 "register_operand"))
23878 (use (match_operand:XF 1 "register_operand"))]
23879 "TARGET_USE_FANCY_MATH_387
23880 && flag_finite_math_only
23881 && flag_unsafe_math_optimizations"
23883 ix86_emit_i387_sinh (operands[0], operands[1]);
23887 (define_expand "sinh<mode>2"
23888 [(use (match_operand:MODEF 0 "register_operand"))
23889 (use (match_operand:MODEF 1 "general_operand"))]
23890 "TARGET_USE_FANCY_MATH_387
23891 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
23892 || TARGET_MIX_SSE_I387)
23893 && flag_finite_math_only
23894 && flag_unsafe_math_optimizations"
23896 rtx op0 = gen_reg_rtx (XFmode);
23897 rtx op1 = gen_reg_rtx (XFmode);
23899 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
23900 emit_insn (gen_sinhxf2 (op0, op1));
23901 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
23905 (define_expand "coshxf2"
23906 [(use (match_operand:XF 0 "register_operand"))
23907 (use (match_operand:XF 1 "register_operand"))]
23908 "TARGET_USE_FANCY_MATH_387
23909 && flag_unsafe_math_optimizations"
23911 ix86_emit_i387_cosh (operands[0], operands[1]);
23915 (define_expand "cosh<mode>2"
23916 [(use (match_operand:MODEF 0 "register_operand"))
23917 (use (match_operand:MODEF 1 "general_operand"))]
23918 "TARGET_USE_FANCY_MATH_387
23919 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
23920 || TARGET_MIX_SSE_I387)
23921 && flag_unsafe_math_optimizations"
23923 rtx op0 = gen_reg_rtx (XFmode);
23924 rtx op1 = gen_reg_rtx (XFmode);
23926 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
23927 emit_insn (gen_coshxf2 (op0, op1));
23928 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
23932 (define_expand "tanhxf2"
23933 [(use (match_operand:XF 0 "register_operand"))
23934 (use (match_operand:XF 1 "register_operand"))]
23935 "TARGET_USE_FANCY_MATH_387
23936 && flag_unsafe_math_optimizations"
23938 ix86_emit_i387_tanh (operands[0], operands[1]);
23942 (define_expand "tanh<mode>2"
23943 [(use (match_operand:MODEF 0 "register_operand"))
23944 (use (match_operand:MODEF 1 "general_operand"))]
23945 "TARGET_USE_FANCY_MATH_387
23946 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
23947 || TARGET_MIX_SSE_I387)
23948 && flag_unsafe_math_optimizations"
23950 rtx op0 = gen_reg_rtx (XFmode);
23951 rtx op1 = gen_reg_rtx (XFmode);
23953 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
23954 emit_insn (gen_tanhxf2 (op0, op1));
23955 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
23959 (define_expand "asinhxf2"
23960 [(use (match_operand:XF 0 "register_operand"))
23961 (use (match_operand:XF 1 "register_operand"))]
23962 "TARGET_USE_FANCY_MATH_387
23963 && flag_finite_math_only
23964 && flag_unsafe_math_optimizations"
23966 ix86_emit_i387_asinh (operands[0], operands[1]);
23970 (define_expand "asinh<mode>2"
23971 [(use (match_operand:MODEF 0 "register_operand"))
23972 (use (match_operand:MODEF 1 "general_operand"))]
23973 "TARGET_USE_FANCY_MATH_387
23974 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
23975 || TARGET_MIX_SSE_I387)
23976 && flag_finite_math_only
23977 && flag_unsafe_math_optimizations"
23979 rtx op0 = gen_reg_rtx (XFmode);
23980 rtx op1 = gen_reg_rtx (XFmode);
23982 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
23983 emit_insn (gen_asinhxf2 (op0, op1));
23984 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
23988 (define_expand "acoshxf2"
23989 [(use (match_operand:XF 0 "register_operand"))
23990 (use (match_operand:XF 1 "register_operand"))]
23991 "TARGET_USE_FANCY_MATH_387
23992 && flag_unsafe_math_optimizations"
23994 ix86_emit_i387_acosh (operands[0], operands[1]);
23998 (define_expand "acosh<mode>2"
23999 [(use (match_operand:MODEF 0 "register_operand"))
24000 (use (match_operand:MODEF 1 "general_operand"))]
24001 "TARGET_USE_FANCY_MATH_387
24002 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
24003 || TARGET_MIX_SSE_I387)
24004 && flag_unsafe_math_optimizations"
24006 rtx op0 = gen_reg_rtx (XFmode);
24007 rtx op1 = gen_reg_rtx (XFmode);
24009 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
24010 emit_insn (gen_acoshxf2 (op0, op1));
24011 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
24015 (define_expand "atanhxf2"
24016 [(use (match_operand:XF 0 "register_operand"))
24017 (use (match_operand:XF 1 "register_operand"))]
24018 "TARGET_USE_FANCY_MATH_387
24019 && flag_unsafe_math_optimizations"
24021 ix86_emit_i387_atanh (operands[0], operands[1]);
24025 (define_expand "atanh<mode>2"
24026 [(use (match_operand:MODEF 0 "register_operand"))
24027 (use (match_operand:MODEF 1 "general_operand"))]
24028 "TARGET_USE_FANCY_MATH_387
24029 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
24030 || TARGET_MIX_SSE_I387)
24031 && flag_unsafe_math_optimizations"
24033 rtx op0 = gen_reg_rtx (XFmode);
24034 rtx op1 = gen_reg_rtx (XFmode);
24036 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
24037 emit_insn (gen_atanhxf2 (op0, op1));
24038 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
24042 (define_insn "fyl2xxf3_i387"
24043 [(set (match_operand:XF 0 "register_operand" "=f")
24044 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
24045 (match_operand:XF 2 "register_operand" "f")]
24047 (clobber (match_scratch:XF 3 "=2"))]
24048 "TARGET_USE_FANCY_MATH_387
24049 && flag_unsafe_math_optimizations"
24051 [(set_attr "type" "fpspc")
24052 (set_attr "znver1_decode" "vector")
24053 (set_attr "mode" "XF")])
24055 (define_expand "logxf2"
24056 [(parallel [(set (match_operand:XF 0 "register_operand")
24057 (unspec:XF [(match_operand:XF 1 "register_operand")
24058 (match_dup 2)] UNSPEC_FYL2X))
24059 (clobber (scratch:XF))])]
24060 "TARGET_USE_FANCY_MATH_387
24061 && flag_unsafe_math_optimizations"
24064 = force_reg (XFmode, standard_80387_constant_rtx (4)); /* fldln2 */
24067 (define_expand "log<mode>2"
24068 [(use (match_operand:MODEF 0 "register_operand"))
24069 (use (match_operand:MODEF 1 "general_operand"))]
24070 "TARGET_USE_FANCY_MATH_387
24071 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
24072 || TARGET_MIX_SSE_I387)
24073 && flag_unsafe_math_optimizations"
24075 rtx op0 = gen_reg_rtx (XFmode);
24076 rtx op1 = gen_reg_rtx (XFmode);
24078 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
24079 emit_insn (gen_logxf2 (op0, op1));
24080 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
24084 (define_expand "log10xf2"
24085 [(parallel [(set (match_operand:XF 0 "register_operand")
24086 (unspec:XF [(match_operand:XF 1 "register_operand")
24087 (match_dup 2)] UNSPEC_FYL2X))
24088 (clobber (scratch:XF))])]
24089 "TARGET_USE_FANCY_MATH_387
24090 && flag_unsafe_math_optimizations"
24093 = force_reg (XFmode, standard_80387_constant_rtx (3)); /* fldlg2 */
24096 (define_expand "log10<mode>2"
24097 [(use (match_operand:MODEF 0 "register_operand"))
24098 (use (match_operand:MODEF 1 "general_operand"))]
24099 "TARGET_USE_FANCY_MATH_387
24100 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
24101 || TARGET_MIX_SSE_I387)
24102 && flag_unsafe_math_optimizations"
24104 rtx op0 = gen_reg_rtx (XFmode);
24105 rtx op1 = gen_reg_rtx (XFmode);
24107 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
24108 emit_insn (gen_log10xf2 (op0, op1));
24109 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
24113 (define_expand "log2xf2"
24114 [(parallel [(set (match_operand:XF 0 "register_operand")
24115 (unspec:XF [(match_operand:XF 1 "register_operand")
24116 (match_dup 2)] UNSPEC_FYL2X))
24117 (clobber (scratch:XF))])]
24118 "TARGET_USE_FANCY_MATH_387
24119 && flag_unsafe_math_optimizations"
24120 "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
24122 (define_expand "log2<mode>2"
24123 [(use (match_operand:MODEF 0 "register_operand"))
24124 (use (match_operand:MODEF 1 "general_operand"))]
24125 "TARGET_USE_FANCY_MATH_387
24126 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
24127 || TARGET_MIX_SSE_I387)
24128 && flag_unsafe_math_optimizations"
24130 rtx op0 = gen_reg_rtx (XFmode);
24131 rtx op1 = gen_reg_rtx (XFmode);
24133 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
24134 emit_insn (gen_log2xf2 (op0, op1));
24135 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
24139 (define_insn "fyl2xp1xf3_i387"
24140 [(set (match_operand:XF 0 "register_operand" "=f")
24141 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
24142 (match_operand:XF 2 "register_operand" "f")]
24144 (clobber (match_scratch:XF 3 "=2"))]
24145 "TARGET_USE_FANCY_MATH_387
24146 && flag_unsafe_math_optimizations"
24148 [(set_attr "type" "fpspc")
24149 (set_attr "znver1_decode" "vector")
24150 (set_attr "mode" "XF")])
24152 (define_expand "log1pxf2"
24153 [(use (match_operand:XF 0 "register_operand"))
24154 (use (match_operand:XF 1 "register_operand"))]
24155 "TARGET_USE_FANCY_MATH_387
24156 && flag_unsafe_math_optimizations"
24158 ix86_emit_i387_log1p (operands[0], operands[1]);
24162 (define_expand "log1p<mode>2"
24163 [(use (match_operand:MODEF 0 "register_operand"))
24164 (use (match_operand:MODEF 1 "general_operand"))]
24165 "TARGET_USE_FANCY_MATH_387
24166 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
24167 || TARGET_MIX_SSE_I387)
24168 && flag_unsafe_math_optimizations"
24170 rtx op0 = gen_reg_rtx (XFmode);
24171 rtx op1 = gen_reg_rtx (XFmode);
24173 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
24174 emit_insn (gen_log1pxf2 (op0, op1));
24175 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
24179 (define_insn "fxtractxf3_i387"
24180 [(set (match_operand:XF 0 "register_operand" "=f")
24181 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
24182 UNSPEC_XTRACT_FRACT))
24183 (set (match_operand:XF 1 "register_operand" "=f")
24184 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
24185 "TARGET_USE_FANCY_MATH_387
24186 && flag_unsafe_math_optimizations"
24188 [(set_attr "type" "fpspc")
24189 (set_attr "znver1_decode" "vector")
24190 (set_attr "mode" "XF")])
24192 (define_expand "logbxf2"
24193 [(parallel [(set (match_dup 2)
24194 (unspec:XF [(match_operand:XF 1 "register_operand")]
24195 UNSPEC_XTRACT_FRACT))
24196 (set (match_operand:XF 0 "register_operand")
24197 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
24198 "TARGET_USE_FANCY_MATH_387
24199 && flag_unsafe_math_optimizations"
24200 "operands[2] = gen_reg_rtx (XFmode);")
24202 (define_expand "logb<mode>2"
24203 [(use (match_operand:MODEF 0 "register_operand"))
24204 (use (match_operand:MODEF 1 "general_operand"))]
24205 "TARGET_USE_FANCY_MATH_387
24206 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
24207 || TARGET_MIX_SSE_I387)
24208 && flag_unsafe_math_optimizations"
24210 rtx op0 = gen_reg_rtx (XFmode);
24211 rtx op1 = gen_reg_rtx (XFmode);
24213 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
24214 emit_insn (gen_logbxf2 (op0, op1));
24215 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
24219 (define_expand "ilogbxf2"
24220 [(use (match_operand:SI 0 "register_operand"))
24221 (use (match_operand:XF 1 "register_operand"))]
24222 "TARGET_USE_FANCY_MATH_387
24223 && flag_unsafe_math_optimizations"
24227 if (optimize_insn_for_size_p ())
24230 op0 = gen_reg_rtx (XFmode);
24231 op1 = gen_reg_rtx (XFmode);
24233 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
24234 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
24238 (define_expand "ilogb<mode>2"
24239 [(use (match_operand:SI 0 "register_operand"))
24240 (use (match_operand:MODEF 1 "general_operand"))]
24241 "TARGET_USE_FANCY_MATH_387
24242 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
24243 || TARGET_MIX_SSE_I387)
24244 && flag_unsafe_math_optimizations"
24248 if (optimize_insn_for_size_p ())
24251 op0 = gen_reg_rtx (XFmode);
24252 op1 = gen_reg_rtx (XFmode);
24253 op2 = gen_reg_rtx (XFmode);
24255 emit_insn (gen_extend<mode>xf2 (op2, operands[1]));
24256 emit_insn (gen_fxtractxf3_i387 (op0, op1, op2));
24257 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
24261 (define_insn "*f2xm1xf2_i387"
24262 [(set (match_operand:XF 0 "register_operand" "=f")
24263 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
24265 "TARGET_USE_FANCY_MATH_387
24266 && flag_unsafe_math_optimizations"
24268 [(set_attr "type" "fpspc")
24269 (set_attr "znver1_decode" "vector")
24270 (set_attr "mode" "XF")])
24272 (define_insn "fscalexf4_i387"
24273 [(set (match_operand:XF 0 "register_operand" "=f")
24274 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
24275 (match_operand:XF 3 "register_operand" "1")]
24276 UNSPEC_FSCALE_FRACT))
24277 (set (match_operand:XF 1 "register_operand" "=f")
24278 (unspec:XF [(match_dup 2) (match_dup 3)]
24279 UNSPEC_FSCALE_EXP))]
24280 "TARGET_USE_FANCY_MATH_387
24281 && flag_unsafe_math_optimizations"
24283 [(set_attr "type" "fpspc")
24284 (set_attr "znver1_decode" "vector")
24285 (set_attr "mode" "XF")])
24287 (define_expand "expNcorexf3"
24288 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
24289 (match_operand:XF 2 "register_operand")))
24290 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
24291 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
24292 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
24293 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
24294 (parallel [(set (match_operand:XF 0 "register_operand")
24295 (unspec:XF [(match_dup 8) (match_dup 4)]
24296 UNSPEC_FSCALE_FRACT))
24298 (unspec:XF [(match_dup 8) (match_dup 4)]
24299 UNSPEC_FSCALE_EXP))])]
24300 "TARGET_USE_FANCY_MATH_387
24301 && flag_unsafe_math_optimizations"
24305 for (i = 3; i < 10; i++)
24306 operands[i] = gen_reg_rtx (XFmode);
24308 emit_move_insn (operands[7], CONST1_RTX (XFmode));
24311 (define_expand "expxf2"
24312 [(use (match_operand:XF 0 "register_operand"))
24313 (use (match_operand:XF 1 "register_operand"))]
24314 "TARGET_USE_FANCY_MATH_387
24315 && flag_unsafe_math_optimizations"
24317 rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (5)); /* fldl2e */
24319 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
24323 (define_expand "exp<mode>2"
24324 [(use (match_operand:MODEF 0 "register_operand"))
24325 (use (match_operand:MODEF 1 "general_operand"))]
24326 "TARGET_USE_FANCY_MATH_387
24327 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
24328 || TARGET_MIX_SSE_I387)
24329 && flag_unsafe_math_optimizations"
24331 rtx op0 = gen_reg_rtx (XFmode);
24332 rtx op1 = gen_reg_rtx (XFmode);
24334 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
24335 emit_insn (gen_expxf2 (op0, op1));
24336 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
24340 (define_expand "exp10xf2"
24341 [(use (match_operand:XF 0 "register_operand"))
24342 (use (match_operand:XF 1 "register_operand"))]
24343 "TARGET_USE_FANCY_MATH_387
24344 && flag_unsafe_math_optimizations"
24346 rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (6)); /* fldl2t */
24348 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
24352 (define_expand "exp10<mode>2"
24353 [(use (match_operand:MODEF 0 "register_operand"))
24354 (use (match_operand:MODEF 1 "general_operand"))]
24355 "TARGET_USE_FANCY_MATH_387
24356 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
24357 || TARGET_MIX_SSE_I387)
24358 && flag_unsafe_math_optimizations"
24360 rtx op0 = gen_reg_rtx (XFmode);
24361 rtx op1 = gen_reg_rtx (XFmode);
24363 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
24364 emit_insn (gen_exp10xf2 (op0, op1));
24365 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
24369 (define_expand "exp2xf2"
24370 [(use (match_operand:XF 0 "register_operand"))
24371 (use (match_operand:XF 1 "register_operand"))]
24372 "TARGET_USE_FANCY_MATH_387
24373 && flag_unsafe_math_optimizations"
24375 rtx op2 = force_reg (XFmode, CONST1_RTX (XFmode));
24377 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
24381 (define_expand "exp2<mode>2"
24382 [(use (match_operand:MODEF 0 "register_operand"))
24383 (use (match_operand:MODEF 1 "general_operand"))]
24384 "TARGET_USE_FANCY_MATH_387
24385 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
24386 || TARGET_MIX_SSE_I387)
24387 && flag_unsafe_math_optimizations"
24389 rtx op0 = gen_reg_rtx (XFmode);
24390 rtx op1 = gen_reg_rtx (XFmode);
24392 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
24393 emit_insn (gen_exp2xf2 (op0, op1));
24394 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
24398 (define_expand "expm1xf2"
24399 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
24401 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
24402 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
24403 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
24404 (parallel [(set (match_dup 7)
24405 (unspec:XF [(match_dup 6) (match_dup 4)]
24406 UNSPEC_FSCALE_FRACT))
24408 (unspec:XF [(match_dup 6) (match_dup 4)]
24409 UNSPEC_FSCALE_EXP))])
24410 (parallel [(set (match_dup 10)
24411 (unspec:XF [(match_dup 9) (match_dup 8)]
24412 UNSPEC_FSCALE_FRACT))
24413 (set (match_dup 11)
24414 (unspec:XF [(match_dup 9) (match_dup 8)]
24415 UNSPEC_FSCALE_EXP))])
24416 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
24417 (set (match_operand:XF 0 "register_operand")
24418 (plus:XF (match_dup 12) (match_dup 7)))]
24419 "TARGET_USE_FANCY_MATH_387
24420 && flag_unsafe_math_optimizations"
24424 for (i = 2; i < 13; i++)
24425 operands[i] = gen_reg_rtx (XFmode);
24427 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
24428 emit_move_insn (operands[9], CONST1_RTX (XFmode));
24431 (define_expand "expm1<mode>2"
24432 [(use (match_operand:MODEF 0 "register_operand"))
24433 (use (match_operand:MODEF 1 "general_operand"))]
24434 "TARGET_USE_FANCY_MATH_387
24435 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
24436 || TARGET_MIX_SSE_I387)
24437 && flag_unsafe_math_optimizations"
24439 rtx op0 = gen_reg_rtx (XFmode);
24440 rtx op1 = gen_reg_rtx (XFmode);
24442 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
24443 emit_insn (gen_expm1xf2 (op0, op1));
24444 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
24448 (define_insn "avx512f_scalef<mode>2"
24449 [(set (match_operand:MODEF 0 "register_operand" "=v")
24451 [(match_operand:MODEF 1 "register_operand" "v")
24452 (match_operand:MODEF 2 "nonimmediate_operand" "vm")]
24455 "vscalef<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
24456 [(set_attr "prefix" "evex")
24457 (set_attr "mode" "<MODE>")])
24459 (define_expand "ldexpxf3"
24460 [(match_operand:XF 0 "register_operand")
24461 (match_operand:XF 1 "register_operand")
24462 (match_operand:SI 2 "register_operand")]
24463 "TARGET_USE_FANCY_MATH_387
24464 && flag_unsafe_math_optimizations"
24466 rtx tmp1 = gen_reg_rtx (XFmode);
24467 rtx tmp2 = gen_reg_rtx (XFmode);
24469 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
24470 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
24471 operands[1], tmp1));
24475 (define_expand "ldexp<mode>3"
24476 [(use (match_operand:MODEF 0 "register_operand"))
24477 (use (match_operand:MODEF 1 "general_operand"))
24478 (use (match_operand:SI 2 "register_operand"))]
24479 "((TARGET_USE_FANCY_MATH_387
24480 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
24481 || TARGET_MIX_SSE_I387))
24482 || (TARGET_AVX512F && TARGET_SSE_MATH))
24483 && flag_unsafe_math_optimizations"
24485 /* Prefer avx512f version. */
24486 if (TARGET_AVX512F && TARGET_SSE_MATH)
24488 rtx op2 = gen_reg_rtx (<MODE>mode);
24489 operands[1] = force_reg (<MODE>mode, operands[1]);
24491 emit_insn (gen_floatsi<mode>2 (op2, operands[2]));
24492 emit_insn (gen_avx512f_scalef<mode>2 (operands[0], operands[1], op2));
24496 rtx op0 = gen_reg_rtx (XFmode);
24497 rtx op1 = gen_reg_rtx (XFmode);
24499 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
24500 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
24501 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
24506 (define_expand "scalbxf3"
24507 [(parallel [(set (match_operand:XF 0 " register_operand")
24508 (unspec:XF [(match_operand:XF 1 "register_operand")
24509 (match_operand:XF 2 "register_operand")]
24510 UNSPEC_FSCALE_FRACT))
24512 (unspec:XF [(match_dup 1) (match_dup 2)]
24513 UNSPEC_FSCALE_EXP))])]
24514 "TARGET_USE_FANCY_MATH_387
24515 && flag_unsafe_math_optimizations"
24516 "operands[3] = gen_reg_rtx (XFmode);")
24518 (define_expand "scalb<mode>3"
24519 [(use (match_operand:MODEF 0 "register_operand"))
24520 (use (match_operand:MODEF 1 "general_operand"))
24521 (use (match_operand:MODEF 2 "general_operand"))]
24522 "TARGET_USE_FANCY_MATH_387
24523 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
24524 || TARGET_MIX_SSE_I387)
24525 && flag_unsafe_math_optimizations"
24527 rtx op0 = gen_reg_rtx (XFmode);
24528 rtx op1 = gen_reg_rtx (XFmode);
24529 rtx op2 = gen_reg_rtx (XFmode);
24531 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
24532 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
24533 emit_insn (gen_scalbxf3 (op0, op1, op2));
24534 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
24538 (define_expand "significandxf2"
24539 [(parallel [(set (match_operand:XF 0 "register_operand")
24540 (unspec:XF [(match_operand:XF 1 "register_operand")]
24541 UNSPEC_XTRACT_FRACT))
24543 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
24544 "TARGET_USE_FANCY_MATH_387
24545 && flag_unsafe_math_optimizations"
24546 "operands[2] = gen_reg_rtx (XFmode);")
24548 (define_expand "significand<mode>2"
24549 [(use (match_operand:MODEF 0 "register_operand"))
24550 (use (match_operand:MODEF 1 "general_operand"))]
24551 "TARGET_USE_FANCY_MATH_387
24552 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
24553 || TARGET_MIX_SSE_I387)
24554 && flag_unsafe_math_optimizations"
24556 rtx op0 = gen_reg_rtx (XFmode);
24557 rtx op1 = gen_reg_rtx (XFmode);
24559 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
24560 emit_insn (gen_significandxf2 (op0, op1));
24561 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
24566 (define_insn "sse4_1_round<mode>2"
24567 [(set (match_operand:MODEFH 0 "register_operand" "=x,x,x,v,v")
24569 [(match_operand:MODEFH 1 "nonimmediate_operand" "0,x,jm,v,m")
24570 (match_operand:SI 2 "const_0_to_15_operand")]
24574 %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
24575 %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
24576 %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
24577 vrndscale<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
24578 vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
24579 [(set_attr "type" "ssecvt")
24580 (set_attr "prefix_extra" "1,1,1,*,*")
24581 (set_attr "length_immediate" "1")
24582 (set_attr "addr" "*,*,gpr16,*,*")
24583 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,evex,evex")
24584 (set_attr "isa" "noavx512f,noavx512f,noavx512f,avx512f,avx512f")
24585 (set_attr "avx_partial_xmm_update" "false,false,true,false,true")
24586 (set_attr "mode" "<MODE>")
24587 (set (attr "preferred_for_speed")
24588 (cond [(match_test "TARGET_AVX")
24589 (symbol_ref "true")
24590 (eq_attr "alternative" "1,2")
24591 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
24593 (symbol_ref "true")))])
24595 (define_insn "rintxf2"
24596 [(set (match_operand:XF 0 "register_operand" "=f")
24597 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
24599 "TARGET_USE_FANCY_MATH_387"
24601 [(set_attr "type" "fpspc")
24602 (set_attr "znver1_decode" "vector")
24603 (set_attr "mode" "XF")])
24605 (define_expand "rinthf2"
24606 [(match_operand:HF 0 "register_operand")
24607 (match_operand:HF 1 "nonimmediate_operand")]
24608 "TARGET_AVX512FP16"
24610 emit_insn (gen_sse4_1_roundhf2 (operands[0],
24612 GEN_INT (ROUND_MXCSR)));
24616 (define_expand "rint<mode>2"
24617 [(use (match_operand:MODEF 0 "register_operand"))
24618 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
24619 "TARGET_USE_FANCY_MATH_387
24620 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
24622 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
24625 emit_insn (gen_sse4_1_round<mode>2
24626 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
24628 ix86_expand_rint (operands[0], operands[1]);
24632 rtx op0 = gen_reg_rtx (XFmode);
24633 rtx op1 = gen_reg_rtx (XFmode);
24635 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
24636 emit_insn (gen_rintxf2 (op0, op1));
24637 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
24642 (define_expand "nearbyintxf2"
24643 [(set (match_operand:XF 0 "register_operand")
24644 (unspec:XF [(match_operand:XF 1 "register_operand")]
24646 "TARGET_USE_FANCY_MATH_387
24647 && !flag_trapping_math")
24649 (define_expand "nearbyinthf2"
24650 [(match_operand:HF 0 "register_operand")
24651 (match_operand:HF 1 "nonimmediate_operand")]
24652 "TARGET_AVX512FP16"
24654 emit_insn (gen_sse4_1_roundhf2 (operands[0],
24656 GEN_INT (ROUND_MXCSR | ROUND_NO_EXC)));
24660 (define_expand "nearbyint<mode>2"
24661 [(use (match_operand:MODEF 0 "register_operand"))
24662 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
24663 "(TARGET_USE_FANCY_MATH_387
24664 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
24665 || TARGET_MIX_SSE_I387)
24666 && !flag_trapping_math)
24667 || (TARGET_SSE4_1 && TARGET_SSE_MATH)"
24669 if (TARGET_SSE4_1 && TARGET_SSE_MATH)
24670 emit_insn (gen_sse4_1_round<mode>2
24671 (operands[0], operands[1], GEN_INT (ROUND_MXCSR
24675 rtx op0 = gen_reg_rtx (XFmode);
24676 rtx op1 = gen_reg_rtx (XFmode);
24678 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
24679 emit_insn (gen_nearbyintxf2 (op0, op1));
24680 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
24685 (define_expand "roundhf2"
24686 [(match_operand:HF 0 "register_operand")
24687 (match_operand:HF 1 "register_operand")]
24688 "TARGET_AVX512FP16 && !flag_trapping_math && !flag_rounding_math"
24690 ix86_expand_round_sse4 (operands[0], operands[1]);
24694 (define_expand "round<mode>2"
24695 [(match_operand:X87MODEF 0 "register_operand")
24696 (match_operand:X87MODEF 1 "nonimmediate_operand")]
24697 "(TARGET_USE_FANCY_MATH_387
24698 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
24699 || TARGET_MIX_SSE_I387)
24700 && flag_unsafe_math_optimizations
24701 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
24702 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
24703 && !flag_trapping_math && !flag_rounding_math)"
24705 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
24706 && !flag_trapping_math && !flag_rounding_math)
24710 operands[1] = force_reg (<MODE>mode, operands[1]);
24711 ix86_expand_round_sse4 (operands[0], operands[1]);
24713 else if (TARGET_64BIT || (<MODE>mode != DFmode))
24714 ix86_expand_round (operands[0], operands[1]);
24716 ix86_expand_rounddf_32 (operands[0], operands[1]);
24720 operands[1] = force_reg (<MODE>mode, operands[1]);
24721 ix86_emit_i387_round (operands[0], operands[1]);
24726 (define_insn "lrintxfdi2"
24727 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
24728 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
24730 (clobber (match_scratch:XF 2 "=&f"))]
24731 "TARGET_USE_FANCY_MATH_387"
24732 "* return output_fix_trunc (insn, operands, false);"
24733 [(set_attr "type" "fpspc")
24734 (set_attr "mode" "DI")])
24736 (define_insn "lrintxf<mode>2"
24737 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
24738 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
24740 "TARGET_USE_FANCY_MATH_387"
24741 "* return output_fix_trunc (insn, operands, false);"
24742 [(set_attr "type" "fpspc")
24743 (set_attr "mode" "<MODE>")])
24745 (define_expand "lroundhf<mode>2"
24746 [(set (match_operand:SWI248 0 "register_operand")
24747 (unspec:SWI248 [(match_operand:HF 1 "nonimmediate_operand")]
24748 UNSPEC_FIX_NOTRUNC))]
24749 "TARGET_AVX512FP16 && !flag_trapping_math && !flag_rounding_math"
24751 ix86_expand_lround (operands[0], operands[1]);
24755 (define_expand "lrinthf<mode>2"
24756 [(set (match_operand:SWI48 0 "register_operand")
24757 (unspec:SWI48 [(match_operand:HF 1 "nonimmediate_operand")]
24758 UNSPEC_FIX_NOTRUNC))]
24759 "TARGET_AVX512FP16")
24761 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
24762 [(set (match_operand:SWI48 0 "register_operand")
24763 (unspec:SWI48 [(match_operand:MODEF 1 "nonimmediate_operand")]
24764 UNSPEC_FIX_NOTRUNC))]
24765 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
24767 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
24768 [(match_operand:SWI248x 0 "nonimmediate_operand")
24769 (match_operand:X87MODEF 1 "register_operand")]
24770 "(TARGET_USE_FANCY_MATH_387
24771 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
24772 || TARGET_MIX_SSE_I387)
24773 && flag_unsafe_math_optimizations)
24774 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
24775 && <SWI248x:MODE>mode != HImode
24776 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
24777 && !flag_trapping_math && !flag_rounding_math)"
24779 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
24780 && <SWI248x:MODE>mode != HImode
24781 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
24782 && !flag_trapping_math && !flag_rounding_math)
24783 ix86_expand_lround (operands[0], operands[1]);
24785 ix86_emit_i387_round (operands[0], operands[1]);
24789 (define_int_iterator FRNDINT_ROUNDING
24790 [UNSPEC_FRNDINT_ROUNDEVEN
24791 UNSPEC_FRNDINT_FLOOR
24792 UNSPEC_FRNDINT_CEIL
24793 UNSPEC_FRNDINT_TRUNC])
24795 (define_int_iterator FIST_ROUNDING
24799 ;; Base name for define_insn
24800 (define_int_attr rounding_insn
24801 [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven")
24802 (UNSPEC_FRNDINT_FLOOR "floor")
24803 (UNSPEC_FRNDINT_CEIL "ceil")
24804 (UNSPEC_FRNDINT_TRUNC "btrunc")
24805 (UNSPEC_FIST_FLOOR "floor")
24806 (UNSPEC_FIST_CEIL "ceil")])
24808 (define_int_attr rounding
24809 [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven")
24810 (UNSPEC_FRNDINT_FLOOR "floor")
24811 (UNSPEC_FRNDINT_CEIL "ceil")
24812 (UNSPEC_FRNDINT_TRUNC "trunc")
24813 (UNSPEC_FIST_FLOOR "floor")
24814 (UNSPEC_FIST_CEIL "ceil")])
24816 (define_int_attr ROUNDING
24817 [(UNSPEC_FRNDINT_ROUNDEVEN "ROUNDEVEN")
24818 (UNSPEC_FRNDINT_FLOOR "FLOOR")
24819 (UNSPEC_FRNDINT_CEIL "CEIL")
24820 (UNSPEC_FRNDINT_TRUNC "TRUNC")
24821 (UNSPEC_FIST_FLOOR "FLOOR")
24822 (UNSPEC_FIST_CEIL "CEIL")])
24824 ;; Rounding mode control word calculation could clobber FLAGS_REG.
24825 (define_insn_and_split "frndintxf2_<rounding>"
24826 [(set (match_operand:XF 0 "register_operand")
24827 (unspec:XF [(match_operand:XF 1 "register_operand")]
24829 (clobber (reg:CC FLAGS_REG))]
24830 "TARGET_USE_FANCY_MATH_387
24831 && (flag_fp_int_builtin_inexact || !flag_trapping_math)
24832 && ix86_pre_reload_split ()"
24837 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
24839 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
24840 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
24842 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
24843 operands[2], operands[3]));
24846 [(set_attr "type" "frndint")
24847 (set_attr "i387_cw" "<rounding>")
24848 (set_attr "mode" "XF")])
24850 (define_insn "frndintxf2_<rounding>_i387"
24851 [(set (match_operand:XF 0 "register_operand" "=f")
24852 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
24854 (use (match_operand:HI 2 "memory_operand" "m"))
24855 (use (match_operand:HI 3 "memory_operand" "m"))]
24856 "TARGET_USE_FANCY_MATH_387
24857 && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
24858 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
24859 [(set_attr "type" "frndint")
24860 (set_attr "i387_cw" "<rounding>")
24861 (set_attr "mode" "XF")])
24863 (define_expand "<rounding_insn>xf2"
24864 [(parallel [(set (match_operand:XF 0 "register_operand")
24865 (unspec:XF [(match_operand:XF 1 "register_operand")]
24867 (clobber (reg:CC FLAGS_REG))])]
24868 "TARGET_USE_FANCY_MATH_387
24869 && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
24871 (define_expand "<rounding_insn>hf2"
24872 [(parallel [(set (match_operand:HF 0 "register_operand")
24873 (unspec:HF [(match_operand:HF 1 "register_operand")]
24875 (clobber (reg:CC FLAGS_REG))])]
24876 "TARGET_AVX512FP16"
24878 emit_insn (gen_sse4_1_roundhf2 (operands[0], operands[1],
24879 GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
24883 (define_expand "<rounding_insn><mode>2"
24884 [(parallel [(set (match_operand:MODEF 0 "register_operand")
24885 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
24887 (clobber (reg:CC FLAGS_REG))])]
24888 "(TARGET_USE_FANCY_MATH_387
24889 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
24890 || TARGET_MIX_SSE_I387)
24891 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
24892 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
24894 || (ROUND_<ROUNDING> != ROUND_ROUNDEVEN
24895 && (flag_fp_int_builtin_inexact || !flag_trapping_math))))"
24897 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
24899 || (ROUND_<ROUNDING> != ROUND_ROUNDEVEN
24900 && (flag_fp_int_builtin_inexact || !flag_trapping_math))))
24903 emit_insn (gen_sse4_1_round<mode>2
24904 (operands[0], operands[1],
24905 GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
24906 else if (TARGET_64BIT || (<MODE>mode != DFmode))
24908 if (ROUND_<ROUNDING> == ROUND_FLOOR)
24909 ix86_expand_floorceil (operands[0], operands[1], true);
24910 else if (ROUND_<ROUNDING> == ROUND_CEIL)
24911 ix86_expand_floorceil (operands[0], operands[1], false);
24912 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
24913 ix86_expand_trunc (operands[0], operands[1]);
24915 gcc_unreachable ();
24919 if (ROUND_<ROUNDING> == ROUND_FLOOR)
24920 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
24921 else if (ROUND_<ROUNDING> == ROUND_CEIL)
24922 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
24923 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
24924 ix86_expand_truncdf_32 (operands[0], operands[1]);
24926 gcc_unreachable ();
24931 rtx op0 = gen_reg_rtx (XFmode);
24932 rtx op1 = gen_reg_rtx (XFmode);
24934 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
24935 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
24936 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
24941 ;; Rounding mode control word calculation could clobber FLAGS_REG.
24942 (define_insn_and_split "*fist<mode>2_<rounding>_1"
24943 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
24944 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
24946 (clobber (reg:CC FLAGS_REG))]
24947 "TARGET_USE_FANCY_MATH_387
24948 && flag_unsafe_math_optimizations
24949 && ix86_pre_reload_split ()"
24954 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
24956 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
24957 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
24959 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
24960 operands[2], operands[3]));
24963 [(set_attr "type" "fistp")
24964 (set_attr "i387_cw" "<rounding>")
24965 (set_attr "mode" "<MODE>")])
24967 (define_insn "fistdi2_<rounding>"
24968 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
24969 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
24971 (use (match_operand:HI 2 "memory_operand" "m"))
24972 (use (match_operand:HI 3 "memory_operand" "m"))
24973 (clobber (match_scratch:XF 4 "=&f"))]
24974 "TARGET_USE_FANCY_MATH_387
24975 && flag_unsafe_math_optimizations"
24976 "* return output_fix_trunc (insn, operands, false);"
24977 [(set_attr "type" "fistp")
24978 (set_attr "i387_cw" "<rounding>")
24979 (set_attr "mode" "DI")])
24981 (define_insn "fist<mode>2_<rounding>"
24982 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
24983 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
24985 (use (match_operand:HI 2 "memory_operand" "m"))
24986 (use (match_operand:HI 3 "memory_operand" "m"))]
24987 "TARGET_USE_FANCY_MATH_387
24988 && flag_unsafe_math_optimizations"
24989 "* return output_fix_trunc (insn, operands, false);"
24990 [(set_attr "type" "fistp")
24991 (set_attr "i387_cw" "<rounding>")
24992 (set_attr "mode" "<MODE>")])
24994 (define_expand "l<rounding_insn>xf<mode>2"
24995 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
24996 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
24998 (clobber (reg:CC FLAGS_REG))])]
24999 "TARGET_USE_FANCY_MATH_387
25000 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
25001 && flag_unsafe_math_optimizations")
25003 (define_expand "l<rounding_insn>hf<mode>2"
25004 [(set (match_operand:SWI48 0 "nonimmediate_operand")
25005 (unspec:SWI48 [(match_operand:HF 1 "register_operand")]
25007 "TARGET_AVX512FP16"
25009 rtx tmp = gen_reg_rtx (HFmode);
25010 emit_insn (gen_sse4_1_roundhf2 (tmp, operands[1],
25011 GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
25012 emit_insn (gen_fix_trunchf<mode>2 (operands[0], tmp));
25016 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
25017 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
25018 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
25020 (clobber (reg:CC FLAGS_REG))])]
25021 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
25022 && (TARGET_SSE4_1 || !flag_trapping_math)"
25026 rtx tmp = gen_reg_rtx (<MODEF:MODE>mode);
25028 emit_insn (gen_sse4_1_round<MODEF:mode>2
25029 (tmp, operands[1], GEN_INT (ROUND_<ROUNDING>
25031 emit_insn (gen_fix_trunc<MODEF:mode><SWI48:mode>2
25032 (operands[0], tmp));
25034 else if (ROUND_<ROUNDING> == ROUND_FLOOR)
25035 ix86_expand_lfloorceil (operands[0], operands[1], true);
25036 else if (ROUND_<ROUNDING> == ROUND_CEIL)
25037 ix86_expand_lfloorceil (operands[0], operands[1], false);
25039 gcc_unreachable ();
25044 (define_insn "fxam<mode>2_i387"
25045 [(set (match_operand:HI 0 "register_operand" "=a")
25047 [(match_operand:X87MODEF 1 "register_operand" "f")]
25049 "TARGET_USE_FANCY_MATH_387"
25050 "fxam\n\tfnstsw\t%0"
25051 [(set_attr "type" "multi")
25052 (set_attr "length" "4")
25053 (set_attr "unit" "i387")
25054 (set_attr "mode" "<MODE>")])
25056 (define_expand "signbittf2"
25057 [(use (match_operand:SI 0 "register_operand"))
25058 (use (match_operand:TF 1 "register_operand"))]
25063 rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
25064 rtx scratch = gen_reg_rtx (QImode);
25066 emit_insn (gen_ptesttf2 (operands[1], mask));
25067 ix86_expand_setcc (scratch, NE,
25068 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
25070 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
25074 emit_insn (gen_sse_movmskps (operands[0],
25075 gen_lowpart (V4SFmode, operands[1])));
25076 emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8)));
25081 (define_expand "signbitxf2"
25082 [(use (match_operand:SI 0 "register_operand"))
25083 (use (match_operand:XF 1 "register_operand"))]
25084 "TARGET_USE_FANCY_MATH_387"
25086 rtx scratch = gen_reg_rtx (HImode);
25088 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
25089 emit_insn (gen_andsi3 (operands[0],
25090 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
25094 (define_insn "movmsk_df"
25095 [(set (match_operand:SI 0 "register_operand" "=r,jr")
25097 [(match_operand:DF 1 "register_operand" "x,x")]
25099 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
25100 "%vmovmskpd\t{%1, %0|%0, %1}"
25101 [(set_attr "isa" "noavx,avx")
25102 (set_attr "type" "ssemov")
25103 (set_attr "prefix" "maybe_evex")
25104 (set_attr "mode" "DF")])
25106 ;; Use movmskpd in SSE mode to avoid store forwarding stall
25107 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
25108 (define_expand "signbitdf2"
25109 [(use (match_operand:SI 0 "register_operand"))
25110 (use (match_operand:DF 1 "register_operand"))]
25111 "TARGET_USE_FANCY_MATH_387
25112 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
25114 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
25116 emit_insn (gen_movmsk_df (operands[0], operands[1]));
25117 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
25121 rtx scratch = gen_reg_rtx (HImode);
25123 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
25124 emit_insn (gen_andsi3 (operands[0],
25125 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
25130 (define_expand "signbitsf2"
25131 [(use (match_operand:SI 0 "register_operand"))
25132 (use (match_operand:SF 1 "register_operand"))]
25133 "TARGET_USE_FANCY_MATH_387
25134 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
25136 rtx scratch = gen_reg_rtx (HImode);
25138 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
25139 emit_insn (gen_andsi3 (operands[0],
25140 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
25144 ;; Block operation instructions
25147 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
25150 [(set_attr "length" "1")
25151 (set_attr "length_immediate" "0")
25152 (set_attr "modrm" "0")])
25154 (define_expand "cpymem<mode>"
25155 [(use (match_operand:BLK 0 "memory_operand"))
25156 (use (match_operand:BLK 1 "memory_operand"))
25157 (use (match_operand:SWI48 2 "nonmemory_operand"))
25158 (use (match_operand:SWI48 3 "const_int_operand"))
25159 (use (match_operand:SI 4 "const_int_operand"))
25160 (use (match_operand:SI 5 "const_int_operand"))
25161 (use (match_operand:SI 6 ""))
25162 (use (match_operand:SI 7 ""))
25163 (use (match_operand:SI 8 ""))]
25166 if (ix86_expand_set_or_cpymem (operands[0], operands[1],
25167 operands[2], NULL, operands[3],
25168 operands[4], operands[5],
25169 operands[6], operands[7],
25170 operands[8], false))
25176 ;; Most CPUs don't like single string operations
25177 ;; Handle this case here to simplify previous expander.
25179 (define_expand "strmov"
25180 [(set (match_dup 4) (match_operand 3 "memory_operand"))
25181 (set (match_operand 1 "memory_operand") (match_dup 4))
25182 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
25183 (clobber (reg:CC FLAGS_REG))])
25184 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
25185 (clobber (reg:CC FLAGS_REG))])]
25188 /* Can't use this for non-default address spaces. */
25189 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
25192 int piece_size = GET_MODE_SIZE (GET_MODE (operands[1]));
25194 /* If .md ever supports :P for Pmode, these can be directly
25195 in the pattern above. */
25196 operands[5] = plus_constant (Pmode, operands[0], piece_size);
25197 operands[6] = plus_constant (Pmode, operands[2], piece_size);
25199 /* Can't use this if the user has appropriated esi or edi. */
25200 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
25201 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
25203 emit_insn (gen_strmov_singleop (operands[0], operands[1],
25204 operands[2], operands[3],
25205 operands[5], operands[6]));
25209 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
25212 (define_expand "strmov_singleop"
25213 [(parallel [(set (match_operand 1 "memory_operand")
25214 (match_operand 3 "memory_operand"))
25215 (set (match_operand 0 "register_operand")
25217 (set (match_operand 2 "register_operand")
25218 (match_operand 5))])]
25222 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
25225 (define_insn "*strmovdi_rex_1"
25226 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
25227 (mem:DI (match_operand:P 3 "register_operand" "1")))
25228 (set (match_operand:P 0 "register_operand" "=D")
25229 (plus:P (match_dup 2)
25231 (set (match_operand:P 1 "register_operand" "=S")
25232 (plus:P (match_dup 3)
25235 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
25236 && ix86_check_no_addr_space (insn)"
25238 [(set_attr "type" "str")
25239 (set_attr "memory" "both")
25240 (set_attr "mode" "DI")])
25242 (define_insn "*strmovsi_1"
25243 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
25244 (mem:SI (match_operand:P 3 "register_operand" "1")))
25245 (set (match_operand:P 0 "register_operand" "=D")
25246 (plus:P (match_dup 2)
25248 (set (match_operand:P 1 "register_operand" "=S")
25249 (plus:P (match_dup 3)
25251 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
25252 && ix86_check_no_addr_space (insn)"
25254 [(set_attr "type" "str")
25255 (set_attr "memory" "both")
25256 (set_attr "mode" "SI")])
25258 (define_insn "*strmovhi_1"
25259 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
25260 (mem:HI (match_operand:P 3 "register_operand" "1")))
25261 (set (match_operand:P 0 "register_operand" "=D")
25262 (plus:P (match_dup 2)
25264 (set (match_operand:P 1 "register_operand" "=S")
25265 (plus:P (match_dup 3)
25267 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
25268 && ix86_check_no_addr_space (insn)"
25270 [(set_attr "type" "str")
25271 (set_attr "memory" "both")
25272 (set_attr "mode" "HI")])
25274 (define_insn "*strmovqi_1"
25275 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
25276 (mem:QI (match_operand:P 3 "register_operand" "1")))
25277 (set (match_operand:P 0 "register_operand" "=D")
25278 (plus:P (match_dup 2)
25280 (set (match_operand:P 1 "register_operand" "=S")
25281 (plus:P (match_dup 3)
25283 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
25284 && ix86_check_no_addr_space (insn)"
25286 [(set_attr "type" "str")
25287 (set_attr "memory" "both")
25288 (set (attr "prefix_rex")
25290 (match_test "<P:MODE>mode == DImode")
25292 (const_string "*")))
25293 (set_attr "mode" "QI")])
25295 (define_expand "rep_mov"
25296 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
25297 (set (match_operand 0 "register_operand")
25299 (set (match_operand 2 "register_operand")
25301 (set (match_operand 1 "memory_operand")
25302 (match_operand 3 "memory_operand"))
25303 (use (match_dup 4))])]
25307 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
25310 (define_insn "*rep_movdi_rex64"
25311 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
25312 (set (match_operand:P 0 "register_operand" "=D")
25313 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
25315 (match_operand:P 3 "register_operand" "0")))
25316 (set (match_operand:P 1 "register_operand" "=S")
25317 (plus:P (ashift:P (match_dup 5) (const_int 3))
25318 (match_operand:P 4 "register_operand" "1")))
25319 (set (mem:BLK (match_dup 3))
25320 (mem:BLK (match_dup 4)))
25321 (use (match_dup 5))]
25323 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
25324 && ix86_check_no_addr_space (insn)"
25326 [(set_attr "type" "str")
25327 (set_attr "prefix_rep" "1")
25328 (set_attr "memory" "both")
25329 (set_attr "mode" "DI")])
25331 (define_insn "*rep_movsi"
25332 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
25333 (set (match_operand:P 0 "register_operand" "=D")
25334 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
25336 (match_operand:P 3 "register_operand" "0")))
25337 (set (match_operand:P 1 "register_operand" "=S")
25338 (plus:P (ashift:P (match_dup 5) (const_int 2))
25339 (match_operand:P 4 "register_operand" "1")))
25340 (set (mem:BLK (match_dup 3))
25341 (mem:BLK (match_dup 4)))
25342 (use (match_dup 5))]
25343 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
25344 && ix86_check_no_addr_space (insn)"
25345 "%^rep{%;} movs{l|d}"
25346 [(set_attr "type" "str")
25347 (set_attr "prefix_rep" "1")
25348 (set_attr "memory" "both")
25349 (set_attr "mode" "SI")])
25351 (define_insn "*rep_movqi"
25352 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
25353 (set (match_operand:P 0 "register_operand" "=D")
25354 (plus:P (match_operand:P 3 "register_operand" "0")
25355 (match_operand:P 5 "register_operand" "2")))
25356 (set (match_operand:P 1 "register_operand" "=S")
25357 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
25358 (set (mem:BLK (match_dup 3))
25359 (mem:BLK (match_dup 4)))
25360 (use (match_dup 5))]
25361 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
25362 && ix86_check_no_addr_space (insn)"
25364 [(set_attr "type" "str")
25365 (set_attr "prefix_rep" "1")
25366 (set_attr "memory" "both")
25367 (set_attr "mode" "QI")])
25369 (define_expand "setmem<mode>"
25370 [(use (match_operand:BLK 0 "memory_operand"))
25371 (use (match_operand:SWI48 1 "nonmemory_operand"))
25372 (use (match_operand:QI 2 "nonmemory_operand"))
25373 (use (match_operand 3 "const_int_operand"))
25374 (use (match_operand:SI 4 "const_int_operand"))
25375 (use (match_operand:SI 5 "const_int_operand"))
25376 (use (match_operand:SI 6 ""))
25377 (use (match_operand:SI 7 ""))
25378 (use (match_operand:SI 8 ""))]
25381 if (ix86_expand_set_or_cpymem (operands[0], NULL,
25382 operands[1], operands[2],
25383 operands[3], operands[4],
25384 operands[5], operands[6],
25385 operands[7], operands[8], true))
25391 ;; Most CPUs don't like single string operations
25392 ;; Handle this case here to simplify previous expander.
25394 (define_expand "strset"
25395 [(set (match_operand 1 "memory_operand")
25396 (match_operand 2 "register_operand"))
25397 (parallel [(set (match_operand 0 "register_operand")
25399 (clobber (reg:CC FLAGS_REG))])]
25402 /* Can't use this for non-default address spaces. */
25403 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
25406 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
25407 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
25409 /* If .md ever supports :P for Pmode, this can be directly
25410 in the pattern above. */
25411 operands[3] = plus_constant (Pmode, operands[0],
25412 GET_MODE_SIZE (GET_MODE (operands[2])));
25414 /* Can't use this if the user has appropriated eax or edi. */
25415 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
25416 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
25418 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
25424 (define_expand "strset_singleop"
25425 [(parallel [(set (match_operand 1 "memory_operand")
25426 (match_operand 2 "register_operand"))
25427 (set (match_operand 0 "register_operand")
25429 (unspec [(const_int 0)] UNSPEC_STOS)])]
25433 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
25436 (define_insn "*strsetdi_rex_1"
25437 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
25438 (match_operand:DI 2 "register_operand" "a"))
25439 (set (match_operand:P 0 "register_operand" "=D")
25440 (plus:P (match_dup 1)
25442 (unspec [(const_int 0)] UNSPEC_STOS)]
25444 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
25445 && ix86_check_no_addr_space (insn)"
25447 [(set_attr "type" "str")
25448 (set_attr "memory" "store")
25449 (set_attr "mode" "DI")])
25451 (define_insn "*strsetsi_1"
25452 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
25453 (match_operand:SI 2 "register_operand" "a"))
25454 (set (match_operand:P 0 "register_operand" "=D")
25455 (plus:P (match_dup 1)
25457 (unspec [(const_int 0)] UNSPEC_STOS)]
25458 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
25459 && ix86_check_no_addr_space (insn)"
25461 [(set_attr "type" "str")
25462 (set_attr "memory" "store")
25463 (set_attr "mode" "SI")])
25465 (define_insn "*strsethi_1"
25466 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
25467 (match_operand:HI 2 "register_operand" "a"))
25468 (set (match_operand:P 0 "register_operand" "=D")
25469 (plus:P (match_dup 1)
25471 (unspec [(const_int 0)] UNSPEC_STOS)]
25472 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
25473 && ix86_check_no_addr_space (insn)"
25475 [(set_attr "type" "str")
25476 (set_attr "memory" "store")
25477 (set_attr "mode" "HI")])
25479 (define_insn "*strsetqi_1"
25480 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
25481 (match_operand:QI 2 "register_operand" "a"))
25482 (set (match_operand:P 0 "register_operand" "=D")
25483 (plus:P (match_dup 1)
25485 (unspec [(const_int 0)] UNSPEC_STOS)]
25486 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
25487 && ix86_check_no_addr_space (insn)"
25489 [(set_attr "type" "str")
25490 (set_attr "memory" "store")
25491 (set (attr "prefix_rex")
25493 (match_test "<P:MODE>mode == DImode")
25495 (const_string "*")))
25496 (set_attr "mode" "QI")])
25498 (define_expand "rep_stos"
25499 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
25500 (set (match_operand 0 "register_operand")
25502 (set (match_operand 2 "memory_operand") (const_int 0))
25503 (use (match_operand 3 "register_operand"))
25504 (use (match_dup 1))])]
25508 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
25511 (define_insn "*rep_stosdi_rex64"
25512 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
25513 (set (match_operand:P 0 "register_operand" "=D")
25514 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
25516 (match_operand:P 3 "register_operand" "0")))
25517 (set (mem:BLK (match_dup 3))
25519 (use (match_operand:DI 2 "register_operand" "a"))
25520 (use (match_dup 4))]
25522 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
25523 && ix86_check_no_addr_space (insn)"
25525 [(set_attr "type" "str")
25526 (set_attr "prefix_rep" "1")
25527 (set_attr "memory" "store")
25528 (set_attr "mode" "DI")])
25530 (define_insn "*rep_stossi"
25531 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
25532 (set (match_operand:P 0 "register_operand" "=D")
25533 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
25535 (match_operand:P 3 "register_operand" "0")))
25536 (set (mem:BLK (match_dup 3))
25538 (use (match_operand:SI 2 "register_operand" "a"))
25539 (use (match_dup 4))]
25540 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
25541 && ix86_check_no_addr_space (insn)"
25542 "%^rep{%;} stos{l|d}"
25543 [(set_attr "type" "str")
25544 (set_attr "prefix_rep" "1")
25545 (set_attr "memory" "store")
25546 (set_attr "mode" "SI")])
25548 (define_insn "*rep_stosqi"
25549 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
25550 (set (match_operand:P 0 "register_operand" "=D")
25551 (plus:P (match_operand:P 3 "register_operand" "0")
25552 (match_operand:P 4 "register_operand" "1")))
25553 (set (mem:BLK (match_dup 3))
25555 (use (match_operand:QI 2 "register_operand" "a"))
25556 (use (match_dup 4))]
25557 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
25558 && ix86_check_no_addr_space (insn)"
25560 [(set_attr "type" "str")
25561 (set_attr "prefix_rep" "1")
25562 (set_attr "memory" "store")
25563 (set (attr "prefix_rex")
25565 (match_test "<P:MODE>mode == DImode")
25567 (const_string "*")))
25568 (set_attr "mode" "QI")])
25570 (define_expand "cmpmemsi"
25571 [(set (match_operand:SI 0 "register_operand" "")
25572 (compare:SI (match_operand:BLK 1 "memory_operand" "")
25573 (match_operand:BLK 2 "memory_operand" "") ) )
25574 (use (match_operand 3 "general_operand"))
25575 (use (match_operand 4 "immediate_operand"))]
25578 if (ix86_expand_cmpstrn_or_cmpmem (operands[0], operands[1],
25579 operands[2], operands[3],
25580 operands[4], false))
25586 (define_expand "cmpstrnsi"
25587 [(set (match_operand:SI 0 "register_operand")
25588 (compare:SI (match_operand:BLK 1 "general_operand")
25589 (match_operand:BLK 2 "general_operand")))
25590 (use (match_operand 3 "general_operand"))
25591 (use (match_operand 4 "immediate_operand"))]
25594 if (ix86_expand_cmpstrn_or_cmpmem (operands[0], operands[1],
25595 operands[2], operands[3],
25596 operands[4], true))
25602 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
25604 (define_expand "cmpintqi"
25605 [(set (match_dup 1)
25606 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
25608 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
25609 (parallel [(set (match_operand:QI 0 "register_operand")
25610 (minus:QI (match_dup 1)
25612 (clobber (reg:CC FLAGS_REG))])]
25615 operands[1] = gen_reg_rtx (QImode);
25616 operands[2] = gen_reg_rtx (QImode);
25619 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
25620 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
25622 (define_expand "cmpstrnqi_nz_1"
25623 [(parallel [(set (reg:CC FLAGS_REG)
25624 (compare:CC (match_operand 4 "memory_operand")
25625 (match_operand 5 "memory_operand")))
25626 (use (match_operand 2 "register_operand"))
25627 (use (match_operand:SI 3 "immediate_operand"))
25628 (clobber (match_operand 0 "register_operand"))
25629 (clobber (match_operand 1 "register_operand"))
25630 (clobber (match_dup 2))])]
25634 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
25637 (define_insn "*cmpstrnqi_nz_1"
25638 [(set (reg:CC FLAGS_REG)
25639 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
25640 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
25641 (use (match_operand:P 6 "register_operand" "2"))
25642 (use (match_operand:SI 3 "immediate_operand" "i"))
25643 (clobber (match_operand:P 0 "register_operand" "=S"))
25644 (clobber (match_operand:P 1 "register_operand" "=D"))
25645 (clobber (match_operand:P 2 "register_operand" "=c"))]
25646 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
25647 && ix86_check_no_addr_space (insn)"
25649 [(set_attr "type" "str")
25650 (set_attr "mode" "QI")
25651 (set (attr "prefix_rex")
25653 (match_test "<P:MODE>mode == DImode")
25655 (const_string "*")))
25656 (set_attr "prefix_rep" "1")])
25658 ;; The same, but the count is not known to not be zero.
25660 (define_expand "cmpstrnqi_1"
25661 [(parallel [(set (reg:CC FLAGS_REG)
25662 (if_then_else:CC (ne (match_operand 2 "register_operand")
25664 (compare:CC (match_operand 4 "memory_operand")
25665 (match_operand 5 "memory_operand"))
25666 (reg:CC FLAGS_REG)))
25667 (use (match_operand:SI 3 "immediate_operand"))
25668 (clobber (match_operand 0 "register_operand"))
25669 (clobber (match_operand 1 "register_operand"))
25670 (clobber (match_dup 2))])]
25674 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
25677 (define_insn "*cmpstrnqi_1"
25678 [(set (reg:CC FLAGS_REG)
25679 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
25681 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
25682 (mem:BLK (match_operand:P 5 "register_operand" "1")))
25683 (reg:CC FLAGS_REG)))
25684 (use (match_operand:SI 3 "immediate_operand" "i"))
25685 (clobber (match_operand:P 0 "register_operand" "=S"))
25686 (clobber (match_operand:P 1 "register_operand" "=D"))
25687 (clobber (match_operand:P 2 "register_operand" "=c"))]
25688 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
25689 && ix86_check_no_addr_space (insn)"
25691 [(set_attr "type" "str")
25692 (set_attr "mode" "QI")
25693 (set (attr "prefix_rex")
25695 (match_test "<P:MODE>mode == DImode")
25697 (const_string "*")))
25698 (set_attr "prefix_rep" "1")])
25700 (define_expand "strlen<mode>"
25701 [(set (match_operand:P 0 "register_operand")
25702 (unspec:P [(match_operand:BLK 1 "general_operand")
25703 (match_operand:QI 2 "immediate_operand")
25704 (match_operand 3 "immediate_operand")]
25708 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
25714 (define_expand "strlenqi_1"
25715 [(parallel [(set (match_operand 0 "register_operand")
25717 (clobber (match_operand 1 "register_operand"))
25718 (clobber (reg:CC FLAGS_REG))])]
25722 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
25725 (define_insn "*strlenqi_1"
25726 [(set (match_operand:P 0 "register_operand" "=&c")
25727 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
25728 (match_operand:QI 2 "register_operand" "a")
25729 (match_operand:P 3 "immediate_operand" "i")
25730 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
25731 (clobber (match_operand:P 1 "register_operand" "=D"))
25732 (clobber (reg:CC FLAGS_REG))]
25733 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
25734 && ix86_check_no_addr_space (insn)"
25735 "%^repnz{%;} scasb"
25736 [(set_attr "type" "str")
25737 (set_attr "mode" "QI")
25738 (set (attr "prefix_rex")
25740 (match_test "<P:MODE>mode == DImode")
25742 (const_string "*")))
25743 (set_attr "prefix_rep" "1")])
25745 ;; Peephole optimizations to clean up after cmpstrn*. This should be
25746 ;; handled in combine, but it is not currently up to the task.
25747 ;; When used for their truth value, the cmpstrn* expanders generate
25756 ;; The intermediate three instructions are unnecessary.
25758 ;; This one handles cmpstrn*_nz_1...
25761 (set (reg:CC FLAGS_REG)
25762 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
25763 (mem:BLK (match_operand 5 "register_operand"))))
25764 (use (match_operand 6 "register_operand"))
25765 (use (match_operand:SI 3 "immediate_operand"))
25766 (clobber (match_operand 0 "register_operand"))
25767 (clobber (match_operand 1 "register_operand"))
25768 (clobber (match_operand 2 "register_operand"))])
25769 (set (match_operand:QI 7 "register_operand")
25770 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
25771 (set (match_operand:QI 8 "register_operand")
25772 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
25773 (set (reg FLAGS_REG)
25774 (compare (match_dup 7) (match_dup 8)))
25776 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
25778 (set (reg:CC FLAGS_REG)
25779 (compare:CC (mem:BLK (match_dup 4))
25780 (mem:BLK (match_dup 5))))
25781 (use (match_dup 6))
25782 (use (match_dup 3))
25783 (clobber (match_dup 0))
25784 (clobber (match_dup 1))
25785 (clobber (match_dup 2))])])
25787 ;; ...and this one handles cmpstrn*_1.
25790 (set (reg:CC FLAGS_REG)
25791 (if_then_else:CC (ne (match_operand 6 "register_operand")
25793 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
25794 (mem:BLK (match_operand 5 "register_operand")))
25795 (reg:CC FLAGS_REG)))
25796 (use (match_operand:SI 3 "immediate_operand"))
25797 (clobber (match_operand 0 "register_operand"))
25798 (clobber (match_operand 1 "register_operand"))
25799 (clobber (match_operand 2 "register_operand"))])
25800 (set (match_operand:QI 7 "register_operand")
25801 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
25802 (set (match_operand:QI 8 "register_operand")
25803 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
25804 (set (reg FLAGS_REG)
25805 (compare (match_dup 7) (match_dup 8)))
25807 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
25809 (set (reg:CC FLAGS_REG)
25810 (if_then_else:CC (ne (match_dup 6)
25812 (compare:CC (mem:BLK (match_dup 4))
25813 (mem:BLK (match_dup 5)))
25814 (reg:CC FLAGS_REG)))
25815 (use (match_dup 3))
25816 (clobber (match_dup 0))
25817 (clobber (match_dup 1))
25818 (clobber (match_dup 2))])])
25820 ;; Conditional move instructions.
25822 (define_expand "mov<mode>cc"
25823 [(set (match_operand:SWIM 0 "register_operand")
25824 (if_then_else:SWIM (match_operand 1 "comparison_operator")
25825 (match_operand:SWIM 2 "<general_operand>")
25826 (match_operand:SWIM 3 "<general_operand>")))]
25828 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
25830 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
25831 ;; the register first winds up with `sbbl $0,reg', which is also weird.
25832 ;; So just document what we're doing explicitly.
25834 (define_expand "x86_mov<mode>cc_0_m1"
25836 [(set (match_operand:SWI48 0 "register_operand")
25837 (if_then_else:SWI48
25838 (match_operator:SWI48 2 "ix86_carry_flag_operator"
25839 [(match_operand 1 "flags_reg_operand")
25843 (clobber (reg:CC FLAGS_REG))])])
25845 (define_insn "*x86_mov<mode>cc_0_m1"
25846 [(set (match_operand:SWI48 0 "register_operand" "=r")
25847 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
25848 [(reg FLAGS_REG) (const_int 0)])
25851 (clobber (reg:CC FLAGS_REG))]
25853 "sbb{<imodesuffix>}\t%0, %0"
25854 [(set_attr "type" "alu1")
25855 (set_attr "use_carry" "1")
25856 (set_attr "pent_pair" "pu")
25857 (set_attr "mode" "<MODE>")
25858 (set_attr "length_immediate" "0")])
25860 (define_insn "*x86_mov<mode>cc_0_m1_se"
25861 [(set (match_operand:SWI48 0 "register_operand" "=r")
25862 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
25863 [(reg FLAGS_REG) (const_int 0)])
25866 (clobber (reg:CC FLAGS_REG))]
25868 "sbb{<imodesuffix>}\t%0, %0"
25869 [(set_attr "type" "alu1")
25870 (set_attr "use_carry" "1")
25871 (set_attr "pent_pair" "pu")
25872 (set_attr "mode" "<MODE>")
25873 (set_attr "length_immediate" "0")])
25875 (define_insn "*x86_mov<mode>cc_0_m1_neg"
25876 [(set (match_operand:SWI 0 "register_operand" "=<r>")
25877 (neg:SWI (match_operator 1 "ix86_carry_flag_operator"
25878 [(reg FLAGS_REG) (const_int 0)])))
25879 (clobber (reg:CC FLAGS_REG))]
25881 "sbb{<imodesuffix>}\t%0, %0"
25882 [(set_attr "type" "alu1")
25883 (set_attr "use_carry" "1")
25884 (set_attr "pent_pair" "pu")
25885 (set_attr "mode" "<MODE>")
25886 (set_attr "length_immediate" "0")])
25888 (define_expand "x86_mov<mode>cc_0_m1_neg"
25890 [(set (match_operand:SWI 0 "register_operand")
25891 (neg:SWI (ltu:SWI (reg:CCC FLAGS_REG) (const_int 0))))
25892 (clobber (reg:CC FLAGS_REG))])])
25895 [(set (match_operand:SWI48 0 "register_operand")
25898 (match_operand 1 "int_nonimmediate_operand")
25899 (match_operand 2 "const_int_operand"))))]
25900 "x86_64_immediate_operand (operands[2], VOIDmode)
25901 && INTVAL (operands[2]) != -1
25902 && INTVAL (operands[2]) != 2147483647"
25903 [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
25905 (neg:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))))]
25906 "operands[2] = GEN_INT (INTVAL (operands[2]) + 1);")
25909 [(set (match_operand:SWI 0 "register_operand")
25912 (match_operand 1 "int_nonimmediate_operand")
25915 [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (const_int 1)))
25917 (neg:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))))])
25920 [(set (match_operand:SWI 0 "register_operand")
25923 (match_operand 1 "int_nonimmediate_operand")
25926 [(set (reg:CCC FLAGS_REG)
25927 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
25929 (neg:SWI (ltu:SWI (reg:CCC FLAGS_REG) (const_int 0))))])
25931 (define_insn "*mov<mode>cc_noc"
25932 [(set (match_operand:SWI248 0 "register_operand" "=r,r,r,r")
25933 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
25934 [(reg FLAGS_REG) (const_int 0)])
25935 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0,rm,r")
25936 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm,r,rm")))]
25937 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
25939 cmov%O2%C1\t{%2, %0|%0, %2}
25940 cmov%O2%c1\t{%3, %0|%0, %3}
25941 cmov%O2%C1\t{%2, %3, %0|%0, %3, %2}
25942 cmov%O2%c1\t{%3, %2, %0|%0, %2, %3}"
25943 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
25944 (set_attr "type" "icmov")
25945 (set_attr "mode" "<MODE>")])
25947 (define_insn "*movsicc_noc_zext"
25948 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
25949 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
25950 [(reg FLAGS_REG) (const_int 0)])
25952 (match_operand:SI 2 "nonimmediate_operand" "rm,0,rm,r"))
25954 (match_operand:SI 3 "nonimmediate_operand" "0,rm,r,rm"))))]
25956 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
25958 cmov%O2%C1\t{%2, %k0|%k0, %2}
25959 cmov%O2%c1\t{%3, %k0|%k0, %3}
25960 cmov%O2%C1\t{%2, %3, %k0|%k0, %3, %2}
25961 cmov%O2%c1\t{%3, %2, %k0|%k0, %2, %3}"
25962 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
25963 (set_attr "type" "icmov")
25964 (set_attr "mode" "SI")])
25966 (define_insn "*movsicc_noc_zext_1"
25967 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r")
25969 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
25970 [(reg FLAGS_REG) (const_int 0)])
25971 (match_operand:SI 2 "nonimmediate_operand" "rm,0,rm,r")
25972 (match_operand:SI 3 "nonimmediate_operand" "0,rm,r,rm"))))]
25974 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
25976 cmov%O2%C1\t{%2, %k0|%k0, %2}
25977 cmov%O2%c1\t{%3, %k0|%k0, %3}
25978 cmov%O2%C1\t{%2, %3, %k0|%k0, %3, %2}
25979 cmov%O2%c1\t{%3, %2, %k0|%k0, %2, %3}"
25980 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
25981 (set_attr "type" "icmov")
25982 (set_attr "mode" "SI")])
25985 ;; Don't do conditional moves with memory inputs. This splitter helps
25986 ;; register starved x86_32 by forcing inputs into registers before reload.
25988 [(set (match_operand:SWI248 0 "register_operand")
25989 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
25990 [(reg FLAGS_REG) (const_int 0)])
25991 (match_operand:SWI248 2 "nonimmediate_operand")
25992 (match_operand:SWI248 3 "nonimmediate_operand")))]
25993 "!TARGET_64BIT && TARGET_CMOVE
25994 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
25995 && (MEM_P (operands[2]) || MEM_P (operands[3]))
25996 && can_create_pseudo_p ()
25997 && optimize_insn_for_speed_p ()"
25998 [(set (match_dup 0)
25999 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
26001 operands[2] = force_reg (<MODE>mode, operands[2]);
26002 operands[3] = force_reg (<MODE>mode, operands[3]);
26005 (define_insn "*movqicc_noc"
26006 [(set (match_operand:QI 0 "register_operand" "=r,r,r")
26007 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
26008 [(reg FLAGS_REG) (const_int 0)])
26009 (match_operand:QI 2 "register_operand" "r,0,r")
26010 (match_operand:QI 3 "register_operand" "0,r,r")))]
26011 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
26013 [(set_attr "isa" "*,*,apx_ndd")
26014 (set_attr "type" "icmov")
26015 (set_attr "mode" "QI")])
26018 [(set (match_operand:SWI12 0 "register_operand")
26019 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
26020 [(reg FLAGS_REG) (const_int 0)])
26021 (match_operand:SWI12 2 "register_operand")
26022 (match_operand:SWI12 3 "register_operand")))]
26023 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
26024 && reload_completed"
26025 [(set (match_dup 0)
26026 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
26028 operands[0] = gen_lowpart (SImode, operands[0]);
26029 operands[2] = gen_lowpart (SImode, operands[2]);
26030 operands[3] = gen_lowpart (SImode, operands[3]);
26033 ;; Don't do conditional moves with memory inputs
26035 [(match_scratch:SWI248 4 "r")
26036 (set (match_operand:SWI248 0 "register_operand")
26037 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
26038 [(reg FLAGS_REG) (const_int 0)])
26039 (match_operand:SWI248 2 "nonimmediate_operand")
26040 (match_operand:SWI248 3 "nonimmediate_operand")))]
26041 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
26042 && (MEM_P (operands[2]) || MEM_P (operands[3]))
26043 && optimize_insn_for_speed_p ()"
26044 [(set (match_dup 4) (match_dup 5))
26046 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
26048 if (MEM_P (operands[2]))
26050 operands[5] = operands[2];
26051 operands[2] = operands[4];
26053 else if (MEM_P (operands[3]))
26055 operands[5] = operands[3];
26056 operands[3] = operands[4];
26059 gcc_unreachable ();
26063 [(match_scratch:SI 4 "r")
26064 (set (match_operand:DI 0 "register_operand")
26065 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
26066 [(reg FLAGS_REG) (const_int 0)])
26068 (match_operand:SI 2 "nonimmediate_operand"))
26070 (match_operand:SI 3 "nonimmediate_operand"))))]
26072 && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
26073 && (MEM_P (operands[2]) || MEM_P (operands[3]))
26074 && optimize_insn_for_speed_p ()"
26075 [(set (match_dup 4) (match_dup 5))
26077 (if_then_else:DI (match_dup 1)
26078 (zero_extend:DI (match_dup 2))
26079 (zero_extend:DI (match_dup 3))))]
26081 if (MEM_P (operands[2]))
26083 operands[5] = operands[2];
26084 operands[2] = operands[4];
26086 else if (MEM_P (operands[3]))
26088 operands[5] = operands[3];
26089 operands[3] = operands[4];
26092 gcc_unreachable ();
26095 ;; Eliminate a reg-reg mov by inverting the condition of a cmov (#1).
26096 ;; mov r0,r1; dec r0; mov r2,r3; cmov r0,r2 -> dec r1; mov r0,r3; cmov r0, r1
26098 [(set (match_operand:SWI248 0 "general_reg_operand")
26099 (match_operand:SWI248 1 "general_reg_operand"))
26100 (parallel [(set (reg FLAGS_REG) (match_operand 5))
26101 (set (match_dup 0) (match_operand:SWI248 6))])
26102 (set (match_operand:SWI248 2 "general_reg_operand")
26103 (match_operand:SWI248 3 "general_gr_operand"))
26105 (if_then_else:SWI248 (match_operator 4 "ix86_comparison_operator"
26106 [(reg FLAGS_REG) (const_int 0)])
26110 && REGNO (operands[2]) != REGNO (operands[0])
26111 && REGNO (operands[2]) != REGNO (operands[1])
26112 && peep2_reg_dead_p (1, operands[1])
26113 && peep2_reg_dead_p (4, operands[2])
26114 && !reg_overlap_mentioned_p (operands[0], operands[3])"
26115 [(parallel [(set (match_dup 7) (match_dup 8))
26116 (set (match_dup 1) (match_dup 9))])
26117 (set (match_dup 0) (match_dup 3))
26118 (set (match_dup 0) (if_then_else:SWI248 (match_dup 4)
26122 operands[7] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
26124 = ix86_replace_reg_with_reg (operands[5], operands[0], operands[1]);
26126 = ix86_replace_reg_with_reg (operands[6], operands[0], operands[1]);
26129 ;; Eliminate a reg-reg mov by inverting the condition of a cmov (#2).
26130 ;; mov r2,r3; mov r0,r1; dec r0; cmov r0,r2 -> dec r1; mov r0,r3; cmov r0, r1
26132 [(set (match_operand:SWI248 2 "general_reg_operand")
26133 (match_operand:SWI248 3 "general_gr_operand"))
26134 (set (match_operand:SWI248 0 "general_reg_operand")
26135 (match_operand:SWI248 1 "general_reg_operand"))
26136 (parallel [(set (reg FLAGS_REG) (match_operand 5))
26137 (set (match_dup 0) (match_operand:SWI248 6))])
26139 (if_then_else:SWI248 (match_operator 4 "ix86_comparison_operator"
26140 [(reg FLAGS_REG) (const_int 0)])
26144 && REGNO (operands[2]) != REGNO (operands[0])
26145 && REGNO (operands[2]) != REGNO (operands[1])
26146 && peep2_reg_dead_p (2, operands[1])
26147 && peep2_reg_dead_p (4, operands[2])
26148 && !reg_overlap_mentioned_p (operands[0], operands[3])
26149 && !reg_mentioned_p (operands[2], operands[6])"
26150 [(parallel [(set (match_dup 7) (match_dup 8))
26151 (set (match_dup 1) (match_dup 9))])
26152 (set (match_dup 0) (match_dup 3))
26153 (set (match_dup 0) (if_then_else:SWI248 (match_dup 4)
26157 operands[7] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (2)), 0, 0));
26159 = ix86_replace_reg_with_reg (operands[5], operands[0], operands[1]);
26161 = ix86_replace_reg_with_reg (operands[6], operands[0], operands[1]);
26164 (define_insn "movhf_mask"
26165 [(set (match_operand:HF 0 "nonimmediate_operand" "=v,m,v")
26167 [(match_operand:HF 1 "nonimmediate_operand" "m,v,v")
26168 (match_operand:HF 2 "nonimm_or_0_operand" "0C,0C,0C")
26169 (match_operand:QI 3 "register_operand" "Yk,Yk,Yk")]
26170 UNSPEC_MOVCC_MASK))]
26171 "TARGET_AVX512FP16"
26173 vmovsh\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}
26174 vmovsh\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}
26175 vmovsh\t{%d1, %0%{%3%}%N2|%0%{%3%}%N2, %d1}"
26176 [(set_attr "type" "ssemov")
26177 (set_attr "prefix" "evex")
26178 (set_attr "mode" "HF")])
26180 (define_expand "movhfcc"
26181 [(set (match_operand:HF 0 "register_operand")
26183 (match_operand 1 "comparison_operator")
26184 (match_operand:HF 2 "register_operand")
26185 (match_operand:HF 3 "register_operand")))]
26186 "TARGET_AVX512FP16"
26187 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
26189 (define_expand "mov<mode>cc"
26190 [(set (match_operand:X87MODEF 0 "register_operand")
26191 (if_then_else:X87MODEF
26192 (match_operand 1 "comparison_operator")
26193 (match_operand:X87MODEF 2 "register_operand")
26194 (match_operand:X87MODEF 3 "register_operand")))]
26195 "(TARGET_80387 && TARGET_CMOVE)
26196 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
26197 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
26199 (define_insn "*movxfcc_1"
26200 [(set (match_operand:XF 0 "register_operand" "=f,f")
26201 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
26202 [(reg FLAGS_REG) (const_int 0)])
26203 (match_operand:XF 2 "register_operand" "f,0")
26204 (match_operand:XF 3 "register_operand" "0,f")))]
26205 "TARGET_80387 && TARGET_CMOVE"
26207 fcmov%F1\t{%2, %0|%0, %2}
26208 fcmov%f1\t{%3, %0|%0, %3}"
26209 [(set_attr "type" "fcmov")
26210 (set_attr "mode" "XF")])
26212 (define_insn "*movdfcc_1"
26213 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
26214 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
26215 [(reg FLAGS_REG) (const_int 0)])
26216 (match_operand:DF 2 "nonimmediate_operand"
26218 (match_operand:DF 3 "nonimmediate_operand"
26219 "0 ,f,0 ,rm,0, rm")))]
26220 "TARGET_80387 && TARGET_CMOVE
26221 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
26223 fcmov%F1\t{%2, %0|%0, %2}
26224 fcmov%f1\t{%3, %0|%0, %3}
26227 cmov%O2%C1\t{%2, %0|%0, %2}
26228 cmov%O2%c1\t{%3, %0|%0, %3}"
26229 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
26230 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
26231 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
26234 [(set (match_operand:DF 0 "general_reg_operand")
26235 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
26236 [(reg FLAGS_REG) (const_int 0)])
26237 (match_operand:DF 2 "nonimmediate_operand")
26238 (match_operand:DF 3 "nonimmediate_operand")))]
26239 "!TARGET_64BIT && reload_completed"
26240 [(set (match_dup 2)
26241 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
26243 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
26245 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
26246 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
26249 (define_insn "*movsfcc_1_387"
26250 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
26251 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
26252 [(reg FLAGS_REG) (const_int 0)])
26253 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
26254 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
26255 "TARGET_80387 && TARGET_CMOVE
26256 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
26258 fcmov%F1\t{%2, %0|%0, %2}
26259 fcmov%f1\t{%3, %0|%0, %3}
26260 cmov%O2%C1\t{%2, %0|%0, %2}
26261 cmov%O2%c1\t{%3, %0|%0, %3}"
26262 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
26263 (set_attr "mode" "SF,SF,SI,SI")])
26265 ;; Don't do conditional moves with memory inputs. This splitter helps
26266 ;; register starved x86_32 by forcing inputs into registers before reload.
26268 [(set (match_operand:MODEF 0 "register_operand")
26269 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
26270 [(reg FLAGS_REG) (const_int 0)])
26271 (match_operand:MODEF 2 "nonimmediate_operand")
26272 (match_operand:MODEF 3 "nonimmediate_operand")))]
26273 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
26274 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
26275 && (MEM_P (operands[2]) || MEM_P (operands[3]))
26276 && can_create_pseudo_p ()
26277 && optimize_insn_for_speed_p ()"
26278 [(set (match_dup 0)
26279 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
26281 operands[2] = force_reg (<MODE>mode, operands[2]);
26282 operands[3] = force_reg (<MODE>mode, operands[3]);
26285 ;; Don't do conditional moves with memory inputs
26287 [(match_scratch:MODEF 4 "r")
26288 (set (match_operand:MODEF 0 "general_reg_operand")
26289 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
26290 [(reg FLAGS_REG) (const_int 0)])
26291 (match_operand:MODEF 2 "nonimmediate_operand")
26292 (match_operand:MODEF 3 "nonimmediate_operand")))]
26293 "(<MODE>mode != DFmode || TARGET_64BIT)
26294 && TARGET_80387 && TARGET_CMOVE
26295 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
26296 && (MEM_P (operands[2]) || MEM_P (operands[3]))
26297 && optimize_insn_for_speed_p ()"
26298 [(set (match_dup 4) (match_dup 5))
26300 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
26302 if (MEM_P (operands[2]))
26304 operands[5] = operands[2];
26305 operands[2] = operands[4];
26307 else if (MEM_P (operands[3]))
26309 operands[5] = operands[3];
26310 operands[3] = operands[4];
26313 gcc_unreachable ();
26316 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
26317 ;; the scalar versions to have only XMM registers as operands.
26319 ;; XOP conditional move
26320 (define_insn "*xop_pcmov_<mode>"
26321 [(set (match_operand:MODEF 0 "register_operand" "=x")
26322 (if_then_else:MODEF
26323 (match_operand:MODEF 1 "register_operand" "x")
26324 (match_operand:MODEF 2 "register_operand" "x")
26325 (match_operand:MODEF 3 "register_operand" "x")))]
26327 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
26328 [(set_attr "type" "sse4arg")
26329 (set_attr "mode" "TI")])
26331 ;; These versions of the min/max patterns are intentionally ignorant of
26332 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
26333 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
26334 ;; are undefined in this condition, we're certain this is correct.
26336 (define_insn "<code><mode>3"
26337 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
26339 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
26340 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
26341 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
26343 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
26344 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
26345 [(set_attr "isa" "noavx,avx")
26346 (set_attr "prefix" "orig,vex")
26347 (set_attr "type" "sseadd")
26348 (set_attr "mode" "<MODE>")])
26350 (define_insn "<code>hf3"
26351 [(set (match_operand:HF 0 "register_operand" "=v")
26353 (match_operand:HF 1 "nonimmediate_operand" "%v")
26354 (match_operand:HF 2 "nonimmediate_operand" "vm")))]
26355 "TARGET_AVX512FP16"
26356 "v<maxmin_float>sh\t{%2, %1, %0|%0, %1, %2}"
26357 [(set_attr "prefix" "evex")
26358 (set_attr "type" "sseadd")
26359 (set_attr "mode" "HF")])
26361 ;; These versions of the min/max patterns implement exactly the operations
26362 ;; min = (op1 < op2 ? op1 : op2)
26363 ;; max = (!(op1 < op2) ? op1 : op2)
26364 ;; Their operands are not commutative, and thus they may be used in the
26365 ;; presence of -0.0 and NaN.
26367 (define_insn "*ieee_s<ieee_maxmin>hf3"
26368 [(set (match_operand:HF 0 "register_operand" "=v")
26370 [(match_operand:HF 1 "register_operand" "v")
26371 (match_operand:HF 2 "nonimmediate_operand" "vm")]
26373 "TARGET_AVX512FP16"
26374 "v<ieee_maxmin>sh\t{%2, %1, %0|%0, %1, %2}"
26375 [(set_attr "prefix" "evex")
26376 (set_attr "type" "sseadd")
26377 (set_attr "mode" "HF")])
26379 (define_insn "*ieee_s<ieee_maxmin><mode>3"
26380 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
26382 [(match_operand:MODEF 1 "register_operand" "0,v")
26383 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
26385 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
26387 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
26388 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
26389 [(set_attr "isa" "noavx,avx")
26390 (set_attr "prefix" "orig,maybe_evex")
26391 (set_attr "type" "sseadd")
26392 (set_attr "mode" "<MODE>")])
26394 ;; Operands order in min/max instruction matters for signed zero and NANs.
26395 (define_insn_and_split "*ieee_max<mode>3_1"
26396 [(set (match_operand:MODEF 0 "register_operand")
26398 [(match_operand:MODEF 1 "register_operand")
26399 (match_operand:MODEF 2 "register_operand")
26401 (match_operand:MODEF 3 "register_operand")
26402 (match_operand:MODEF 4 "register_operand"))]
26404 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
26405 && (rtx_equal_p (operands[1], operands[3])
26406 && rtx_equal_p (operands[2], operands[4]))
26407 && ix86_pre_reload_split ()"
26410 [(set (match_dup 0)
26414 UNSPEC_IEEE_MAX))])
26416 (define_insn_and_split "*ieee_min<mode>3_1"
26417 [(set (match_operand:MODEF 0 "register_operand")
26419 [(match_operand:MODEF 1 "register_operand")
26420 (match_operand:MODEF 2 "register_operand")
26422 (match_operand:MODEF 3 "register_operand")
26423 (match_operand:MODEF 4 "register_operand"))]
26425 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
26426 && (rtx_equal_p (operands[1], operands[4])
26427 && rtx_equal_p (operands[2], operands[3]))
26428 && ix86_pre_reload_split ()"
26431 [(set (match_dup 0)
26435 UNSPEC_IEEE_MIN))])
26437 ;; Make two stack loads independent:
26439 ;; fld %st(0) -> fld bb
26440 ;; fmul bb fmul %st(1), %st
26442 ;; Actually we only match the last two instructions for simplicity.
26445 [(set (match_operand 0 "fp_register_operand")
26446 (match_operand 1 "fp_register_operand"))
26448 (match_operator 2 "binary_fp_operator"
26450 (match_operand 3 "memory_operand")]))]
26451 "REGNO (operands[0]) != REGNO (operands[1])"
26452 [(set (match_dup 0) (match_dup 3))
26455 [(match_dup 5) (match_dup 4)]))]
26457 operands[4] = operands[0];
26458 operands[5] = operands[1];
26460 /* The % modifier is not operational anymore in peephole2's, so we have to
26461 swap the operands manually in the case of addition and multiplication. */
26462 if (COMMUTATIVE_ARITH_P (operands[2]))
26463 std::swap (operands[4], operands[5]);
26467 [(set (match_operand 0 "fp_register_operand")
26468 (match_operand 1 "fp_register_operand"))
26470 (match_operator 2 "binary_fp_operator"
26471 [(match_operand 3 "memory_operand")
26473 "REGNO (operands[0]) != REGNO (operands[1])"
26474 [(set (match_dup 0) (match_dup 3))
26477 [(match_dup 4) (match_dup 5)]))]
26479 operands[4] = operands[0];
26480 operands[5] = operands[1];
26482 /* The % modifier is not operational anymore in peephole2's, so we have to
26483 swap the operands manually in the case of addition and multiplication. */
26484 if (COMMUTATIVE_ARITH_P (operands[2]))
26485 std::swap (operands[4], operands[5]);
26488 ;; Conditional addition patterns
26489 (define_expand "add<mode>cc"
26490 [(match_operand:SWI 0 "register_operand")
26491 (match_operand 1 "ordered_comparison_operator")
26492 (match_operand:SWI 2 "register_operand")
26493 (match_operand:SWI 3 "const_int_operand")]
26495 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
26497 ;; min/max patterns
26499 (define_code_attr maxmin_rel
26500 [(smax "GE") (smin "LE") (umax "GEU") (umin "LEU")])
26502 (define_expand "<code><mode>3"
26504 [(set (match_operand:SDWIM 0 "register_operand")
26506 (match_operand:SDWIM 1 "register_operand")
26507 (match_operand:SDWIM 2 "general_operand")))
26508 (clobber (reg:CC FLAGS_REG))])]
26510 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)")
26512 (define_insn_and_split "*<code><dwi>3_doubleword"
26513 [(set (match_operand:<DWI> 0 "register_operand")
26515 (match_operand:<DWI> 1 "register_operand")
26516 (match_operand:<DWI> 2 "general_operand")))
26517 (clobber (reg:CC FLAGS_REG))]
26519 && ix86_pre_reload_split ()"
26522 [(set (match_dup 0)
26523 (if_then_else:DWIH (match_dup 6)
26527 (if_then_else:DWIH (match_dup 6)
26531 operands[2] = force_reg (<DWI>mode, operands[2]);
26533 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
26535 rtx cmplo[2] = { operands[1], operands[2] };
26536 rtx cmphi[2] = { operands[4], operands[5] };
26538 enum rtx_code code = <maxmin_rel>;
26543 std::swap (cmplo[0], cmplo[1]);
26544 std::swap (cmphi[0], cmphi[1]);
26545 code = swap_condition (code);
26550 bool uns = (code == GEU);
26551 rtx (*sbb_insn) (machine_mode, rtx, rtx, rtx)
26552 = uns ? gen_sub3_carry_ccc : gen_sub3_carry_ccgz;
26554 emit_insn (gen_cmp_1 (<MODE>mode, cmplo[0], cmplo[1]));
26556 rtx tmp = gen_rtx_SCRATCH (<MODE>mode);
26557 emit_insn (sbb_insn (<MODE>mode, tmp, cmphi[0], cmphi[1]));
26559 rtx flags = gen_rtx_REG (uns ? CCCmode : CCGZmode, FLAGS_REG);
26560 operands[6] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
26566 gcc_unreachable ();
26570 (define_insn_and_split "*<code><mode>3_1"
26571 [(set (match_operand:SWI 0 "register_operand")
26573 (match_operand:SWI 1 "register_operand")
26574 (match_operand:SWI 2 "general_operand")))
26575 (clobber (reg:CC FLAGS_REG))]
26577 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
26578 && ix86_pre_reload_split ()"
26581 [(set (match_dup 0)
26582 (if_then_else:SWI (match_dup 3)
26586 machine_mode mode = <MODE>mode;
26587 rtx cmp_op = operands[2];
26589 operands[2] = force_reg (mode, cmp_op);
26591 enum rtx_code code = <maxmin_rel>;
26593 if (cmp_op == const1_rtx)
26595 /* Convert smax (x, 1) into (x > 0 ? x : 1).
26596 Convert umax (x, 1) into (x != 0 ? x : 1).
26597 Convert ?min (x, 1) into (x <= 0 ? x : 1). */
26598 cmp_op = const0_rtx;
26601 else if (code == GEU)
26604 /* Convert smin (x, -1) into (x < 0 ? x : -1). */
26605 else if (cmp_op == constm1_rtx && code == LE)
26607 cmp_op = const0_rtx;
26610 /* Convert smax (x, -1) into (x >= 0 ? x : -1). */
26611 else if (cmp_op == constm1_rtx && code == GE)
26612 cmp_op = const0_rtx;
26613 else if (cmp_op != const0_rtx)
26614 cmp_op = operands[2];
26616 machine_mode cmpmode = SELECT_CC_MODE (code, operands[1], cmp_op);
26617 rtx flags = gen_rtx_REG (cmpmode, FLAGS_REG);
26619 rtx tmp = gen_rtx_COMPARE (cmpmode, operands[1], cmp_op);
26620 emit_insn (gen_rtx_SET (flags, tmp));
26622 operands[3] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
26625 ;; Avoid clearing a register between a flags setting comparison and its use,
26626 ;; i.e. prefer "xorl %eax,%eax; test/cmp" over "test/cmp; movl $0, %eax".
26628 [(set (reg FLAGS_REG) (match_operand 0))
26629 (set (match_operand:SWI 1 "general_reg_operand") (const_int 0))]
26630 "peep2_regno_dead_p (0, FLAGS_REG)
26631 && !reg_overlap_mentioned_p (operands[1], operands[0])"
26632 [(set (match_dup 2) (match_dup 0))]
26634 operands[2] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
26635 ix86_expand_clear (operands[1]);
26638 ;; When optimizing for size, zeroing memory should use a register.
26640 [(match_scratch:SWI48 0 "r")
26641 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
26642 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))
26643 (set (match_operand:SWI48 3 "memory_operand") (const_int 0))
26644 (set (match_operand:SWI48 4 "memory_operand") (const_int 0))]
26645 "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
26648 ix86_expand_clear (operands[0]);
26649 emit_move_insn (operands[1], operands[0]);
26650 emit_move_insn (operands[2], operands[0]);
26651 emit_move_insn (operands[3], operands[0]);
26652 ix86_last_zero_store_uid
26653 = INSN_UID (emit_move_insn (operands[4], operands[0]));
26658 [(match_scratch:SWI48 0 "r")
26659 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
26660 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))]
26661 "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
26664 ix86_expand_clear (operands[0]);
26665 emit_move_insn (operands[1], operands[0]);
26666 ix86_last_zero_store_uid
26667 = INSN_UID (emit_move_insn (operands[2], operands[0]));
26672 [(match_scratch:SWI48 0 "r")
26673 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))]
26674 "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
26677 ix86_expand_clear (operands[0]);
26678 ix86_last_zero_store_uid
26679 = INSN_UID (emit_move_insn (operands[1], operands[0]));
26684 [(set (match_operand:SWI48 5 "memory_operand")
26685 (match_operand:SWI48 0 "general_reg_operand"))
26686 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
26687 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))
26688 (set (match_operand:SWI48 3 "memory_operand") (const_int 0))
26689 (set (match_operand:SWI48 4 "memory_operand") (const_int 0))]
26690 "optimize_insn_for_size_p ()
26691 && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
26694 emit_move_insn (operands[5], operands[0]);
26695 emit_move_insn (operands[1], operands[0]);
26696 emit_move_insn (operands[2], operands[0]);
26697 emit_move_insn (operands[3], operands[0]);
26698 ix86_last_zero_store_uid
26699 = INSN_UID (emit_move_insn (operands[4], operands[0]));
26704 [(set (match_operand:SWI48 3 "memory_operand")
26705 (match_operand:SWI48 0 "general_reg_operand"))
26706 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
26707 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))]
26708 "optimize_insn_for_size_p ()
26709 && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
26712 emit_move_insn (operands[3], operands[0]);
26713 emit_move_insn (operands[1], operands[0]);
26714 ix86_last_zero_store_uid
26715 = INSN_UID (emit_move_insn (operands[2], operands[0]));
26720 [(set (match_operand:SWI48 2 "memory_operand")
26721 (match_operand:SWI48 0 "general_reg_operand"))
26722 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))]
26723 "optimize_insn_for_size_p ()
26724 && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
26727 emit_move_insn (operands[2], operands[0]);
26728 ix86_last_zero_store_uid
26729 = INSN_UID (emit_move_insn (operands[1], operands[0]));
26733 ;; Reload dislikes loading constants directly into class_likely_spilled
26734 ;; hard registers. Try to tidy things up here.
26736 [(set (match_operand:SWI 0 "general_reg_operand")
26737 (match_operand:SWI 1 "x86_64_general_operand"))
26738 (set (match_operand:SWI 2 "general_reg_operand")
26740 "peep2_reg_dead_p (2, operands[0])"
26741 [(set (match_dup 2) (match_dup 1))])
26743 ;; Misc patterns (?)
26745 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
26746 ;; Otherwise there will be nothing to keep
26748 ;; [(set (reg ebp) (reg esp))]
26749 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
26750 ;; (clobber (eflags)]
26751 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
26753 ;; in proper program order.
26755 (define_insn "@pro_epilogue_adjust_stack_add_<mode>"
26756 [(set (match_operand:P 0 "register_operand" "=r,r")
26757 (plus:P (match_operand:P 1 "register_operand" "0,r")
26758 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
26759 (clobber (reg:CC FLAGS_REG))
26760 (clobber (mem:BLK (scratch)))]
26763 switch (get_attr_type (insn))
26766 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
26769 gcc_assert (rtx_equal_p (operands[0], operands[1]));
26770 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
26771 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
26773 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
26776 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
26777 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
26780 [(set (attr "type")
26781 (cond [(and (eq_attr "alternative" "0")
26782 (not (match_test "TARGET_OPT_AGU")))
26783 (const_string "alu")
26784 (match_operand:<MODE> 2 "const0_operand")
26785 (const_string "imov")
26787 (const_string "lea")))
26788 (set (attr "length_immediate")
26789 (cond [(eq_attr "type" "imov")
26791 (and (eq_attr "type" "alu")
26792 (match_operand 2 "const128_operand"))
26795 (const_string "*")))
26796 (set_attr "mode" "<MODE>")])
26798 (define_insn "@pro_epilogue_adjust_stack_sub_<mode>"
26799 [(set (match_operand:P 0 "register_operand" "=r")
26800 (minus:P (match_operand:P 1 "register_operand" "0")
26801 (match_operand:P 2 "register_operand" "r")))
26802 (clobber (reg:CC FLAGS_REG))
26803 (clobber (mem:BLK (scratch)))]
26805 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
26806 [(set_attr "type" "alu")
26807 (set_attr "mode" "<MODE>")])
26809 (define_insn "@allocate_stack_worker_probe_<mode>"
26810 [(set (match_operand:P 0 "register_operand" "=a")
26811 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
26812 UNSPECV_STACK_PROBE))
26813 (clobber (reg:CC FLAGS_REG))]
26814 "ix86_target_stack_probe ()"
26815 "call\t___chkstk_ms"
26816 [(set_attr "type" "multi")
26817 (set_attr "length" "5")])
26819 (define_expand "allocate_stack"
26820 [(match_operand 0 "register_operand")
26821 (match_operand 1 "general_operand")]
26822 "ix86_target_stack_probe ()"
26826 #ifndef CHECK_STACK_LIMIT
26827 #define CHECK_STACK_LIMIT 0
26830 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
26831 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
26835 x = copy_to_mode_reg (Pmode, operands[1]);
26837 emit_insn (gen_allocate_stack_worker_probe (Pmode, x, x));
26840 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
26841 stack_pointer_rtx, 0, OPTAB_DIRECT);
26843 if (x != stack_pointer_rtx)
26844 emit_move_insn (stack_pointer_rtx, x);
26846 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
26850 (define_expand "probe_stack"
26851 [(match_operand 0 "memory_operand")]
26854 emit_insn (gen_probe_stack_1
26855 (word_mode, operands[0], const0_rtx));
26859 ;; Use OR for stack probes, this is shorter.
26860 (define_insn "@probe_stack_1_<mode>"
26861 [(set (match_operand:W 0 "memory_operand" "=m")
26862 (unspec:W [(match_operand:W 1 "const0_operand")]
26863 UNSPEC_PROBE_STACK))
26864 (clobber (reg:CC FLAGS_REG))]
26866 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
26867 [(set_attr "type" "alu1")
26868 (set_attr "mode" "<MODE>")
26869 (set_attr "length_immediate" "1")])
26871 (define_insn "@adjust_stack_and_probe_<mode>"
26872 [(set (match_operand:P 0 "register_operand" "=r")
26873 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
26874 UNSPECV_PROBE_STACK_RANGE))
26875 (set (reg:P SP_REG)
26876 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand")))
26877 (clobber (reg:CC FLAGS_REG))
26878 (clobber (mem:BLK (scratch)))]
26880 "* return output_adjust_stack_and_probe (operands[0]);"
26881 [(set_attr "type" "multi")])
26883 (define_insn "@probe_stack_range_<mode>"
26884 [(set (match_operand:P 0 "register_operand" "=r")
26885 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
26886 (match_operand:P 2 "const_int_operand")]
26887 UNSPECV_PROBE_STACK_RANGE))
26888 (clobber (reg:CC FLAGS_REG))]
26890 "* return output_probe_stack_range (operands[0], operands[2]);"
26891 [(set_attr "type" "multi")])
26893 (define_expand "builtin_setjmp_receiver"
26894 [(label_ref (match_operand 0))]
26895 "!TARGET_64BIT && flag_pic"
26901 rtx_code_label *label_rtx = gen_label_rtx ();
26902 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
26903 xops[0] = xops[1] = pic_offset_table_rtx;
26904 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
26905 ix86_expand_binary_operator (MINUS, SImode, xops);
26909 emit_insn (gen_set_got (pic_offset_table_rtx));
26913 (define_expand "save_stack_nonlocal"
26914 [(set (match_operand 0 "memory_operand")
26915 (match_operand 1 "register_operand"))]
26920 if (flag_cf_protection & CF_RETURN)
26922 /* Copy shadow stack pointer to the first slot
26923 and stack pointer to the second slot. */
26924 rtx ssp_slot = adjust_address (operands[0], word_mode, 0);
26925 stack_slot = adjust_address (operands[0], Pmode, UNITS_PER_WORD);
26927 rtx reg_ssp = force_reg (word_mode, const0_rtx);
26928 emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
26929 emit_move_insn (ssp_slot, reg_ssp);
26932 stack_slot = adjust_address (operands[0], Pmode, 0);
26933 emit_move_insn (stack_slot, operands[1]);
26937 (define_expand "restore_stack_nonlocal"
26938 [(set (match_operand 0 "register_operand" "")
26939 (match_operand 1 "memory_operand" ""))]
26944 if (flag_cf_protection & CF_RETURN)
26946 /* Restore shadow stack pointer from the first slot
26947 and stack pointer from the second slot. */
26948 rtx ssp_slot = adjust_address (operands[1], word_mode, 0);
26949 stack_slot = adjust_address (operands[1], Pmode, UNITS_PER_WORD);
26951 /* Get the current shadow stack pointer. The code below will check if
26952 SHSTK feature is enabled. If it is not enabled the RDSSP instruction
26954 rtx reg_ssp = force_reg (word_mode, const0_rtx);
26955 emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
26957 /* Compare through subtraction the saved and the current ssp
26958 to decide if ssp has to be adjusted. */
26959 reg_ssp = expand_simple_binop (word_mode, MINUS,
26961 reg_ssp, 1, OPTAB_DIRECT);
26963 /* Compare and jump over adjustment code. */
26964 rtx noadj_label = gen_label_rtx ();
26965 emit_cmp_and_jump_insns (reg_ssp, const0_rtx, EQ, NULL_RTX,
26966 word_mode, 1, noadj_label);
26968 /* Compute the number of frames to adjust. */
26969 rtx reg_adj = gen_lowpart (ptr_mode, reg_ssp);
26970 rtx reg_adj_neg = expand_simple_unop (ptr_mode, NEG, reg_adj,
26973 reg_adj = expand_simple_binop (ptr_mode, LSHIFTRT, reg_adj_neg,
26974 GEN_INT (exact_log2 (UNITS_PER_WORD)),
26975 reg_adj, 1, OPTAB_DIRECT);
26977 /* Check if number of frames <= 255 so no loop is needed. */
26978 rtx inc_label = gen_label_rtx ();
26979 emit_cmp_and_jump_insns (reg_adj, GEN_INT (255), LEU, NULL_RTX,
26980 ptr_mode, 1, inc_label);
26982 /* Adjust the ssp in a loop. */
26983 rtx loop_label = gen_label_rtx ();
26984 emit_label (loop_label);
26985 LABEL_NUSES (loop_label) = 1;
26987 rtx reg_255 = force_reg (word_mode, GEN_INT (255));
26988 emit_insn (gen_incssp (word_mode, reg_255));
26990 reg_adj = expand_simple_binop (ptr_mode, MINUS,
26991 reg_adj, GEN_INT (255),
26992 reg_adj, 1, OPTAB_DIRECT);
26994 /* Compare and jump to the loop label. */
26995 emit_cmp_and_jump_insns (reg_adj, GEN_INT (255), GTU, NULL_RTX,
26996 ptr_mode, 1, loop_label);
26998 emit_label (inc_label);
26999 LABEL_NUSES (inc_label) = 1;
27001 emit_insn (gen_incssp (word_mode, reg_ssp));
27003 emit_label (noadj_label);
27004 LABEL_NUSES (noadj_label) = 1;
27007 stack_slot = adjust_address (operands[1], Pmode, 0);
27008 emit_move_insn (operands[0], stack_slot);
27012 (define_expand "stack_protect_set"
27013 [(match_operand 0 "memory_operand")
27014 (match_operand 1 "memory_operand")]
27017 rtx scratch = gen_reg_rtx (word_mode);
27019 emit_insn (gen_stack_protect_set_1
27020 (ptr_mode, word_mode, operands[0], operands[1], scratch));
27024 (define_insn "@stack_protect_set_1_<PTR:mode>_<W:mode>"
27025 [(set (match_operand:PTR 0 "memory_operand" "=m")
27026 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
27028 (set (match_operand:W 2 "register_operand" "=&r") (const_int 0))
27029 (clobber (reg:CC FLAGS_REG))]
27032 output_asm_insn ("mov{<PTR:imodesuffix>}\t{%1, %<PTR:k>2|%<PTR:k>2, %1}",
27034 output_asm_insn ("mov{<PTR:imodesuffix>}\t{%<PTR:k>2, %0|%0, %<PTR:k>2}",
27036 if (!TARGET_USE_MOV0 || optimize_insn_for_size_p ())
27037 return "xor{l}\t%k2, %k2";
27039 return "mov{l}\t{$0, %k2|%k2, 0}";
27041 [(set_attr "type" "multi")])
27043 ;; Patterns and peephole2s to optimize stack_protect_set_1_<mode>
27044 ;; immediately followed by *mov{s,d}i_internal, where we can avoid
27045 ;; the xor{l} above. We don't split this, so that scheduling or
27046 ;; anything else doesn't separate the *stack_protect_set* pattern from
27047 ;; the set of the register that overwrites the register with a new value.
27050 [(parallel [(set (match_operand:PTR 0 "memory_operand")
27051 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
27053 (set (match_operand 2 "general_reg_operand") (const_int 0))
27054 (clobber (reg:CC FLAGS_REG))])
27055 (set (match_operand 3 "general_reg_operand")
27056 (match_operand 4 "const0_operand"))]
27057 "GET_MODE (operands[2]) == word_mode
27058 && GET_MODE_SIZE (GET_MODE (operands[3])) <= UNITS_PER_WORD
27059 && peep2_reg_dead_p (0, operands[3])
27060 && peep2_reg_dead_p (1, operands[2])"
27061 [(parallel [(set (match_dup 0)
27062 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
27063 (set (match_dup 3) (const_int 0))
27064 (clobber (reg:CC FLAGS_REG))])]
27065 "operands[3] = gen_lowpart (word_mode, operands[3]);")
27067 (define_insn "*stack_protect_set_2_<mode>_si"
27068 [(set (match_operand:PTR 0 "memory_operand" "=m")
27069 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
27071 (set (match_operand:SI 1 "register_operand" "=&r")
27072 (match_operand:SI 2 "general_operand" "g"))]
27075 output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
27076 output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
27077 if (pic_32bit_operand (operands[2], SImode)
27078 || ix86_use_lea_for_mov (insn, operands + 1))
27079 return "lea{l}\t{%E2, %1|%1, %E2}";
27081 return "mov{l}\t{%2, %1|%1, %2}";
27083 [(set_attr "type" "multi")
27084 (set_attr "length" "24")])
27086 (define_insn "*stack_protect_set_2_<mode>_di"
27087 [(set (match_operand:PTR 0 "memory_operand" "=m,m,m")
27088 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m,m,m")]
27090 (set (match_operand:DI 1 "register_operand" "=&r,&r,&r")
27091 (match_operand:DI 2 "general_operand" "Z,rem,i"))]
27092 "TARGET_64BIT && reload_completed"
27094 output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
27095 output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
27096 if (pic_32bit_operand (operands[2], DImode))
27097 return "lea{q}\t{%E2, %1|%1, %E2}";
27098 else if (which_alternative == 0)
27099 return "mov{l}\t{%k2, %k1|%k1, %k2}";
27100 else if (which_alternative == 2)
27101 return "movabs{q}\t{%2, %1|%1, %2}";
27102 else if (ix86_use_lea_for_mov (insn, operands + 1))
27103 return "lea{q}\t{%E2, %1|%1, %E2}";
27105 return "mov{q}\t{%2, %1|%1, %2}";
27107 [(set_attr "type" "multi")
27108 (set_attr "length" "24")])
27111 [(parallel [(set (match_operand:PTR 0 "memory_operand")
27112 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
27114 (set (match_operand 2 "general_reg_operand") (const_int 0))
27115 (clobber (reg:CC FLAGS_REG))])
27116 (set (match_operand:SWI48 3 "general_reg_operand")
27117 (match_operand:SWI48 4 "general_gr_operand"))]
27118 "GET_MODE (operands[2]) == word_mode
27119 && peep2_reg_dead_p (0, operands[3])
27120 && peep2_reg_dead_p (1, operands[2])"
27121 [(parallel [(set (match_dup 0)
27122 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
27123 (set (match_dup 3) (match_dup 4))])])
27126 [(set (match_operand:SWI48 3 "general_reg_operand")
27127 (match_operand:SWI48 4 "general_gr_operand"))
27128 (parallel [(set (match_operand:PTR 0 "memory_operand")
27129 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
27131 (set (match_operand 2 "general_reg_operand") (const_int 0))
27132 (clobber (reg:CC FLAGS_REG))])]
27133 "GET_MODE (operands[2]) == word_mode
27134 && peep2_reg_dead_p (0, operands[3])
27135 && peep2_reg_dead_p (2, operands[2])
27136 && !reg_mentioned_p (operands[3], operands[0])
27137 && !reg_mentioned_p (operands[3], operands[1])"
27138 [(parallel [(set (match_dup 0)
27139 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
27140 (set (match_dup 3) (match_dup 4))])])
27142 (define_insn "*stack_protect_set_3_<PTR:mode>_<SWI48:mode>"
27143 [(set (match_operand:PTR 0 "memory_operand" "=m")
27144 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
27146 (set (match_operand:SWI48 1 "register_operand" "=&r")
27147 (match_operand:SWI48 2 "address_no_seg_operand" "Ts"))]
27150 output_asm_insn ("mov{<PTR:imodesuffix>}\t{%3, %<PTR:k>1|%<PTR:k>1, %3}",
27152 output_asm_insn ("mov{<PTR:imodesuffix>}\t{%<PTR:k>1, %0|%0, %<PTR:k>1}",
27154 if (SImode_address_operand (operands[2], VOIDmode))
27156 gcc_assert (TARGET_64BIT);
27157 return "lea{l}\t{%E2, %k1|%k1, %E2}";
27160 return "lea{<SWI48:imodesuffix>}\t{%E2, %1|%1, %E2}";
27162 [(set_attr "type" "multi")
27163 (set_attr "length" "24")])
27166 [(parallel [(set (match_operand:PTR 0 "memory_operand")
27167 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
27169 (set (match_operand 2 "general_reg_operand") (const_int 0))
27170 (clobber (reg:CC FLAGS_REG))])
27171 (set (match_operand:SWI48 3 "general_reg_operand")
27172 (match_operand:SWI48 4 "address_no_seg_operand"))]
27173 "GET_MODE (operands[2]) == word_mode
27174 && peep2_reg_dead_p (0, operands[3])
27175 && peep2_reg_dead_p (1, operands[2])"
27176 [(parallel [(set (match_dup 0)
27177 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
27178 (set (match_dup 3) (match_dup 4))])])
27180 (define_insn "*stack_protect_set_4z_<mode>_di"
27181 [(set (match_operand:PTR 0 "memory_operand" "=m")
27182 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
27184 (set (match_operand:DI 1 "register_operand" "=&r")
27185 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))]
27186 "TARGET_64BIT && reload_completed"
27188 output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
27189 output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
27190 if (ix86_use_lea_for_mov (insn, operands + 1))
27191 return "lea{l}\t{%E2, %k1|%k1, %E2}";
27193 return "mov{l}\t{%2, %k1|%k1, %2}";
27195 [(set_attr "type" "multi")
27196 (set_attr "length" "24")])
27198 (define_insn "*stack_protect_set_4s_<mode>_di"
27199 [(set (match_operand:PTR 0 "memory_operand" "=m")
27200 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
27202 (set (match_operand:DI 1 "register_operand" "=&r")
27203 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))]
27204 "TARGET_64BIT && reload_completed"
27206 output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
27207 output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
27208 return "movs{lq|x}\t{%2, %1|%1, %2}";
27210 [(set_attr "type" "multi")
27211 (set_attr "length" "24")])
27214 [(parallel [(set (match_operand:PTR 0 "memory_operand")
27215 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
27217 (set (match_operand 2 "general_reg_operand") (const_int 0))
27218 (clobber (reg:CC FLAGS_REG))])
27219 (set (match_operand:DI 3 "general_reg_operand")
27221 (match_operand:SI 4 "nonimmediate_gr_operand")))]
27223 && GET_MODE (operands[2]) == word_mode
27224 && peep2_reg_dead_p (0, operands[3])
27225 && peep2_reg_dead_p (1, operands[2])"
27226 [(parallel [(set (match_dup 0)
27227 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
27229 (any_extend:DI (match_dup 4)))])])
27231 (define_expand "stack_protect_test"
27232 [(match_operand 0 "memory_operand")
27233 (match_operand 1 "memory_operand")
27237 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
27239 emit_insn (gen_stack_protect_test_1
27240 (ptr_mode, flags, operands[0], operands[1]));
27242 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
27243 flags, const0_rtx, operands[2]));
27247 (define_insn "@stack_protect_test_1_<mode>"
27248 [(set (match_operand:CCZ 0 "flags_reg_operand")
27249 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
27250 (match_operand:PTR 2 "memory_operand" "m")]
27252 (clobber (match_scratch:PTR 3 "=&r"))]
27255 output_asm_insn ("mov{<imodesuffix>}\t{%1, %3|%3, %1}", operands);
27256 return "sub{<imodesuffix>}\t{%2, %3|%3, %2}";
27258 [(set_attr "type" "multi")])
27260 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
27261 ;; Do not split instructions with mask registers.
27263 [(set (match_operand 0 "general_reg_operand")
27264 (match_operator 3 "promotable_binary_operator"
27265 [(match_operand 1 "general_reg_operand")
27266 (match_operand 2 "aligned_operand")]))
27267 (clobber (reg:CC FLAGS_REG))]
27268 "! TARGET_PARTIAL_REG_STALL && reload_completed
27269 && ((GET_MODE (operands[0]) == HImode
27270 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
27271 /* ??? next two lines just !satisfies_constraint_K (...) */
27272 || !CONST_INT_P (operands[2])
27273 || satisfies_constraint_K (operands[2])))
27274 || (GET_MODE (operands[0]) == QImode
27275 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
27276 [(parallel [(set (match_dup 0)
27277 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
27278 (clobber (reg:CC FLAGS_REG))])]
27280 operands[0] = gen_lowpart (SImode, operands[0]);
27281 operands[1] = gen_lowpart (SImode, operands[1]);
27282 if (GET_CODE (operands[3]) != ASHIFT)
27283 operands[2] = gen_lowpart (SImode, operands[2]);
27284 operands[3] = shallow_copy_rtx (operands[3]);
27285 PUT_MODE (operands[3], SImode);
27288 ; Promote the QImode tests, as i386 has encoding of the AND
27289 ; instruction with 32-bit sign-extended immediate and thus the
27290 ; instruction size is unchanged, except in the %eax case for
27291 ; which it is increased by one byte, hence the ! optimize_size.
27293 [(set (match_operand 0 "flags_reg_operand")
27294 (match_operator 2 "compare_operator"
27295 [(and (match_operand 3 "aligned_operand")
27296 (match_operand 4 "const_int_operand"))
27298 (set (match_operand 1 "register_operand")
27299 (and (match_dup 3) (match_dup 4)))]
27300 "! TARGET_PARTIAL_REG_STALL && reload_completed
27301 && optimize_insn_for_speed_p ()
27302 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
27303 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
27304 /* Ensure that the operand will remain sign-extended immediate. */
27305 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
27306 [(parallel [(set (match_dup 0)
27307 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
27310 (and:SI (match_dup 3) (match_dup 4)))])]
27313 = gen_int_mode (INTVAL (operands[4])
27314 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
27315 operands[1] = gen_lowpart (SImode, operands[1]);
27316 operands[3] = gen_lowpart (SImode, operands[3]);
27319 ; Don't promote the QImode tests, as i386 doesn't have encoding of
27320 ; the TEST instruction with 32-bit sign-extended immediate and thus
27321 ; the instruction size would at least double, which is not what we
27322 ; want even with ! optimize_size.
27324 [(set (match_operand 0 "flags_reg_operand")
27325 (match_operator 1 "compare_operator"
27326 [(and (match_operand:HI 2 "aligned_operand")
27327 (match_operand:HI 3 "const_int_operand"))
27329 "! TARGET_PARTIAL_REG_STALL && reload_completed
27330 && ! TARGET_FAST_PREFIX
27331 && optimize_insn_for_speed_p ()
27332 /* Ensure that the operand will remain sign-extended immediate. */
27333 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
27334 [(set (match_dup 0)
27335 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
27339 = gen_int_mode (INTVAL (operands[3])
27340 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
27341 operands[2] = gen_lowpart (SImode, operands[2]);
27345 [(set (match_operand 0 "register_operand")
27346 (neg (match_operand 1 "register_operand")))
27347 (clobber (reg:CC FLAGS_REG))]
27348 "! TARGET_PARTIAL_REG_STALL && reload_completed
27349 && (GET_MODE (operands[0]) == HImode
27350 || (GET_MODE (operands[0]) == QImode && TARGET_PROMOTE_QImode))"
27351 [(parallel [(set (match_dup 0)
27352 (neg:SI (match_dup 1)))
27353 (clobber (reg:CC FLAGS_REG))])]
27355 operands[0] = gen_lowpart (SImode, operands[0]);
27356 operands[1] = gen_lowpart (SImode, operands[1]);
27359 ;; Do not split instructions with mask regs.
27361 [(set (match_operand 0 "general_reg_operand")
27362 (not (match_operand 1 "general_reg_operand")))]
27363 "! TARGET_PARTIAL_REG_STALL && reload_completed
27364 && (GET_MODE (operands[0]) == HImode
27365 || (GET_MODE (operands[0]) == QImode && TARGET_PROMOTE_QImode))"
27366 [(set (match_dup 0)
27367 (not:SI (match_dup 1)))]
27369 operands[0] = gen_lowpart (SImode, operands[0]);
27370 operands[1] = gen_lowpart (SImode, operands[1]);
27374 [(set (match_operand 0 "general_reg_operand")
27375 (neg (match_operator 1 "ix86_carry_flag_operator"
27376 [(reg FLAGS_REG) (const_int 0)])))
27377 (clobber (reg:CC FLAGS_REG))]
27378 "! TARGET_PARTIAL_REG_STALL && reload_completed
27379 && (GET_MODE (operands[0]) == HImode
27380 || (GET_MODE (operands[0]) == QImode && TARGET_PROMOTE_QImode))"
27381 [(parallel [(set (match_dup 0)
27382 (neg:SI (match_dup 1)))
27383 (clobber (reg:CC FLAGS_REG))])]
27385 operands[0] = gen_lowpart (SImode, operands[0]);
27386 operands[1] = shallow_copy_rtx (operands[1]);
27387 PUT_MODE (operands[1], SImode);
27390 ;; RTL Peephole optimizations, run before sched2. These primarily look to
27391 ;; transform a complex memory operation into two memory to register operations.
27393 ;; Don't push memory operands
27395 [(set (match_operand:SWI 0 "push_operand")
27396 (match_operand:SWI 1 "memory_operand"))
27397 (match_scratch:SWI 2 "<r>")]
27398 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
27399 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
27400 [(set (match_dup 2) (match_dup 1))
27401 (set (match_dup 0) (match_dup 2))])
27403 ;; We need to handle SFmode only, because DFmode and XFmode are split to
27406 [(set (match_operand:SF 0 "push_operand")
27407 (match_operand:SF 1 "memory_operand"))
27408 (match_scratch:SF 2 "r")]
27409 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
27410 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
27411 [(set (match_dup 2) (match_dup 1))
27412 (set (match_dup 0) (match_dup 2))])
27414 ;; Don't move an immediate directly to memory when the instruction
27415 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
27417 [(match_scratch:SWI124 1 "<r>")
27418 (set (match_operand:SWI124 0 "memory_operand")
27420 "optimize_insn_for_speed_p ()
27421 && ((<MODE>mode == HImode
27422 && TARGET_LCP_STALL)
27423 || (!TARGET_USE_MOV0
27424 && TARGET_SPLIT_LONG_MOVES
27425 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
27426 && peep2_regno_dead_p (0, FLAGS_REG)"
27427 [(parallel [(set (match_dup 2) (const_int 0))
27428 (clobber (reg:CC FLAGS_REG))])
27429 (set (match_dup 0) (match_dup 1))]
27430 "operands[2] = gen_lowpart (SImode, operands[1]);")
27433 [(match_scratch:SWI124 2 "<r>")
27434 (set (match_operand:SWI124 0 "memory_operand")
27435 (match_operand:SWI124 1 "immediate_operand"))]
27436 "optimize_insn_for_speed_p ()
27437 && ((<MODE>mode == HImode
27438 && TARGET_LCP_STALL)
27439 || (TARGET_SPLIT_LONG_MOVES
27440 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
27441 [(set (match_dup 2) (match_dup 1))
27442 (set (match_dup 0) (match_dup 2))])
27444 ;; Don't compare memory with zero, load and use a test instead.
27446 [(set (match_operand 0 "flags_reg_operand")
27447 (match_operator 1 "compare_operator"
27448 [(match_operand:SI 2 "memory_operand")
27450 (match_scratch:SI 3 "r")]
27451 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
27452 [(set (match_dup 3) (match_dup 2))
27453 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
27455 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
27456 ;; Don't split NOTs with a displacement operand, because resulting XOR
27457 ;; will not be pairable anyway.
27459 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
27460 ;; represented using a modRM byte. The XOR replacement is long decoded,
27461 ;; so this split helps here as well.
27463 ;; Note: Can't do this as a regular split because we can't get proper
27464 ;; lifetime information then.
27467 [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
27468 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
27469 "optimize_insn_for_speed_p ()
27470 && ((TARGET_NOT_UNPAIRABLE
27471 && (!MEM_P (operands[0])
27472 || !memory_displacement_operand (operands[0], <MODE>mode)))
27473 || (TARGET_NOT_VECTORMODE
27474 && long_memory_operand (operands[0], <MODE>mode)))
27475 && peep2_regno_dead_p (0, FLAGS_REG)"
27476 [(parallel [(set (match_dup 0)
27477 (xor:SWI124 (match_dup 1) (const_int -1)))
27478 (clobber (reg:CC FLAGS_REG))])])
27480 ;; Non pairable "test imm, reg" instructions can be translated to
27481 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
27482 ;; byte opcode instead of two, have a short form for byte operands),
27483 ;; so do it for other CPUs as well. Given that the value was dead,
27484 ;; this should not create any new dependencies. Pass on the sub-word
27485 ;; versions if we're concerned about partial register stalls.
27488 [(set (match_operand 0 "flags_reg_operand")
27489 (match_operator 1 "compare_operator"
27490 [(and:SI (match_operand:SI 2 "register_operand")
27491 (match_operand:SI 3 "immediate_operand"))
27493 "ix86_match_ccmode (insn, CCNOmode)
27494 && (REGNO (operands[2]) != AX_REG
27495 || satisfies_constraint_K (operands[3]))
27496 && peep2_reg_dead_p (1, operands[2])"
27498 [(set (match_dup 0)
27499 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
27502 (and:SI (match_dup 2) (match_dup 3)))])])
27504 ;; We don't need to handle HImode case, because it will be promoted to SImode
27505 ;; on ! TARGET_PARTIAL_REG_STALL
27508 [(set (match_operand 0 "flags_reg_operand")
27509 (match_operator 1 "compare_operator"
27510 [(and:QI (match_operand:QI 2 "register_operand")
27511 (match_operand:QI 3 "immediate_operand"))
27513 "! TARGET_PARTIAL_REG_STALL
27514 && ix86_match_ccmode (insn, CCNOmode)
27515 && REGNO (operands[2]) != AX_REG
27516 && peep2_reg_dead_p (1, operands[2])"
27518 [(set (match_dup 0)
27519 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
27522 (and:QI (match_dup 2) (match_dup 3)))])])
27525 [(set (match_operand 0 "flags_reg_operand")
27526 (match_operator 1 "compare_operator"
27529 (match_operator:SWI248 4 "extract_operator"
27530 [(match_operand 2 "int248_register_operand")
27533 (match_operand 3 "const_int_operand"))
27535 "! TARGET_PARTIAL_REG_STALL
27536 && ix86_match_ccmode (insn, CCNOmode)
27537 && REGNO (operands[2]) != AX_REG
27538 && peep2_reg_dead_p (1, operands[2])"
27540 [(set (match_dup 0)
27544 (match_op_dup 4 [(match_dup 2)
27549 (set (zero_extract:SWI248 (match_dup 2)
27555 (match_op_dup 4 [(match_dup 2)
27558 (match_dup 3)) 0))])])
27560 ;; Don't do logical operations with memory inputs.
27562 [(match_scratch:SWI 2 "<r>")
27563 (parallel [(set (match_operand:SWI 0 "register_operand")
27564 (match_operator:SWI 3 "arith_or_logical_operator"
27566 (match_operand:SWI 1 "memory_operand")]))
27567 (clobber (reg:CC FLAGS_REG))])]
27568 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
27569 [(set (match_dup 2) (match_dup 1))
27570 (parallel [(set (match_dup 0)
27571 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
27572 (clobber (reg:CC FLAGS_REG))])])
27575 [(match_scratch:SWI 2 "<r>")
27576 (parallel [(set (match_operand:SWI 0 "register_operand")
27577 (match_operator:SWI 3 "arith_or_logical_operator"
27578 [(match_operand:SWI 1 "memory_operand")
27580 (clobber (reg:CC FLAGS_REG))])]
27581 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
27582 [(set (match_dup 2) (match_dup 1))
27583 (parallel [(set (match_dup 0)
27584 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
27585 (clobber (reg:CC FLAGS_REG))])])
27587 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when
27588 ;; the memory address refers to the destination of the load!
27591 [(set (match_operand:SWI 0 "general_reg_operand")
27592 (match_operand:SWI 1 "general_reg_operand"))
27593 (parallel [(set (match_dup 0)
27594 (match_operator:SWI 3 "commutative_operator"
27596 (match_operand:SWI 2 "memory_operand")]))
27597 (clobber (reg:CC FLAGS_REG))])]
27598 "REGNO (operands[0]) != REGNO (operands[1])
27599 && (<MODE>mode != QImode
27600 || any_QIreg_operand (operands[1], QImode))"
27601 [(set (match_dup 0) (match_dup 4))
27602 (parallel [(set (match_dup 0)
27603 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
27604 (clobber (reg:CC FLAGS_REG))])]
27607 = ix86_replace_reg_with_reg (operands[2], operands[0], operands[1]);
27611 [(set (match_operand 0 "mmx_reg_operand")
27612 (match_operand 1 "mmx_reg_operand"))
27614 (match_operator 3 "commutative_operator"
27616 (match_operand 2 "memory_operand")]))]
27617 "REGNO (operands[0]) != REGNO (operands[1])"
27618 [(set (match_dup 0) (match_dup 2))
27620 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
27623 [(set (match_operand 0 "sse_reg_operand")
27624 (match_operand 1 "sse_reg_operand"))
27626 (match_operator 3 "commutative_operator"
27628 (match_operand 2 "memory_operand")]))]
27629 "REGNO (operands[0]) != REGNO (operands[1])
27630 /* Punt if operands[1] is %[xy]mm16+ and AVX512BW is not enabled,
27631 as EVEX encoded vpadd[bw], vpmullw, vpmin[su][bw] and vpmax[su][bw]
27632 instructions require AVX512BW and AVX512VL, but with the original
27633 instructions it might require just AVX512VL.
27634 AVX512VL is implied from TARGET_HARD_REGNO_MODE_OK. */
27635 && (!EXT_REX_SSE_REGNO_P (REGNO (operands[1]))
27637 || GET_MODE_SIZE (GET_MODE_INNER (GET_MODE (operands[0]))) > 2
27638 || logic_operator (operands[3], VOIDmode))"
27639 [(set (match_dup 0) (match_dup 2))
27641 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
27643 ; Don't do logical operations with memory outputs
27645 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
27646 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
27647 ; the same decoder scheduling characteristics as the original.
27650 [(match_scratch:SWI 2 "<r>")
27651 (parallel [(set (match_operand:SWI 0 "memory_operand")
27652 (match_operator:SWI 3 "arith_or_logical_operator"
27654 (match_operand:SWI 1 "<nonmemory_operand>")]))
27655 (clobber (reg:CC FLAGS_REG))])]
27656 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
27657 [(set (match_dup 2) (match_dup 0))
27658 (parallel [(set (match_dup 2)
27659 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
27660 (clobber (reg:CC FLAGS_REG))])
27661 (set (match_dup 0) (match_dup 2))])
27664 [(match_scratch:SWI 2 "<r>")
27665 (parallel [(set (match_operand:SWI 0 "memory_operand")
27666 (match_operator:SWI 3 "arith_or_logical_operator"
27667 [(match_operand:SWI 1 "<nonmemory_operand>")
27669 (clobber (reg:CC FLAGS_REG))])]
27670 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
27671 [(set (match_dup 2) (match_dup 0))
27672 (parallel [(set (match_dup 2)
27673 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
27674 (clobber (reg:CC FLAGS_REG))])
27675 (set (match_dup 0) (match_dup 2))])
27677 ;; Attempt to use arith or logical operations with memory outputs with
27678 ;; setting of flags.
27680 [(set (match_operand:SWI 0 "register_operand")
27681 (match_operand:SWI 1 "memory_operand"))
27682 (parallel [(set (match_dup 0)
27683 (match_operator:SWI 3 "plusminuslogic_operator"
27685 (match_operand:SWI 2 "<nonmemory_operand>")]))
27686 (clobber (reg:CC FLAGS_REG))])
27687 (set (match_dup 1) (match_dup 0))
27688 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
27689 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
27690 && peep2_reg_dead_p (4, operands[0])
27691 && !reg_overlap_mentioned_p (operands[0], operands[1])
27692 && !reg_overlap_mentioned_p (operands[0], operands[2])
27693 && (<MODE>mode != QImode
27694 || immediate_operand (operands[2], QImode)
27695 || any_QIreg_operand (operands[2], QImode))
27696 && ix86_match_ccmode (peep2_next_insn (3),
27697 (GET_CODE (operands[3]) == PLUS
27698 || GET_CODE (operands[3]) == MINUS)
27699 ? CCGOCmode : CCNOmode)"
27700 [(parallel [(set (match_dup 4) (match_dup 6))
27701 (set (match_dup 1) (match_dup 5))])]
27703 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
27705 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
27706 copy_rtx (operands[1]),
27709 = gen_rtx_COMPARE (GET_MODE (operands[4]),
27710 copy_rtx (operands[5]),
27714 ;; Likewise for cmpelim optimized pattern.
27716 [(set (match_operand:SWI 0 "register_operand")
27717 (match_operand:SWI 1 "memory_operand"))
27718 (parallel [(set (reg FLAGS_REG)
27719 (compare (match_operator:SWI 3 "plusminuslogic_operator"
27721 (match_operand:SWI 2 "<nonmemory_operand>")])
27723 (set (match_dup 0) (match_dup 3))])
27724 (set (match_dup 1) (match_dup 0))]
27725 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
27726 && peep2_reg_dead_p (3, operands[0])
27727 && !reg_overlap_mentioned_p (operands[0], operands[1])
27728 && !reg_overlap_mentioned_p (operands[0], operands[2])
27729 && ix86_match_ccmode (peep2_next_insn (1),
27730 (GET_CODE (operands[3]) == PLUS
27731 || GET_CODE (operands[3]) == MINUS)
27732 ? CCGOCmode : CCNOmode)"
27733 [(parallel [(set (match_dup 4) (match_dup 6))
27734 (set (match_dup 1) (match_dup 5))])]
27736 operands[4] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
27738 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
27739 copy_rtx (operands[1]), operands[2]);
27741 = gen_rtx_COMPARE (GET_MODE (operands[4]), copy_rtx (operands[5]),
27745 ;; Likewise for instances where we have a lea pattern.
27747 [(set (match_operand:SWI 0 "register_operand")
27748 (match_operand:SWI 1 "memory_operand"))
27749 (set (match_operand:<LEAMODE> 3 "register_operand")
27750 (plus:<LEAMODE> (match_operand:<LEAMODE> 4 "register_operand")
27751 (match_operand:<LEAMODE> 2 "<nonmemory_operand>")))
27752 (set (match_dup 1) (match_operand:SWI 5 "register_operand"))
27753 (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
27754 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
27755 && REGNO (operands[4]) == REGNO (operands[0])
27756 && REGNO (operands[5]) == REGNO (operands[3])
27757 && peep2_reg_dead_p (4, operands[3])
27758 && ((REGNO (operands[0]) == REGNO (operands[3]))
27759 || peep2_reg_dead_p (2, operands[0]))
27760 && !reg_overlap_mentioned_p (operands[0], operands[1])
27761 && !reg_overlap_mentioned_p (operands[3], operands[1])
27762 && !reg_overlap_mentioned_p (operands[0], operands[2])
27763 && (<MODE>mode != QImode
27764 || immediate_operand (operands[2], QImode)
27765 || any_QIreg_operand (operands[2], QImode))
27766 && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
27767 [(parallel [(set (match_dup 6) (match_dup 8))
27768 (set (match_dup 1) (match_dup 7))])]
27770 operands[6] = SET_DEST (PATTERN (peep2_next_insn (3)));
27772 = gen_rtx_PLUS (<MODE>mode,
27773 copy_rtx (operands[1]),
27774 gen_lowpart (<MODE>mode, operands[2]));
27776 = gen_rtx_COMPARE (GET_MODE (operands[6]),
27777 copy_rtx (operands[7]),
27782 [(parallel [(set (match_operand:SWI 0 "register_operand")
27783 (match_operator:SWI 2 "plusminuslogic_operator"
27785 (match_operand:SWI 1 "memory_operand")]))
27786 (clobber (reg:CC FLAGS_REG))])
27787 (set (match_dup 1) (match_dup 0))
27788 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
27789 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
27790 && COMMUTATIVE_ARITH_P (operands[2])
27791 && peep2_reg_dead_p (3, operands[0])
27792 && !reg_overlap_mentioned_p (operands[0], operands[1])
27793 && ix86_match_ccmode (peep2_next_insn (2),
27794 GET_CODE (operands[2]) == PLUS
27795 ? CCGOCmode : CCNOmode)"
27796 [(parallel [(set (match_dup 3) (match_dup 5))
27797 (set (match_dup 1) (match_dup 4))])]
27799 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
27801 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
27802 copy_rtx (operands[1]),
27805 = gen_rtx_COMPARE (GET_MODE (operands[3]),
27806 copy_rtx (operands[4]),
27810 ;; Likewise for cmpelim optimized pattern.
27812 [(parallel [(set (reg FLAGS_REG)
27813 (compare (match_operator:SWI 2 "plusminuslogic_operator"
27814 [(match_operand:SWI 0 "register_operand")
27815 (match_operand:SWI 1 "memory_operand")])
27817 (set (match_dup 0) (match_dup 2))])
27818 (set (match_dup 1) (match_dup 0))]
27819 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
27820 && COMMUTATIVE_ARITH_P (operands[2])
27821 && peep2_reg_dead_p (2, operands[0])
27822 && !reg_overlap_mentioned_p (operands[0], operands[1])
27823 && ix86_match_ccmode (peep2_next_insn (0),
27824 GET_CODE (operands[2]) == PLUS
27825 ? CCGOCmode : CCNOmode)"
27826 [(parallel [(set (match_dup 3) (match_dup 5))
27827 (set (match_dup 1) (match_dup 4))])]
27829 operands[3] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (0)), 0, 0));
27831 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
27832 copy_rtx (operands[1]), operands[0]);
27834 = gen_rtx_COMPARE (GET_MODE (operands[3]), copy_rtx (operands[4]),
27839 [(set (match_operand:SWI12 0 "register_operand")
27840 (match_operand:SWI12 1 "memory_operand"))
27841 (parallel [(set (match_operand:SI 4 "register_operand")
27842 (match_operator:SI 3 "plusminuslogic_operator"
27844 (match_operand:SI 2 "nonmemory_operand")]))
27845 (clobber (reg:CC FLAGS_REG))])
27846 (set (match_dup 1) (match_dup 0))
27847 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
27848 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
27849 && REGNO (operands[0]) == REGNO (operands[4])
27850 && peep2_reg_dead_p (4, operands[0])
27851 && (<MODE>mode != QImode
27852 || immediate_operand (operands[2], SImode)
27853 || any_QIreg_operand (operands[2], SImode))
27854 && !reg_overlap_mentioned_p (operands[0], operands[1])
27855 && !reg_overlap_mentioned_p (operands[0], operands[2])
27856 && ix86_match_ccmode (peep2_next_insn (3),
27857 (GET_CODE (operands[3]) == PLUS
27858 || GET_CODE (operands[3]) == MINUS)
27859 ? CCGOCmode : CCNOmode)"
27860 [(parallel [(set (match_dup 5) (match_dup 7))
27861 (set (match_dup 1) (match_dup 6))])]
27863 operands[5] = SET_DEST (PATTERN (peep2_next_insn (3)));
27865 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
27866 copy_rtx (operands[1]),
27867 gen_lowpart (<MODE>mode, operands[2]));
27869 = gen_rtx_COMPARE (GET_MODE (operands[5]),
27870 copy_rtx (operands[6]),
27874 ;; peephole2 comes before regcprop, so deal also with a case that
27875 ;; would be cleaned up by regcprop.
27877 [(set (match_operand:SWI 0 "register_operand")
27878 (match_operand:SWI 1 "memory_operand"))
27879 (parallel [(set (match_dup 0)
27880 (match_operator:SWI 3 "plusminuslogic_operator"
27882 (match_operand:SWI 2 "<nonmemory_operand>")]))
27883 (clobber (reg:CC FLAGS_REG))])
27884 (set (match_operand:SWI 4 "register_operand") (match_dup 0))
27885 (set (match_dup 1) (match_dup 4))
27886 (set (reg FLAGS_REG) (compare (match_dup 4) (const_int 0)))]
27887 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
27888 && peep2_reg_dead_p (3, operands[0])
27889 && peep2_reg_dead_p (5, operands[4])
27890 && !reg_overlap_mentioned_p (operands[0], operands[1])
27891 && !reg_overlap_mentioned_p (operands[0], operands[2])
27892 && !reg_overlap_mentioned_p (operands[4], operands[1])
27893 && (<MODE>mode != QImode
27894 || immediate_operand (operands[2], QImode)
27895 || any_QIreg_operand (operands[2], QImode))
27896 && ix86_match_ccmode (peep2_next_insn (4),
27897 (GET_CODE (operands[3]) == PLUS
27898 || GET_CODE (operands[3]) == MINUS)
27899 ? CCGOCmode : CCNOmode)"
27900 [(parallel [(set (match_dup 5) (match_dup 7))
27901 (set (match_dup 1) (match_dup 6))])]
27903 operands[5] = SET_DEST (PATTERN (peep2_next_insn (4)));
27905 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
27906 copy_rtx (operands[1]),
27909 = gen_rtx_COMPARE (GET_MODE (operands[5]),
27910 copy_rtx (operands[6]),
27915 [(set (match_operand:SWI12 0 "register_operand")
27916 (match_operand:SWI12 1 "memory_operand"))
27917 (parallel [(set (match_operand:SI 4 "register_operand")
27918 (match_operator:SI 3 "plusminuslogic_operator"
27920 (match_operand:SI 2 "nonmemory_operand")]))
27921 (clobber (reg:CC FLAGS_REG))])
27922 (set (match_operand:SWI12 5 "register_operand") (match_dup 0))
27923 (set (match_dup 1) (match_dup 5))
27924 (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
27925 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
27926 && REGNO (operands[0]) == REGNO (operands[4])
27927 && peep2_reg_dead_p (3, operands[0])
27928 && peep2_reg_dead_p (5, operands[5])
27929 && (<MODE>mode != QImode
27930 || immediate_operand (operands[2], SImode)
27931 || any_QIreg_operand (operands[2], SImode))
27932 && !reg_overlap_mentioned_p (operands[0], operands[1])
27933 && !reg_overlap_mentioned_p (operands[0], operands[2])
27934 && !reg_overlap_mentioned_p (operands[5], operands[1])
27935 && ix86_match_ccmode (peep2_next_insn (4),
27936 (GET_CODE (operands[3]) == PLUS
27937 || GET_CODE (operands[3]) == MINUS)
27938 ? CCGOCmode : CCNOmode)"
27939 [(parallel [(set (match_dup 6) (match_dup 8))
27940 (set (match_dup 1) (match_dup 7))])]
27942 operands[6] = SET_DEST (PATTERN (peep2_next_insn (4)));
27944 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
27945 copy_rtx (operands[1]),
27946 gen_lowpart (<MODE>mode, operands[2]));
27948 = gen_rtx_COMPARE (GET_MODE (operands[6]),
27949 copy_rtx (operands[7]),
27953 ;; Likewise for cmpelim optimized pattern.
27955 [(set (match_operand:SWI 0 "register_operand")
27956 (match_operand:SWI 1 "memory_operand"))
27957 (parallel [(set (reg FLAGS_REG)
27958 (compare (match_operator:SWI 3 "plusminuslogic_operator"
27960 (match_operand:SWI 2 "<nonmemory_operand>")])
27962 (set (match_dup 0) (match_dup 3))])
27963 (set (match_operand:SWI 4 "register_operand") (match_dup 0))
27964 (set (match_dup 1) (match_dup 4))]
27965 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
27966 && peep2_reg_dead_p (3, operands[0])
27967 && peep2_reg_dead_p (4, operands[4])
27968 && !reg_overlap_mentioned_p (operands[0], operands[1])
27969 && !reg_overlap_mentioned_p (operands[0], operands[2])
27970 && !reg_overlap_mentioned_p (operands[4], operands[1])
27971 && ix86_match_ccmode (peep2_next_insn (1),
27972 (GET_CODE (operands[3]) == PLUS
27973 || GET_CODE (operands[3]) == MINUS)
27974 ? CCGOCmode : CCNOmode)"
27975 [(parallel [(set (match_dup 5) (match_dup 7))
27976 (set (match_dup 1) (match_dup 6))])]
27978 operands[5] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
27980 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
27981 copy_rtx (operands[1]), operands[2]);
27983 = gen_rtx_COMPARE (GET_MODE (operands[5]), copy_rtx (operands[6]),
27987 ;; Special cases for xor, where (x ^= y) != 0 is (misoptimized)
27988 ;; into x = z; x ^= y; x != z
27990 [(set (match_operand:SWI 0 "register_operand")
27991 (match_operand:SWI 1 "memory_operand"))
27992 (set (match_operand:SWI 3 "register_operand") (match_dup 0))
27993 (parallel [(set (match_operand:SWI 4 "register_operand")
27994 (xor:SWI (match_dup 4)
27995 (match_operand:SWI 2 "<nonmemory_operand>")))
27996 (clobber (reg:CC FLAGS_REG))])
27997 (set (match_dup 1) (match_dup 4))
27998 (set (reg:CCZ FLAGS_REG)
27999 (compare:CCZ (match_operand:SWI 5 "register_operand")
28000 (match_operand:SWI 6 "<nonmemory_operand>")))]
28001 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
28002 && (REGNO (operands[4]) == REGNO (operands[0])
28003 || REGNO (operands[4]) == REGNO (operands[3]))
28004 && (rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
28005 ? 3 : 0], operands[5])
28006 ? rtx_equal_p (operands[2], operands[6])
28007 : rtx_equal_p (operands[2], operands[5])
28008 && rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
28009 ? 3 : 0], operands[6]))
28010 && peep2_reg_dead_p (4, operands[4])
28011 && peep2_reg_dead_p (5, operands[REGNO (operands[4]) == REGNO (operands[0])
28013 && !reg_overlap_mentioned_p (operands[0], operands[1])
28014 && !reg_overlap_mentioned_p (operands[0], operands[2])
28015 && !reg_overlap_mentioned_p (operands[3], operands[0])
28016 && !reg_overlap_mentioned_p (operands[3], operands[1])
28017 && !reg_overlap_mentioned_p (operands[3], operands[2])
28018 && (<MODE>mode != QImode
28019 || immediate_operand (operands[2], QImode)
28020 || any_QIreg_operand (operands[2], QImode))"
28021 [(parallel [(set (match_dup 7) (match_dup 9))
28022 (set (match_dup 1) (match_dup 8))])]
28024 operands[7] = SET_DEST (PATTERN (peep2_next_insn (4)));
28025 operands[8] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
28028 = gen_rtx_COMPARE (GET_MODE (operands[7]),
28029 copy_rtx (operands[8]),
28034 [(set (match_operand:SWI12 0 "register_operand")
28035 (match_operand:SWI12 1 "memory_operand"))
28036 (set (match_operand:SWI12 3 "register_operand") (match_dup 0))
28037 (parallel [(set (match_operand:SI 4 "register_operand")
28038 (xor:SI (match_dup 4)
28039 (match_operand:SI 2 "<nonmemory_operand>")))
28040 (clobber (reg:CC FLAGS_REG))])
28041 (set (match_dup 1) (match_operand:SWI12 5 "register_operand"))
28042 (set (reg:CCZ FLAGS_REG)
28043 (compare:CCZ (match_operand:SWI12 6 "register_operand")
28044 (match_operand:SWI12 7 "<nonmemory_operand>")))]
28045 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
28046 && (REGNO (operands[5]) == REGNO (operands[0])
28047 || REGNO (operands[5]) == REGNO (operands[3]))
28048 && REGNO (operands[5]) == REGNO (operands[4])
28049 && (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
28050 ? 3 : 0], operands[6])
28051 ? (REG_P (operands[2])
28052 ? REG_P (operands[7]) && REGNO (operands[2]) == REGNO (operands[7])
28053 : rtx_equal_p (operands[2], operands[7]))
28054 : (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
28055 ? 3 : 0], operands[7])
28056 && REG_P (operands[2])
28057 && REGNO (operands[2]) == REGNO (operands[6])))
28058 && peep2_reg_dead_p (4, operands[5])
28059 && peep2_reg_dead_p (5, operands[REGNO (operands[5]) == REGNO (operands[0])
28061 && !reg_overlap_mentioned_p (operands[0], operands[1])
28062 && !reg_overlap_mentioned_p (operands[0], operands[2])
28063 && !reg_overlap_mentioned_p (operands[3], operands[0])
28064 && !reg_overlap_mentioned_p (operands[3], operands[1])
28065 && !reg_overlap_mentioned_p (operands[3], operands[2])
28066 && (<MODE>mode != QImode
28067 || immediate_operand (operands[2], SImode)
28068 || any_QIreg_operand (operands[2], SImode))"
28069 [(parallel [(set (match_dup 8) (match_dup 10))
28070 (set (match_dup 1) (match_dup 9))])]
28072 operands[8] = SET_DEST (PATTERN (peep2_next_insn (4)));
28073 operands[9] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
28074 gen_lowpart (<MODE>mode, operands[2]));
28076 = gen_rtx_COMPARE (GET_MODE (operands[8]),
28077 copy_rtx (operands[9]),
28081 ;; Attempt to optimize away memory stores of values the memory already
28082 ;; has. See PR79593.
28084 [(set (match_operand 0 "register_operand")
28085 (match_operand 1 "memory_operand"))
28086 (set (match_operand 2 "memory_operand") (match_dup 0))]
28087 "!MEM_VOLATILE_P (operands[1])
28088 && !MEM_VOLATILE_P (operands[2])
28089 && rtx_equal_p (operands[1], operands[2])
28090 && !reg_overlap_mentioned_p (operands[0], operands[2])"
28091 [(set (match_dup 0) (match_dup 1))])
28093 ;; Attempt to always use XOR for zeroing registers (including FP modes).
28095 [(set (match_operand 0 "general_reg_operand")
28096 (match_operand 1 "const0_operand"))]
28097 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
28098 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
28099 && peep2_regno_dead_p (0, FLAGS_REG)"
28100 [(parallel [(set (match_dup 0) (const_int 0))
28101 (clobber (reg:CC FLAGS_REG))])]
28102 "operands[0] = gen_lowpart (word_mode, operands[0]);")
28105 [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
28107 "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
28108 && peep2_regno_dead_p (0, FLAGS_REG)"
28109 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
28110 (clobber (reg:CC FLAGS_REG))])])
28112 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
28114 [(set (match_operand:SWI248 0 "general_reg_operand")
28116 "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
28117 && peep2_regno_dead_p (0, FLAGS_REG)"
28118 [(parallel [(set (match_dup 0) (const_int -1))
28119 (clobber (reg:CC FLAGS_REG))])]
28121 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
28122 operands[0] = gen_lowpart (SImode, operands[0]);
28125 ;; Attempt to convert simple lea to add/shift.
28126 ;; These can be created by move expanders.
28127 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
28128 ;; relevant lea instructions were already split.
28131 [(set (match_operand:SWI48 0 "register_operand")
28132 (plus:SWI48 (match_dup 0)
28133 (match_operand:SWI48 1 "<nonmemory_operand>")))]
28135 && peep2_regno_dead_p (0, FLAGS_REG)"
28136 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
28137 (clobber (reg:CC FLAGS_REG))])])
28140 [(set (match_operand:SWI48 0 "register_operand")
28141 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
28144 && peep2_regno_dead_p (0, FLAGS_REG)"
28145 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
28146 (clobber (reg:CC FLAGS_REG))])])
28149 [(set (match_operand:DI 0 "register_operand")
28151 (plus:SI (match_operand:SI 1 "register_operand")
28152 (match_operand:SI 2 "nonmemory_operand"))))]
28153 "TARGET_64BIT && !TARGET_OPT_AGU
28154 && REGNO (operands[0]) == REGNO (operands[1])
28155 && peep2_regno_dead_p (0, FLAGS_REG)"
28156 [(parallel [(set (match_dup 0)
28157 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
28158 (clobber (reg:CC FLAGS_REG))])])
28161 [(set (match_operand:DI 0 "register_operand")
28163 (plus:SI (match_operand:SI 1 "nonmemory_operand")
28164 (match_operand:SI 2 "register_operand"))))]
28165 "TARGET_64BIT && !TARGET_OPT_AGU
28166 && REGNO (operands[0]) == REGNO (operands[2])
28167 && peep2_regno_dead_p (0, FLAGS_REG)"
28168 [(parallel [(set (match_dup 0)
28169 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
28170 (clobber (reg:CC FLAGS_REG))])])
28173 [(set (match_operand:SWI48 0 "register_operand")
28174 (mult:SWI48 (match_dup 0)
28175 (match_operand:SWI48 1 "const_int_operand")))]
28176 "pow2p_hwi (INTVAL (operands[1]))
28177 && peep2_regno_dead_p (0, FLAGS_REG)"
28178 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
28179 (clobber (reg:CC FLAGS_REG))])]
28180 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
28183 [(set (match_operand:DI 0 "register_operand")
28185 (mult:SI (match_operand:SI 1 "register_operand")
28186 (match_operand:SI 2 "const_int_operand"))))]
28188 && pow2p_hwi (INTVAL (operands[2]))
28189 && REGNO (operands[0]) == REGNO (operands[1])
28190 && peep2_regno_dead_p (0, FLAGS_REG)"
28191 [(parallel [(set (match_dup 0)
28192 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
28193 (clobber (reg:CC FLAGS_REG))])]
28194 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
28196 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
28197 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
28198 ;; On many CPUs it is also faster, since special hardware to avoid esp
28199 ;; dependencies is present.
28201 ;; While some of these conversions may be done using splitters, we use
28202 ;; peepholes in order to allow combine_stack_adjustments pass to see
28203 ;; nonobfuscated RTL.
28205 ;; Convert prologue esp subtractions to push.
28206 ;; We need register to push. In order to keep verify_flow_info happy we have
28208 ;; - use scratch and clobber it in order to avoid dependencies
28209 ;; - use already live register
28210 ;; We can't use the second way right now, since there is no reliable way how to
28211 ;; verify that given register is live. First choice will also most likely in
28212 ;; fewer dependencies. On the place of esp adjustments it is very likely that
28213 ;; call clobbered registers are dead. We may want to use base pointer as an
28214 ;; alternative when no register is available later.
28217 [(match_scratch:W 1 "r")
28218 (parallel [(set (reg:P SP_REG)
28219 (plus:P (reg:P SP_REG)
28220 (match_operand:P 0 "const_int_operand")))
28221 (clobber (reg:CC FLAGS_REG))
28222 (clobber (mem:BLK (scratch)))])]
28223 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
28224 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
28225 && !ix86_red_zone_used"
28226 [(clobber (match_dup 1))
28227 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
28228 (clobber (mem:BLK (scratch)))])])
28231 [(match_scratch:W 1 "r")
28232 (parallel [(set (reg:P SP_REG)
28233 (plus:P (reg:P SP_REG)
28234 (match_operand:P 0 "const_int_operand")))
28235 (clobber (reg:CC FLAGS_REG))
28236 (clobber (mem:BLK (scratch)))])]
28237 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
28238 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
28239 && !ix86_red_zone_used"
28240 [(clobber (match_dup 1))
28241 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
28242 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
28243 (clobber (mem:BLK (scratch)))])])
28245 ;; Convert esp subtractions to push.
28247 [(match_scratch:W 1 "r")
28248 (parallel [(set (reg:P SP_REG)
28249 (plus:P (reg:P SP_REG)
28250 (match_operand:P 0 "const_int_operand")))
28251 (clobber (reg:CC FLAGS_REG))])]
28252 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
28253 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
28254 && !ix86_red_zone_used"
28255 [(clobber (match_dup 1))
28256 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
28259 [(match_scratch:W 1 "r")
28260 (parallel [(set (reg:P SP_REG)
28261 (plus:P (reg:P SP_REG)
28262 (match_operand:P 0 "const_int_operand")))
28263 (clobber (reg:CC FLAGS_REG))])]
28264 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
28265 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
28266 && !ix86_red_zone_used"
28267 [(clobber (match_dup 1))
28268 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
28269 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
28271 ;; Convert epilogue deallocator to pop.
28273 [(match_scratch:W 1 "r")
28274 (parallel [(set (reg:P SP_REG)
28275 (plus:P (reg:P SP_REG)
28276 (match_operand:P 0 "const_int_operand")))
28277 (clobber (reg:CC FLAGS_REG))
28278 (clobber (mem:BLK (scratch)))])]
28279 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
28280 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
28281 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
28282 (clobber (mem:BLK (scratch)))])])
28284 ;; Two pops case is tricky, since pop causes dependency
28285 ;; on destination register. We use two registers if available.
28287 [(match_scratch:W 1 "r")
28288 (match_scratch:W 2 "r")
28289 (parallel [(set (reg:P SP_REG)
28290 (plus:P (reg:P SP_REG)
28291 (match_operand:P 0 "const_int_operand")))
28292 (clobber (reg:CC FLAGS_REG))
28293 (clobber (mem:BLK (scratch)))])]
28294 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
28295 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
28296 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
28297 (clobber (mem:BLK (scratch)))])
28298 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
28301 [(match_scratch:W 1 "r")
28302 (parallel [(set (reg:P SP_REG)
28303 (plus:P (reg:P SP_REG)
28304 (match_operand:P 0 "const_int_operand")))
28305 (clobber (reg:CC FLAGS_REG))
28306 (clobber (mem:BLK (scratch)))])]
28307 "optimize_insn_for_size_p ()
28308 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
28309 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
28310 (clobber (mem:BLK (scratch)))])
28311 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
28313 ;; Convert esp additions to pop.
28315 [(match_scratch:W 1 "r")
28316 (parallel [(set (reg:P SP_REG)
28317 (plus:P (reg:P SP_REG)
28318 (match_operand:P 0 "const_int_operand")))
28319 (clobber (reg:CC FLAGS_REG))])]
28320 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
28321 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
28323 ;; Two pops case is tricky, since pop causes dependency
28324 ;; on destination register. We use two registers if available.
28326 [(match_scratch:W 1 "r")
28327 (match_scratch:W 2 "r")
28328 (parallel [(set (reg:P SP_REG)
28329 (plus:P (reg:P SP_REG)
28330 (match_operand:P 0 "const_int_operand")))
28331 (clobber (reg:CC FLAGS_REG))])]
28332 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
28333 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
28334 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
28337 [(match_scratch:W 1 "r")
28338 (parallel [(set (reg:P SP_REG)
28339 (plus:P (reg:P SP_REG)
28340 (match_operand:P 0 "const_int_operand")))
28341 (clobber (reg:CC FLAGS_REG))])]
28342 "optimize_insn_for_size_p ()
28343 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
28344 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
28345 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
28347 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
28348 ;; required and register dies. Similarly for 128 to -128.
28350 [(set (match_operand 0 "flags_reg_operand")
28351 (match_operator 1 "compare_operator"
28352 [(match_operand 2 "register_operand")
28353 (match_operand 3 "const_int_operand")]))]
28354 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
28355 && incdec_operand (operands[3], GET_MODE (operands[3])))
28356 || (!TARGET_FUSE_CMP_AND_BRANCH
28357 && INTVAL (operands[3]) == 128))
28358 && ix86_match_ccmode (insn, CCGCmode)
28359 && peep2_reg_dead_p (1, operands[2])"
28360 [(parallel [(set (match_dup 0)
28361 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
28362 (clobber (match_dup 2))])])
28364 ;; Convert imul by three, five and nine into lea
28367 [(set (match_operand:SWI48 0 "register_operand")
28368 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
28369 (match_operand:SWI48 2 "const359_operand")))
28370 (clobber (reg:CC FLAGS_REG))])]
28371 "!TARGET_PARTIAL_REG_STALL
28372 || <MODE>mode == SImode
28373 || optimize_function_for_size_p (cfun)"
28374 [(set (match_dup 0)
28375 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
28377 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
28381 [(set (match_operand:SWI48 0 "register_operand")
28382 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
28383 (match_operand:SWI48 2 "const359_operand")))
28384 (clobber (reg:CC FLAGS_REG))])]
28385 "optimize_insn_for_speed_p ()
28386 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
28387 [(set (match_dup 0) (match_dup 1))
28389 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
28391 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
28393 ;; imul $32bit_imm, mem, reg is vector decoded, while
28394 ;; imul $32bit_imm, reg, reg is direct decoded.
28396 [(match_scratch:SWI48 3 "r")
28397 (parallel [(set (match_operand:SWI48 0 "register_operand")
28398 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
28399 (match_operand:SWI48 2 "immediate_operand")))
28400 (clobber (reg:CC FLAGS_REG))])]
28401 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
28402 && !satisfies_constraint_K (operands[2])"
28403 [(set (match_dup 3) (match_dup 1))
28404 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
28405 (clobber (reg:CC FLAGS_REG))])])
28408 [(match_scratch:SI 3 "r")
28409 (parallel [(set (match_operand:DI 0 "register_operand")
28411 (mult:SI (match_operand:SI 1 "memory_operand")
28412 (match_operand:SI 2 "immediate_operand"))))
28413 (clobber (reg:CC FLAGS_REG))])]
28415 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
28416 && !satisfies_constraint_K (operands[2])"
28417 [(set (match_dup 3) (match_dup 1))
28418 (parallel [(set (match_dup 0)
28419 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
28420 (clobber (reg:CC FLAGS_REG))])])
28422 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
28423 ;; Convert it into imul reg, reg
28424 ;; It would be better to force assembler to encode instruction using long
28425 ;; immediate, but there is apparently no way to do so.
28427 [(parallel [(set (match_operand:SWI248 0 "register_operand")
28429 (match_operand:SWI248 1 "nonimmediate_operand")
28430 (match_operand:SWI248 2 "const_int_operand")))
28431 (clobber (reg:CC FLAGS_REG))])
28432 (match_scratch:SWI248 3 "r")]
28433 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
28434 && satisfies_constraint_K (operands[2])"
28435 [(set (match_dup 3) (match_dup 2))
28436 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
28437 (clobber (reg:CC FLAGS_REG))])]
28439 if (!rtx_equal_p (operands[0], operands[1]))
28440 emit_move_insn (operands[0], operands[1]);
28443 ;; After splitting up read-modify operations, array accesses with memory
28444 ;; operands might end up in form:
28446 ;; movl 4(%esp), %edx
28448 ;; instead of pre-splitting:
28450 ;; addl 4(%esp), %eax
28452 ;; movl 4(%esp), %edx
28453 ;; leal (%edx,%eax,4), %eax
28456 [(match_scratch:W 5 "r")
28457 (parallel [(set (match_operand 0 "register_operand")
28458 (ashift (match_operand 1 "register_operand")
28459 (match_operand 2 "const_int_operand")))
28460 (clobber (reg:CC FLAGS_REG))])
28461 (parallel [(set (match_operand 3 "register_operand")
28462 (plus (match_dup 0)
28463 (match_operand 4 "x86_64_general_operand")))
28464 (clobber (reg:CC FLAGS_REG))])]
28465 "IN_RANGE (INTVAL (operands[2]), 1, 3)
28466 /* Validate MODE for lea. */
28467 && ((!TARGET_PARTIAL_REG_STALL
28468 && (GET_MODE (operands[0]) == QImode
28469 || GET_MODE (operands[0]) == HImode))
28470 || GET_MODE (operands[0]) == SImode
28471 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
28472 && (rtx_equal_p (operands[0], operands[3])
28473 || peep2_reg_dead_p (2, operands[0]))
28474 /* We reorder load and the shift. */
28475 && !reg_overlap_mentioned_p (operands[0], operands[4])"
28476 [(set (match_dup 5) (match_dup 4))
28477 (set (match_dup 0) (match_dup 1))]
28479 machine_mode op1mode = GET_MODE (operands[1]);
28480 machine_mode mode = op1mode == DImode ? DImode : SImode;
28481 int scale = 1 << INTVAL (operands[2]);
28482 rtx index = gen_lowpart (word_mode, operands[1]);
28483 rtx base = gen_lowpart (word_mode, operands[5]);
28484 rtx dest = gen_lowpart (mode, operands[3]);
28486 operands[1] = gen_rtx_PLUS (word_mode, base,
28487 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
28488 if (mode != word_mode)
28489 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
28491 operands[5] = base;
28492 if (op1mode != word_mode)
28493 operands[5] = gen_lowpart (op1mode, operands[5]);
28495 operands[0] = dest;
28498 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
28499 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
28500 ;; caught for use by garbage collectors and the like. Using an insn that
28501 ;; maps to SIGILL makes it more likely the program will rightfully die.
28502 ;; Keeping with tradition, "6" is in honor of #UD.
28503 (define_insn "trap"
28504 [(trap_if (const_int 1) (const_int 6))]
28507 #ifdef HAVE_AS_IX86_UD2
28510 return ASM_SHORT "0x0b0f";
28513 [(set_attr "length" "2")])
28516 [(unspec_volatile [(const_int 0)] UNSPECV_UD2)]
28519 #ifdef HAVE_AS_IX86_UD2
28522 return ASM_SHORT "0x0b0f";
28525 [(set_attr "length" "2")])
28527 (define_expand "prefetch"
28528 [(prefetch (match_operand 0 "address_operand")
28529 (match_operand:SI 1 "const_int_operand")
28530 (match_operand:SI 2 "const_int_operand"))]
28531 "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW"
28533 bool write = operands[1] != const0_rtx;
28534 int locality = INTVAL (operands[2]);
28536 gcc_assert (IN_RANGE (locality, 0, 3));
28538 /* Use 3dNOW prefetch in case we are asking for write prefetch not
28539 supported by SSE counterpart (non-SSE2 athlon machines) or the
28540 SSE prefetch is not available (K6 machines). Otherwise use SSE
28541 prefetch as it allows specifying of locality. */
28546 operands[2] = GEN_INT (3);
28547 else if (TARGET_3DNOW && !TARGET_SSE2)
28548 operands[2] = GEN_INT (3);
28549 else if (TARGET_PREFETCH_SSE)
28550 operands[1] = const0_rtx;
28553 gcc_assert (TARGET_3DNOW);
28554 operands[2] = GEN_INT (3);
28559 if (TARGET_PREFETCH_SSE)
28563 gcc_assert (TARGET_3DNOW);
28564 operands[2] = GEN_INT (3);
28569 (define_insn "*prefetch_sse"
28570 [(prefetch (match_operand 0 "address_operand" "p")
28572 (match_operand:SI 1 "const_int_operand"))]
28573 "TARGET_PREFETCH_SSE"
28575 static const char * const patterns[4] = {
28576 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
28579 int locality = INTVAL (operands[1]);
28580 gcc_assert (IN_RANGE (locality, 0, 3));
28582 return patterns[locality];
28584 [(set_attr "type" "sse")
28585 (set_attr "atom_sse_attr" "prefetch")
28586 (set (attr "length_address")
28587 (symbol_ref "memory_address_length (operands[0], false)"))
28588 (set_attr "memory" "none")])
28590 (define_insn "*prefetch_3dnow"
28591 [(prefetch (match_operand 0 "address_operand" "p")
28592 (match_operand:SI 1 "const_int_operand")
28594 "TARGET_3DNOW || TARGET_PRFCHW"
28596 if (operands[1] == const0_rtx)
28597 return "prefetch\t%a0";
28599 return "prefetchw\t%a0";
28601 [(set_attr "type" "mmx")
28602 (set (attr "length_address")
28603 (symbol_ref "memory_address_length (operands[0], false)"))
28604 (set_attr "memory" "none")])
28606 (define_insn "prefetchi"
28607 [(unspec_volatile [(match_operand 0 "local_func_symbolic_operand" "p")
28608 (match_operand:SI 1 "const_int_operand")]
28609 UNSPECV_PREFETCHI)]
28610 "TARGET_PREFETCHI && TARGET_64BIT"
28612 static const char * const patterns[2] = {
28613 "prefetchit1\t%a0", "prefetchit0\t%a0"
28616 int locality = INTVAL (operands[1]);
28617 gcc_assert (IN_RANGE (locality, 2, 3));
28619 return patterns[locality - 2];
28621 [(set_attr "type" "sse")
28622 (set (attr "length_address")
28623 (symbol_ref "memory_address_length (operands[0], false)"))
28624 (set_attr "memory" "none")])
28626 (define_insn "sse4_2_crc32<mode>"
28627 [(set (match_operand:SI 0 "register_operand" "=r")
28629 [(match_operand:SI 1 "register_operand" "0")
28630 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
28633 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
28634 [(set_attr "type" "sselog1")
28635 (set_attr "prefix_rep" "1")
28636 (set_attr "prefix_extra" "1")
28637 (set (attr "prefix_data16")
28638 (if_then_else (match_operand:HI 2)
28640 (const_string "*")))
28641 (set (attr "prefix_rex")
28642 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
28644 (const_string "*")))
28645 (set_attr "mode" "SI")])
28647 (define_insn "sse4_2_crc32di"
28648 [(set (match_operand:DI 0 "register_operand" "=r")
28651 [(match_operand:SI 1 "register_operand" "0")
28652 (match_operand:DI 2 "nonimmediate_operand" "rm")]
28654 "TARGET_64BIT && TARGET_CRC32"
28655 "crc32{q}\t{%2, %0|%0, %2}"
28656 [(set_attr "type" "sselog1")
28657 (set_attr "prefix_rep" "1")
28658 (set_attr "prefix_extra" "1")
28659 (set_attr "mode" "DI")])
28661 (define_insn "rdpmc"
28662 [(set (match_operand:DI 0 "register_operand" "=A")
28663 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
28667 [(set_attr "type" "other")
28668 (set_attr "length" "2")])
28670 (define_insn "rdpmc_rex64"
28671 [(set (match_operand:DI 0 "register_operand" "=a")
28672 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
28674 (set (match_operand:DI 1 "register_operand" "=d")
28675 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
28678 [(set_attr "type" "other")
28679 (set_attr "length" "2")])
28681 (define_insn "rdtsc"
28682 [(set (match_operand:DI 0 "register_operand" "=A")
28683 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
28686 [(set_attr "type" "other")
28687 (set_attr "length" "2")])
28689 (define_insn "rdtsc_rex64"
28690 [(set (match_operand:DI 0 "register_operand" "=a")
28691 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
28692 (set (match_operand:DI 1 "register_operand" "=d")
28693 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
28696 [(set_attr "type" "other")
28697 (set_attr "length" "2")])
28699 (define_insn "rdtscp"
28700 [(set (match_operand:DI 0 "register_operand" "=A")
28701 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
28702 (set (match_operand:SI 1 "register_operand" "=c")
28703 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
28706 [(set_attr "type" "other")
28707 (set_attr "length" "3")])
28709 (define_insn "rdtscp_rex64"
28710 [(set (match_operand:DI 0 "register_operand" "=a")
28711 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
28712 (set (match_operand:DI 1 "register_operand" "=d")
28713 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
28714 (set (match_operand:SI 2 "register_operand" "=c")
28715 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
28718 [(set_attr "type" "other")
28719 (set_attr "length" "3")])
28721 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
28723 ;; FXSR, XSAVE and XSAVEOPT instructions
28725 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
28727 (define_insn "fxsave"
28728 [(set (match_operand:BLK 0 "memory_operand" "=m")
28729 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
28732 [(set_attr "type" "other")
28733 (set_attr "memory" "store")
28734 (set (attr "length")
28735 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
28737 (define_insn "fxsave64"
28738 [(set (match_operand:BLK 0 "memory_operand" "=jm")
28739 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
28740 "TARGET_64BIT && TARGET_FXSR"
28742 [(set_attr "type" "other")
28743 (set_attr "addr" "gpr16")
28744 (set_attr "memory" "store")
28745 (set (attr "length")
28746 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
28748 (define_insn "fxrstor"
28749 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
28753 [(set_attr "type" "other")
28754 (set_attr "memory" "load")
28755 (set (attr "length")
28756 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
28758 (define_insn "fxrstor64"
28759 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "jm")]
28760 UNSPECV_FXRSTOR64)]
28761 "TARGET_64BIT && TARGET_FXSR"
28763 [(set_attr "type" "other")
28764 (set_attr "addr" "gpr16")
28765 (set_attr "memory" "load")
28766 (set (attr "length")
28767 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
28769 (define_int_iterator ANY_XSAVE
28771 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
28772 (UNSPECV_XSAVEC "TARGET_XSAVEC")
28773 (UNSPECV_XSAVES "TARGET_XSAVES")])
28775 (define_int_iterator ANY_XSAVE64
28777 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
28778 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
28779 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
28781 (define_int_attr xsave
28782 [(UNSPECV_XSAVE "xsave")
28783 (UNSPECV_XSAVE64 "xsave64")
28784 (UNSPECV_XSAVEOPT "xsaveopt")
28785 (UNSPECV_XSAVEOPT64 "xsaveopt64")
28786 (UNSPECV_XSAVEC "xsavec")
28787 (UNSPECV_XSAVEC64 "xsavec64")
28788 (UNSPECV_XSAVES "xsaves")
28789 (UNSPECV_XSAVES64 "xsaves64")])
28791 (define_int_iterator ANY_XRSTOR
28793 (UNSPECV_XRSTORS "TARGET_XSAVES")])
28795 (define_int_iterator ANY_XRSTOR64
28797 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
28799 (define_int_attr xrstor
28800 [(UNSPECV_XRSTOR "xrstor")
28801 (UNSPECV_XRSTOR64 "xrstor")
28802 (UNSPECV_XRSTORS "xrstors")
28803 (UNSPECV_XRSTORS64 "xrstors")])
28805 (define_insn "<xsave>"
28806 [(set (match_operand:BLK 0 "memory_operand" "=m")
28807 (unspec_volatile:BLK
28808 [(match_operand:DI 1 "register_operand" "A")]
28810 "!TARGET_64BIT && TARGET_XSAVE"
28812 [(set_attr "type" "other")
28813 (set_attr "memory" "store")
28814 (set (attr "length")
28815 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
28817 (define_insn "<xsave>_rex64"
28818 [(set (match_operand:BLK 0 "memory_operand" "=jm")
28819 (unspec_volatile:BLK
28820 [(match_operand:SI 1 "register_operand" "a")
28821 (match_operand:SI 2 "register_operand" "d")]
28823 "TARGET_64BIT && TARGET_XSAVE"
28825 [(set_attr "type" "other")
28826 (set_attr "memory" "store")
28827 (set_attr "addr" "gpr16")
28828 (set (attr "length")
28829 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
28831 (define_insn "<xsave>"
28832 [(set (match_operand:BLK 0 "memory_operand" "=jm")
28833 (unspec_volatile:BLK
28834 [(match_operand:SI 1 "register_operand" "a")
28835 (match_operand:SI 2 "register_operand" "d")]
28837 "TARGET_64BIT && TARGET_XSAVE"
28839 [(set_attr "type" "other")
28840 (set_attr "memory" "store")
28841 (set_attr "addr" "gpr16")
28842 (set (attr "length")
28843 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
28845 (define_insn "<xrstor>"
28846 [(unspec_volatile:BLK
28847 [(match_operand:BLK 0 "memory_operand" "m")
28848 (match_operand:DI 1 "register_operand" "A")]
28850 "!TARGET_64BIT && TARGET_XSAVE"
28852 [(set_attr "type" "other")
28853 (set_attr "memory" "load")
28854 (set (attr "length")
28855 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
28857 (define_insn "<xrstor>_rex64"
28858 [(unspec_volatile:BLK
28859 [(match_operand:BLK 0 "memory_operand" "jm")
28860 (match_operand:SI 1 "register_operand" "a")
28861 (match_operand:SI 2 "register_operand" "d")]
28863 "TARGET_64BIT && TARGET_XSAVE"
28865 [(set_attr "type" "other")
28866 (set_attr "memory" "load")
28867 (set_attr "addr" "gpr16")
28868 (set (attr "length")
28869 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
28871 (define_insn "<xrstor>64"
28872 [(unspec_volatile:BLK
28873 [(match_operand:BLK 0 "memory_operand" "jm")
28874 (match_operand:SI 1 "register_operand" "a")
28875 (match_operand:SI 2 "register_operand" "d")]
28877 "TARGET_64BIT && TARGET_XSAVE"
28879 [(set_attr "type" "other")
28880 (set_attr "memory" "load")
28881 (set_attr "addr" "gpr16")
28882 (set (attr "length")
28883 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
28885 (define_insn "xsetbv"
28886 [(unspec_volatile:SI
28887 [(match_operand:SI 0 "register_operand" "c")
28888 (match_operand:DI 1 "register_operand" "A")]
28890 "!TARGET_64BIT && TARGET_XSAVE"
28892 [(set_attr "type" "other")])
28894 (define_insn "xsetbv_rex64"
28895 [(unspec_volatile:SI
28896 [(match_operand:SI 0 "register_operand" "c")
28897 (match_operand:SI 1 "register_operand" "a")
28898 (match_operand:SI 2 "register_operand" "d")]
28900 "TARGET_64BIT && TARGET_XSAVE"
28902 [(set_attr "type" "other")])
28904 (define_insn "xgetbv"
28905 [(set (match_operand:DI 0 "register_operand" "=A")
28906 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
28908 "!TARGET_64BIT && TARGET_XSAVE"
28910 [(set_attr "type" "other")])
28912 (define_insn "xgetbv_rex64"
28913 [(set (match_operand:DI 0 "register_operand" "=a")
28914 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
28916 (set (match_operand:DI 1 "register_operand" "=d")
28917 (unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))]
28918 "TARGET_64BIT && TARGET_XSAVE"
28920 [(set_attr "type" "other")])
28922 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
28924 ;; Floating-point instructions for atomic compound assignments
28926 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
28928 ; Clobber all floating-point registers on environment save and restore
28929 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
28930 (define_insn "fnstenv"
28931 [(set (match_operand:BLK 0 "memory_operand" "=m")
28932 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
28933 (clobber (reg:XF ST0_REG))
28934 (clobber (reg:XF ST1_REG))
28935 (clobber (reg:XF ST2_REG))
28936 (clobber (reg:XF ST3_REG))
28937 (clobber (reg:XF ST4_REG))
28938 (clobber (reg:XF ST5_REG))
28939 (clobber (reg:XF ST6_REG))
28940 (clobber (reg:XF ST7_REG))]
28943 [(set_attr "type" "other")
28944 (set_attr "memory" "store")
28945 (set (attr "length")
28946 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
28948 (define_insn "fldenv"
28949 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
28951 (clobber (reg:XF ST0_REG))
28952 (clobber (reg:XF ST1_REG))
28953 (clobber (reg:XF ST2_REG))
28954 (clobber (reg:XF ST3_REG))
28955 (clobber (reg:XF ST4_REG))
28956 (clobber (reg:XF ST5_REG))
28957 (clobber (reg:XF ST6_REG))
28958 (clobber (reg:XF ST7_REG))]
28961 [(set_attr "type" "other")
28962 (set_attr "memory" "load")
28963 (set (attr "length")
28964 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
28966 (define_insn "fnstsw"
28967 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
28968 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
28971 [(set_attr "type" "other,other")
28972 (set_attr "memory" "none,store")
28973 (set (attr "length")
28974 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
28976 (define_insn "fnclex"
28977 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
28980 [(set_attr "type" "other")
28981 (set_attr "memory" "none")
28982 (set_attr "length" "2")])
28984 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
28986 ;; LWP instructions
28988 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
28990 (define_insn "@lwp_llwpcb<mode>"
28991 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
28992 UNSPECV_LLWP_INTRINSIC)]
28995 [(set_attr "type" "lwp")
28996 (set_attr "mode" "<MODE>")
28997 (set_attr "length" "5")])
28999 (define_insn "@lwp_slwpcb<mode>"
29000 [(set (match_operand:P 0 "register_operand" "=r")
29001 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
29004 [(set_attr "type" "lwp")
29005 (set_attr "mode" "<MODE>")
29006 (set_attr "length" "5")])
29008 (define_insn "@lwp_lwpval<mode>"
29009 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
29010 (match_operand:SI 1 "nonimmediate_operand" "rm")
29011 (match_operand:SI 2 "const_int_operand")]
29012 UNSPECV_LWPVAL_INTRINSIC)]
29014 "lwpval\t{%2, %1, %0|%0, %1, %2}"
29015 [(set_attr "type" "lwp")
29016 (set_attr "mode" "<MODE>")
29017 (set (attr "length")
29018 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
29020 (define_insn "@lwp_lwpins<mode>"
29021 [(set (reg:CCC FLAGS_REG)
29022 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
29023 (match_operand:SI 1 "nonimmediate_operand" "rm")
29024 (match_operand:SI 2 "const_int_operand")]
29025 UNSPECV_LWPINS_INTRINSIC))]
29027 "lwpins\t{%2, %1, %0|%0, %1, %2}"
29028 [(set_attr "type" "lwp")
29029 (set_attr "mode" "<MODE>")
29030 (set (attr "length")
29031 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
29033 (define_int_iterator RDFSGSBASE
29037 (define_int_iterator WRFSGSBASE
29041 (define_int_attr fsgs
29042 [(UNSPECV_RDFSBASE "fs")
29043 (UNSPECV_RDGSBASE "gs")
29044 (UNSPECV_WRFSBASE "fs")
29045 (UNSPECV_WRGSBASE "gs")])
29047 (define_insn "rd<fsgs>base<mode>"
29048 [(set (match_operand:SWI48 0 "register_operand" "=r")
29049 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
29050 "TARGET_64BIT && TARGET_FSGSBASE"
29052 [(set_attr "type" "other")
29053 (set_attr "prefix_0f" "1")
29054 (set_attr "prefix_rep" "1")])
29056 (define_insn "wr<fsgs>base<mode>"
29057 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
29059 "TARGET_64BIT && TARGET_FSGSBASE"
29061 [(set_attr "type" "other")
29062 (set_attr "prefix_0f" "1")
29063 (set_attr "prefix_rep" "1")])
29065 (define_insn "ptwrite<mode>"
29066 [(unspec_volatile [(match_operand:SWI48 0 "nonimmediate_operand" "rm")]
29070 [(set_attr "type" "other")
29071 (set_attr "prefix_0f" "1")
29072 (set_attr "prefix_rep" "1")])
29074 (define_insn "@rdrand<mode>"
29075 [(set (match_operand:SWI248 0 "register_operand" "=r")
29076 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
29077 (set (reg:CCC FLAGS_REG)
29078 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
29081 [(set_attr "type" "other")
29082 (set_attr "prefix_0f" "1")])
29084 (define_insn "@rdseed<mode>"
29085 [(set (match_operand:SWI248 0 "register_operand" "=r")
29086 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
29087 (set (reg:CCC FLAGS_REG)
29088 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
29091 [(set_attr "type" "other")
29092 (set_attr "prefix_0f" "1")])
29094 (define_expand "pause"
29095 [(set (match_dup 0)
29096 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
29099 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
29100 MEM_VOLATILE_P (operands[0]) = 1;
29103 ;; Use "rep; nop", instead of "pause", to support older assemblers.
29104 ;; They have the same encoding.
29105 (define_insn "*pause"
29106 [(set (match_operand:BLK 0)
29107 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
29110 [(set_attr "length" "2")
29111 (set_attr "memory" "unknown")])
29113 ;; CET instructions
29114 (define_insn "@rdssp<mode>"
29115 [(set (match_operand:SWI48 0 "register_operand" "=r")
29116 (unspec_volatile:SWI48 [(match_operand:SWI48 1 "register_operand" "0")]
29117 UNSPECV_NOP_RDSSP))]
29118 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
29119 "rdssp<mskmodesuffix>\t%0"
29120 [(set_attr "length" "6")
29121 (set_attr "type" "other")])
29123 (define_insn "@incssp<mode>"
29124 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
29126 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
29127 "incssp<mskmodesuffix>\t%0"
29128 [(set_attr "length" "4")
29129 (set_attr "type" "other")])
29131 (define_insn "saveprevssp"
29132 [(unspec_volatile [(const_int 0)] UNSPECV_SAVEPREVSSP)]
29135 [(set_attr "length" "5")
29136 (set_attr "type" "other")])
29138 (define_insn "rstorssp"
29139 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")]
29143 [(set_attr "length" "5")
29144 (set_attr "type" "other")])
29146 (define_insn "@wrss<mode>"
29147 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
29148 (match_operand:SWI48 1 "memory_operand" "m")]
29151 "wrss<mskmodesuffix>\t%0, %1"
29152 [(set_attr "length" "3")
29153 (set_attr "type" "other")])
29155 (define_insn "@wruss<mode>"
29156 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
29157 (match_operand:SWI48 1 "memory_operand" "m")]
29160 "wruss<mskmodesuffix>\t%0, %1"
29161 [(set_attr "length" "4")
29162 (set_attr "type" "other")])
29164 (define_insn "setssbsy"
29165 [(unspec_volatile [(const_int 0)] UNSPECV_SETSSBSY)]
29168 [(set_attr "length" "4")
29169 (set_attr "type" "other")])
29171 (define_insn "clrssbsy"
29172 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")]
29176 [(set_attr "length" "4")
29177 (set_attr "type" "other")])
29179 (define_insn "nop_endbr"
29180 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]
29181 "(flag_cf_protection & CF_BRANCH)"
29183 return TARGET_64BIT ? "endbr64" : "endbr32";
29185 [(set_attr "length" "4")
29186 (set_attr "length_immediate" "0")
29187 (set_attr "modrm" "0")])
29190 (define_expand "xbegin"
29191 [(set (match_operand:SI 0 "register_operand")
29192 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
29195 rtx_code_label *label = gen_label_rtx ();
29197 /* xbegin is emitted as jump_insn, so reload won't be able
29198 to reload its operand. Force the value into AX hard register. */
29199 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
29200 emit_move_insn (ax_reg, constm1_rtx);
29202 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
29204 emit_label (label);
29205 LABEL_NUSES (label) = 1;
29207 emit_move_insn (operands[0], ax_reg);
29212 (define_insn "xbegin_1"
29214 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
29216 (label_ref (match_operand 1))
29218 (set (match_operand:SI 0 "register_operand" "+a")
29219 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
29222 [(set_attr "type" "other")
29223 (set_attr "length" "6")])
29225 (define_insn "xend"
29226 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
29229 [(set_attr "type" "other")
29230 (set_attr "length" "3")])
29232 (define_insn "xabort"
29233 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand")]
29237 [(set_attr "type" "other")
29238 (set_attr "length" "3")])
29240 (define_expand "xtest"
29241 [(set (match_operand:QI 0 "register_operand")
29242 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
29245 emit_insn (gen_xtest_1 ());
29247 ix86_expand_setcc (operands[0], NE,
29248 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
29252 (define_insn "xtest_1"
29253 [(set (reg:CCZ FLAGS_REG)
29254 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
29257 [(set_attr "type" "other")
29258 (set_attr "length" "3")])
29260 (define_insn "clwb"
29261 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
29265 [(set_attr "type" "sse")
29266 (set_attr "atom_sse_attr" "fence")
29267 (set_attr "memory" "unknown")])
29269 (define_insn "clflushopt"
29270 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
29271 UNSPECV_CLFLUSHOPT)]
29272 "TARGET_CLFLUSHOPT"
29274 [(set_attr "type" "sse")
29275 (set_attr "atom_sse_attr" "fence")
29276 (set_attr "memory" "unknown")])
29278 ;; MONITORX and MWAITX
29279 (define_insn "mwaitx"
29280 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
29281 (match_operand:SI 1 "register_operand" "a")
29282 (match_operand:SI 2 "register_operand" "b")]
29285 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
29286 ;; Since 32bit register operands are implicitly zero extended to 64bit,
29287 ;; we only need to set up 32bit registers.
29289 [(set_attr "length" "3")])
29291 (define_insn "@monitorx_<mode>"
29292 [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
29293 (match_operand:SI 1 "register_operand" "c")
29294 (match_operand:SI 2 "register_operand" "d")]
29297 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
29298 ;; RCX and RDX are used. Since 32bit register operands are implicitly
29299 ;; zero extended to 64bit, we only need to set up 32bit registers.
29301 [(set (attr "length")
29302 (symbol_ref ("(Pmode != word_mode) + 3")))])
29305 (define_insn "@clzero_<mode>"
29306 [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
29310 [(set_attr "length" "3")
29311 (set_attr "memory" "unknown")])
29313 ;; RDPKRU and WRPKRU
29315 (define_expand "rdpkru"
29317 [(set (match_operand:SI 0 "register_operand")
29318 (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
29319 (set (match_dup 2) (const_int 0))])]
29322 operands[1] = force_reg (SImode, const0_rtx);
29323 operands[2] = gen_reg_rtx (SImode);
29326 (define_insn "*rdpkru"
29327 [(set (match_operand:SI 0 "register_operand" "=a")
29328 (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
29330 (set (match_operand:SI 1 "register_operand" "=d")
29334 [(set_attr "type" "other")])
29336 (define_expand "wrpkru"
29337 [(unspec_volatile:SI
29338 [(match_operand:SI 0 "register_operand")
29339 (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
29342 operands[1] = force_reg (SImode, const0_rtx);
29343 operands[2] = force_reg (SImode, const0_rtx);
29346 (define_insn "*wrpkru"
29347 [(unspec_volatile:SI
29348 [(match_operand:SI 0 "register_operand" "a")
29349 (match_operand:SI 1 "register_operand" "d")
29350 (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
29353 [(set_attr "type" "other")])
29355 (define_insn "rdpid"
29356 [(set (match_operand:SI 0 "register_operand" "=r")
29357 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDPID))]
29358 "!TARGET_64BIT && TARGET_RDPID"
29360 [(set_attr "type" "other")])
29362 (define_insn "rdpid_rex64"
29363 [(set (match_operand:DI 0 "register_operand" "=r")
29364 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPID))]
29365 "TARGET_64BIT && TARGET_RDPID"
29367 [(set_attr "type" "other")])
29369 ;; Intirinsics for > i486
29371 (define_insn "wbinvd"
29372 [(unspec_volatile [(const_int 0)] UNSPECV_WBINVD)]
29375 [(set_attr "type" "other")])
29377 (define_insn "wbnoinvd"
29378 [(unspec_volatile [(const_int 0)] UNSPECV_WBNOINVD)]
29381 [(set_attr "type" "other")])
29383 ;; MOVDIRI and MOVDIR64B
29385 (define_insn "movdiri<mode>"
29386 [(set (match_operand:SWI48 0 "memory_operand" "=m")
29387 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")]
29390 "movdiri\t{%1, %0|%0, %1}"
29391 [(set_attr "type" "other")])
29393 (define_insn "@movdir64b_<mode>"
29394 [(set (mem:XI (match_operand:P 0 "register_operand" "r"))
29395 (unspec:XI [(match_operand:XI 1 "memory_operand" "m")]
29396 UNSPEC_MOVDIR64B))]
29398 "movdir64b\t{%1, %0|%0, %1}"
29399 [(set_attr "type" "other")])
29402 (define_int_iterator TSXLDTRK [UNSPECV_XSUSLDTRK UNSPECV_XRESLDTRK])
29403 (define_int_attr tsxldtrk [(UNSPECV_XSUSLDTRK "xsusldtrk")
29404 (UNSPECV_XRESLDTRK "xresldtrk")])
29405 (define_insn "<tsxldtrk>"
29406 [(unspec_volatile [(const_int 0)] TSXLDTRK)]
29409 [(set_attr "type" "other")
29410 (set_attr "length" "4")])
29412 ;; ENQCMD and ENQCMDS
29414 (define_int_iterator ENQCMD [UNSPECV_ENQCMD UNSPECV_ENQCMDS])
29415 (define_int_attr enqcmd_sfx [(UNSPECV_ENQCMD "") (UNSPECV_ENQCMDS "s")])
29417 (define_insn "@enqcmd<enqcmd_sfx>_<mode>"
29418 [(set (reg:CCZ FLAGS_REG)
29419 (unspec_volatile:CCZ [(match_operand:P 0 "register_operand" "r")
29420 (match_operand:XI 1 "memory_operand" "m")]
29423 "enqcmd<enqcmd_sfx>\t{%1, %0|%0, %1}"
29424 [(set_attr "type" "other")])
29427 (define_int_iterator UINTR [UNSPECV_CLUI UNSPECV_STUI])
29428 (define_int_attr uintr [(UNSPECV_CLUI "clui") (UNSPECV_STUI "stui")])
29430 (define_insn "<uintr>"
29431 [(unspec_volatile [(const_int 0)] UINTR)]
29432 "TARGET_UINTR && TARGET_64BIT"
29434 [(set_attr "type" "other")
29435 (set_attr "length" "4")])
29437 (define_insn "testui"
29438 [(set (reg:CCC FLAGS_REG)
29439 (unspec_volatile:CCC [(const_int 0)] UNSPECV_TESTUI))]
29440 "TARGET_UINTR && TARGET_64BIT"
29442 [(set_attr "type" "other")
29443 (set_attr "length" "4")])
29445 (define_insn "senduipi"
29447 [(match_operand:DI 0 "register_operand" "r")]
29449 "TARGET_UINTR && TARGET_64BIT"
29451 [(set_attr "type" "other")
29452 (set_attr "length" "4")])
29456 (define_insn "umwait"
29457 [(set (reg:CCC FLAGS_REG)
29458 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
29459 (match_operand:DI 1 "register_operand" "A")]
29461 "!TARGET_64BIT && TARGET_WAITPKG"
29463 [(set_attr "length" "3")])
29465 (define_insn "umwait_rex64"
29466 [(set (reg:CCC FLAGS_REG)
29467 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
29468 (match_operand:SI 1 "register_operand" "a")
29469 (match_operand:SI 2 "register_operand" "d")]
29471 "TARGET_64BIT && TARGET_WAITPKG"
29473 [(set_attr "length" "3")])
29475 (define_insn "@umonitor_<mode>"
29476 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
29480 [(set (attr "length")
29481 (symbol_ref ("(Pmode != word_mode) + 3")))])
29483 (define_insn "tpause"
29484 [(set (reg:CCC FLAGS_REG)
29485 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
29486 (match_operand:DI 1 "register_operand" "A")]
29488 "!TARGET_64BIT && TARGET_WAITPKG"
29490 [(set_attr "length" "3")])
29492 (define_insn "tpause_rex64"
29493 [(set (reg:CCC FLAGS_REG)
29494 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
29495 (match_operand:SI 1 "register_operand" "a")
29496 (match_operand:SI 2 "register_operand" "d")]
29498 "TARGET_64BIT && TARGET_WAITPKG"
29500 [(set_attr "length" "3")])
29502 (define_insn "cldemote"
29503 [(unspec_volatile[(match_operand 0 "address_operand" "p")]
29507 [(set_attr "type" "other")
29508 (set_attr "memory" "unknown")])
29510 (define_insn "speculation_barrier"
29511 [(unspec_volatile [(const_int 0)] UNSPECV_SPECULATION_BARRIER)]
29514 [(set_attr "type" "other")
29515 (set_attr "length" "3")])
29517 (define_insn "serialize"
29518 [(unspec_volatile [(const_int 0)] UNSPECV_SERIALIZE)]
29521 [(set_attr "type" "other")
29522 (set_attr "length" "3")])
29524 (define_insn "patchable_area"
29525 [(unspec_volatile [(match_operand 0 "const_int_operand")
29526 (match_operand 1 "const_int_operand")]
29527 UNSPECV_PATCHABLE_AREA)]
29530 ix86_output_patchable_area (INTVAL (operands[0]),
29531 INTVAL (operands[1]) != 0);
29534 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
29535 (set_attr "length_immediate" "0")
29536 (set_attr "modrm" "0")])
29538 (define_insn "hreset"
29539 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")]
29543 [(set_attr "type" "other")
29544 (set_attr "length" "4")])
29546 ;; Spaceship optimization
29547 (define_expand "spaceship<mode>4"
29548 [(match_operand:SI 0 "register_operand")
29549 (match_operand:MODEF 1 "cmp_fp_expander_operand")
29550 (match_operand:MODEF 2 "cmp_fp_expander_operand")
29551 (match_operand:SI 3 "const_int_operand")]
29552 "(TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
29553 && (TARGET_CMOVE || (TARGET_SAHF && TARGET_USE_SAHF))"
29555 ix86_expand_fp_spaceship (operands[0], operands[1], operands[2],
29560 (define_expand "spaceshipxf4"
29561 [(match_operand:SI 0 "register_operand")
29562 (match_operand:XF 1 "nonmemory_operand")
29563 (match_operand:XF 2 "nonmemory_operand")
29564 (match_operand:SI 3 "const_int_operand")]
29565 "TARGET_80387 && (TARGET_CMOVE || (TARGET_SAHF && TARGET_USE_SAHF))"
29567 ix86_expand_fp_spaceship (operands[0], operands[1], operands[2],
29572 (define_expand "spaceship<mode>4"
29573 [(match_operand:SI 0 "register_operand")
29574 (match_operand:SWI 1 "nonimmediate_operand")
29575 (match_operand:SWI 2 "<general_operand>")
29576 (match_operand:SI 3 "const_int_operand")]
29579 ix86_expand_int_spaceship (operands[0], operands[1], operands[2],
29584 ;; Defined because the generic expand_builtin_issignaling for XFmode
29585 ;; only tests for sNaNs, but i387 treats also pseudo numbers as always
29587 (define_expand "issignalingxf2"
29588 [(match_operand:SI 0 "register_operand")
29589 (match_operand:XF 1 "general_operand")]
29592 rtx temp = operands[1];
29595 rtx mem = assign_stack_temp (XFmode, GET_MODE_SIZE (XFmode));
29596 emit_move_insn (mem, temp);
29599 rtx ex = adjust_address (temp, HImode, 8);
29600 rtx hi = adjust_address (temp, SImode, 4);
29601 rtx lo = adjust_address (temp, SImode, 0);
29602 rtx val = GEN_INT (HOST_WIDE_INT_M1U << 30);
29603 rtx mask = GEN_INT (0x7fff);
29604 rtx bit = GEN_INT (HOST_WIDE_INT_1U << 30);
29606 ((ex & mask) && (int) hi >= 0)
29607 || ((ex & mask) == mask && ((hi ^ bit) | ((lo | -lo) >> 31)) > val). */
29608 rtx nlo = expand_unop (SImode, neg_optab, lo, NULL_RTX, 0);
29609 lo = expand_binop (SImode, ior_optab, lo, nlo,
29610 NULL_RTX, 1, OPTAB_LIB_WIDEN);
29611 lo = expand_shift (RSHIFT_EXPR, SImode, lo, 31, NULL_RTX, 1);
29612 temp = expand_binop (SImode, xor_optab, hi, bit,
29613 NULL_RTX, 1, OPTAB_LIB_WIDEN);
29614 temp = expand_binop (SImode, ior_optab, temp, lo,
29615 NULL_RTX, 1, OPTAB_LIB_WIDEN);
29616 temp = emit_store_flag_force (gen_reg_rtx (SImode), GTU, temp, val,
29618 ex = expand_binop (HImode, and_optab, ex, mask,
29619 NULL_RTX, 1, OPTAB_LIB_WIDEN);
29620 rtx temp2 = emit_store_flag_force (gen_reg_rtx (SImode), NE,
29621 ex, const0_rtx, SImode, 1, 1);
29622 ex = emit_store_flag_force (gen_reg_rtx (SImode), EQ,
29623 ex, mask, HImode, 1, 1);
29624 temp = expand_binop (SImode, and_optab, temp, ex,
29625 NULL_RTX, 1, OPTAB_LIB_WIDEN);
29626 rtx temp3 = emit_store_flag_force (gen_reg_rtx (SImode), GE,
29627 hi, const0_rtx, SImode, 0, 1);
29628 temp2 = expand_binop (SImode, and_optab, temp2, temp3,
29629 NULL_RTX, 1, OPTAB_LIB_WIDEN);
29630 temp = expand_binop (SImode, ior_optab, temp, temp2,
29631 NULL_RTX, 1, OPTAB_LIB_WIDEN);
29632 emit_move_insn (operands[0], temp);
29636 (define_insn "urdmsr"
29637 [(set (match_operand:DI 0 "register_operand" "=r")
29638 (unspec_volatile:DI
29639 [(match_operand:DI 1 "x86_64_szext_nonmemory_operand" "reZ")]
29641 "TARGET_USER_MSR && TARGET_64BIT"
29642 "urdmsr\t{%1, %0|%0, %1}"
29643 [(set_attr "prefix" "vex")
29644 (set_attr "type" "other")])
29646 (define_insn "uwrmsr"
29648 [(match_operand:DI 0 "x86_64_szext_nonmemory_operand" "reZ")
29649 (match_operand:DI 1 "register_operand" "r")]
29651 "TARGET_USER_MSR && TARGET_64BIT"
29652 "uwrmsr\t{%1, %0|%0, %1}"
29653 [(set_attr "prefix" "vex")
29654 (set_attr "type" "other")])
29656 (define_insn "ldtilecfg"
29657 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
29658 UNSPECV_LDTILECFG)]
29661 [(set_attr "type" "other")
29662 (set_attr "prefix" "maybe_evex")
29663 (set_attr "memory" "load")])
29665 (define_insn "sttilecfg"
29666 [(set (match_operand:BLK 0 "memory_operand" "=m")
29667 (unspec_volatile:BLK [(const_int 0)] UNSPECV_STTILECFG))]
29670 [(set_attr "type" "other")
29671 (set_attr "prefix" "maybe_evex")
29672 (set_attr "memory" "store")])
29676 (include "sync.md")