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
121 ;; For SSE/MMX support:
134 ;; Different from generic us_truncate RTX
135 ;; as it does unsigned saturation of signed source.
138 ;; For AVX/AVX512F support
143 ;; Generic math support
144 UNSPEC_IEEE_MIN ; not commutative
145 UNSPEC_IEEE_MAX ; not commutative
147 ;; x87 Floating point
160 UNSPEC_FRNDINT_ROUNDEVEN
167 ;; x87 Double output FP
192 ;; For LZCNT suppoprt
204 UNSPEC_INTERRUPT_RETURN
206 ;; For MOVDIRI and MOVDIR64B support
210 ;; For insn_callee_abi:
213 ;; For APX PUSH2/POP2 support
218 ;; For APX PPX support
222 (define_c_enum "unspecv" [
226 UNSPECV_PROBE_STACK_RANGE
229 UNSPECV_SPLIT_STACK_RETURN
235 UNSPECV_LLWP_INTRINSIC
236 UNSPECV_SLWP_INTRINSIC
237 UNSPECV_LWPVAL_INTRINSIC
238 UNSPECV_LWPINS_INTRINSIC
264 ;; For atomic compound assignments.
270 ;; For RDRAND support
273 ;; For RDSEED support
287 ;; For CLFLUSHOPT support
290 ;; For MONITORX and MWAITX support
294 ;; For CLZERO support
297 ;; For RDPKRU and WRPKRU support
314 ;; For TSXLDTRK support
318 ;; For WAITPKG support
329 ;; For CLDEMOTE support
332 ;; For Speculation Barrier support
333 UNSPECV_SPECULATION_BARRIER
337 ;; For ENQCMD and ENQCMDS support
341 ;; For SERIALIZE support
344 ;; For patchable area support
345 UNSPECV_PATCHABLE_AREA
347 ;; For HRESET support
350 ;; For PREFETCHI support
353 ;; For USER_MSR support
362 ;; Constants to represent rounding modes in the ROUND instruction
364 [(ROUND_ROUNDEVEN 0x0)
372 ;; Constants to represent AVX512F embeded rounding
374 [(ROUND_NEAREST_INT 0)
382 ;; Constants to represent pcomtrue/pcomfalse variants
392 ;; Constants used in the XOP pperm instruction
394 [(PPERM_SRC 0x00) /* copy source */
395 (PPERM_INVERT 0x20) /* invert source */
396 (PPERM_REVERSE 0x40) /* bit reverse source */
397 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
398 (PPERM_ZERO 0x80) /* all 0's */
399 (PPERM_ONES 0xa0) /* all 1's */
400 (PPERM_SIGN 0xc0) /* propagate sign bit */
401 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
402 (PPERM_SRC1 0x00) /* use first source byte */
403 (PPERM_SRC2 0x10) /* use second source byte */
406 ;; Registers by name.
500 (FIRST_PSEUDO_REG 92)
503 ;; Insn callee abi index.
509 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
512 ;; In C guard expressions, put expressions which may be compile-time
513 ;; constants first. This allows for better optimization. For
514 ;; example, write "TARGET_64BIT && reload_completed", not
515 ;; "reload_completed && TARGET_64BIT".
519 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
520 atom,slm,glm,haswell,generic,lujiazui,yongfeng,amdfam10,bdver1,
521 bdver2,bdver3,bdver4,btver2,znver1,znver2,znver3,znver4,
523 (const (symbol_ref "ix86_schedule")))
525 ;; A basic instruction type. Refinements due to arguments to be
526 ;; provided in other attributes.
529 alu,alu1,negnot,imov,imovx,lea,
530 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
531 imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
532 push,pop,call,callv,leave,
534 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
535 fxch,fistp,fisttp,frndint,
536 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
537 ssemul,sseimul,ssediv,sselog,sselog1,
538 sseishft,sseishft1,ssecmp,ssecomi,
539 ssecvt,ssecvt1,sseicvt,sseins,
540 sseshuf,sseshuf1,ssemuladd,sse4arg,
542 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
543 (const_string "other"))
545 ;; Main data type used by the insn
547 "unknown,none,QI,HI,SI,DI,TI,OI,XI,HF,BF,SF,DF,XF,TF,
548 V32HF,V16HF,V8HF,V4HF,V2HF,V32BF,V16BF,V8BF,V4BF,V2BF,
549 V16SF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF,V8DF"
550 (const_string "unknown"))
552 ;; The CPU unit operations uses.
553 (define_attr "unit" "integer,i387,sse,mmx,unknown"
554 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
555 fxch,fistp,fisttp,frndint")
556 (const_string "i387")
557 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
558 ssemul,sseimul,ssediv,sselog,sselog1,
559 sseishft,sseishft1,ssecmp,ssecomi,
560 ssecvt,ssecvt1,sseicvt,sseins,
561 sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
563 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
565 (eq_attr "type" "other")
566 (const_string "unknown")]
567 (const_string "integer")))
569 ;; Used to control the "enabled" attribute on a per-instruction basis.
570 (define_attr "isa" "base,x64,nox64,x64_sse2,x64_sse4,x64_sse4_noavx,
571 x64_avx,x64_avx512bw,x64_avx512dq,apx_ndd,apx_ndd_64,
572 sse_noavx,sse2,sse2_noavx,sse3,sse3_noavx,sse4,sse4_noavx,
573 avx,noavx,avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,avx512f_512,
574 noavx512f,avx512bw,avx512bw_512,noavx512bw,avx512dq,
575 noavx512dq,fma_or_avx512vl,avx512vl,noavx512vl,avxvnni,
576 avx512vnnivl,avx512fp16,avxifma,avx512ifmavl,avxneconvert,
577 avx512bf16vl,vpclmulqdqvl,avx_noavx512f,avx_noavx512vl,
579 (const_string "base"))
581 ;; The (bounding maximum) length of an instruction immediate.
582 (define_attr "length_immediate" ""
583 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
584 bitmanip,imulx,msklog,mskmov")
586 (ior (eq_attr "type" "sse4arg")
587 (eq_attr "isa" "fma4"))
589 (eq_attr "unit" "i387,sse,mmx")
591 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
592 rotate,rotatex,rotate1,imul,icmp,push,pop")
593 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
594 (eq_attr "type" "imov,test")
595 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
596 (eq_attr "type" "call")
597 (if_then_else (match_operand 0 "constant_call_address_operand")
600 (eq_attr "type" "callv")
601 (if_then_else (match_operand 1 "constant_call_address_operand")
604 ;; We don't know the size before shorten_branches. Expect
605 ;; the instruction to fit for better scheduling.
606 (eq_attr "type" "ibr")
609 (symbol_ref "/* Update immediate_length and other attributes! */
610 gcc_unreachable (),1")))
612 ;; The (bounding maximum) length of an instruction address.
613 (define_attr "length_address" ""
614 (cond [(eq_attr "type" "str,other,multi,fxch")
616 (and (eq_attr "type" "call")
617 (match_operand 0 "constant_call_address_operand"))
619 (and (eq_attr "type" "callv")
620 (match_operand 1 "constant_call_address_operand"))
623 (symbol_ref "ix86_attr_length_address_default (insn)")))
625 ;; Set when length prefix is used.
626 (define_attr "prefix_data16" ""
627 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
629 (eq_attr "mode" "HI")
631 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
636 ;; Set when string REP prefix is used.
637 (define_attr "prefix_rep" ""
638 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
640 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
645 ;; Set when 0f opcode prefix is used.
646 (define_attr "prefix_0f" ""
648 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov")
649 (eq_attr "unit" "sse,mmx"))
653 ;; Set when REX opcode prefix is used.
654 (define_attr "prefix_rex" ""
655 (cond [(not (match_test "TARGET_64BIT"))
657 (and (eq_attr "mode" "DI")
658 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
659 (eq_attr "unit" "!mmx")))
661 (and (eq_attr "mode" "QI")
662 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
664 (match_test "x86_extended_reg_mentioned_p (insn)")
666 (and (eq_attr "type" "imovx")
667 (match_operand:QI 1 "ext_QIreg_operand"))
672 ;; There are also additional prefixes in 3DNOW, SSSE3.
673 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
674 ;; While generally inapplicable to VEX/XOP/EVEX encodings, "length_vex" uses
675 ;; the attribute evaluating to zero to know that VEX2 encoding may be usable.
676 (define_attr "prefix_extra" ""
677 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
682 ;; Prefix used: original, VEX or maybe VEX.
683 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
684 (cond [(eq_attr "mode" "OI,V8SF,V4DF")
686 (eq_attr "mode" "XI,V16SF,V8DF")
687 (const_string "evex")
688 (eq_attr "type" "ssemuladd")
689 (if_then_else (eq_attr "isa" "fma4")
691 (const_string "maybe_evex"))
692 (eq_attr "type" "sse4arg")
695 (const_string "orig")))
697 ;; VEX W bit is used.
698 (define_attr "prefix_vex_w" "" (const_int 0))
700 ;; The length of VEX prefix
701 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
702 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
703 ;; still prefix_0f 1, with prefix_extra 1.
704 (define_attr "length_vex" ""
705 (if_then_else (and (eq_attr "prefix_0f" "1")
706 (eq_attr "prefix_extra" "0"))
707 (if_then_else (eq_attr "prefix_vex_w" "1")
708 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
709 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
710 (if_then_else (eq_attr "prefix_vex_w" "1")
711 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
712 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
714 ;; 4-bytes evex prefix and 1 byte opcode.
715 (define_attr "length_evex" "" (const_int 5))
717 ;; Set when modrm byte is used.
718 (define_attr "modrm" ""
719 (cond [(eq_attr "type" "str,leave")
721 (eq_attr "unit" "i387")
723 (and (eq_attr "type" "incdec")
724 (and (not (match_test "TARGET_64BIT"))
725 (ior (match_operand:SI 1 "register_operand")
726 (match_operand:HI 1 "register_operand"))))
728 (and (eq_attr "type" "push")
729 (not (match_operand 1 "memory_operand")))
731 (and (eq_attr "type" "pop")
732 (not (match_operand 0 "memory_operand")))
734 (and (eq_attr "type" "imov")
735 (and (not (eq_attr "mode" "DI"))
736 (ior (and (match_operand 0 "register_operand")
737 (match_operand 1 "immediate_operand"))
738 (ior (and (match_operand 0 "ax_reg_operand")
739 (match_operand 1 "memory_displacement_only_operand"))
740 (and (match_operand 0 "memory_displacement_only_operand")
741 (match_operand 1 "ax_reg_operand"))))))
743 (and (eq_attr "type" "call")
744 (match_operand 0 "constant_call_address_operand"))
746 (and (eq_attr "type" "callv")
747 (match_operand 1 "constant_call_address_operand"))
749 (and (eq_attr "type" "alu,alu1,icmp,test")
750 (match_operand 0 "ax_reg_operand"))
751 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
755 ;; The (bounding maximum) length of an instruction in bytes.
756 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
757 ;; Later we may want to split them and compute proper length as for
759 (define_attr "length" ""
760 (cond [(eq_attr "type" "other,multi,fistp,frndint")
762 (eq_attr "type" "fcmp")
764 (eq_attr "unit" "i387")
766 (plus (attr "prefix_data16")
767 (attr "length_address")))
768 (ior (eq_attr "prefix" "evex")
769 (and (ior (eq_attr "prefix" "maybe_evex")
770 (eq_attr "prefix" "maybe_vex"))
771 (match_test "TARGET_AVX512F")))
772 (plus (attr "length_evex")
773 (plus (attr "length_immediate")
775 (attr "length_address"))))
776 (ior (eq_attr "prefix" "vex")
777 (and (ior (eq_attr "prefix" "maybe_vex")
778 (eq_attr "prefix" "maybe_evex"))
779 (match_test "TARGET_AVX")))
780 (plus (attr "length_vex")
781 (plus (attr "length_immediate")
783 (attr "length_address"))))]
784 (plus (plus (attr "modrm")
785 (plus (attr "prefix_0f")
786 (plus (attr "prefix_rex")
787 (plus (attr "prefix_extra")
789 (plus (attr "prefix_rep")
790 (plus (attr "prefix_data16")
791 (plus (attr "length_immediate")
792 (attr "length_address")))))))
794 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
795 ;; `store' if there is a simple memory reference therein, or `unknown'
796 ;; if the instruction is complex.
798 (define_attr "memory" "none,load,store,both,unknown"
799 (cond [(eq_attr "type" "other,multi,str,lwp")
800 (const_string "unknown")
801 (eq_attr "type" "lea,fcmov,fpspc")
802 (const_string "none")
803 (eq_attr "type" "fistp,leave")
804 (const_string "both")
805 (eq_attr "type" "frndint")
806 (const_string "load")
807 (eq_attr "type" "push")
808 (if_then_else (match_operand 1 "memory_operand")
809 (const_string "both")
810 (const_string "store"))
811 (eq_attr "type" "pop")
812 (if_then_else (match_operand 0 "memory_operand")
813 (const_string "both")
814 (const_string "load"))
815 (eq_attr "type" "setcc")
816 (if_then_else (match_operand 0 "memory_operand")
817 (const_string "store")
818 (const_string "none"))
819 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
820 (if_then_else (ior (match_operand 0 "memory_operand")
821 (match_operand 1 "memory_operand"))
822 (const_string "load")
823 (const_string "none"))
824 (eq_attr "type" "ibr")
825 (if_then_else (match_operand 0 "memory_operand")
826 (const_string "load")
827 (const_string "none"))
828 (eq_attr "type" "call")
829 (if_then_else (match_operand 0 "constant_call_address_operand")
830 (const_string "none")
831 (const_string "load"))
832 (eq_attr "type" "callv")
833 (if_then_else (match_operand 1 "constant_call_address_operand")
834 (const_string "none")
835 (const_string "load"))
836 (and (eq_attr "type" "alu1,negnot,ishift1,rotate1,sselog1,sseshuf1")
837 (match_operand 1 "memory_operand"))
838 (const_string "both")
839 (and (match_operand 0 "memory_operand")
840 (match_operand 1 "memory_operand"))
841 (const_string "both")
842 (match_operand 0 "memory_operand")
843 (const_string "store")
844 (match_operand 1 "memory_operand")
845 (const_string "load")
847 "!alu1,negnot,ishift1,rotate1,
848 imov,imovx,icmp,test,bitmanip,
850 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
851 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
852 mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog")
853 (match_operand 2 "memory_operand"))
854 (const_string "load")
855 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
856 (match_operand 3 "memory_operand"))
857 (const_string "load")
859 (const_string "none")))
861 ;; Indicates if an instruction has both an immediate and a displacement.
863 (define_attr "imm_disp" "false,true,unknown"
864 (cond [(eq_attr "type" "other,multi")
865 (const_string "unknown")
866 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
867 (and (match_operand 0 "memory_displacement_operand")
868 (match_operand 1 "immediate_operand")))
869 (const_string "true")
870 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
871 (and (match_operand 0 "memory_displacement_operand")
872 (match_operand 2 "immediate_operand")))
873 (const_string "true")
875 (const_string "false")))
877 ;; Indicates if an FP operation has an integer source.
879 (define_attr "fp_int_src" "false,true"
880 (const_string "false"))
882 ;; Defines rounding mode of an FP operation.
884 (define_attr "i387_cw" "roundeven,floor,ceil,trunc,uninitialized,any"
885 (const_string "any"))
887 ;; Define attribute to indicate AVX insns with partial XMM register update.
888 (define_attr "avx_partial_xmm_update" "false,true"
889 (const_string "false"))
891 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
892 (define_attr "use_carry" "0,1" (const_string "0"))
894 ;; Define attribute to indicate unaligned ssemov insns
895 (define_attr "movu" "0,1" (const_string "0"))
897 ;; Define attribute to limit memory address register set.
898 (define_attr "addr" "gpr8,gpr16,gpr32" (const_string "gpr32"))
900 ;; Define instruction set of MMX instructions
901 (define_attr "mmx_isa" "base,native,sse,sse_noavx,avx"
902 (const_string "base"))
904 (define_attr "enabled" ""
905 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
906 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
907 (eq_attr "isa" "x64_sse2")
908 (symbol_ref "TARGET_64BIT && TARGET_SSE2")
909 (eq_attr "isa" "x64_sse4")
910 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
911 (eq_attr "isa" "x64_sse4_noavx")
912 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
913 (eq_attr "isa" "x64_avx")
914 (symbol_ref "TARGET_64BIT && TARGET_AVX")
915 (eq_attr "isa" "x64_avx512bw")
916 (symbol_ref "TARGET_64BIT && TARGET_AVX512BW")
917 (eq_attr "isa" "x64_avx512dq")
918 (symbol_ref "TARGET_64BIT && TARGET_AVX512DQ")
919 (eq_attr "isa" "sse_noavx")
920 (symbol_ref "TARGET_SSE && !TARGET_AVX")
921 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
922 (eq_attr "isa" "sse2_noavx")
923 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
924 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
925 (eq_attr "isa" "sse3_noavx")
926 (symbol_ref "TARGET_SSE3 && !TARGET_AVX")
927 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
928 (eq_attr "isa" "sse4_noavx")
929 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
930 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
931 (eq_attr "isa" "avx_noavx512f")
932 (symbol_ref "TARGET_AVX && !TARGET_AVX512F")
933 (eq_attr "isa" "avx_noavx512vl")
934 (symbol_ref "TARGET_AVX && !TARGET_AVX512VL")
935 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
936 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
937 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
938 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
939 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
940 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
941 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
942 (eq_attr "isa" "fma_or_avx512vl")
943 (symbol_ref "TARGET_FMA || TARGET_AVX512VL")
944 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
945 (eq_attr "isa" "avx512f_512")
946 (symbol_ref "TARGET_AVX512F && TARGET_EVEX512")
947 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
948 (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
949 (eq_attr "isa" "avx512bw_512")
950 (symbol_ref "TARGET_AVX512BW && TARGET_EVEX512")
951 (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
952 (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
953 (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
954 (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
955 (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
956 (eq_attr "isa" "avxvnni") (symbol_ref "TARGET_AVXVNNI")
957 (eq_attr "isa" "avx512vnnivl")
958 (symbol_ref "TARGET_AVX512VNNI && TARGET_AVX512VL")
959 (eq_attr "isa" "avx512fp16")
960 (symbol_ref "TARGET_AVX512FP16")
961 (eq_attr "isa" "avxifma") (symbol_ref "TARGET_AVXIFMA")
962 (eq_attr "isa" "avx512ifmavl")
963 (symbol_ref "TARGET_AVX512IFMA && TARGET_AVX512VL")
964 (eq_attr "isa" "avxneconvert") (symbol_ref "TARGET_AVXNECONVERT")
965 (eq_attr "isa" "avx512bf16vl")
966 (symbol_ref "TARGET_AVX512BF16 && TARGET_AVX512VL")
967 (eq_attr "isa" "vpclmulqdqvl")
968 (symbol_ref "TARGET_VPCLMULQDQ && TARGET_AVX512VL")
969 (eq_attr "isa" "apx_ndd")
970 (symbol_ref "TARGET_APX_NDD")
971 (eq_attr "isa" "apx_ndd_64")
972 (symbol_ref "TARGET_APX_NDD && Pmode == DImode")
973 (eq_attr "isa" "vaes_avx512vl")
974 (symbol_ref "TARGET_VAES && TARGET_AVX512VL")
976 (eq_attr "mmx_isa" "native")
977 (symbol_ref "!TARGET_MMX_WITH_SSE")
978 (eq_attr "mmx_isa" "sse")
979 (symbol_ref "TARGET_MMX_WITH_SSE")
980 (eq_attr "mmx_isa" "sse_noavx")
981 (symbol_ref "TARGET_MMX_WITH_SSE && !TARGET_AVX")
982 (eq_attr "mmx_isa" "avx")
983 (symbol_ref "TARGET_MMX_WITH_SSE && TARGET_AVX")
987 (define_attr "preferred_for_size" "" (const_int 1))
988 (define_attr "preferred_for_speed" "" (const_int 1))
990 ;; Describe a user's asm statement.
991 (define_asm_attributes
992 [(set_attr "length" "128")
993 (set_attr "type" "multi")])
995 (define_code_iterator plusminus [plus minus])
996 (define_code_iterator plusminusmult [plus minus mult])
997 (define_code_iterator plusminusmultdiv [plus minus mult div])
999 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
1001 ;; Base name for insn mnemonic.
1002 (define_code_attr plusminus_mnemonic
1003 [(plus "add") (ss_plus "adds") (us_plus "addus")
1004 (minus "sub") (ss_minus "subs") (us_minus "subus")])
1006 (define_code_iterator multdiv [mult div])
1008 (define_code_attr multdiv_mnemonic
1009 [(mult "mul") (div "div")])
1011 ;; Mark commutative operators as such in constraints.
1012 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
1013 (minus "") (ss_minus "") (us_minus "")
1014 (mult "%") (div "")])
1016 ;; Mapping of max and min
1017 (define_code_iterator maxmin [smax smin umax umin])
1019 ;; Mapping of signed max and min
1020 (define_code_iterator smaxmin [smax smin])
1022 ;; Mapping of unsigned max and min
1023 (define_code_iterator umaxmin [umax umin])
1025 ;; Base name for integer and FP insn mnemonic
1026 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
1027 (umax "maxu") (umin "minu")])
1028 (define_code_attr maxmin_float [(smax "max") (smin "min")])
1030 (define_int_iterator IEEE_MAXMIN
1034 (define_int_attr ieee_maxmin
1035 [(UNSPEC_IEEE_MAX "max")
1036 (UNSPEC_IEEE_MIN "min")])
1038 ;; Mapping of logic operators
1039 (define_code_iterator any_logic [and ior xor])
1040 (define_code_iterator any_or [ior xor])
1041 (define_code_iterator fpint_logic [and xor])
1043 ;; Base name for insn mnemonic.
1044 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
1046 ;; Mapping of logic-shift operators
1047 (define_code_iterator any_lshift [ashift lshiftrt])
1049 ;; Mapping of shift-right operators
1050 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
1052 ;; Mapping of all shift operators
1053 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
1055 ;; Base name for insn mnemonic.
1056 (define_code_attr shift [(ashift "sal") (lshiftrt "shr") (ashiftrt "sar")])
1057 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
1059 ;; Mapping of rotate operators
1060 (define_code_iterator any_rotate [rotate rotatert])
1062 ;; Base name for insn mnemonic.
1063 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
1065 ;; Mapping of abs neg operators
1066 (define_code_iterator absneg [abs neg])
1068 ;; Mapping of abs neg operators to logic operation
1069 (define_code_attr absneg_op [(abs "and") (neg "xor")])
1071 ;; Base name for x87 insn mnemonic.
1072 (define_code_attr absneg_mnemonic [(abs "fabs") (neg "fchs")])
1074 ;; Mapping of extend operators
1075 (define_code_iterator any_extend [sign_extend zero_extend])
1077 ;; Mapping of highpart multiply operators
1078 (define_code_iterator any_mul_highpart [smul_highpart umul_highpart])
1080 ;; Prefix for insn menmonic.
1081 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
1082 (smul_highpart "i") (umul_highpart "")
1083 (div "i") (udiv "")])
1084 ;; Prefix for define_insn
1085 (define_code_attr s [(sign_extend "s") (zero_extend "u")
1086 (smul_highpart "s") (umul_highpart "u")])
1087 (define_code_attr u [(sign_extend "") (zero_extend "u")
1088 (div "") (udiv "u")])
1089 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")
1090 (div "false") (udiv "true")])
1092 ;; Used in signed and unsigned truncations.
1093 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
1094 ;; Instruction suffix for truncations.
1095 (define_code_attr trunsuffix
1096 [(ss_truncate "s") (truncate "") (us_truncate "us")])
1098 ;; Instruction suffix for SSE sign and zero extensions.
1099 (define_code_attr extsuffix [(sign_extend "sx") (zero_extend "zx")])
1101 ;; Used in signed and unsigned fix.
1102 (define_code_iterator any_fix [fix unsigned_fix])
1103 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
1104 (define_code_attr fixunssuffix [(fix "") (unsigned_fix "uns")])
1105 (define_code_attr fixprefix [(fix "s") (unsigned_fix "u")])
1107 ;; Used in signed and unsigned float.
1108 (define_code_iterator any_float [float unsigned_float])
1109 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
1110 (define_code_attr floatunssuffix [(float "") (unsigned_float "uns")])
1111 (define_code_attr floatprefix [(float "s") (unsigned_float "u")])
1113 ;; Base name for expression
1114 (define_code_attr insn
1115 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
1116 (minus "sub") (ss_minus "sssub") (us_minus "ussub")
1117 (sign_extend "extend") (zero_extend "zero_extend")
1118 (ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")
1119 (rotate "rotl") (rotatert "rotr")
1120 (mult "mul") (div "div")])
1122 ;; All integer modes.
1123 (define_mode_iterator SWI1248x [QI HI SI DI])
1125 ;; All integer modes without QImode.
1126 (define_mode_iterator SWI248x [HI SI DI])
1128 ;; All integer modes without QImode and HImode.
1129 (define_mode_iterator SWI48x [SI DI])
1131 ;; All integer modes without SImode and DImode.
1132 (define_mode_iterator SWI12 [QI HI])
1134 ;; All integer modes without DImode.
1135 (define_mode_iterator SWI124 [QI HI SI])
1137 ;; All integer modes without QImode and DImode.
1138 (define_mode_iterator SWI24 [HI SI])
1140 ;; Single word integer modes.
1141 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
1143 ;; Single word integer modes without QImode.
1144 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
1146 ;; Single word integer modes without QImode and HImode.
1147 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
1149 ;; All math-dependant single and double word integer modes.
1150 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
1151 (HI "TARGET_HIMODE_MATH")
1152 SI DI (TI "TARGET_64BIT")])
1154 ;; Math-dependant single word integer modes.
1155 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
1156 (HI "TARGET_HIMODE_MATH")
1157 SI (DI "TARGET_64BIT")])
1159 ;; Math-dependant integer modes without DImode.
1160 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
1161 (HI "TARGET_HIMODE_MATH")
1164 ;; Math-dependant integer modes with DImode.
1165 (define_mode_iterator SWIM1248x
1166 [(QI "TARGET_QIMODE_MATH")
1167 (HI "TARGET_HIMODE_MATH")
1170 ;; Math-dependant single word integer modes without QImode.
1171 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
1172 SI (DI "TARGET_64BIT")])
1174 ;; Double word integer modes.
1175 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
1176 (TI "TARGET_64BIT")])
1178 ;; SWI and DWI together.
1179 (define_mode_iterator SWIDWI [QI HI SI DI (TI "TARGET_64BIT")])
1181 ;; SWI48 and DWI together.
1182 (define_mode_iterator SWI48DWI [SI DI (TI "TARGET_64BIT")])
1184 ;; GET_MODE_SIZE for selected modes. As GET_MODE_SIZE is not
1185 ;; compile time constant, it is faster to use <MODE_SIZE> than
1186 ;; GET_MODE_SIZE (<MODE>mode). For XFmode which depends on
1187 ;; command line options just use GET_MODE_SIZE macro.
1188 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8")
1189 (TI "16") (HF "2") (BF "2") (SF "4") (DF "8")
1190 (XF "GET_MODE_SIZE (XFmode)")
1191 (V16QI "16") (V32QI "32") (V64QI "64")
1192 (V8HI "16") (V16HI "32") (V32HI "64")
1193 (V4SI "16") (V8SI "32") (V16SI "64")
1194 (V2DI "16") (V4DI "32") (V8DI "64")
1195 (V1TI "16") (V2TI "32") (V4TI "64")
1196 (V2DF "16") (V4DF "32") (V8DF "64")
1197 (V4SF "16") (V8SF "32") (V16SF "64")
1198 (V8HF "16") (V16HF "32") (V32HF "64")
1199 (V4HF "8") (V2HF "4")
1200 (V8BF "16") (V16BF "32") (V32BF "64")
1201 (V4BF "8") (V2BF "4")])
1203 ;; Double word integer modes as mode attribute.
1204 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI") (TI "OI")])
1205 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti") (TI "oi")])
1207 ;; Half sized integer modes.
1208 (define_mode_attr HALF [(TI "DI") (DI "SI")])
1209 (define_mode_attr half [(TI "di") (DI "si")])
1211 ;; LEA mode corresponding to an integer mode
1212 (define_mode_attr LEAMODE [(QI "SI") (HI "SI") (SI "SI") (DI "DI")])
1214 ;; Half mode for double word integer modes.
1215 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1216 (DI "TARGET_64BIT")])
1218 ;; Instruction suffix for integer modes.
1219 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1221 ;; Instruction suffix for masks.
1222 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1224 ;; Pointer size prefix for integer modes (Intel asm dialect)
1225 (define_mode_attr iptrsize [(QI "BYTE")
1230 ;; Register class for integer modes.
1231 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1233 ;; Immediate operand constraint for integer modes.
1234 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1236 ;; General operand constraint for word modes.
1237 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1239 ;; Memory operand constraint for word modes.
1240 (define_mode_attr m [(QI "m") (HI "m") (SI "BM") (DI "BM")])
1242 ;; Immediate operand constraint for double integer modes.
1243 (define_mode_attr di [(SI "nF") (DI "Wd")])
1245 ;; Immediate operand constraint for shifts.
1246 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1247 (define_mode_attr KS [(QI "Wb") (HI "Ww") (SI "I") (DI "J")])
1249 ;; Print register name in the specified mode.
1250 (define_mode_attr k [(QI "b") (HI "w") (SI "k") (DI "q")])
1252 ;; General operand predicate for integer modes.
1253 (define_mode_attr general_operand
1254 [(QI "general_operand")
1255 (HI "general_operand")
1256 (SI "x86_64_general_operand")
1257 (DI "x86_64_general_operand")
1258 (TI "x86_64_general_operand")])
1260 ;; General operand predicate for integer modes, where for TImode
1261 ;; we need both words of the operand to be general operands.
1262 (define_mode_attr general_hilo_operand
1263 [(QI "general_operand")
1264 (HI "general_operand")
1265 (SI "x86_64_general_operand")
1266 (DI "x86_64_general_operand")
1267 (TI "x86_64_hilo_general_operand")])
1269 ;; General sign extend operand predicate for integer modes,
1270 ;; which disallows VOIDmode operands and thus it is suitable
1271 ;; for use inside sign_extend.
1272 (define_mode_attr general_sext_operand
1273 [(QI "sext_operand")
1275 (SI "x86_64_sext_operand")
1276 (DI "x86_64_sext_operand")])
1278 ;; General sign/zero extend operand predicate for integer modes.
1279 (define_mode_attr general_szext_operand
1280 [(QI "general_operand")
1281 (HI "general_operand")
1282 (SI "x86_64_szext_general_operand")
1283 (DI "x86_64_szext_general_operand")
1284 (TI "x86_64_hilo_general_operand")])
1286 (define_mode_attr nonmemory_szext_operand
1287 [(QI "nonmemory_operand")
1288 (HI "nonmemory_operand")
1289 (SI "x86_64_szext_nonmemory_operand")
1290 (DI "x86_64_szext_nonmemory_operand")])
1292 ;; Immediate operand predicate for integer modes.
1293 (define_mode_attr immediate_operand
1294 [(QI "immediate_operand")
1295 (HI "immediate_operand")
1296 (SI "x86_64_immediate_operand")
1297 (DI "x86_64_immediate_operand")])
1299 ;; Nonmemory operand predicate for integer modes.
1300 (define_mode_attr nonmemory_operand
1301 [(QI "nonmemory_operand")
1302 (HI "nonmemory_operand")
1303 (SI "x86_64_nonmemory_operand")
1304 (DI "x86_64_nonmemory_operand")])
1306 ;; Operand predicate for shifts.
1307 (define_mode_attr shift_operand
1308 [(QI "nonimmediate_operand")
1309 (HI "nonimmediate_operand")
1310 (SI "nonimmediate_operand")
1311 (DI "shiftdi_operand")
1312 (TI "register_operand")])
1314 ;; Operand predicate for shift argument.
1315 (define_mode_attr shift_immediate_operand
1316 [(QI "const_1_to_31_operand")
1317 (HI "const_1_to_31_operand")
1318 (SI "const_1_to_31_operand")
1319 (DI "const_1_to_63_operand")])
1321 ;; Input operand predicate for arithmetic left shifts.
1322 (define_mode_attr ashl_input_operand
1323 [(QI "nonimmediate_operand")
1324 (HI "nonimmediate_operand")
1325 (SI "nonimmediate_operand")
1326 (DI "ashldi_input_operand")
1327 (TI "reg_or_pm1_operand")])
1329 ;; SSE and x87 SFmode and DFmode floating point modes
1330 (define_mode_iterator MODEF [SF DF])
1332 (define_mode_iterator MODEF248 [BF HF SF (DF "TARGET_SSE2")])
1334 ;; SSE floating point modes
1335 (define_mode_iterator MODEFH [(HF "TARGET_AVX512FP16") SF DF])
1337 ;; All x87 floating point modes
1338 (define_mode_iterator X87MODEF [SF DF XF])
1340 ;; All x87 floating point modes plus HFmode
1341 (define_mode_iterator X87MODEFH [HF SF DF XF BF])
1343 ;; All SSE floating point modes
1344 (define_mode_iterator SSEMODEF [HF SF DF TF])
1345 (define_mode_attr ssevecmodef [(HF "V8HF") (SF "V4SF") (DF "V2DF") (TF "TF")])
1347 ;; SSE instruction suffix for various modes
1348 (define_mode_attr ssemodesuffix
1349 [(HF "sh") (SF "ss") (DF "sd")
1350 (V32HF "ph") (V16SF "ps") (V8DF "pd")
1351 (V16HF "ph") (V16BF "bf") (V8SF "ps") (V4DF "pd")
1352 (V8HF "ph") (V8BF "bf") (V4SF "ps") (V2DF "pd")
1353 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1354 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1355 (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1357 ;; SSE vector suffix for floating point modes
1358 ;; BF HF use same suffix as SF for logic operations.
1359 (define_mode_attr ssevecmodesuffix [(BF "ps") (HF "ps") (SF "ps") (DF "pd")])
1361 ;; SSE vector mode corresponding to a scalar mode
1362 (define_mode_attr ssevecmode
1363 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (HF "V8HF") (BF "V8BF") (SF "V4SF") (DF "V2DF")])
1364 (define_mode_attr ssevecmodelower
1365 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1367 ;; AVX512F vector mode corresponding to a scalar mode
1368 (define_mode_attr avx512fvecmode
1369 [(QI "V64QI") (HI "V32HI") (SI "V16SI") (DI "V8DI")
1370 (HF "V32HF") (BF "V32BF") (SF "V16SF") (DF "V8DF")])
1372 ;; Instruction suffix for REX 64bit operators.
1373 (define_mode_attr rex64suffix [(SI "{l}") (DI "{q}")])
1374 (define_mode_attr rex64namesuffix [(SI "") (DI "q")])
1376 ;; This mode iterator allows :P to be used for patterns that operate on
1377 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1378 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1380 ;; This mode iterator allows :W to be used for patterns that operate on
1381 ;; word_mode sized quantities.
1382 (define_mode_iterator W
1383 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1385 ;; This mode iterator allows :PTR to be used for patterns that operate on
1386 ;; ptr_mode sized quantities.
1387 (define_mode_iterator PTR
1388 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1390 ;; Scheduling descriptions
1392 (include "pentium.md")
1395 (include "athlon.md")
1396 (include "bdver1.md")
1397 (include "bdver3.md")
1398 (include "btver2.md")
1399 (include "znver.md")
1400 (include "zn4zn5.md")
1401 (include "geode.md")
1405 (include "core2.md")
1406 (include "haswell.md")
1407 (include "lujiazui.md")
1408 (include "yongfeng.md")
1411 ;; Operand and operator predicates and constraints
1413 (include "predicates.md")
1414 (include "constraints.md")
1417 ;; Compare and branch/compare and store instructions.
1419 (define_expand "cbranch<mode>4"
1420 [(set (reg:CC FLAGS_REG)
1421 (compare:CC (match_operand:SWIM1248x 1 "nonimmediate_operand")
1422 (match_operand:SWIM1248x 2 "<general_operand>")))
1423 (set (pc) (if_then_else
1424 (match_operator 0 "ordered_comparison_operator"
1425 [(reg:CC FLAGS_REG) (const_int 0)])
1426 (label_ref (match_operand 3))
1430 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1431 operands[1] = force_reg (<MODE>mode, operands[1]);
1432 ix86_expand_branch (GET_CODE (operands[0]),
1433 operands[1], operands[2], operands[3]);
1437 (define_expand "cbranchti4"
1438 [(set (reg:CC FLAGS_REG)
1439 (compare:CC (match_operand:TI 1 "nonimmediate_operand")
1440 (match_operand:TI 2 "ix86_timode_comparison_operand")))
1441 (set (pc) (if_then_else
1442 (match_operator 0 "ix86_timode_comparison_operator"
1443 [(reg:CC FLAGS_REG) (const_int 0)])
1444 (label_ref (match_operand 3))
1446 "TARGET_64BIT || TARGET_SSE4_1"
1448 ix86_expand_branch (GET_CODE (operands[0]),
1449 operands[1], operands[2], operands[3]);
1453 (define_expand "cbranchoi4"
1454 [(set (reg:CC FLAGS_REG)
1455 (compare:CC (match_operand:OI 1 "nonimmediate_operand")
1456 (match_operand:OI 2 "nonimmediate_operand")))
1457 (set (pc) (if_then_else
1458 (match_operator 0 "bt_comparison_operator"
1459 [(reg:CC FLAGS_REG) (const_int 0)])
1460 (label_ref (match_operand 3))
1464 ix86_expand_branch (GET_CODE (operands[0]),
1465 operands[1], operands[2], operands[3]);
1469 (define_expand "cbranchxi4"
1470 [(set (reg:CC FLAGS_REG)
1471 (compare:CC (match_operand:XI 1 "nonimmediate_operand")
1472 (match_operand:XI 2 "nonimmediate_operand")))
1473 (set (pc) (if_then_else
1474 (match_operator 0 "bt_comparison_operator"
1475 [(reg:CC FLAGS_REG) (const_int 0)])
1476 (label_ref (match_operand 3))
1478 "TARGET_AVX512F && TARGET_EVEX512 && !TARGET_PREFER_AVX256"
1480 ix86_expand_branch (GET_CODE (operands[0]),
1481 operands[1], operands[2], operands[3]);
1485 (define_expand "cstore<mode>4"
1486 [(set (reg:CC FLAGS_REG)
1487 (compare:CC (match_operand:SDWIM 2 "nonimmediate_operand")
1488 (match_operand:SDWIM 3 "<general_operand>")))
1489 (set (match_operand:QI 0 "register_operand")
1490 (match_operator 1 "ordered_comparison_operator"
1491 [(reg:CC FLAGS_REG) (const_int 0)]))]
1494 if (<MODE>mode == (TARGET_64BIT ? TImode : DImode))
1496 if (GET_CODE (operands[1]) != EQ
1497 && GET_CODE (operands[1]) != NE)
1500 else if (MEM_P (operands[2]) && MEM_P (operands[3]))
1501 operands[2] = force_reg (<MODE>mode, operands[2]);
1502 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1503 operands[2], operands[3]);
1507 (define_expand "@cmp<mode>_1"
1508 [(set (reg:CC FLAGS_REG)
1509 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1510 (match_operand:SWI48 1 "<general_operand>")))])
1512 (define_mode_iterator SWI1248_AVX512BWDQ_64
1513 [(QI "TARGET_AVX512DQ") HI
1514 (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW && TARGET_64BIT")])
1516 (define_insn "*cmp<mode>_ccz_1"
1517 [(set (reg FLAGS_REG)
1518 (compare (match_operand:SWI1248_AVX512BWDQ_64 0
1519 "nonimmediate_operand" "<r>,?m<r>,$k")
1520 (match_operand:SWI1248_AVX512BWDQ_64 1 "const0_operand")))]
1521 "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
1523 test{<imodesuffix>}\t%0, %0
1524 cmp{<imodesuffix>}\t{%1, %0|%0, %1}
1525 kortest<mskmodesuffix>\t%0, %0"
1526 [(set_attr "type" "test,icmp,msklog")
1527 (set_attr "length_immediate" "0,1,*")
1528 (set_attr "prefix" "*,*,vex")
1529 (set_attr "mode" "<MODE>")])
1531 (define_insn "*cmp<mode>_ccno_1"
1532 [(set (reg FLAGS_REG)
1533 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1534 (match_operand:SWI 1 "const0_operand")))]
1535 "ix86_match_ccmode (insn, CCNOmode)"
1537 test{<imodesuffix>}\t%0, %0
1538 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1539 [(set_attr "type" "test,icmp")
1540 (set_attr "length_immediate" "0,1")
1541 (set_attr "mode" "<MODE>")])
1543 (define_insn "*cmp<mode>_1"
1544 [(set (reg FLAGS_REG)
1545 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1546 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r><m>")))]
1547 "ix86_match_ccmode (insn, CCmode)"
1548 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1549 [(set_attr "type" "icmp")
1550 (set_attr "mode" "<MODE>")])
1552 (define_insn "*cmp<mode>_minus_1"
1553 [(set (reg FLAGS_REG)
1555 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1556 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r><m>"))
1558 "ix86_match_ccmode (insn, CCGOCmode)"
1559 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1560 [(set_attr "type" "icmp")
1561 (set_attr "mode" "<MODE>")])
1563 (define_insn "*cmpqi_ext<mode>_1"
1564 [(set (reg FLAGS_REG)
1566 (match_operand:QI 0 "nonimmediate_operand" "QBn")
1568 (match_operator:SWI248 2 "extract_operator"
1569 [(match_operand 1 "int248_register_operand" "Q")
1571 (const_int 8)]) 0)))]
1572 "ix86_match_ccmode (insn, CCmode)"
1573 "cmp{b}\t{%h1, %0|%0, %h1}"
1574 [(set_attr "addr" "gpr8")
1575 (set_attr "type" "icmp")
1576 (set_attr "mode" "QI")])
1578 (define_insn "*cmpqi_ext<mode>_2"
1579 [(set (reg FLAGS_REG)
1582 (match_operator:SWI248 2 "extract_operator"
1583 [(match_operand 0 "int248_register_operand" "Q")
1586 (match_operand:QI 1 "const0_operand")))]
1587 "ix86_match_ccmode (insn, CCNOmode)"
1589 [(set_attr "type" "test")
1590 (set_attr "length_immediate" "0")
1591 (set_attr "mode" "QI")])
1593 (define_expand "cmpqi_ext_3"
1594 [(set (reg:CC FLAGS_REG)
1598 (match_operand:HI 0 "register_operand")
1601 (match_operand:QI 1 "const_int_operand")))])
1603 (define_insn "*cmpqi_ext<mode>_3"
1604 [(set (reg FLAGS_REG)
1607 (match_operator:SWI248 2 "extract_operator"
1608 [(match_operand 0 "int248_register_operand" "Q")
1611 (match_operand:QI 1 "general_operand" "QnBn")))]
1612 "ix86_match_ccmode (insn, CCmode)"
1613 "cmp{b}\t{%1, %h0|%h0, %1}"
1614 [(set_attr "addr" "gpr8")
1615 (set_attr "type" "icmp")
1616 (set_attr "mode" "QI")])
1618 (define_insn "*cmpqi_ext<mode>_4"
1619 [(set (reg FLAGS_REG)
1622 (match_operator:SWI248 2 "extract_operator"
1623 [(match_operand 0 "int248_register_operand" "Q")
1627 (match_operator:SWI248 3 "extract_operator"
1628 [(match_operand 1 "int248_register_operand" "Q")
1630 (const_int 8)]) 0)))]
1631 "ix86_match_ccmode (insn, CCmode)"
1632 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1633 [(set_attr "type" "icmp")
1634 (set_attr "mode" "QI")])
1636 (define_insn_and_split "*cmp<dwi>_doubleword"
1637 [(set (reg:CCZ FLAGS_REG)
1638 (compare:CCZ (match_operand:<DWI> 0 "nonimmediate_operand")
1639 (match_operand:<DWI> 1 "general_operand")))]
1640 "ix86_pre_reload_split ()"
1643 [(parallel [(set (reg:CCZ FLAGS_REG)
1644 (compare:CCZ (ior:DWIH (match_dup 4) (match_dup 5))
1646 (set (match_dup 4) (ior:DWIH (match_dup 4) (match_dup 5)))])]
1648 split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);
1650 operands[4] = gen_reg_rtx (<MODE>mode);
1652 /* Special case comparisons against -1. */
1653 if (operands[1] == constm1_rtx && operands[3] == constm1_rtx)
1655 emit_insn (gen_and<mode>3 (operands[4], operands[0], operands[2]));
1656 emit_insn (gen_cmp_1 (<MODE>mode, operands[4], constm1_rtx));
1660 if (operands[1] == const0_rtx)
1661 emit_move_insn (operands[4], operands[0]);
1662 else if (operands[0] == const0_rtx)
1663 emit_move_insn (operands[4], operands[1]);
1664 else if (operands[1] == constm1_rtx)
1665 emit_insn (gen_one_cmpl<mode>2 (operands[4], operands[0]));
1666 else if (operands[0] == constm1_rtx)
1667 emit_insn (gen_one_cmpl<mode>2 (operands[4], operands[1]));
1670 if (CONST_SCALAR_INT_P (operands[1])
1671 && !x86_64_immediate_operand (operands[1], <MODE>mode))
1672 operands[1] = force_reg (<MODE>mode, operands[1]);
1673 emit_insn (gen_xor<mode>3 (operands[4], operands[0], operands[1]));
1676 if (operands[3] == const0_rtx)
1677 operands[5] = operands[2];
1678 else if (operands[2] == const0_rtx)
1679 operands[5] = operands[3];
1682 operands[5] = gen_reg_rtx (<MODE>mode);
1683 if (operands[3] == constm1_rtx)
1684 emit_insn (gen_one_cmpl<mode>2 (operands[5], operands[2]));
1685 else if (operands[2] == constm1_rtx)
1686 emit_insn (gen_one_cmpl<mode>2 (operands[5], operands[3]));
1689 if (CONST_SCALAR_INT_P (operands[3])
1690 && !x86_64_immediate_operand (operands[3], <MODE>mode))
1691 operands[3] = force_reg (<MODE>mode, operands[3]);
1692 emit_insn (gen_xor<mode>3 (operands[5], operands[2], operands[3]));
1697 ;; These implement float point compares.
1698 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1699 ;; which would allow mix and match FP modes on the compares. Which is what
1700 ;; the old patterns did, but with many more of them.
1702 (define_expand "cbranchxf4"
1703 [(set (reg:CC FLAGS_REG)
1704 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1705 (match_operand:XF 2 "nonmemory_operand")))
1706 (set (pc) (if_then_else
1707 (match_operator 0 "ix86_fp_comparison_operator"
1710 (label_ref (match_operand 3))
1714 ix86_expand_branch (GET_CODE (operands[0]),
1715 operands[1], operands[2], operands[3]);
1719 (define_expand "cstorexf4"
1720 [(set (reg:CC FLAGS_REG)
1721 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1722 (match_operand:XF 3 "nonmemory_operand")))
1723 (set (match_operand:QI 0 "register_operand")
1724 (match_operator 1 "ix86_fp_comparison_operator"
1729 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1730 operands[2], operands[3]);
1734 (define_expand "cbranchhf4"
1735 [(set (reg:CC FLAGS_REG)
1736 (compare:CC (match_operand:HF 1 "cmp_fp_expander_operand")
1737 (match_operand:HF 2 "cmp_fp_expander_operand")))
1738 (set (pc) (if_then_else
1739 (match_operator 0 "ix86_fp_comparison_operator"
1742 (label_ref (match_operand 3))
1746 ix86_expand_branch (GET_CODE (operands[0]),
1747 operands[1], operands[2], operands[3]);
1751 (define_expand "cbranch<mode>4"
1752 [(set (reg:CC FLAGS_REG)
1753 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1754 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1755 (set (pc) (if_then_else
1756 (match_operator 0 "ix86_fp_comparison_operator"
1759 (label_ref (match_operand 3))
1761 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1763 ix86_expand_branch (GET_CODE (operands[0]),
1764 operands[1], operands[2], operands[3]);
1768 (define_expand "cbranchbf4"
1769 [(set (reg:CC FLAGS_REG)
1770 (compare:CC (match_operand:BF 1 "cmp_fp_expander_operand")
1771 (match_operand:BF 2 "cmp_fp_expander_operand")))
1772 (set (pc) (if_then_else
1773 (match_operator 0 "comparison_operator"
1776 (label_ref (match_operand 3))
1778 "TARGET_80387 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
1780 rtx op1 = ix86_expand_fast_convert_bf_to_sf (operands[1]);
1781 rtx op2 = ix86_expand_fast_convert_bf_to_sf (operands[2]);
1782 do_compare_rtx_and_jump (op1, op2, GET_CODE (operands[0]), 0,
1783 SFmode, NULL_RTX, NULL,
1784 as_a <rtx_code_label *> (operands[3]),
1785 /* Unfortunately this isn't propagated. */
1786 profile_probability::even ());
1790 (define_expand "cstorehf4"
1791 [(set (reg:CC FLAGS_REG)
1792 (compare:CC (match_operand:HF 2 "cmp_fp_expander_operand")
1793 (match_operand:HF 3 "cmp_fp_expander_operand")))
1794 (set (match_operand:QI 0 "register_operand")
1795 (match_operator 1 "ix86_fp_comparison_operator"
1800 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1801 operands[2], operands[3]);
1805 (define_expand "cstorebf4"
1806 [(set (reg:CC FLAGS_REG)
1807 (compare:CC (match_operand:BF 2 "cmp_fp_expander_operand")
1808 (match_operand:BF 3 "cmp_fp_expander_operand")))
1809 (set (match_operand:QI 0 "register_operand")
1810 (match_operator 1 "comparison_operator"
1813 "TARGET_80387 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
1815 rtx op1 = ix86_expand_fast_convert_bf_to_sf (operands[2]);
1816 rtx op2 = ix86_expand_fast_convert_bf_to_sf (operands[3]);
1817 rtx res = emit_store_flag_force (operands[0], GET_CODE (operands[1]),
1818 op1, op2, SFmode, 0, 1);
1819 if (!rtx_equal_p (res, operands[0]))
1820 emit_move_insn (operands[0], res);
1824 (define_expand "cstore<mode>4"
1825 [(set (reg:CC FLAGS_REG)
1826 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1827 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1828 (set (match_operand:QI 0 "register_operand")
1829 (match_operator 1 "ix86_fp_comparison_operator"
1832 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1834 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1835 operands[2], operands[3]);
1839 (define_expand "cbranchcc4"
1840 [(set (pc) (if_then_else
1841 (match_operator 0 "comparison_operator"
1842 [(match_operand 1 "flags_reg_operand")
1843 (match_operand 2 "const0_operand")])
1844 (label_ref (match_operand 3))
1848 ix86_expand_branch (GET_CODE (operands[0]),
1849 operands[1], operands[2], operands[3]);
1853 (define_expand "cstorecc4"
1854 [(set (match_operand:QI 0 "register_operand")
1855 (match_operator 1 "comparison_operator"
1856 [(match_operand 2 "flags_reg_operand")
1857 (match_operand 3 "const0_operand")]))]
1860 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1861 operands[2], operands[3]);
1865 ;; FP compares, step 1:
1866 ;; Set the FP condition codes and move fpsr to ax.
1868 ;; We may not use "#" to split and emit these
1869 ;; due to reg-stack pops killing fpsr.
1871 (define_insn "*cmpxf_i387"
1872 [(set (match_operand:HI 0 "register_operand" "=a")
1875 (match_operand:XF 1 "register_operand" "f")
1876 (match_operand:XF 2 "reg_or_0_operand" "fC"))]
1879 "* return output_fp_compare (insn, operands, false, false);"
1880 [(set_attr "type" "multi")
1881 (set_attr "unit" "i387")
1882 (set_attr "mode" "XF")])
1884 (define_insn "*cmp<mode>_i387"
1885 [(set (match_operand:HI 0 "register_operand" "=a")
1888 (match_operand:MODEF 1 "register_operand" "f")
1889 (match_operand:MODEF 2 "nonimm_or_0_operand" "fmC"))]
1892 "* return output_fp_compare (insn, operands, false, false);"
1893 [(set_attr "type" "multi")
1894 (set_attr "unit" "i387")
1895 (set_attr "mode" "<MODE>")])
1897 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1898 [(set (match_operand:HI 0 "register_operand" "=a")
1901 (match_operand:X87MODEF 1 "register_operand" "f")
1903 (match_operand:SWI24 2 "nonimmediate_operand" "m")))]
1906 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1907 || optimize_function_for_size_p (cfun))"
1908 "* return output_fp_compare (insn, operands, false, false);"
1909 [(set_attr "type" "multi")
1910 (set_attr "unit" "i387")
1911 (set_attr "fp_int_src" "true")
1912 (set_attr "mode" "<SWI24:MODE>")])
1914 (define_insn "*cmpu<mode>_i387"
1915 [(set (match_operand:HI 0 "register_operand" "=a")
1919 (match_operand:X87MODEF 1 "register_operand" "f")
1920 (match_operand:X87MODEF 2 "register_operand" "f"))]
1924 "* return output_fp_compare (insn, operands, false, true);"
1925 [(set_attr "type" "multi")
1926 (set_attr "unit" "i387")
1927 (set_attr "mode" "<MODE>")])
1929 ;; FP compares, step 2:
1930 ;; Get ax into flags, general case.
1932 (define_insn "x86_sahf_1"
1933 [(set (reg:CC FLAGS_REG)
1934 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1938 #ifndef HAVE_AS_IX86_SAHF
1940 return ASM_BYTE "0x9e";
1945 [(set_attr "length" "1")
1946 (set_attr "athlon_decode" "vector")
1947 (set_attr "amdfam10_decode" "direct")
1948 (set_attr "bdver1_decode" "direct")
1949 (set_attr "mode" "SI")])
1951 ;; Pentium Pro can do both steps in one go.
1952 ;; (these instructions set flags directly)
1954 (define_subst_attr "unord" "unord_subst" "" "u")
1955 (define_subst_attr "unordered" "unord_subst" "false" "true")
1957 (define_subst "unord_subst"
1958 [(set (match_operand:CCFP 0)
1959 (match_operand:CCFP 1))]
1966 (define_insn "*cmpi<unord>xf_i387"
1967 [(set (reg:CCFP FLAGS_REG)
1969 (match_operand:XF 0 "register_operand" "f")
1970 (match_operand:XF 1 "register_operand" "f")))]
1971 "TARGET_80387 && TARGET_CMOVE"
1972 "* return output_fp_compare (insn, operands, true, <unordered>);"
1973 [(set_attr "type" "fcmp")
1974 (set_attr "mode" "XF")
1975 (set_attr "athlon_decode" "vector")
1976 (set_attr "amdfam10_decode" "direct")
1977 (set_attr "bdver1_decode" "double")
1978 (set_attr "znver1_decode" "double")])
1980 (define_insn "*cmpi<unord><MODEF:mode>"
1981 [(set (reg:CCFP FLAGS_REG)
1983 (match_operand:MODEF 0 "register_operand" "f,v")
1984 (match_operand:MODEF 1 "register_ssemem_operand" "f,vm")))]
1985 "(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
1986 || (TARGET_80387 && TARGET_CMOVE)"
1988 * return output_fp_compare (insn, operands, true, <unordered>);
1989 %v<unord>comi<MODEF:ssemodesuffix>\t{%1, %0|%0, %1}"
1990 [(set_attr "type" "fcmp,ssecomi")
1991 (set_attr "prefix" "orig,maybe_vex")
1992 (set_attr "mode" "<MODEF:MODE>")
1993 (set_attr "prefix_rep" "*,0")
1994 (set (attr "prefix_data16")
1995 (cond [(eq_attr "alternative" "0")
1997 (eq_attr "mode" "DF")
2000 (const_string "0")))
2001 (set_attr "athlon_decode" "vector")
2002 (set_attr "amdfam10_decode" "direct")
2003 (set_attr "bdver1_decode" "double")
2004 (set_attr "znver1_decode" "double")
2005 (set (attr "enabled")
2007 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
2009 (eq_attr "alternative" "0")
2010 (symbol_ref "TARGET_MIX_SSE_I387")
2011 (symbol_ref "true"))
2013 (eq_attr "alternative" "0")
2015 (symbol_ref "false"))))])
2017 (define_insn "*cmpi<unord>hf"
2018 [(set (reg:CCFP FLAGS_REG)
2020 (match_operand:HF 0 "register_operand" "v")
2021 (match_operand:HF 1 "nonimmediate_operand" "vm")))]
2023 "v<unord>comish\t{%1, %0|%0, %1}"
2024 [(set_attr "type" "ssecomi")
2025 (set_attr "prefix" "evex")
2026 (set_attr "mode" "HF")])
2029 (define_insn "x86_stc"
2030 [(set (reg:CCC FLAGS_REG) (unspec:CCC [(const_int 0)] UNSPEC_STC))]
2033 [(set_attr "length" "1")
2034 (set_attr "length_immediate" "0")
2035 (set_attr "modrm" "0")])
2037 ;; On Pentium 4, set the carry flag using mov $1,%al;addb $-1,%al.
2039 [(match_scratch:QI 0 "r")
2040 (set (reg:CCC FLAGS_REG) (unspec:CCC [(const_int 0)] UNSPEC_STC))]
2041 "TARGET_SLOW_STC && !optimize_insn_for_size_p ()"
2042 [(set (match_dup 0) (const_int 1))
2044 [(set (reg:CCC FLAGS_REG)
2045 (compare:CCC (plus:QI (match_dup 0) (const_int -1))
2047 (set (match_dup 0) (plus:QI (match_dup 0) (const_int -1)))])])
2049 ;; Complement carry flag.
2050 (define_insn "*x86_cmc"
2051 [(set (reg:CCC FLAGS_REG)
2052 (compare:CCC (neg:QI (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
2053 (geu:QI (reg:CCC FLAGS_REG) (const_int 0))))]
2056 [(set_attr "length" "1")
2057 (set_attr "length_immediate" "0")
2058 (set_attr "use_carry" "1")
2059 (set_attr "modrm" "0")])
2061 ;; On Pentium 4, cmc is replaced with setnc %al;addb $-1,%al.
2063 [(match_scratch:QI 0 "r")
2064 (set (reg:CCC FLAGS_REG)
2065 (compare:CCC (neg:QI (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
2066 (geu:QI (reg:CCC FLAGS_REG) (const_int 0))))]
2067 "TARGET_SLOW_STC && !optimize_insn_for_size_p ()"
2068 [(set (match_dup 0) (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))
2070 [(set (reg:CCC FLAGS_REG)
2071 (compare:CCC (plus:QI (match_dup 0) (const_int -1))
2073 (set (match_dup 0) (plus:QI (match_dup 0) (const_int -1)))])])
2075 ;; Push/pop instructions.
2077 (define_insn_and_split "*pushv1ti2"
2078 [(set (match_operand:V1TI 0 "push_operand" "=<")
2079 (match_operand:V1TI 1 "register_operand" "v"))]
2080 "TARGET_64BIT && TARGET_STV"
2082 "&& reload_completed"
2083 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2084 (set (match_dup 0) (match_dup 1))]
2086 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (V1TImode)));
2087 /* Preserve memory attributes. */
2088 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2090 [(set_attr "type" "multi")
2091 (set_attr "mode" "TI")])
2093 (define_insn "*push<mode>2"
2094 [(set (match_operand:DWI 0 "push_operand" "=<,<")
2095 (match_operand:DWI 1 "general_no_elim_operand" "riF*o,*v"))]
2098 [(set_attr "type" "multi")
2099 (set_attr "mode" "<MODE>")])
2102 [(set (match_operand:DWI 0 "push_operand")
2103 (match_operand:DWI 1 "general_gr_operand"))]
2106 "ix86_split_long_move (operands); DONE;")
2108 (define_insn "*pushdi2_rex64"
2109 [(set (match_operand:DI 0 "push_operand" "=<,<,!<")
2110 (match_operand:DI 1 "general_no_elim_operand" "re*m,*v,n"))]
2116 [(set_attr "type" "push,multi,multi")
2117 (set_attr "mode" "DI")])
2119 ;; Convert impossible pushes of immediate to existing instructions.
2120 ;; First try to get scratch register and go through it. In case this
2121 ;; fails, push sign extended lower part first and then overwrite
2122 ;; upper part by 32bit move.
2125 [(match_scratch:DI 2 "r")
2126 (set (match_operand:DI 0 "push_operand")
2127 (match_operand:DI 1 "immediate_operand"))]
2129 && !symbolic_operand (operands[1], DImode)
2130 && !x86_64_immediate_operand (operands[1], DImode)"
2131 [(set (match_dup 2) (match_dup 1))
2132 (set (match_dup 0) (match_dup 2))])
2135 [(set (match_operand:DI 0 "push_operand")
2136 (match_operand:DI 1 "immediate_operand"))]
2137 "TARGET_64BIT && epilogue_completed
2138 && !symbolic_operand (operands[1], DImode)
2139 && !x86_64_immediate_operand (operands[1], DImode)"
2140 [(set (match_dup 0) (match_dup 1))
2141 (set (match_dup 2) (match_dup 3))]
2143 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
2145 operands[1] = gen_lowpart (DImode, operands[2]);
2146 operands[2] = gen_rtx_MEM (SImode,
2147 plus_constant (Pmode, stack_pointer_rtx, 4));
2150 ;; For TARGET_64BIT we always round up to 8 bytes.
2151 (define_insn "*pushsi2_rex64"
2152 [(set (match_operand:SI 0 "push_operand" "=X,X")
2153 (match_operand:SI 1 "nonmemory_no_elim_operand" "re,*v"))]
2158 [(set_attr "type" "push,multi")
2159 (set_attr "mode" "DI")])
2161 (define_insn "*pushsi2"
2162 [(set (match_operand:SI 0 "push_operand" "=<,<")
2163 (match_operand:SI 1 "general_no_elim_operand" "ri*m,*v"))]
2168 [(set_attr "type" "push,multi")
2169 (set_attr "mode" "SI")])
2172 [(set (match_operand:SWI48DWI 0 "push_operand")
2173 (match_operand:SWI48DWI 1 "sse_reg_operand"))]
2174 "TARGET_SSE && reload_completed"
2175 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2176 (set (match_dup 0) (match_dup 1))]
2178 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (<SWI48DWI:MODE>mode)));
2179 /* Preserve memory attributes. */
2180 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2183 ;; emit_push_insn when it calls move_by_pieces requires an insn to
2184 ;; "push a byte/word". But actually we use push{l,q}, which has
2185 ;; the effect of rounding the amount pushed up to a word.
2187 (define_insn "*push<mode>2"
2188 [(set (match_operand:SWI12 0 "push_operand" "=X")
2189 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
2191 "* return TARGET_64BIT ? \"push{q}\t%q1\" : \"push{l}\t%k1\";"
2192 [(set_attr "type" "push")
2194 (if_then_else (match_test "TARGET_64BIT")
2196 (const_string "SI")))])
2198 (define_insn "*push<mode>2_prologue"
2199 [(set (match_operand:W 0 "push_operand" "=<")
2200 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
2201 (clobber (mem:BLK (scratch)))]
2203 "push{<imodesuffix>}\t%1"
2204 [(set_attr "type" "push")
2205 (set_attr "mode" "<MODE>")])
2207 (define_insn "*pop<mode>1"
2208 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
2209 (match_operand:W 1 "pop_operand" ">"))]
2211 "pop{<imodesuffix>}\t%0"
2212 [(set_attr "type" "pop")
2213 (set_attr "mode" "<MODE>")])
2215 (define_insn "*pop<mode>1_epilogue"
2216 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
2217 (match_operand:W 1 "pop_operand" ">"))
2218 (clobber (mem:BLK (scratch)))]
2220 "pop{<imodesuffix>}\t%0"
2221 [(set_attr "type" "pop")
2222 (set_attr "mode" "<MODE>")])
2224 (define_insn "@pushfl<mode>2"
2225 [(set (match_operand:W 0 "push_operand" "=<")
2226 (unspec:W [(match_operand 1 "flags_reg_operand")]
2228 "GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_CC"
2229 "pushf{<imodesuffix>}"
2230 [(set_attr "type" "push")
2231 (set_attr "mode" "<MODE>")])
2233 (define_insn "@popfl<mode>1"
2234 [(set (match_operand:CC 0 "flags_reg_operand")
2235 (unspec:CC [(match_operand:W 1 "pop_operand" ">")]
2238 "popf{<imodesuffix>}"
2239 [(set_attr "type" "pop")
2240 (set_attr "mode" "<MODE>")])
2243 ;; Reload patterns to support multi-word load/store
2244 ;; with non-offsetable address.
2245 (define_expand "reload_noff_store"
2246 [(parallel [(match_operand 0 "memory_operand" "=m")
2247 (match_operand 1 "register_operand" "r")
2248 (match_operand:DI 2 "register_operand" "=&r")])]
2251 rtx mem = operands[0];
2252 rtx addr = XEXP (mem, 0);
2254 emit_move_insn (operands[2], addr);
2255 mem = replace_equiv_address_nv (mem, operands[2]);
2257 emit_insn (gen_rtx_SET (mem, operands[1]));
2261 (define_expand "reload_noff_load"
2262 [(parallel [(match_operand 0 "register_operand" "=r")
2263 (match_operand 1 "memory_operand" "m")
2264 (match_operand:DI 2 "register_operand" "=r")])]
2267 rtx mem = operands[1];
2268 rtx addr = XEXP (mem, 0);
2270 emit_move_insn (operands[2], addr);
2271 mem = replace_equiv_address_nv (mem, operands[2]);
2273 emit_insn (gen_rtx_SET (operands[0], mem));
2277 ;; Move instructions.
2279 (define_expand "movxi"
2280 [(set (match_operand:XI 0 "nonimmediate_operand")
2281 (match_operand:XI 1 "general_operand"))]
2282 "TARGET_AVX512F && TARGET_EVEX512"
2283 "ix86_expand_vector_move (XImode, operands); DONE;")
2285 (define_expand "movoi"
2286 [(set (match_operand:OI 0 "nonimmediate_operand")
2287 (match_operand:OI 1 "general_operand"))]
2289 "ix86_expand_vector_move (OImode, operands); DONE;")
2291 (define_expand "movti"
2292 [(set (match_operand:TI 0 "nonimmediate_operand")
2293 (match_operand:TI 1 "general_operand"))]
2294 "TARGET_64BIT || TARGET_SSE"
2297 ix86_expand_move (TImode, operands);
2299 ix86_expand_vector_move (TImode, operands);
2303 ;; This expands to what emit_move_complex would generate if we didn't
2304 ;; have a movti pattern. Having this avoids problems with reload on
2305 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2306 ;; to have around all the time.
2307 (define_expand "movcdi"
2308 [(set (match_operand:CDI 0 "nonimmediate_operand")
2309 (match_operand:CDI 1 "general_operand"))]
2312 if (push_operand (operands[0], CDImode))
2313 emit_move_complex_push (CDImode, operands[0], operands[1]);
2315 emit_move_complex_parts (operands[0], operands[1]);
2319 (define_expand "mov<mode>"
2320 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
2321 (match_operand:SWI1248x 1 "general_operand"))]
2323 "ix86_expand_move (<MODE>mode, operands); DONE;")
2325 (define_insn "*mov<mode>_xor"
2326 [(set (match_operand:SWI48 0 "register_operand" "=r")
2327 (match_operand:SWI48 1 "const0_operand"))
2328 (clobber (reg:CC FLAGS_REG))]
2331 [(set_attr "type" "alu1")
2332 (set_attr "mode" "SI")
2333 (set_attr "length_immediate" "0")])
2335 (define_insn "*mov<mode>_and"
2336 [(set (match_operand:SWI248 0 "memory_operand" "=m")
2337 (match_operand:SWI248 1 "const0_operand"))
2338 (clobber (reg:CC FLAGS_REG))]
2340 "and{<imodesuffix>}\t{%1, %0|%0, %1}"
2341 [(set_attr "type" "alu1")
2342 (set_attr "mode" "<MODE>")
2343 (set_attr "length_immediate" "1")])
2345 (define_insn "*mov<mode>_or"
2346 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
2347 (match_operand:SWI248 1 "constm1_operand"))
2348 (clobber (reg:CC FLAGS_REG))]
2350 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
2351 [(set_attr "type" "alu1")
2352 (set_attr "mode" "<MODE>")
2353 (set_attr "length_immediate" "1")])
2355 (define_insn "*movxi_internal_avx512f"
2356 [(set (match_operand:XI 0 "nonimmediate_operand" "=v,v ,v ,m")
2357 (match_operand:XI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2358 "TARGET_AVX512F && TARGET_EVEX512
2359 && (register_operand (operands[0], XImode)
2360 || register_operand (operands[1], XImode))"
2362 switch (get_attr_type (insn))
2365 return standard_sse_constant_opcode (insn, operands);
2368 return ix86_output_ssemov (insn, operands);
2374 [(set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2375 (set_attr "prefix" "evex")
2376 (set_attr "mode" "XI")])
2378 (define_insn "*movoi_internal_avx"
2379 [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,v ,m")
2380 (match_operand:OI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2382 && (register_operand (operands[0], OImode)
2383 || register_operand (operands[1], OImode))"
2385 switch (get_attr_type (insn))
2388 return standard_sse_constant_opcode (insn, operands);
2391 return ix86_output_ssemov (insn, operands);
2397 [(set_attr "isa" "*,avx2,*,*")
2398 (set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2399 (set_attr "prefix" "vex")
2400 (set_attr "mode" "OI")])
2402 (define_insn "*movti_internal"
2403 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,v ,m,?jc,?Yd")
2404 (match_operand:TI 1 "general_operand" "riFo,re,C,BC,vm,v,Yd,jc"))]
2406 && !(MEM_P (operands[0]) && MEM_P (operands[1])))
2408 && nonimmediate_or_sse_const_operand (operands[1], TImode)
2409 && (register_operand (operands[0], TImode)
2410 || register_operand (operands[1], TImode)))"
2412 switch (get_attr_type (insn))
2418 return standard_sse_constant_opcode (insn, operands);
2421 return ix86_output_ssemov (insn, operands);
2428 (cond [(eq_attr "alternative" "0,1,6,7")
2429 (const_string "x64")
2430 (eq_attr "alternative" "3")
2431 (const_string "sse2")
2433 (const_string "*")))
2435 (cond [(eq_attr "alternative" "0,1,6,7")
2436 (const_string "multi")
2437 (eq_attr "alternative" "2,3")
2438 (const_string "sselog1")
2440 (const_string "ssemov")))
2441 (set (attr "prefix")
2442 (if_then_else (eq_attr "type" "sselog1,ssemov")
2443 (const_string "maybe_vex")
2444 (const_string "orig")))
2446 (cond [(eq_attr "alternative" "0,1")
2448 (match_test "TARGET_AVX")
2450 (ior (not (match_test "TARGET_SSE2"))
2451 (match_test "optimize_function_for_size_p (cfun)"))
2452 (const_string "V4SF")
2453 (and (eq_attr "alternative" "5")
2454 (match_test "TARGET_SSE_TYPELESS_STORES"))
2455 (const_string "V4SF")
2457 (const_string "TI")))
2458 (set (attr "preferred_for_speed")
2459 (cond [(eq_attr "alternative" "6")
2460 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2461 (eq_attr "alternative" "7")
2462 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2464 (symbol_ref "true")))])
2467 [(set (match_operand:TI 0 "sse_reg_operand")
2468 (match_operand:TI 1 "general_reg_operand"))]
2469 "TARGET_64BIT && TARGET_SSE4_1
2470 && reload_completed"
2473 (vec_duplicate:V2DI (match_dup 3))
2477 operands[2] = lowpart_subreg (V2DImode, operands[0], TImode);
2478 operands[3] = gen_highpart (DImode, operands[1]);
2480 emit_move_insn (gen_lowpart (DImode, operands[0]),
2481 gen_lowpart (DImode, operands[1]));
2484 (define_insn "*movdi_internal"
2485 [(set (match_operand:DI 0 "nonimmediate_operand"
2486 "=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")
2487 (match_operand:DI 1 "general_operand"
2488 "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"))]
2489 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2490 && ix86_hardreg_mov_ok (operands[0], operands[1])"
2492 switch (get_attr_type (insn))
2495 return "kmovq\t{%1, %0|%0, %1}";
2498 if (operands[1] == const0_rtx)
2499 return "kxorq\t%0, %0, %0";
2500 else if (operands[1] == constm1_rtx)
2501 return "kxnorq\t%0, %0, %0";
2508 return "pxor\t%0, %0";
2511 /* Handle broken assemblers that require movd instead of movq. */
2512 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2513 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2514 return "movd\t{%1, %0|%0, %1}";
2515 return "movq\t{%1, %0|%0, %1}";
2518 return standard_sse_constant_opcode (insn, operands);
2521 return ix86_output_ssemov (insn, operands);
2524 if (SSE_REG_P (operands[0]))
2525 return "movq2dq\t{%1, %0|%0, %1}";
2527 return "movdq2q\t{%1, %0|%0, %1}";
2530 return "lea{q}\t{%E1, %0|%0, %E1}";
2533 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2534 if (get_attr_mode (insn) == MODE_SI)
2535 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2536 else if (which_alternative == 4)
2537 return "movabs{q}\t{%1, %0|%0, %1}";
2538 else if (ix86_use_lea_for_mov (insn, operands))
2539 return "lea{q}\t{%E1, %0|%0, %E1}";
2541 return "mov{q}\t{%1, %0|%0, %1}";
2548 (cond [(eq_attr "alternative" "0,1,17,18")
2549 (const_string "nox64")
2550 (eq_attr "alternative" "2,3,4,5,10,11,23,25")
2551 (const_string "x64")
2552 (eq_attr "alternative" "19,20")
2553 (const_string "x64_sse2")
2554 (eq_attr "alternative" "21,22")
2555 (const_string "sse2")
2557 (const_string "*")))
2559 (cond [(eq_attr "alternative" "0,1,17,18")
2560 (const_string "multi")
2561 (eq_attr "alternative" "6")
2562 (const_string "mmx")
2563 (eq_attr "alternative" "7,8,9,10,11")
2564 (const_string "mmxmov")
2565 (eq_attr "alternative" "12")
2566 (const_string "sselog1")
2567 (eq_attr "alternative" "13,14,15,16,19,20")
2568 (const_string "ssemov")
2569 (eq_attr "alternative" "21,22")
2570 (const_string "ssecvt")
2571 (eq_attr "alternative" "23,24,25,26")
2572 (const_string "mskmov")
2573 (eq_attr "alternative" "27")
2574 (const_string "msklog")
2575 (and (match_operand 0 "register_operand")
2576 (match_operand 1 "pic_32bit_operand"))
2577 (const_string "lea")
2579 (const_string "imov")))
2582 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2584 (const_string "*")))
2585 (set (attr "length_immediate")
2587 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2589 (const_string "*")))
2590 (set (attr "prefix_rex")
2592 (eq_attr "alternative" "10,11,19,20")
2594 (const_string "*")))
2595 (set (attr "prefix")
2596 (if_then_else (eq_attr "type" "sselog1,ssemov")
2597 (const_string "maybe_vex")
2598 (const_string "orig")))
2599 (set (attr "prefix_data16")
2600 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2602 (const_string "*")))
2604 (cond [(eq_attr "alternative" "2")
2606 (eq_attr "alternative" "12")
2607 (cond [(match_test "TARGET_AVX")
2609 (ior (not (match_test "TARGET_SSE2"))
2610 (match_test "optimize_function_for_size_p (cfun)"))
2611 (const_string "V4SF")
2613 (const_string "TI"))
2614 (eq_attr "alternative" "13")
2615 (cond [(match_test "TARGET_AVX512VL")
2617 (match_test "TARGET_AVX512F")
2619 (match_test "TARGET_AVX")
2621 (ior (not (match_test "TARGET_SSE2"))
2622 (match_test "optimize_function_for_size_p (cfun)"))
2623 (const_string "V4SF")
2625 (const_string "TI"))
2627 (and (eq_attr "alternative" "14,15,16")
2628 (not (match_test "TARGET_SSE2")))
2629 (const_string "V2SF")
2631 (const_string "DI")))
2632 (set (attr "preferred_for_speed")
2633 (cond [(eq_attr "alternative" "10,17,19")
2634 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2635 (eq_attr "alternative" "11,18,20")
2636 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2638 (symbol_ref "true")))
2639 (set (attr "enabled")
2640 (cond [(eq_attr "alternative" "15")
2642 (match_test "TARGET_STV && TARGET_SSE2")
2643 (symbol_ref "false")
2645 (eq_attr "alternative" "16")
2647 (match_test "TARGET_STV && TARGET_SSE2")
2649 (symbol_ref "false"))
2651 (const_string "*")))])
2654 [(set (match_operand:<DWI> 0 "general_reg_operand")
2655 (match_operand:<DWI> 1 "sse_reg_operand"))]
2657 && reload_completed"
2661 (parallel [(const_int 1)])))]
2663 operands[2] = gen_highpart (<MODE>mode, operands[0]);
2664 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[1], <DWI>mode);
2666 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]),
2667 gen_lowpart (<MODE>mode, operands[1]));
2671 [(set (match_operand:DWI 0 "nonimmediate_gr_operand")
2672 (match_operand:DWI 1 "general_gr_operand"))]
2675 "ix86_split_long_move (operands); DONE;")
2678 [(set (match_operand:DI 0 "sse_reg_operand")
2679 (match_operand:DI 1 "general_reg_operand"))]
2680 "!TARGET_64BIT && TARGET_SSE4_1
2681 && reload_completed"
2684 (vec_duplicate:V4SI (match_dup 3))
2688 operands[2] = lowpart_subreg (V4SImode, operands[0], DImode);
2689 operands[3] = gen_highpart (SImode, operands[1]);
2691 emit_move_insn (gen_lowpart (SImode, operands[0]),
2692 gen_lowpart (SImode, operands[1]));
2695 ;; movabsq $0x0012345678000000, %rax is longer
2696 ;; than movl $0x12345678, %eax; shlq $24, %rax.
2698 [(set (match_operand:DI 0 "register_operand")
2699 (match_operand:DI 1 "const_int_operand"))]
2701 && optimize_insn_for_size_p ()
2702 && LEGACY_INT_REG_P (operands[0])
2703 && !x86_64_immediate_operand (operands[1], DImode)
2704 && !x86_64_zext_immediate_operand (operands[1], DImode)
2705 && !((UINTVAL (operands[1]) >> ctz_hwi (UINTVAL (operands[1])))
2706 & ~HOST_WIDE_INT_C (0xffffffff))
2707 && peep2_regno_dead_p (0, FLAGS_REG)"
2708 [(set (match_dup 0) (match_dup 1))
2709 (parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
2710 (clobber (reg:CC FLAGS_REG))])]
2712 int shift = ctz_hwi (UINTVAL (operands[1]));
2713 rtx op1 = gen_int_mode (UINTVAL (operands[1]) >> shift, DImode);
2714 if (ix86_endbr_immediate_operand (op1, VOIDmode))
2717 operands[2] = gen_int_mode (shift, QImode);
2720 (define_insn "*movsi_internal"
2721 [(set (match_operand:SI 0 "nonimmediate_operand"
2722 "=r,m ,*y,*y,?*y,?m,?r,?*y,?Yv,?v,?v,m ,?r,?v,*k,*k ,*rm,*k")
2723 (match_operand:SI 1 "general_operand"
2724 "g ,re,C ,*y,Bk ,*y,*y,r ,C ,?v,Bk,?v,?v,r ,*r,*kBk,*k ,CBC"))]
2725 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2726 && ix86_hardreg_mov_ok (operands[0], operands[1])"
2728 switch (get_attr_type (insn))
2731 return standard_sse_constant_opcode (insn, operands);
2734 return "kmovd\t{%1, %0|%0, %1}";
2737 if (operands[1] == const0_rtx)
2738 return "kxord\t%0, %0, %0";
2739 else if (operands[1] == constm1_rtx)
2740 return "kxnord\t%0, %0, %0";
2744 return ix86_output_ssemov (insn, operands);
2747 return "pxor\t%0, %0";
2750 switch (get_attr_mode (insn))
2753 return "movq\t{%1, %0|%0, %1}";
2755 return "movd\t{%1, %0|%0, %1}";
2762 return "lea{l}\t{%E1, %0|%0, %E1}";
2765 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2766 if (ix86_use_lea_for_mov (insn, operands))
2767 return "lea{l}\t{%E1, %0|%0, %E1}";
2769 return "mov{l}\t{%1, %0|%0, %1}";
2776 (cond [(eq_attr "alternative" "12,13")
2777 (const_string "sse2")
2779 (const_string "*")))
2781 (cond [(eq_attr "alternative" "2")
2782 (const_string "mmx")
2783 (eq_attr "alternative" "3,4,5,6,7")
2784 (const_string "mmxmov")
2785 (eq_attr "alternative" "8")
2786 (const_string "sselog1")
2787 (eq_attr "alternative" "9,10,11,12,13")
2788 (const_string "ssemov")
2789 (eq_attr "alternative" "14,15,16")
2790 (const_string "mskmov")
2791 (eq_attr "alternative" "17")
2792 (const_string "msklog")
2793 (and (match_operand 0 "register_operand")
2794 (match_operand 1 "pic_32bit_operand"))
2795 (const_string "lea")
2797 (const_string "imov")))
2798 (set (attr "prefix")
2799 (if_then_else (eq_attr "type" "sselog1,ssemov")
2800 (const_string "maybe_vex")
2801 (const_string "orig")))
2802 (set (attr "prefix_data16")
2803 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2805 (const_string "*")))
2807 (cond [(eq_attr "alternative" "2,3")
2809 (eq_attr "alternative" "8")
2810 (cond [(match_test "TARGET_AVX")
2812 (ior (not (match_test "TARGET_SSE2"))
2813 (match_test "optimize_function_for_size_p (cfun)"))
2814 (const_string "V4SF")
2816 (const_string "TI"))
2817 (eq_attr "alternative" "9")
2818 (cond [(match_test "TARGET_AVX512VL")
2820 (match_test "TARGET_AVX512F")
2822 (match_test "TARGET_AVX")
2824 (ior (not (match_test "TARGET_SSE2"))
2825 (match_test "optimize_function_for_size_p (cfun)"))
2826 (const_string "V4SF")
2828 (const_string "TI"))
2830 (and (eq_attr "alternative" "10,11")
2831 (not (match_test "TARGET_SSE2")))
2834 (const_string "SI")))
2835 (set (attr "preferred_for_speed")
2836 (cond [(eq_attr "alternative" "6,12")
2837 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2838 (eq_attr "alternative" "7,13")
2839 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2841 (symbol_ref "true")))])
2843 ;; With -Oz, transform mov $imm,reg to the shorter push $imm; pop reg.
2845 [(set (match_operand:SWI248 0 "general_reg_operand")
2846 (match_operand:SWI248 1 "const_int_operand"))]
2847 "optimize_insn_for_size_p () && optimize_size > 1
2848 && operands[1] != const0_rtx
2849 && IN_RANGE (INTVAL (operands[1]), -128, 127)
2850 && !ix86_red_zone_used
2851 && REGNO (operands[0]) != SP_REG"
2852 [(set (match_dup 2) (match_dup 1))
2853 (set (match_dup 0) (match_dup 3))]
2855 if (GET_MODE (operands[0]) != word_mode)
2856 operands[0] = gen_rtx_REG (word_mode, REGNO (operands[0]));
2858 operands[2] = gen_rtx_MEM (word_mode,
2859 gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
2860 operands[3] = gen_rtx_MEM (word_mode,
2861 gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
2864 ;; With -Oz, transform mov $0,mem to the shorter and $0,mem.
2865 ;; Likewise, transform mov $-1,mem to the shorter or $-1,mem.
2867 [(set (match_operand:SWI248 0 "memory_operand")
2868 (match_operand:SWI248 1 "const_int_operand"))]
2869 "(operands[1] == const0_rtx || operands[1] == constm1_rtx)
2870 && optimize_insn_for_size_p () && optimize_size > 1
2871 && peep2_regno_dead_p (0, FLAGS_REG)"
2872 [(parallel [(set (match_dup 0) (match_dup 1))
2873 (clobber (reg:CC FLAGS_REG))])])
2875 (define_insn "*movhi_internal"
2876 [(set (match_operand:HI 0 "nonimmediate_operand"
2877 "=r,r,r,m ,*k,*k ,r ,m ,*k ,?r,?*v,*Yv,*v,*v,jm,m")
2878 (match_operand:HI 1 "general_operand"
2879 "r ,n,m,rn,r ,*km,*k,*k,CBC,*v,r ,C ,*v,m ,*x,*v"))]
2880 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2881 && ix86_hardreg_mov_ok (operands[0], operands[1])"
2883 switch (get_attr_type (insn))
2886 /* movzwl is faster than movw on p2 due to partial word stalls,
2887 though not as fast as an aligned movl. */
2888 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2891 switch (which_alternative)
2894 return "kmovw\t{%k1, %0|%0, %k1}";
2896 return "kmovw\t{%1, %k0|%k0, %1}";
2899 return "kmovw\t{%1, %0|%0, %1}";
2905 return ix86_output_ssemov (insn, operands);
2908 if (satisfies_constraint_C (operands[1]))
2909 return standard_sse_constant_opcode (insn, operands);
2911 if (SSE_REG_P (operands[0]))
2912 return "%vpinsrw\t{$0, %1, %d0|%d0, %1, 0}";
2914 return "%vpextrw\t{$0, %1, %0|%0, %1, 0}";
2917 if (operands[1] == const0_rtx)
2918 return "kxorw\t%0, %0, %0";
2919 else if (operands[1] == constm1_rtx)
2920 return "kxnorw\t%0, %0, %0";
2924 if (get_attr_mode (insn) == MODE_SI)
2925 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2927 return "mov{w}\t{%1, %0|%0, %1}";
2931 (cond [(eq_attr "alternative" "9,10,11,12,13")
2932 (const_string "sse2")
2933 (eq_attr "alternative" "14")
2934 (const_string "sse4_noavx")
2935 (eq_attr "alternative" "15")
2936 (const_string "avx")
2938 (const_string "*")))
2940 (if_then_else (eq_attr "alternative" "14")
2941 (const_string "gpr16")
2942 (const_string "*")))
2944 (cond [(eq_attr "alternative" "4,5,6,7")
2945 (const_string "mskmov")
2946 (eq_attr "alternative" "8")
2947 (const_string "msklog")
2948 (eq_attr "alternative" "13,14,15")
2949 (if_then_else (match_test "TARGET_AVX512FP16")
2950 (const_string "ssemov")
2951 (const_string "sselog1"))
2952 (eq_attr "alternative" "11")
2953 (const_string "sselog1")
2954 (eq_attr "alternative" "9,10,12")
2955 (const_string "ssemov")
2956 (match_test "optimize_function_for_size_p (cfun)")
2957 (const_string "imov")
2958 (and (eq_attr "alternative" "0")
2959 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2960 (not (match_test "TARGET_HIMODE_MATH"))))
2961 (const_string "imov")
2962 (and (eq_attr "alternative" "1,2")
2963 (match_operand:HI 1 "aligned_operand"))
2964 (const_string "imov")
2965 (and (match_test "TARGET_MOVX")
2966 (eq_attr "alternative" "0,2"))
2967 (const_string "imovx")
2969 (const_string "imov")))
2970 (set (attr "prefix")
2971 (cond [(eq_attr "alternative" "4,5,6,7,8")
2972 (const_string "vex")
2973 (eq_attr "alternative" "9,10,11,12,13,14,15")
2974 (const_string "maybe_evex")
2976 (const_string "orig")))
2978 (cond [(eq_attr "alternative" "9,10")
2979 (if_then_else (match_test "TARGET_AVX512FP16")
2981 (const_string "SI"))
2982 (eq_attr "alternative" "13,14,15")
2983 (if_then_else (match_test "TARGET_AVX512FP16")
2985 (const_string "TI"))
2986 (eq_attr "alternative" "11")
2987 (cond [(match_test "TARGET_AVX")
2989 (ior (not (match_test "TARGET_SSE2"))
2990 (match_test "optimize_function_for_size_p (cfun)"))
2991 (const_string "V4SF")
2993 (const_string "TI"))
2994 (eq_attr "alternative" "12")
2995 (cond [(match_test "TARGET_AVX512VL")
2997 (match_test "TARGET_AVX512FP16")
2999 (match_test "TARGET_AVX512F")
3001 (match_test "TARGET_AVX")
3003 (ior (not (match_test "TARGET_SSE2"))
3004 (match_test "optimize_function_for_size_p (cfun)"))
3005 (const_string "V4SF")
3007 (const_string "TI"))
3008 (eq_attr "type" "imovx")
3010 (and (eq_attr "alternative" "1,2")
3011 (match_operand:HI 1 "aligned_operand"))
3013 (and (eq_attr "alternative" "0")
3014 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
3015 (not (match_test "TARGET_HIMODE_MATH"))))
3018 (const_string "HI")))
3019 (set (attr "preferred_for_speed")
3020 (cond [(eq_attr "alternative" "9")
3021 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3022 (eq_attr "alternative" "10")
3023 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3025 (symbol_ref "true")))])
3027 ;; Situation is quite tricky about when to choose full sized (SImode) move
3028 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
3029 ;; partial register dependency machines (such as AMD Athlon), where QImode
3030 ;; moves issue extra dependency and for partial register stalls machines
3031 ;; that don't use QImode patterns (and QImode move cause stall on the next
3034 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
3035 ;; register stall machines with, where we use QImode instructions, since
3036 ;; partial register stall can be caused there. Then we use movzx.
3038 (define_insn "*movqi_internal"
3039 [(set (match_operand:QI 0 "nonimmediate_operand"
3040 "=Q,R,r,q,q,r,r ,?r,m ,*k,*k,*r,*m,*k,*k,*k")
3041 (match_operand:QI 1 "general_operand"
3042 "Q ,R,r,n,m,q,rn, m,qn,*r,*k,*k,*k,*m,C,BC"))]
3043 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3044 && ix86_hardreg_mov_ok (operands[0], operands[1])"
3051 switch (get_attr_type (insn))
3054 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
3055 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
3058 switch (which_alternative)
3061 ops = "kmov%s\t{%%k1, %%0|%%0, %%k1}";
3064 ops = "kmov%s\t{%%1, %%k0|%%k0, %%1}";
3068 gcc_assert (TARGET_AVX512DQ);
3071 ops = "kmov%s\t{%%1, %%0|%%0, %%1}";
3077 suffix = (get_attr_mode (insn) == MODE_HI) ? "w" : "b";
3079 snprintf (buf, sizeof (buf), ops, suffix);
3080 output_asm_insn (buf, operands);
3084 if (operands[1] == const0_rtx)
3086 if (get_attr_mode (insn) == MODE_HI)
3087 return "kxorw\t%0, %0, %0";
3089 return "kxorb\t%0, %0, %0";
3091 else if (operands[1] == constm1_rtx)
3093 gcc_assert (TARGET_AVX512DQ);
3094 return "kxnorb\t%0, %0, %0";
3099 if (get_attr_mode (insn) == MODE_SI)
3100 return "mov{l}\t{%k1, %k0|%k0, %k1}";
3102 return "mov{b}\t{%1, %0|%0, %1}";
3106 (cond [(eq_attr "alternative" "1,2")
3107 (const_string "x64")
3108 (eq_attr "alternative" "12,13,15")
3109 (const_string "avx512dq")
3111 (const_string "*")))
3113 (cond [(eq_attr "alternative" "9,10,11,12,13")
3114 (const_string "mskmov")
3115 (eq_attr "alternative" "14,15")
3116 (const_string "msklog")
3117 (and (eq_attr "alternative" "7")
3118 (not (match_operand:QI 1 "aligned_operand")))
3119 (const_string "imovx")
3120 (match_test "optimize_function_for_size_p (cfun)")
3121 (const_string "imov")
3122 (and (eq_attr "alternative" "5")
3123 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
3124 (not (match_test "TARGET_QIMODE_MATH"))))
3125 (const_string "imov")
3126 (eq_attr "alternative" "5,7")
3127 (const_string "imovx")
3128 (and (match_test "TARGET_MOVX")
3129 (eq_attr "alternative" "4"))
3130 (const_string "imovx")
3132 (const_string "imov")))
3133 (set (attr "prefix")
3134 (if_then_else (eq_attr "alternative" "9,10,11,12,13,14,15")
3135 (const_string "vex")
3136 (const_string "orig")))
3138 (cond [(eq_attr "alternative" "5,6,7")
3140 (eq_attr "alternative" "8")
3142 (and (eq_attr "alternative" "9,10,11,14")
3143 (not (match_test "TARGET_AVX512DQ")))
3145 (eq_attr "type" "imovx")
3147 ;; For -Os, 8-bit immediates are always shorter than 32-bit
3149 (and (eq_attr "type" "imov")
3150 (and (eq_attr "alternative" "3")
3151 (match_test "optimize_function_for_size_p (cfun)")))
3153 ;; For -Os, movl where one or both operands are NON_Q_REGS
3154 ;; and both are LEGACY_REGS is shorter than movb.
3155 ;; Otherwise movb and movl sizes are the same, so decide purely
3156 ;; based on speed factors.
3157 (and (eq_attr "type" "imov")
3158 (and (eq_attr "alternative" "1")
3159 (match_test "optimize_function_for_size_p (cfun)")))
3161 (and (eq_attr "type" "imov")
3162 (and (eq_attr "alternative" "0,1,2,3")
3163 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
3164 (not (match_test "TARGET_PARTIAL_REG_STALL")))))
3166 ;; Avoid partial register stalls when not using QImode arithmetic
3167 (and (eq_attr "type" "imov")
3168 (and (eq_attr "alternative" "0,1,2,3")
3169 (and (match_test "TARGET_PARTIAL_REG_STALL")
3170 (not (match_test "TARGET_QIMODE_MATH")))))
3173 (const_string "QI")))])
3175 /* Reload dislikes loading 0/-1 directly into mask registers.
3176 Try to tidy things up here. */
3178 [(set (match_operand:SWI 0 "general_reg_operand")
3179 (match_operand:SWI 1 "immediate_operand"))
3180 (set (match_operand:SWI 2 "mask_reg_operand")
3182 "peep2_reg_dead_p (2, operands[0])
3183 && (const0_operand (operands[1], <MODE>mode)
3184 || (constm1_operand (operands[1], <MODE>mode)
3185 && (<MODE_SIZE> > 1 || TARGET_AVX512DQ)))"
3186 [(set (match_dup 2) (match_dup 1))])
3188 ;; Stores and loads of ax to arbitrary constant address.
3189 ;; We fake an second form of instruction to force reload to load address
3190 ;; into register when rax is not available
3191 (define_insn "*movabs<mode>_1"
3192 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
3193 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
3194 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
3196 /* Recover the full memory rtx. */
3197 operands[0] = SET_DEST (PATTERN (insn));
3198 switch (which_alternative)
3201 return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}";
3203 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
3208 [(set_attr "type" "imov")
3209 (set_attr "modrm" "0,*")
3210 (set_attr "length_address" "8,0")
3211 (set_attr "length_immediate" "0,*")
3212 (set_attr "memory" "store")
3213 (set_attr "mode" "<MODE>")])
3215 (define_insn "*movabs<mode>_2"
3216 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
3217 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
3218 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
3220 /* Recover the full memory rtx. */
3221 operands[1] = SET_SRC (PATTERN (insn));
3222 switch (which_alternative)
3225 return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}";
3227 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
3232 [(set_attr "type" "imov")
3233 (set_attr "modrm" "0,*")
3234 (set_attr "length_address" "8,0")
3235 (set_attr "length_immediate" "0")
3236 (set_attr "memory" "load")
3237 (set_attr "mode" "<MODE>")])
3239 (define_insn "swap<mode>"
3240 [(set (match_operand:SWI48 0 "register_operand" "+r")
3241 (match_operand:SWI48 1 "register_operand" "+r"))
3245 "xchg{<imodesuffix>}\t%1, %0"
3246 [(set_attr "type" "imov")
3247 (set_attr "mode" "<MODE>")
3248 (set_attr "pent_pair" "np")
3249 (set_attr "athlon_decode" "vector")
3250 (set_attr "amdfam10_decode" "double")
3251 (set_attr "bdver1_decode" "double")])
3253 (define_insn "*swap<mode>"
3254 [(set (match_operand:SWI12 0 "register_operand" "+<r>,r")
3255 (match_operand:SWI12 1 "register_operand" "+<r>,r"))
3260 xchg{<imodesuffix>}\t%1, %0
3262 [(set_attr "type" "imov")
3263 (set_attr "mode" "<MODE>,SI")
3264 (set (attr "preferred_for_size")
3265 (cond [(eq_attr "alternative" "0")
3266 (symbol_ref "false")]
3267 (symbol_ref "true")))
3268 ;; Potential partial reg stall on alternative 1.
3269 (set (attr "preferred_for_speed")
3270 (cond [(eq_attr "alternative" "1")
3271 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
3272 (symbol_ref "true")))
3273 (set_attr "pent_pair" "np")
3274 (set_attr "athlon_decode" "vector")
3275 (set_attr "amdfam10_decode" "double")
3276 (set_attr "bdver1_decode" "double")])
3279 [(set (match_operand:SWI 0 "general_reg_operand")
3280 (match_operand:SWI 1 "general_reg_operand"))
3282 (match_operand:SWI 2 "general_reg_operand"))
3283 (set (match_dup 2) (match_dup 0))]
3284 "peep2_reg_dead_p (3, operands[0])
3285 && optimize_insn_for_size_p ()"
3286 [(parallel [(set (match_dup 1) (match_dup 2))
3287 (set (match_dup 2) (match_dup 1))])])
3289 ;; Convert xchg with a REG_UNUSED note to a mov (variant #1).
3291 [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
3292 (match_operand:SWI 1 "general_reg_operand"))
3293 (set (match_dup 1) (match_dup 0))])]
3294 "((REGNO (operands[0]) != AX_REG
3295 && REGNO (operands[1]) != AX_REG)
3296 || optimize_size < 2
3297 || !optimize_insn_for_size_p ())
3298 && peep2_reg_dead_p (1, operands[0])"
3299 [(set (match_dup 1) (match_dup 0))])
3301 ;; Convert xchg with a REG_UNUSED note to a mov (variant #2).
3303 [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
3304 (match_operand:SWI 1 "general_reg_operand"))
3305 (set (match_dup 1) (match_dup 0))])]
3306 "((REGNO (operands[0]) != AX_REG
3307 && REGNO (operands[1]) != AX_REG)
3308 || optimize_size < 2
3309 || !optimize_insn_for_size_p ())
3310 && peep2_reg_dead_p (1, operands[1])"
3311 [(set (match_dup 0) (match_dup 1))])
3313 ;; Convert moves to/from AX_REG into xchg with -Oz.
3315 [(set (match_operand:SWI48 0 "general_reg_operand")
3316 (match_operand:SWI48 1 "general_reg_operand"))]
3318 && ((REGNO (operands[0]) == AX_REG)
3319 != (REGNO (operands[1]) == AX_REG))
3320 && optimize_insn_for_size_p ()
3321 && peep2_reg_dead_p (1, operands[1])"
3322 [(parallel [(set (match_dup 0) (match_dup 1))
3323 (set (match_dup 1) (match_dup 0))])])
3325 (define_expand "movstrict<mode>"
3326 [(set (strict_low_part (match_operand:SWI12 0 "register_operand"))
3327 (match_operand:SWI12 1 "general_operand"))]
3330 gcc_assert (SUBREG_P (operands[0]));
3331 if ((TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
3332 || !VALID_INT_MODE_P (GET_MODE (SUBREG_REG (operands[0]))))
3336 (define_insn "*movstrict<mode>_1"
3337 [(set (strict_low_part
3338 (match_operand:SWI12 0 "register_operand" "+<r>"))
3339 (match_operand:SWI12 1 "general_operand" "<r>mn"))]
3340 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
3341 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
3342 [(set_attr "type" "imov")
3343 (set_attr "mode" "<MODE>")])
3345 (define_insn "*movstrict<mode>_xor"
3346 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
3347 (match_operand:SWI12 1 "const0_operand"))
3348 (clobber (reg:CC FLAGS_REG))]
3350 "xor{<imodesuffix>}\t%0, %0"
3351 [(set_attr "type" "alu1")
3352 (set_attr "mode" "<MODE>")
3353 (set_attr "length_immediate" "0")])
3355 (define_insn "*movstrictqi_ext<mode>_1"
3356 [(set (strict_low_part
3357 (match_operand:QI 0 "register_operand" "+Q"))
3359 (match_operator:SWI248 2 "extract_operator"
3360 [(match_operand 1 "int248_register_operand" "Q")
3362 (const_int 8)]) 0))]
3363 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
3364 "mov{b}\t{%h1, %0|%0, %h1}"
3365 [(set_attr "type" "imov")
3366 (set_attr "mode" "QI")])
3368 (define_expand "extv<mode>"
3369 [(set (match_operand:SWI24 0 "register_operand")
3370 (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
3371 (match_operand:QI 2 "const_int_operand")
3372 (match_operand:QI 3 "const_int_operand")))]
3375 /* Handle extractions from %ah et al. */
3376 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
3379 unsigned int regno = reg_or_subregno (operands[1]);
3381 /* Be careful to expand only with registers having upper parts. */
3382 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3383 operands[1] = copy_to_reg (operands[1]);
3386 (define_insn "*extv<mode>"
3387 [(set (match_operand:SWI24 0 "register_operand" "=R")
3388 (sign_extract:SWI24 (match_operand 1 "int248_register_operand" "Q")
3392 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
3393 [(set_attr "type" "imovx")
3394 (set_attr "mode" "SI")])
3396 ;; Split sign-extension of single least significant bit as and x,$1;neg x
3397 (define_insn_and_split "*extv<mode>_1_0"
3398 [(set (match_operand:SWI48 0 "register_operand" "=r")
3399 (sign_extract:SWI48 (match_operand:SWI48 1 "register_operand" "0")
3402 (clobber (reg:CC FLAGS_REG))]
3406 [(parallel [(set (match_dup 0) (and:SWI48 (match_dup 1) (const_int 1)))
3407 (clobber (reg:CC FLAGS_REG))])
3408 (parallel [(set (match_dup 0) (neg:SWI48 (match_dup 0)))
3409 (clobber (reg:CC FLAGS_REG))])])
3411 (define_expand "extzv<mode>"
3412 [(set (match_operand:SWI248 0 "register_operand")
3413 (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
3414 (match_operand:QI 2 "const_int_operand")
3415 (match_operand:QI 3 "const_int_operand")))]
3418 if (ix86_expand_pextr (operands))
3421 /* Handle extractions from %ah et al. */
3422 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
3425 unsigned int regno = reg_or_subregno (operands[1]);
3427 /* Be careful to expand only with registers having upper parts. */
3428 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3429 operands[1] = copy_to_reg (operands[1]);
3432 (define_insn "*extzv<mode>"
3433 [(set (match_operand:SWI248 0 "register_operand" "=R")
3434 (zero_extract:SWI248 (match_operand 1 "int248_register_operand" "Q")
3438 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
3439 [(set_attr "type" "imovx")
3440 (set_attr "mode" "SI")])
3442 (define_insn "*extzvqi"
3443 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn,?R")
3445 (match_operator:SWI248 2 "extract_operator"
3446 [(match_operand 1 "int248_register_operand" "Q,Q")
3448 (const_int 8)]) 0))]
3451 switch (get_attr_type (insn))
3454 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
3456 return "mov{b}\t{%h1, %0|%0, %h1}";
3459 [(set_attr "addr" "gpr8,*")
3461 (if_then_else (and (match_operand:QI 0 "register_operand")
3462 (ior (not (match_operand:QI 0 "QIreg_operand"))
3463 (match_test "TARGET_MOVX")))
3464 (const_string "imovx")
3465 (const_string "imov")))
3467 (if_then_else (eq_attr "type" "imovx")
3469 (const_string "QI")))])
3471 (define_expand "insv<mode>"
3472 [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
3473 (match_operand:QI 1 "const_int_operand")
3474 (match_operand:QI 2 "const_int_operand"))
3475 (match_operand:SWI248 3 "register_operand"))]
3480 if (ix86_expand_pinsr (operands))
3483 /* Handle insertions to %ah et al. */
3484 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
3487 unsigned int regno = reg_or_subregno (operands[0]);
3489 /* Be careful to expand only with registers having upper parts. */
3490 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3491 dst = copy_to_reg (operands[0]);
3495 emit_insn (gen_insv_1 (<MODE>mode, dst, operands[3]));
3497 /* Fix up the destination if needed. */
3498 if (dst != operands[0])
3499 emit_move_insn (operands[0], dst);
3504 (define_insn "@insv<mode>_1"
3505 [(set (zero_extract:SWI248
3506 (match_operand 0 "int248_register_operand" "+Q")
3509 (match_operand:SWI248 1 "general_operand" "QnBn"))]
3512 if (CONST_INT_P (operands[1]))
3513 operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
3514 return "mov{b}\t{%b1, %h0|%h0, %b1}";
3516 [(set_attr "addr" "gpr8")
3517 (set_attr "type" "imov")
3518 (set_attr "mode" "QI")])
3520 (define_insn "*insvqi_1"
3521 [(set (zero_extract:SWI248
3522 (match_operand 0 "int248_register_operand" "+Q")
3526 (match_operand:QI 1 "general_operand" "QnBn") 0))]
3528 "mov{b}\t{%1, %h0|%h0, %1}"
3529 [(set_attr "addr" "gpr8")
3530 (set_attr "type" "imov")
3531 (set_attr "mode" "QI")])
3533 ;; Eliminate redundant insv, e.g. xorl %eax,%eax; movb $0, %ah
3535 [(parallel [(set (match_operand:SWI48 0 "general_reg_operand")
3537 (clobber (reg:CC FLAGS_REG))])
3538 (set (zero_extract:SWI248 (match_operand 1 "int248_register_operand")
3542 "REGNO (operands[0]) == REGNO (operands[1])"
3543 [(parallel [(set (match_operand:SWI48 0 "general_reg_operand")
3545 (clobber (reg:CC FLAGS_REG))])])
3547 ;; Combine movl followed by movb.
3549 [(set (match_operand:SWI48 0 "general_reg_operand")
3550 (match_operand:SWI48 1 "const_int_operand"))
3551 (set (zero_extract:SWI248 (match_operand 2 "int248_register_operand")
3554 (match_operand:SWI248 3 "const_int_operand"))]
3555 "REGNO (operands[0]) == REGNO (operands[2])"
3556 [(set (match_operand:SWI48 0 "general_reg_operand")
3559 HOST_WIDE_INT tmp = INTVAL (operands[1]) & ~HOST_WIDE_INT_C (0xff00);
3560 tmp |= (INTVAL (operands[3]) & 0xff) << 8;
3561 operands[4] = gen_int_mode (tmp, <SWI48:MODE>mode);
3564 (define_insn "*insvqi_2"
3565 [(set (zero_extract:SWI248
3566 (match_operand 0 "int248_register_operand" "+Q")
3569 (match_operator:SWI248 2 "extract_operator"
3570 [(match_operand 1 "int248_register_operand" "Q")
3574 "mov{b}\t{%h1, %h0|%h0, %h1}"
3575 [(set_attr "type" "imov")
3576 (set_attr "mode" "QI")])
3578 (define_insn "*insvqi_3"
3579 [(set (zero_extract:SWI248
3580 (match_operand 0 "int248_register_operand" "+Q")
3584 (match_operand:SWI248 1 "register_operand" "Q")
3587 "mov{b}\t{%h1, %h0|%h0, %h1}"
3588 [(set_attr "type" "imov")
3589 (set_attr "mode" "QI")])
3591 (define_code_iterator any_or_plus [plus ior xor])
3593 (define_insn_and_split "*insvti_highpart_1"
3594 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro,r,r,&r")
3597 (match_operand:TI 1 "nonimmediate_operand" "r,m,r,m")
3598 (match_operand:TI 3 "const_scalar_int_operand" "n,n,n,n"))
3601 (match_operand:DI 2 "nonimmediate_operand" "r,r,m,m"))
3604 && CONST_WIDE_INT_P (operands[3])
3605 && CONST_WIDE_INT_NUNITS (operands[3]) == 2
3606 && CONST_WIDE_INT_ELT (operands[3], 0) == -1
3607 && CONST_WIDE_INT_ELT (operands[3], 1) == 0"
3609 "&& reload_completed"
3612 operands[4] = gen_lowpart (DImode, operands[1]);
3613 split_double_concat (TImode, operands[0], operands[4], operands[2]);
3617 (define_insn_and_split "*insvti_lowpart_1"
3618 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro,r,r,&r")
3621 (match_operand:TI 1 "nonimmediate_operand" "r,m,r,m")
3622 (match_operand:TI 3 "const_scalar_int_operand" "n,n,n,n"))
3624 (match_operand:DI 2 "nonimmediate_operand" "r,r,m,m"))))]
3626 && CONST_WIDE_INT_P (operands[3])
3627 && CONST_WIDE_INT_NUNITS (operands[3]) == 2
3628 && CONST_WIDE_INT_ELT (operands[3], 0) == 0
3629 && CONST_WIDE_INT_ELT (operands[3], 1) == -1"
3631 "&& reload_completed"
3634 operands[4] = gen_highpart (DImode, operands[1]);
3635 split_double_concat (TImode, operands[0], operands[2], operands[4]);
3639 (define_insn_and_split "*insvdi_lowpart_1"
3640 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro,r,r,&r")
3643 (match_operand:DI 1 "nonimmediate_operand" "r,m,r,m")
3644 (match_operand:DI 3 "const_int_operand" "n,n,n,n"))
3646 (match_operand:SI 2 "nonimmediate_operand" "r,r,m,m"))))]
3648 && CONST_INT_P (operands[3])
3649 && UINTVAL (operands[3]) == 0xffffffff00000000ll"
3651 "&& reload_completed"
3654 operands[4] = gen_highpart (SImode, operands[1]);
3655 split_double_concat (DImode, operands[0], operands[2], operands[4]);
3659 ;; Floating point push instructions.
3661 (define_insn "*pushtf"
3662 [(set (match_operand:TF 0 "push_operand" "=<,<")
3663 (match_operand:TF 1 "general_no_elim_operand" "v,*roC"))]
3664 "TARGET_64BIT || TARGET_SSE"
3666 /* This insn should be already split before reg-stack. */
3669 [(set_attr "isa" "*,x64")
3670 (set_attr "type" "multi")
3671 (set_attr "unit" "sse,*")
3672 (set_attr "mode" "TF,DI")])
3674 ;; %%% Kill this when call knows how to work this out.
3676 [(set (match_operand:TF 0 "push_operand")
3677 (match_operand:TF 1 "sse_reg_operand"))]
3678 "TARGET_SSE && reload_completed"
3679 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3680 (set (match_dup 0) (match_dup 1))]
3682 /* Preserve memory attributes. */
3683 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3686 (define_insn "*pushxf"
3687 [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<")
3688 (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF,oC"))]
3691 /* This insn should be already split before reg-stack. */
3694 [(set_attr "isa" "*,*,*,nox64,x64")
3695 (set_attr "type" "multi")
3696 (set_attr "unit" "i387,*,*,*,*")
3698 (cond [(eq_attr "alternative" "1,2,3,4")
3699 (if_then_else (match_test "TARGET_64BIT")
3701 (const_string "SI"))
3703 (const_string "XF")))
3704 (set (attr "preferred_for_size")
3705 (cond [(eq_attr "alternative" "1")
3706 (symbol_ref "false")]
3707 (symbol_ref "true")))])
3709 ;; %%% Kill this when call knows how to work this out.
3711 [(set (match_operand:XF 0 "push_operand")
3712 (match_operand:XF 1 "fp_register_operand"))]
3714 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3715 (set (match_dup 0) (match_dup 1))]
3717 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (XFmode)));
3718 /* Preserve memory attributes. */
3719 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3722 (define_insn "*pushdf"
3723 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
3724 (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmC,v"))]
3727 /* This insn should be already split before reg-stack. */
3730 [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
3731 (set_attr "type" "multi")
3732 (set_attr "unit" "i387,*,*,*,*,sse")
3733 (set_attr "mode" "DF,SI,SI,SI,DI,DF")
3734 (set (attr "preferred_for_size")
3735 (cond [(eq_attr "alternative" "1")
3736 (symbol_ref "false")]
3737 (symbol_ref "true")))
3738 (set (attr "preferred_for_speed")
3739 (cond [(eq_attr "alternative" "1")
3740 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3741 (symbol_ref "true")))])
3743 ;; %%% Kill this when call knows how to work this out.
3745 [(set (match_operand:DF 0 "push_operand")
3746 (match_operand:DF 1 "any_fp_register_operand"))]
3748 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3749 (set (match_dup 0) (match_dup 1))]
3751 /* Preserve memory attributes. */
3752 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3755 (define_mode_iterator HFBF [HF BF])
3757 (define_insn "*push<mode>_rex64"
3758 [(set (match_operand:HFBF 0 "push_operand" "=X,X")
3759 (match_operand:HFBF 1 "nonmemory_no_elim_operand" "r,x"))]
3762 /* Anything else should be already split before reg-stack. */
3763 gcc_assert (which_alternative == 0);
3764 return "push{q}\t%q1";
3766 [(set_attr "isa" "*,sse4")
3767 (set_attr "type" "push,multi")
3768 (set_attr "mode" "DI,TI")])
3770 (define_insn "*push<mode>"
3771 [(set (match_operand:HFBF 0 "push_operand" "=X,X")
3772 (match_operand:HFBF 1 "general_no_elim_operand" "rmF,x"))]
3775 /* Anything else should be already split before reg-stack. */
3776 gcc_assert (which_alternative == 0);
3777 return "push{l}\t%k1";
3779 [(set_attr "isa" "*,sse4")
3780 (set_attr "type" "push,multi")
3781 (set_attr "mode" "SI,TI")])
3783 (define_insn "push2_di"
3784 [(set (match_operand:TI 0 "push_operand" "=<")
3785 (unspec:TI [(match_operand:DI 1 "register_operand" "r")
3786 (match_operand:DI 2 "register_operand" "r")]
3788 "TARGET_APX_PUSH2POP2"
3789 "push2\t{%2, %1|%1, %2}"
3790 [(set_attr "mode" "TI")
3791 (set_attr "type" "multi")
3792 (set_attr "prefix" "evex")])
3794 (define_insn "pop2_di"
3795 [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
3796 (unspec:DI [(match_operand:TI 1 "pop_operand" ">")]
3797 UNSPEC_APXPOP2_LOW))
3798 (set (match_operand:DI 2 "register_operand" "=r")
3799 (unspec:DI [(const_int 0)] UNSPEC_APXPOP2_HIGH))])]
3800 "TARGET_APX_PUSH2POP2"
3801 "pop2\t{%2, %0|%0, %2}"
3802 [(set_attr "mode" "TI")
3803 (set_attr "prefix" "evex")])
3805 (define_insn "pushp_di"
3806 [(set (match_operand:DI 0 "push_operand" "=<")
3807 (match_operand:DI 1 "register_operand" "r"))
3808 (unspec:DI [(const_int 0)] UNSPEC_APX_PPX)]
3811 [(set_attr "mode" "DI")])
3813 (define_insn "popp_di"
3814 [(set (match_operand:DI 0 "register_operand" "=r")
3815 (match_operand:DI 1 "pop_operand" ">"))
3816 (unspec:DI [(const_int 0)] UNSPEC_APX_PPX)]
3819 [(set_attr "mode" "DI")])
3821 (define_insn "push2p_di"
3822 [(set (match_operand:TI 0 "push_operand" "=<")
3823 (unspec:TI [(match_operand:DI 1 "register_operand" "r")
3824 (match_operand:DI 2 "register_operand" "r")]
3826 (unspec:DI [(const_int 0)] UNSPEC_APX_PPX)]
3827 "TARGET_APX_PUSH2POP2 && TARGET_APX_PPX"
3828 "push2p\t{%2, %1|%1, %2}"
3829 [(set_attr "mode" "TI")
3830 (set_attr "type" "multi")
3831 (set_attr "prefix" "evex")])
3833 (define_insn "pop2p_di"
3834 [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
3835 (unspec:DI [(match_operand:TI 1 "pop_operand" ">")]
3836 UNSPEC_APXPOP2_LOW))
3837 (set (match_operand:DI 2 "register_operand" "=r")
3838 (unspec:DI [(const_int 0)] UNSPEC_APXPOP2_HIGH))
3839 (unspec:DI [(const_int 0)] UNSPEC_APX_PPX)])]
3840 "TARGET_APX_PUSH2POP2 && TARGET_APX_PPX"
3841 "pop2p\t{%2, %0|%0, %2}"
3842 [(set_attr "mode" "TI")
3843 (set_attr "prefix" "evex")])
3845 (define_insn "*pushsf_rex64"
3846 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3847 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,v"))]
3850 /* Anything else should be already split before reg-stack. */
3851 if (which_alternative != 1)
3853 return "push{q}\t%q1";
3855 [(set_attr "type" "multi,push,multi")
3856 (set_attr "unit" "i387,*,*")
3857 (set_attr "mode" "SF,DI,SF")])
3859 (define_insn "*pushsf"
3860 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3861 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,v"))]
3864 /* Anything else should be already split before reg-stack. */
3865 if (which_alternative != 1)
3867 return "push{l}\t%1";
3869 [(set_attr "type" "multi,push,multi")
3870 (set_attr "unit" "i387,*,*")
3871 (set_attr "mode" "SF,SI,SF")])
3873 (define_mode_iterator MODESH [SF HF BF])
3874 ;; %%% Kill this when call knows how to work this out.
3876 [(set (match_operand:MODESH 0 "push_operand")
3877 (match_operand:MODESH 1 "any_fp_register_operand"))]
3879 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3880 (set (match_dup 0) (match_dup 1))]
3882 rtx op = XEXP (operands[0], 0);
3883 if (GET_CODE (op) == PRE_DEC)
3885 gcc_assert (!TARGET_64BIT);
3890 op = XEXP (XEXP (op, 1), 1);
3891 gcc_assert (CONST_INT_P (op));
3894 /* Preserve memory attributes. */
3895 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3899 [(set (match_operand:SF 0 "push_operand")
3900 (match_operand:SF 1 "memory_operand"))]
3902 && find_constant_src (insn)"
3903 [(set (match_dup 0) (match_dup 2))]
3904 "operands[2] = find_constant_src (curr_insn);")
3907 [(set (match_operand 0 "push_operand")
3908 (match_operand 1 "general_gr_operand"))]
3910 && (GET_MODE (operands[0]) == TFmode
3911 || GET_MODE (operands[0]) == XFmode
3912 || GET_MODE (operands[0]) == DFmode)"
3914 "ix86_split_long_move (operands); DONE;")
3916 ;; Floating point move instructions.
3918 (define_expand "movtf"
3919 [(set (match_operand:TF 0 "nonimmediate_operand")
3920 (match_operand:TF 1 "nonimmediate_operand"))]
3921 "TARGET_64BIT || TARGET_SSE"
3922 "ix86_expand_move (TFmode, operands); DONE;")
3924 (define_expand "mov<mode>"
3925 [(set (match_operand:X87MODEFH 0 "nonimmediate_operand")
3926 (match_operand:X87MODEFH 1 "general_operand"))]
3928 "ix86_expand_move (<MODE>mode, operands); DONE;")
3930 (define_insn "*movtf_internal"
3931 [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o")
3932 (match_operand:TF 1 "general_operand" "C ,vm,v,*roF,*rC"))]
3933 "(TARGET_64BIT || TARGET_SSE)
3934 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3935 && (lra_in_progress || reload_completed
3936 || !CONST_DOUBLE_P (operands[1])
3937 || (standard_sse_constant_p (operands[1], TFmode) == 1
3938 && !memory_operand (operands[0], TFmode))
3939 || (!TARGET_MEMORY_MISMATCH_STALL
3940 && memory_operand (operands[0], TFmode)))"
3942 switch (get_attr_type (insn))
3945 return standard_sse_constant_opcode (insn, operands);
3948 return ix86_output_ssemov (insn, operands);
3957 [(set_attr "isa" "*,*,*,x64,x64")
3958 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3959 (set (attr "prefix")
3960 (if_then_else (eq_attr "type" "sselog1,ssemov")
3961 (const_string "maybe_vex")
3962 (const_string "orig")))
3964 (cond [(eq_attr "alternative" "3,4")
3966 (match_test "TARGET_AVX")
3968 (ior (not (match_test "TARGET_SSE2"))
3969 (match_test "optimize_function_for_size_p (cfun)"))
3970 (const_string "V4SF")
3971 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3972 (const_string "V4SF")
3973 (and (eq_attr "alternative" "2")
3974 (match_test "TARGET_SSE_TYPELESS_STORES"))
3975 (const_string "V4SF")
3977 (const_string "TI")))])
3980 [(set (match_operand:TF 0 "nonimmediate_gr_operand")
3981 (match_operand:TF 1 "general_gr_operand"))]
3984 "ix86_split_long_move (operands); DONE;")
3986 ;; Possible store forwarding (partial memory) stall
3987 ;; in alternatives 4, 6, 7 and 8.
3988 (define_insn "*movxf_internal"
3989 [(set (match_operand:XF 0 "nonimmediate_operand"
3990 "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r ,o ,o")
3991 (match_operand:XF 1 "general_operand"
3992 "fm,f,G,roF,r ,*roF,*r,F ,C ,roF,rF,rC"))]
3993 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3994 && (lra_in_progress || reload_completed
3995 || !CONST_DOUBLE_P (operands[1])
3996 || ((optimize_function_for_size_p (cfun)
3997 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3998 && standard_80387_constant_p (operands[1]) > 0
3999 && !memory_operand (operands[0], XFmode))
4000 || (!TARGET_MEMORY_MISMATCH_STALL
4001 && memory_operand (operands[0], XFmode))
4002 || !TARGET_HARD_XF_REGS)"
4004 switch (get_attr_type (insn))
4007 if (which_alternative == 2)
4008 return standard_80387_constant_opcode (operands[1]);
4009 return output_387_reg_move (insn, operands);
4019 (cond [(eq_attr "alternative" "7,10")
4020 (const_string "nox64")
4021 (eq_attr "alternative" "8,11")
4022 (const_string "x64")
4024 (const_string "*")))
4026 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
4027 (const_string "multi")
4029 (const_string "fmov")))
4031 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
4032 (if_then_else (match_test "TARGET_64BIT")
4034 (const_string "SI"))
4036 (const_string "XF")))
4037 (set (attr "preferred_for_size")
4038 (cond [(eq_attr "alternative" "3,4")
4039 (symbol_ref "false")]
4040 (symbol_ref "true")))
4041 (set (attr "enabled")
4042 (cond [(eq_attr "alternative" "9,10,11")
4044 (match_test "TARGET_HARD_XF_REGS")
4045 (symbol_ref "false")
4047 (not (match_test "TARGET_HARD_XF_REGS"))
4048 (symbol_ref "false")
4050 (const_string "*")))])
4053 [(set (match_operand:XF 0 "nonimmediate_gr_operand")
4054 (match_operand:XF 1 "general_gr_operand"))]
4057 "ix86_split_long_move (operands); DONE;")
4059 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
4060 (define_insn "*movdf_internal"
4061 [(set (match_operand:DF 0 "nonimmediate_operand"
4062 "=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")
4063 (match_operand:DF 1 "general_operand"
4064 "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"))]
4065 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
4066 && (lra_in_progress || reload_completed
4067 || !CONST_DOUBLE_P (operands[1])
4068 || ((optimize_function_for_size_p (cfun)
4069 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
4070 && IS_STACK_MODE (DFmode)
4071 && standard_80387_constant_p (operands[1]) > 0
4072 && !memory_operand (operands[0], DFmode))
4073 || (TARGET_SSE2 && TARGET_SSE_MATH
4074 && standard_sse_constant_p (operands[1], DFmode) == 1
4075 && !memory_operand (operands[0], DFmode))
4076 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
4077 && memory_operand (operands[0], DFmode))
4078 || !TARGET_HARD_DF_REGS)"
4080 switch (get_attr_type (insn))
4083 if (which_alternative == 2)
4084 return standard_80387_constant_opcode (operands[1]);
4085 return output_387_reg_move (insn, operands);
4091 if (get_attr_mode (insn) == MODE_SI)
4092 return "mov{l}\t{%1, %k0|%k0, %1}";
4093 else if (which_alternative == 11)
4094 return "movabs{q}\t{%1, %0|%0, %1}";
4096 return "mov{q}\t{%1, %0|%0, %1}";
4099 return standard_sse_constant_opcode (insn, operands);
4102 return ix86_output_ssemov (insn, operands);
4109 (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
4110 (const_string "nox64")
4111 (eq_attr "alternative" "8,9,10,11,24,25")
4112 (const_string "x64")
4113 (eq_attr "alternative" "12,13,14,15")
4114 (const_string "sse2")
4115 (eq_attr "alternative" "20,21")
4116 (const_string "x64_sse2")
4118 (const_string "*")))
4120 (cond [(eq_attr "alternative" "0,1,2")
4121 (const_string "fmov")
4122 (eq_attr "alternative" "3,4,5,6,7,22,23")
4123 (const_string "multi")
4124 (eq_attr "alternative" "8,9,10,11,24,25")
4125 (const_string "imov")
4126 (eq_attr "alternative" "12,16")
4127 (const_string "sselog1")
4129 (const_string "ssemov")))
4131 (if_then_else (eq_attr "alternative" "11")
4133 (const_string "*")))
4134 (set (attr "length_immediate")
4135 (if_then_else (eq_attr "alternative" "11")
4137 (const_string "*")))
4138 (set (attr "prefix")
4139 (if_then_else (eq_attr "type" "sselog1,ssemov")
4140 (const_string "maybe_vex")
4141 (const_string "orig")))
4142 (set (attr "prefix_data16")
4144 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
4145 (eq_attr "mode" "V1DF"))
4147 (const_string "*")))
4149 (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
4151 (eq_attr "alternative" "8,9,11,20,21,24,25")
4154 /* xorps is one byte shorter for non-AVX targets. */
4155 (eq_attr "alternative" "12,16")
4156 (cond [(match_test "TARGET_AVX")
4157 (const_string "V2DF")
4158 (ior (not (match_test "TARGET_SSE2"))
4159 (match_test "optimize_function_for_size_p (cfun)"))
4160 (const_string "V4SF")
4161 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
4164 (const_string "V2DF"))
4166 /* For architectures resolving dependencies on
4167 whole SSE registers use movapd to break dependency
4168 chains, otherwise use short move to avoid extra work. */
4170 /* movaps is one byte shorter for non-AVX targets. */
4171 (eq_attr "alternative" "13,17")
4172 (cond [(match_test "TARGET_AVX512VL")
4173 (const_string "V2DF")
4174 (match_test "TARGET_AVX512F")
4176 (match_test "TARGET_AVX")
4177 (const_string "V2DF")
4178 (ior (not (match_test "TARGET_SSE2"))
4179 (match_test "optimize_function_for_size_p (cfun)"))
4180 (const_string "V4SF")
4181 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
4182 (const_string "V4SF")
4183 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
4184 (const_string "V2DF")
4186 (const_string "DF"))
4188 /* For architectures resolving dependencies on register
4189 parts we may avoid extra work to zero out upper part
4191 (eq_attr "alternative" "14,18")
4192 (cond [(not (match_test "TARGET_SSE2"))
4193 (const_string "V2SF")
4194 (match_test "TARGET_AVX")
4196 (match_test "TARGET_SSE_SPLIT_REGS")
4197 (const_string "V1DF")
4199 (const_string "DF"))
4201 (and (eq_attr "alternative" "15,19")
4202 (not (match_test "TARGET_SSE2")))
4203 (const_string "V2SF")
4205 (const_string "DF")))
4206 (set (attr "preferred_for_size")
4207 (cond [(eq_attr "alternative" "3,4")
4208 (symbol_ref "false")]
4209 (symbol_ref "true")))
4210 (set (attr "preferred_for_speed")
4211 (cond [(eq_attr "alternative" "3,4")
4212 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")
4213 (eq_attr "alternative" "20")
4214 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4215 (eq_attr "alternative" "21")
4216 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4218 (symbol_ref "true")))
4219 (set (attr "enabled")
4220 (cond [(eq_attr "alternative" "22,23,24,25")
4222 (match_test "TARGET_HARD_DF_REGS")
4223 (symbol_ref "false")
4225 (not (match_test "TARGET_HARD_DF_REGS"))
4226 (symbol_ref "false")
4228 (const_string "*")))])
4231 [(set (match_operand:DF 0 "nonimmediate_gr_operand")
4232 (match_operand:DF 1 "general_gr_operand"))]
4233 "!TARGET_64BIT && reload_completed"
4235 "ix86_split_long_move (operands); DONE;")
4237 (define_insn "*movsf_internal"
4238 [(set (match_operand:SF 0 "nonimmediate_operand"
4239 "=Yf*f,m ,Yf*f,?r ,?m,Yv,v,v,m,?r,?v,!*y,!*y,!m,!r,!*y,r ,m")
4240 (match_operand:SF 1 "general_operand"
4241 "Yf*fm,Yf*f,G ,rmF,rF,C ,v,m,v,v ,r ,*y ,m ,*y,*y,r ,rmF,rF"))]
4242 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
4243 && (lra_in_progress || reload_completed
4244 || !CONST_DOUBLE_P (operands[1])
4245 || ((optimize_function_for_size_p (cfun)
4246 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
4247 && IS_STACK_MODE (SFmode)
4248 && standard_80387_constant_p (operands[1]) > 0)
4249 || (TARGET_SSE && TARGET_SSE_MATH
4250 && standard_sse_constant_p (operands[1], SFmode) == 1)
4251 || memory_operand (operands[0], SFmode)
4252 || !TARGET_HARD_SF_REGS)"
4254 switch (get_attr_type (insn))
4257 if (which_alternative == 2)
4258 return standard_80387_constant_opcode (operands[1]);
4259 return output_387_reg_move (insn, operands);
4262 return "mov{l}\t{%1, %0|%0, %1}";
4265 return standard_sse_constant_opcode (insn, operands);
4268 return ix86_output_ssemov (insn, operands);
4271 switch (get_attr_mode (insn))
4274 return "movq\t{%1, %0|%0, %1}";
4276 return "movd\t{%1, %0|%0, %1}";
4287 (cond [(eq_attr "alternative" "9,10")
4288 (const_string "sse2")
4290 (const_string "*")))
4292 (cond [(eq_attr "alternative" "0,1,2")
4293 (const_string "fmov")
4294 (eq_attr "alternative" "3,4,16,17")
4295 (const_string "imov")
4296 (eq_attr "alternative" "5")
4297 (const_string "sselog1")
4298 (eq_attr "alternative" "11,12,13,14,15")
4299 (const_string "mmxmov")
4301 (const_string "ssemov")))
4302 (set (attr "prefix")
4303 (if_then_else (eq_attr "type" "sselog1,ssemov")
4304 (const_string "maybe_vex")
4305 (const_string "orig")))
4306 (set (attr "prefix_data16")
4307 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
4309 (const_string "*")))
4311 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
4313 (eq_attr "alternative" "11")
4315 (eq_attr "alternative" "5")
4316 (cond [(and (match_test "TARGET_AVX512F && TARGET_EVEX512")
4317 (not (match_test "TARGET_PREFER_AVX256")))
4318 (const_string "V16SF")
4319 (match_test "TARGET_AVX")
4320 (const_string "V4SF")
4321 (ior (not (match_test "TARGET_SSE2"))
4322 (match_test "optimize_function_for_size_p (cfun)"))
4323 (const_string "V4SF")
4324 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
4327 (const_string "V4SF"))
4329 /* For architectures resolving dependencies on
4330 whole SSE registers use APS move to break dependency
4331 chains, otherwise use short move to avoid extra work.
4333 Do the same for architectures resolving dependencies on
4334 the parts. While in DF mode it is better to always handle
4335 just register parts, the SF mode is different due to lack
4336 of instructions to load just part of the register. It is
4337 better to maintain the whole registers in single format
4338 to avoid problems on using packed logical operations. */
4339 (eq_attr "alternative" "6")
4340 (cond [(match_test "TARGET_AVX512VL")
4341 (const_string "V4SF")
4342 (match_test "TARGET_AVX512F")
4344 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
4345 (match_test "TARGET_SSE_SPLIT_REGS"))
4346 (const_string "V4SF")
4348 (const_string "SF"))
4350 (const_string "SF")))
4351 (set (attr "preferred_for_speed")
4352 (cond [(eq_attr "alternative" "9,14")
4353 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4354 (eq_attr "alternative" "10,15")
4355 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4357 (symbol_ref "true")))
4358 (set (attr "enabled")
4359 (cond [(eq_attr "alternative" "16,17")
4361 (match_test "TARGET_HARD_SF_REGS")
4362 (symbol_ref "false")
4364 (not (match_test "TARGET_HARD_SF_REGS"))
4365 (symbol_ref "false")
4367 (const_string "*")))])
4369 (define_mode_attr hfbfconstf
4372 (define_insn "*mov<mode>_internal"
4373 [(set (match_operand:HFBF 0 "nonimmediate_operand"
4374 "=?r,?r,?r,?m ,Yv,v,?r,jm,m,?v,v")
4375 (match_operand:HFBF 1 "general_operand"
4376 "r ,F ,m ,r<hfbfconstf>,C ,v, v,v ,v,r ,m"))]
4377 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
4380 || !CONST_DOUBLE_P (operands[1])
4382 && standard_sse_constant_p (operands[1], <MODE>mode) == 1)
4383 || memory_operand (operands[0], <MODE>mode))"
4385 switch (get_attr_type (insn))
4388 /* movzwl is faster than movw on p2 due to partial word stalls,
4389 though not as fast as an aligned movl. */
4390 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
4393 return ix86_output_ssemov (insn, operands);
4396 if (satisfies_constraint_C (operands[1]))
4397 return standard_sse_constant_opcode (insn, operands);
4399 if (SSE_REG_P (operands[0]))
4400 return "%vpinsrw\t{$0, %1, %d0|%d0, %1, 0}";
4402 return "%vpextrw\t{$0, %1, %0|%0, %1, 0}";
4405 if (get_attr_mode (insn) == MODE_SI)
4406 return "mov{l}\t{%k1, %k0|%k0, %k1}";
4408 return "mov{w}\t{%1, %0|%0, %1}";
4412 (cond [(eq_attr "alternative" "4,5,6,9,10")
4413 (const_string "sse2")
4414 (eq_attr "alternative" "7")
4415 (const_string "sse4_noavx")
4416 (eq_attr "alternative" "8")
4417 (const_string "avx")
4419 (const_string "*")))
4421 (if_then_else (eq_attr "alternative" "7")
4422 (const_string "gpr16")
4423 (const_string "*")))
4425 (cond [(eq_attr "alternative" "4")
4426 (const_string "sselog1")
4427 (eq_attr "alternative" "5,6,9")
4428 (const_string "ssemov")
4429 (eq_attr "alternative" "7,8,10")
4431 (match_test ("TARGET_AVX512FP16"))
4432 (const_string "ssemov")
4433 (const_string "sselog1"))
4434 (match_test "optimize_function_for_size_p (cfun)")
4435 (const_string "imov")
4436 (and (eq_attr "alternative" "0")
4437 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
4438 (not (match_test "TARGET_HIMODE_MATH"))))
4439 (const_string "imov")
4440 (and (eq_attr "alternative" "1,2")
4441 (match_operand:HI 1 "aligned_operand"))
4442 (const_string "imov")
4443 (and (match_test "TARGET_MOVX")
4444 (eq_attr "alternative" "0,2"))
4445 (const_string "imovx")
4447 (const_string "imov")))
4448 (set (attr "prefix")
4449 (cond [(eq_attr "alternative" "4,5,6,7,8,9,10")
4450 (const_string "maybe_vex")
4452 (const_string "orig")))
4454 (cond [(eq_attr "alternative" "4")
4455 (const_string "V4SF")
4456 (eq_attr "alternative" "6,9")
4458 (match_test "TARGET_AVX512FP16")
4460 (const_string "SI"))
4461 (eq_attr "alternative" "7,8,10")
4463 (match_test "TARGET_AVX512FP16")
4465 (const_string "TI"))
4466 (eq_attr "alternative" "5")
4467 (cond [(match_test "TARGET_AVX512VL")
4468 (const_string "V4SF")
4469 (match_test "TARGET_AVX512FP16")
4471 (match_test "TARGET_AVX512F")
4473 (match_test "TARGET_AVX")
4474 (const_string "V4SF")
4475 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
4476 (match_test "TARGET_SSE_SPLIT_REGS"))
4477 (const_string "V4SF")
4479 (const_string "SF"))
4480 (eq_attr "type" "imovx")
4482 (and (eq_attr "alternative" "1,2")
4483 (match_operand:HI 1 "aligned_operand"))
4485 (and (eq_attr "alternative" "0")
4486 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
4487 (not (match_test "TARGET_HIMODE_MATH"))))
4490 (const_string "HI")))
4491 (set (attr "enabled")
4492 (cond [(and (match_test "<MODE>mode == BFmode")
4493 (eq_attr "alternative" "1"))
4494 (symbol_ref "false")
4496 (const_string "*")))])
4499 [(set (match_operand 0 "any_fp_register_operand")
4500 (match_operand 1 "memory_operand"))]
4502 && (GET_MODE (operands[0]) == TFmode
4503 || GET_MODE (operands[0]) == XFmode
4504 || GET_MODE (operands[0]) == DFmode
4505 || GET_MODE (operands[0]) == SFmode)
4506 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
4507 [(set (match_dup 0) (match_dup 2))]
4508 "operands[2] = find_constant_src (curr_insn);")
4511 [(set (match_operand 0 "any_fp_register_operand")
4512 (float_extend (match_operand 1 "memory_operand")))]
4514 && (GET_MODE (operands[0]) == TFmode
4515 || GET_MODE (operands[0]) == XFmode
4516 || GET_MODE (operands[0]) == DFmode)
4517 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
4518 [(set (match_dup 0) (match_dup 2))]
4519 "operands[2] = find_constant_src (curr_insn);")
4521 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
4523 [(set (match_operand:X87MODEF 0 "fp_register_operand")
4524 (match_operand:X87MODEF 1 "immediate_operand"))]
4526 && (standard_80387_constant_p (operands[1]) == 8
4527 || standard_80387_constant_p (operands[1]) == 9)"
4528 [(set (match_dup 0)(match_dup 1))
4530 (neg:X87MODEF (match_dup 0)))]
4532 if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
4533 operands[1] = CONST0_RTX (<MODE>mode);
4535 operands[1] = CONST1_RTX (<MODE>mode);
4538 (define_insn "*swapxf"
4539 [(set (match_operand:XF 0 "register_operand" "+f")
4540 (match_operand:XF 1 "register_operand" "+f"))
4545 if (STACK_TOP_P (operands[0]))
4550 [(set_attr "type" "fxch")
4551 (set_attr "mode" "XF")])
4554 ;; Zero extension instructions
4556 (define_insn_and_split "zero_extendditi2"
4557 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4558 (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "rm,r")))]
4561 "&& reload_completed"
4562 [(set (match_dup 3) (match_dup 1))
4563 (set (match_dup 4) (const_int 0))]
4564 "split_double_mode (TImode, &operands[0], 1, &operands[3], &operands[4]);")
4566 (define_expand "zero_extendsidi2"
4567 [(set (match_operand:DI 0 "nonimmediate_operand")
4568 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
4570 (define_insn "*zero_extendsidi2"
4571 [(set (match_operand:DI 0 "nonimmediate_operand"
4572 "=r,?r,?o,r ,o,?*y,?!*y,$r,$v,$x,*x,*v,?r,?k")
4574 (match_operand:SI 1 "x86_64_zext_operand"
4575 "0 ,rm,r ,rmWz,0,r ,m ,v ,r ,m ,*x,*v,?k,?km")))]
4578 switch (get_attr_type (insn))
4581 if (ix86_use_lea_for_mov (insn, operands))
4582 return "lea{l}\t{%E1, %k0|%k0, %E1}";
4584 return "mov{l}\t{%1, %k0|%k0, %1}";
4590 return "movd\t{%1, %0|%0, %1}";
4593 if (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1]))
4595 if (EXT_REX_SSE_REG_P (operands[0])
4596 || EXT_REX_SSE_REG_P (operands[1]))
4597 return "vpmovzxdq\t{%t1, %g0|%g0, %t1}";
4599 return "%vpmovzxdq\t{%1, %0|%0, %1}";
4602 if (GENERAL_REG_P (operands[0]))
4603 return "%vmovd\t{%1, %k0|%k0, %1}";
4605 return "%vmovd\t{%1, %0|%0, %1}";
4608 return "kmovd\t{%1, %k0|%k0, %1}";
4615 (cond [(eq_attr "alternative" "0,1,2")
4616 (const_string "nox64")
4617 (eq_attr "alternative" "3")
4618 (const_string "x64")
4619 (eq_attr "alternative" "7,8,9")
4620 (const_string "sse2")
4621 (eq_attr "alternative" "10")
4622 (const_string "sse4")
4623 (eq_attr "alternative" "11")
4624 (const_string "avx512f")
4625 (eq_attr "alternative" "12")
4626 (const_string "x64_avx512bw")
4627 (eq_attr "alternative" "13")
4628 (const_string "avx512bw")
4630 (const_string "*")))
4631 (set (attr "mmx_isa")
4632 (if_then_else (eq_attr "alternative" "5,6")
4633 (const_string "native")
4634 (const_string "*")))
4636 (cond [(eq_attr "alternative" "0,1,2,4")
4637 (const_string "multi")
4638 (eq_attr "alternative" "5,6")
4639 (const_string "mmxmov")
4640 (eq_attr "alternative" "7")
4641 (if_then_else (match_test "TARGET_64BIT")
4642 (const_string "ssemov")
4643 (const_string "multi"))
4644 (eq_attr "alternative" "8,9,10,11")
4645 (const_string "ssemov")
4646 (eq_attr "alternative" "12,13")
4647 (const_string "mskmov")
4649 (const_string "imovx")))
4650 (set (attr "prefix_extra")
4651 (if_then_else (eq_attr "alternative" "10,11")
4653 (const_string "*")))
4654 (set (attr "prefix")
4655 (if_then_else (eq_attr "type" "ssemov")
4656 (const_string "maybe_vex")
4657 (const_string "orig")))
4658 (set (attr "prefix_0f")
4659 (if_then_else (eq_attr "type" "imovx")
4661 (const_string "*")))
4663 (cond [(eq_attr "alternative" "5,6")
4665 (and (eq_attr "alternative" "7")
4666 (match_test "TARGET_64BIT"))
4668 (eq_attr "alternative" "8,10,11")
4671 (const_string "SI")))
4672 (set (attr "preferred_for_speed")
4673 (cond [(eq_attr "alternative" "7")
4674 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4675 (eq_attr "alternative" "5,8")
4676 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4678 (symbol_ref "true")))])
4681 [(set (match_operand:DI 0 "memory_operand")
4682 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
4684 [(set (match_dup 4) (const_int 0))]
4685 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4688 [(set (match_operand:DI 0 "general_reg_operand")
4689 (zero_extend:DI (match_operand:SI 1 "general_reg_operand")))]
4690 "!TARGET_64BIT && reload_completed
4691 && REGNO (operands[0]) == REGNO (operands[1])"
4692 [(set (match_dup 4) (const_int 0))]
4693 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4696 [(set (match_operand:DI 0 "nonimmediate_gr_operand")
4697 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
4698 "!TARGET_64BIT && reload_completed
4699 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
4700 [(set (match_dup 3) (match_dup 1))
4701 (set (match_dup 4) (const_int 0))]
4702 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4704 (define_mode_attr kmov_isa
4705 [(QI "avx512dq") (HI "avx512f") (SI "avx512bw") (DI "avx512bw")])
4707 (define_insn "zero_extend<mode>di2"
4708 [(set (match_operand:DI 0 "register_operand" "=r,?r,?k")
4710 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,?k,?km")))]
4713 movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}
4714 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}
4715 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}"
4716 [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
4717 (set_attr "type" "imovx,mskmov,mskmov")
4718 (set_attr "mode" "SI,<MODE>,<MODE>")])
4720 (define_expand "zero_extend<mode>si2"
4721 [(set (match_operand:SI 0 "register_operand")
4722 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
4725 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4727 operands[1] = force_reg (<MODE>mode, operands[1]);
4728 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
4733 (define_insn_and_split "zero_extend<mode>si2_and"
4734 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
4736 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
4737 (clobber (reg:CC FLAGS_REG))]
4738 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4740 "&& reload_completed"
4741 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
4742 (clobber (reg:CC FLAGS_REG))])]
4744 if (!REG_P (operands[1])
4745 || REGNO (operands[0]) != REGNO (operands[1]))
4747 ix86_expand_clear (operands[0]);
4749 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4750 emit_insn (gen_rtx_SET
4751 (gen_rtx_STRICT_LOW_PART
4752 (VOIDmode, gen_lowpart (<MODE>mode, operands[0])),
4757 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
4759 [(set_attr "type" "alu1")
4760 (set_attr "mode" "SI")])
4762 (define_insn "*zero_extend<mode>si2"
4763 [(set (match_operand:SI 0 "register_operand" "=r,?r,?k")
4765 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,?k,?km")))]
4766 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4768 movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}
4769 kmov<mskmodesuffix>\t{%1, %0|%0, %1}
4770 kmov<mskmodesuffix>\t{%1, %0|%0, %1}"
4771 [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
4772 (set_attr "type" "imovx,mskmov,mskmov")
4773 (set_attr "mode" "SI,<MODE>,<MODE>")])
4775 (define_expand "zero_extendqihi2"
4776 [(set (match_operand:HI 0 "register_operand")
4777 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
4780 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4782 operands[1] = force_reg (QImode, operands[1]);
4783 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
4788 (define_insn_and_split "zero_extendqihi2_and"
4789 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
4790 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4791 (clobber (reg:CC FLAGS_REG))]
4792 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4794 "&& reload_completed"
4795 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4796 (clobber (reg:CC FLAGS_REG))])]
4798 if (!REG_P (operands[1])
4799 || REGNO (operands[0]) != REGNO (operands[1]))
4801 ix86_expand_clear (operands[0]);
4803 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4804 emit_insn (gen_rtx_SET
4805 (gen_rtx_STRICT_LOW_PART
4806 (VOIDmode, gen_lowpart (QImode, operands[0])),
4811 operands[0] = gen_lowpart (SImode, operands[0]);
4813 [(set_attr "type" "alu1")
4814 (set_attr "mode" "SI")])
4816 ; zero extend to SImode to avoid partial register stalls
4817 (define_insn "*zero_extendqihi2"
4818 [(set (match_operand:HI 0 "register_operand" "=r,?r,?k")
4819 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,?k,?km")))]
4820 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4822 movz{bl|x}\t{%1, %k0|%k0, %1}
4823 kmovb\t{%1, %k0|%k0, %1}
4824 kmovb\t{%1, %0|%0, %1}"
4825 [(set_attr "isa" "*,avx512dq,avx512dq")
4826 (set_attr "type" "imovx,mskmov,mskmov")
4827 (set_attr "mode" "SI,QI,QI")])
4829 ;; Transform xorl; mov[bw] (set strict_low_part) into movz[bw]l.
4831 [(parallel [(set (match_operand:SWI48 0 "general_reg_operand")
4833 (clobber (reg:CC FLAGS_REG))])
4834 (set (strict_low_part (match_operand:SWI12 1 "general_reg_operand"))
4835 (match_operand:SWI12 2 "nonimmediate_operand"))]
4836 "REGNO (operands[0]) == REGNO (operands[1])
4837 && (<SWI48:MODE>mode != SImode
4838 || !TARGET_ZERO_EXTEND_WITH_AND
4839 || !optimize_function_for_speed_p (cfun))"
4840 [(set (match_dup 0) (zero_extend:SWI48 (match_dup 2)))])
4842 ;; Likewise, but preserving FLAGS_REG.
4844 [(set (match_operand:SWI48 0 "general_reg_operand") (const_int 0))
4845 (set (strict_low_part (match_operand:SWI12 1 "general_reg_operand"))
4846 (match_operand:SWI12 2 "nonimmediate_operand"))]
4847 "REGNO (operands[0]) == REGNO (operands[1])
4848 && (<SWI48:MODE>mode != SImode
4849 || !TARGET_ZERO_EXTEND_WITH_AND
4850 || !optimize_function_for_speed_p (cfun))"
4851 [(set (match_dup 0) (zero_extend:SWI48 (match_dup 2)))])
4853 ;; Sign extension instructions
4855 (define_expand "extendsidi2"
4856 [(set (match_operand:DI 0 "register_operand")
4857 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
4862 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
4867 (define_insn "*extendsidi2_rex64"
4868 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4869 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4873 movs{lq|x}\t{%1, %0|%0, %1}"
4874 [(set_attr "type" "imovx")
4875 (set_attr "mode" "DI")
4876 (set_attr "prefix_0f" "0")
4877 (set_attr "modrm" "0,1")])
4879 (define_insn "extendsidi2_1"
4880 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4881 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4882 (clobber (reg:CC FLAGS_REG))
4883 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4887 (define_insn "extendditi2"
4888 [(set (match_operand:TI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4889 (sign_extend:TI (match_operand:DI 1 "register_operand" "0,0,r,r")))
4890 (clobber (reg:CC FLAGS_REG))
4891 (clobber (match_scratch:DI 2 "=X,X,X,&r"))]
4895 ;; Split the memory case. If the source register doesn't die, it will stay
4896 ;; this way, if it does die, following peephole2s take care of it.
4898 [(set (match_operand:<DWI> 0 "memory_operand")
4899 (sign_extend:<DWI> (match_operand:DWIH 1 "register_operand")))
4900 (clobber (reg:CC FLAGS_REG))
4901 (clobber (match_operand:DWIH 2 "register_operand"))]
4905 rtx bits = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
4907 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
4909 emit_move_insn (operands[3], operands[1]);
4911 /* Generate a cltd if possible and doing so it profitable. */
4912 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4913 && REGNO (operands[1]) == AX_REG
4914 && REGNO (operands[2]) == DX_REG)
4916 emit_insn (gen_ashr<mode>3_cvt (operands[2], operands[1], bits));
4920 emit_move_insn (operands[2], operands[1]);
4921 emit_insn (gen_ashr<mode>3_cvt (operands[2], operands[2], bits));
4923 emit_move_insn (operands[4], operands[2]);
4927 ;; Peepholes for the case where the source register does die, after
4928 ;; being split with the above splitter.
4930 [(set (match_operand:DWIH 0 "memory_operand")
4931 (match_operand:DWIH 1 "general_reg_operand"))
4932 (set (match_operand:DWIH 2 "general_reg_operand") (match_dup 1))
4933 (parallel [(set (match_dup 2)
4934 (ashiftrt:DWIH (match_dup 2)
4935 (match_operand 4 "const_int_operand")))
4936 (clobber (reg:CC FLAGS_REG))])
4937 (set (match_operand:DWIH 3 "memory_operand") (match_dup 2))]
4938 "REGNO (operands[1]) != REGNO (operands[2])
4939 && INTVAL (operands[4]) == (<MODE_SIZE> * BITS_PER_UNIT - 1)
4940 && peep2_reg_dead_p (2, operands[1])
4941 && peep2_reg_dead_p (4, operands[2])
4942 && !reg_mentioned_p (operands[2], operands[3])"
4943 [(set (match_dup 0) (match_dup 1))
4944 (parallel [(set (match_dup 1) (ashiftrt:DWIH (match_dup 1) (match_dup 4)))
4945 (clobber (reg:CC FLAGS_REG))])
4946 (set (match_dup 3) (match_dup 1))])
4949 [(set (match_operand:DWIH 0 "memory_operand")
4950 (match_operand:DWIH 1 "general_reg_operand"))
4951 (parallel [(set (match_operand:DWIH 2 "general_reg_operand")
4952 (ashiftrt:DWIH (match_dup 1)
4953 (match_operand 4 "const_int_operand")))
4954 (clobber (reg:CC FLAGS_REG))])
4955 (set (match_operand:DWIH 3 "memory_operand") (match_dup 2))]
4956 "/* cltd is shorter than sarl $31, %eax */
4957 !optimize_function_for_size_p (cfun)
4958 && REGNO (operands[1]) == AX_REG
4959 && REGNO (operands[2]) == DX_REG
4960 && INTVAL (operands[4]) == (<MODE_SIZE> * BITS_PER_UNIT - 1)
4961 && peep2_reg_dead_p (2, operands[1])
4962 && peep2_reg_dead_p (3, operands[2])
4963 && !reg_mentioned_p (operands[2], operands[3])"
4964 [(set (match_dup 0) (match_dup 1))
4965 (parallel [(set (match_dup 1) (ashiftrt:DWIH (match_dup 1) (match_dup 4)))
4966 (clobber (reg:CC FLAGS_REG))])
4967 (set (match_dup 3) (match_dup 1))])
4969 ;; Extend to register case. Optimize case where source and destination
4970 ;; registers match and cases where we can use cltd.
4972 [(set (match_operand:<DWI> 0 "register_operand")
4973 (sign_extend:<DWI> (match_operand:DWIH 1 "register_operand")))
4974 (clobber (reg:CC FLAGS_REG))
4975 (clobber (match_scratch:DWIH 2))]
4979 rtx bits = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
4981 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
4983 if (REGNO (operands[3]) != REGNO (operands[1]))
4984 emit_move_insn (operands[3], operands[1]);
4986 rtx src = operands[1];
4987 if (REGNO (operands[3]) == AX_REG)
4990 /* Generate a cltd if possible and doing so it profitable. */
4991 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4992 && REGNO (src) == AX_REG
4993 && REGNO (operands[4]) == DX_REG)
4995 emit_insn (gen_ashr<mode>3_cvt (operands[4], src, bits));
4999 if (REGNO (operands[4]) != REGNO (operands[1]))
5000 emit_move_insn (operands[4], operands[1]);
5002 emit_insn (gen_ashr<mode>3_cvt (operands[4], operands[4], bits));
5006 (define_insn "extend<mode>di2"
5007 [(set (match_operand:DI 0 "register_operand" "=r")
5009 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
5011 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
5012 [(set_attr "type" "imovx")
5013 (set_attr "mode" "DI")])
5015 (define_insn "extendhisi2"
5016 [(set (match_operand:SI 0 "register_operand" "=*a,r")
5017 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
5020 switch (get_attr_prefix_0f (insn))
5023 return "{cwtl|cwde}";
5025 return "movs{wl|x}\t{%1, %0|%0, %1}";
5028 [(set_attr "type" "imovx")
5029 (set_attr "mode" "SI")
5030 (set (attr "prefix_0f")
5031 ;; movsx is short decodable while cwtl is vector decoded.
5032 (if_then_else (and (eq_attr "cpu" "!k6")
5033 (eq_attr "alternative" "0"))
5035 (const_string "1")))
5036 (set (attr "znver1_decode")
5037 (if_then_else (eq_attr "prefix_0f" "0")
5038 (const_string "double")
5039 (const_string "direct")))
5041 (if_then_else (eq_attr "prefix_0f" "0")
5043 (const_string "1")))])
5045 (define_insn "*extendhisi2_zext"
5046 [(set (match_operand:DI 0 "register_operand" "=*a,r")
5049 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
5052 switch (get_attr_prefix_0f (insn))
5055 return "{cwtl|cwde}";
5057 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
5060 [(set_attr "type" "imovx")
5061 (set_attr "mode" "SI")
5062 (set (attr "prefix_0f")
5063 ;; movsx is short decodable while cwtl is vector decoded.
5064 (if_then_else (and (eq_attr "cpu" "!k6")
5065 (eq_attr "alternative" "0"))
5067 (const_string "1")))
5069 (if_then_else (eq_attr "prefix_0f" "0")
5071 (const_string "1")))])
5073 (define_insn "extendqisi2"
5074 [(set (match_operand:SI 0 "register_operand" "=r")
5075 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
5077 "movs{bl|x}\t{%1, %0|%0, %1}"
5078 [(set_attr "type" "imovx")
5079 (set_attr "mode" "SI")])
5081 (define_insn "*extendqisi2_zext"
5082 [(set (match_operand:DI 0 "register_operand" "=r")
5084 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
5086 "movs{bl|x}\t{%1, %k0|%k0, %1}"
5087 [(set_attr "type" "imovx")
5088 (set_attr "mode" "SI")])
5090 (define_insn "extendqihi2"
5091 [(set (match_operand:HI 0 "register_operand" "=*a,r")
5092 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
5095 switch (get_attr_prefix_0f (insn))
5098 return "{cbtw|cbw}";
5100 return "movs{bw|x}\t{%1, %0|%0, %1}";
5103 [(set_attr "type" "imovx")
5104 (set_attr "mode" "HI")
5105 (set (attr "prefix_0f")
5106 ;; movsx is short decodable while cwtl is vector decoded.
5107 (if_then_else (and (eq_attr "cpu" "!k6")
5108 (eq_attr "alternative" "0"))
5110 (const_string "1")))
5112 (if_then_else (eq_attr "prefix_0f" "0")
5114 (const_string "1")))])
5116 (define_insn "*extendqi<SWI24:mode>_ext_1"
5117 [(set (match_operand:SWI24 0 "register_operand" "=R")
5120 (match_operator:SWI248 2 "extract_operator"
5121 [(match_operand 1 "int248_register_operand" "Q")
5123 (const_int 8)]) 0)))]
5125 "movs{b<SWI24:imodesuffix>|x}\t{%h1, %0|%0, %h1}"
5126 [(set_attr "type" "imovx")
5127 (set_attr "mode" "<SWI24:MODE>")])
5129 ;; Conversions between float and double.
5131 ;; These are all no-ops in the model used for the 80387.
5132 ;; So just emit moves.
5134 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
5136 [(set (match_operand:DF 0 "push_operand")
5137 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
5139 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
5140 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
5143 [(set (match_operand:XF 0 "push_operand")
5144 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
5146 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
5147 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
5148 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
5150 (define_expand "extendsfdf2"
5151 [(set (match_operand:DF 0 "nonimm_ssenomem_operand")
5152 (float_extend:DF (match_operand:SF 1 "general_operand")))]
5153 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5155 /* ??? Needed for compress_float_constant since all fp constants
5156 are TARGET_LEGITIMATE_CONSTANT_P. */
5157 if (CONST_DOUBLE_P (operands[1]))
5159 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
5160 && standard_80387_constant_p (operands[1]) > 0)
5162 operands[1] = simplify_const_unary_operation
5163 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
5164 emit_move_insn_1 (operands[0], operands[1]);
5167 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
5171 (define_insn "*extendsfdf2"
5172 [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v,v")
5174 (match_operand:SF 1 "nonimmediate_operand" "fm,f,v,m")))]
5175 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5177 switch (which_alternative)
5181 return output_387_reg_move (insn, operands);
5184 return "%vcvtss2sd\t{%d1, %0|%0, %d1}";
5186 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
5192 [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
5193 (set_attr "avx_partial_xmm_update" "false,false,false,true")
5194 (set_attr "prefix" "orig,orig,maybe_vex,maybe_vex")
5195 (set_attr "mode" "SF,XF,DF,DF")
5196 (set (attr "enabled")
5198 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
5200 (eq_attr "alternative" "0,1")
5201 (symbol_ref "TARGET_MIX_SSE_I387")
5202 (symbol_ref "true"))
5204 (eq_attr "alternative" "0,1")
5206 (symbol_ref "false"))))])
5208 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
5210 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
5212 We do the conversion post reload to avoid producing of 128bit spills
5213 that might lead to ICE on 32bit target. The sequence unlikely combine
5216 [(set (match_operand:DF 0 "sse_reg_operand")
5218 (match_operand:SF 1 "nonimmediate_operand")))]
5219 "TARGET_USE_VECTOR_FP_CONVERTS
5220 && optimize_insn_for_speed_p ()
5222 && (!EXT_REX_SSE_REG_P (operands[0])
5223 || TARGET_AVX512VL)"
5228 (parallel [(const_int 0) (const_int 1)]))))]
5230 operands[2] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5231 operands[3] = lowpart_subreg (V4SFmode, operands[0], DFmode);
5232 /* Use movss for loading from memory, unpcklps reg, reg for registers.
5233 Try to avoid move when unpacking can be done in source. */
5234 if (REG_P (operands[1]))
5236 /* If it is unsafe to overwrite upper half of source, we need
5237 to move to destination and unpack there. */
5238 if (REGNO (operands[0]) != REGNO (operands[1])
5239 || (EXT_REX_SSE_REG_P (operands[1]) && !TARGET_AVX512VL))
5241 rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode);
5242 emit_move_insn (tmp, operands[1]);
5245 operands[3] = lowpart_subreg (V4SFmode, operands[1], SFmode);
5246 /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
5247 =v, v, then vbroadcastss will be only needed for AVX512F without
5249 if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3])))
5250 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
5254 rtx tmp = lowpart_subreg (V16SFmode, operands[3], V4SFmode);
5255 emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
5259 emit_insn (gen_vec_setv4sf_0 (operands[3],
5260 CONST0_RTX (V4SFmode), operands[1]));
5263 ;; It's more profitable to split and then extend in the same register.
5265 [(set (match_operand:DF 0 "sse_reg_operand")
5267 (match_operand:SF 1 "memory_operand")))]
5268 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
5269 && optimize_insn_for_speed_p ()"
5270 [(set (match_dup 2) (match_dup 1))
5271 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
5272 "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);")
5274 ;; Break partial SSE register dependency stall. This splitter should split
5275 ;; late in the pass sequence (after register rename pass), so allocated
5276 ;; registers won't change anymore
5279 [(set (match_operand:DF 0 "sse_reg_operand")
5281 (match_operand:SF 1 "nonimmediate_operand")))]
5283 && TARGET_SSE_PARTIAL_REG_FP_CONVERTS_DEPENDENCY
5284 && epilogue_completed
5285 && optimize_function_for_speed_p (cfun)
5286 && (!REG_P (operands[1])
5287 || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
5288 && (!EXT_REX_SSE_REG_P (operands[0])
5289 || TARGET_AVX512VL)"
5298 operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5299 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5302 (define_expand "extendhfsf2"
5303 [(set (match_operand:SF 0 "register_operand")
5305 (match_operand:HF 1 "nonimmediate_operand")))]
5306 "TARGET_AVX512FP16 || TARGET_F16C || TARGET_AVX512VL"
5308 if (!TARGET_AVX512FP16)
5310 rtx res = gen_reg_rtx (V4SFmode);
5311 rtx tmp = gen_reg_rtx (V8HFmode);
5312 rtx zero = force_reg (V8HFmode, CONST0_RTX (V8HFmode));
5314 emit_insn (gen_vec_setv8hf_0 (tmp, zero, operands[1]));
5315 emit_insn (gen_vcvtph2ps (res, gen_lowpart (V8HImode, tmp)));
5316 emit_move_insn (operands[0], gen_lowpart (SFmode, res));
5321 (define_expand "extendhfdf2"
5322 [(set (match_operand:DF 0 "register_operand")
5324 (match_operand:HF 1 "nonimmediate_operand")))]
5325 "TARGET_AVX512FP16")
5327 (define_insn "*extendhf<mode>2"
5328 [(set (match_operand:MODEF 0 "register_operand" "=v")
5330 (match_operand:HF 1 "nonimmediate_operand" "vm")))]
5332 "vcvtsh2<ssemodesuffix>\t{%1, %0, %0|%0, %0, %1}"
5333 [(set_attr "type" "ssecvt")
5334 (set_attr "prefix" "evex")
5335 (set_attr "mode" "<MODE>")])
5337 (define_expand "extendbfsf2"
5338 [(set (match_operand:SF 0 "register_operand")
5340 [(match_operand:BF 1 "register_operand")]
5342 "TARGET_SSE2 && !HONOR_NANS (BFmode)")
5344 ;; Don't use float_extend since psrlld doesn't raise
5345 ;; exceptions and turn a sNaN into a qNaN.
5346 (define_insn "extendbfsf2_1"
5347 [(set (match_operand:SF 0 "register_operand" "=x,Yv,v")
5349 [(match_operand:BF 1 "register_operand" " 0,Yv,v")]
5353 pslld\t{$16, %0|%0, 16}
5354 vpslld\t{$16, %1, %0|%0, %1, 16}
5355 vpslld\t{$16, %g1, %g0|%g0, %g1, 16}"
5356 [(set_attr "isa" "noavx,avx,*")
5357 (set_attr "type" "sseishft1")
5358 (set_attr "length_immediate" "1")
5359 (set_attr "prefix_data16" "1,*,*")
5360 (set_attr "prefix" "orig,maybe_evex,evex")
5361 (set_attr "mode" "TI,TI,XI")
5362 (set_attr "memory" "none")
5363 (set (attr "enabled")
5364 (if_then_else (eq_attr "alternative" "2")
5365 (symbol_ref "TARGET_AVX512F && TARGET_EVEX512
5366 && !TARGET_AVX512VL && !TARGET_PREFER_AVX256")
5367 (const_string "*")))])
5369 (define_expand "extend<mode>xf2"
5370 [(set (match_operand:XF 0 "nonimmediate_operand")
5371 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
5374 /* ??? Needed for compress_float_constant since all fp constants
5375 are TARGET_LEGITIMATE_CONSTANT_P. */
5376 if (CONST_DOUBLE_P (operands[1]))
5378 if (standard_80387_constant_p (operands[1]) > 0)
5380 operands[1] = simplify_const_unary_operation
5381 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
5382 emit_move_insn_1 (operands[0], operands[1]);
5385 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
5389 (define_insn "*extend<mode>xf2_i387"
5390 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
5392 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
5394 "* return output_387_reg_move (insn, operands);"
5395 [(set_attr "type" "fmov")
5396 (set_attr "mode" "<MODE>,XF")])
5398 ;; %%% This seems like bad news.
5399 ;; This cannot output into an f-reg because there is no way to be sure
5400 ;; of truncating in that case. Otherwise this is just like a simple move
5401 ;; insn. So we pretend we can output to a reg in order to get better
5402 ;; register preferencing, but we really use a stack slot.
5404 ;; Conversion from DFmode to SFmode.
5406 (define_insn "truncdfsf2"
5407 [(set (match_operand:SF 0 "nonimm_ssenomem_operand" "=m,f,v,v")
5409 (match_operand:DF 1 "register_ssemem_operand" "f,f,v,m")))]
5410 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5412 switch (which_alternative)
5416 return output_387_reg_move (insn, operands);
5419 return "%vcvtsd2ss\t{%d1, %0|%0, %d1}";
5421 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
5427 [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
5428 (set_attr "avx_partial_xmm_update" "false,false,false,true")
5429 (set_attr "mode" "SF")
5430 (set (attr "enabled")
5432 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
5433 (cond [(eq_attr "alternative" "0")
5434 (symbol_ref "TARGET_MIX_SSE_I387")
5435 (eq_attr "alternative" "1")
5436 (symbol_ref "TARGET_MIX_SSE_I387
5437 && flag_unsafe_math_optimizations")
5439 (symbol_ref "true"))
5440 (cond [(eq_attr "alternative" "0")
5442 (eq_attr "alternative" "1")
5443 (symbol_ref "flag_unsafe_math_optimizations")
5445 (symbol_ref "false"))))])
5447 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
5449 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
5451 We do the conversion post reload to avoid producing of 128bit spills
5452 that might lead to ICE on 32bit target. The sequence unlikely combine
5455 [(set (match_operand:SF 0 "sse_reg_operand")
5457 (match_operand:DF 1 "nonimmediate_operand")))]
5458 "TARGET_USE_VECTOR_FP_CONVERTS
5459 && optimize_insn_for_speed_p ()
5461 && (!EXT_REX_SSE_REG_P (operands[0])
5462 || TARGET_AVX512VL)"
5465 (float_truncate:V2SF
5469 operands[2] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5470 operands[3] = CONST0_RTX (V2SFmode);
5471 operands[4] = lowpart_subreg (V2DFmode, operands[0], SFmode);
5472 /* Use movsd for loading from memory, unpcklpd for registers.
5473 Try to avoid move when unpacking can be done in source, or SSE3
5474 movddup is available. */
5475 if (REG_P (operands[1]))
5477 if ((!TARGET_SSE3 && REGNO (operands[0]) != REGNO (operands[1]))
5478 || (EXT_REX_SSE_REG_P (operands[1]) && !TARGET_AVX512VL))
5480 rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode);
5481 emit_move_insn (tmp, operands[1]);
5484 else if (!TARGET_SSE3)
5485 operands[4] = lowpart_subreg (V2DFmode, operands[1], DFmode);
5486 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
5489 emit_insn (gen_vec_concatv2df (operands[4], operands[1],
5490 CONST0_RTX (DFmode)));
5493 ;; It's more profitable to split and then truncate in the same register.
5495 [(set (match_operand:SF 0 "sse_reg_operand")
5497 (match_operand:DF 1 "memory_operand")))]
5498 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
5499 && optimize_insn_for_speed_p ()"
5500 [(set (match_dup 2) (match_dup 1))
5501 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
5502 "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
5504 ;; Break partial SSE register dependency stall. This splitter should split
5505 ;; late in the pass sequence (after register rename pass), so allocated
5506 ;; registers won't change anymore
5509 [(set (match_operand:SF 0 "sse_reg_operand")
5511 (match_operand:DF 1 "nonimmediate_operand")))]
5513 && TARGET_SSE_PARTIAL_REG_FP_CONVERTS_DEPENDENCY
5514 && epilogue_completed
5515 && optimize_function_for_speed_p (cfun)
5516 && (!REG_P (operands[1])
5517 || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
5518 && (!EXT_REX_SSE_REG_P (operands[0])
5519 || TARGET_AVX512VL)"
5528 operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5529 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5532 ;; Conversion from XFmode to {SF,DF}mode
5534 (define_insn "truncxf<mode>2"
5535 [(set (match_operand:MODEF 0 "nonimmediate_operand" "=m,f")
5536 (float_truncate:MODEF
5537 (match_operand:XF 1 "register_operand" "f,f")))]
5539 "* return output_387_reg_move (insn, operands);"
5540 [(set_attr "type" "fmov")
5541 (set_attr "mode" "<MODE>")
5542 (set (attr "enabled")
5543 (cond [(eq_attr "alternative" "1")
5544 (symbol_ref "flag_unsafe_math_optimizations")
5546 (symbol_ref "true")))])
5548 ;; Conversion from {SF,DF}mode to HFmode.
5550 (define_expand "truncsfhf2"
5551 [(set (match_operand:HF 0 "register_operand")
5553 (match_operand:SF 1 "nonimmediate_operand")))]
5554 "TARGET_AVX512FP16 || TARGET_F16C || TARGET_AVX512VL"
5556 if (!TARGET_AVX512FP16)
5558 rtx res = gen_reg_rtx (V8HFmode);
5559 rtx tmp = gen_reg_rtx (V4SFmode);
5560 rtx zero = force_reg (V4SFmode, CONST0_RTX (V4SFmode));
5562 emit_insn (gen_vec_setv4sf_0 (tmp, zero, operands[1]));
5563 emit_insn (gen_vcvtps2ph (gen_lowpart (V8HImode, res), tmp, GEN_INT (4)));
5564 emit_move_insn (operands[0], gen_lowpart (HFmode, res));
5569 (define_expand "truncdfhf2"
5570 [(set (match_operand:HF 0 "register_operand")
5572 (match_operand:DF 1 "nonimmediate_operand")))]
5573 "TARGET_AVX512FP16")
5575 (define_insn "*trunc<mode>hf2"
5576 [(set (match_operand:HF 0 "register_operand" "=v")
5578 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5580 "vcvt<ssemodesuffix>2sh\t{%1, %d0|%d0, %1}"
5581 [(set_attr "type" "ssecvt")
5582 (set_attr "prefix" "evex")
5583 (set_attr "mode" "HF")])
5585 (define_insn "truncsfbf2"
5586 [(set (match_operand:BF 0 "register_operand" "=x, v")
5588 (match_operand:SF 1 "register_operand" "x,v")))]
5589 "((TARGET_AVX512BF16 && TARGET_AVX512VL) || TARGET_AVXNECONVERT)
5590 && !HONOR_NANS (BFmode) && flag_unsafe_math_optimizations"
5592 %{vex%} vcvtneps2bf16\t{%1, %0|%0, %1}
5593 vcvtneps2bf16\t{%1, %0|%0, %1}"
5594 [(set_attr "isa" "avxneconvert,avx512bf16vl")
5595 (set_attr "prefix" "vex,evex")])
5597 ;; Signed conversion to DImode.
5599 (define_expand "fix_truncxfdi2"
5600 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
5601 (fix:DI (match_operand:XF 1 "register_operand")))
5602 (clobber (reg:CC FLAGS_REG))])]
5607 emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
5612 (define_expand "fix_trunc<mode>di2"
5613 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
5614 (fix:DI (match_operand:MODEF 1 "register_operand")))
5615 (clobber (reg:CC FLAGS_REG))])]
5616 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
5619 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
5621 emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
5624 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
5626 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
5627 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
5628 if (out != operands[0])
5629 emit_move_insn (operands[0], out);
5634 (define_insn "fix<fixunssuffix>_trunchf<mode>2"
5635 [(set (match_operand:SWI48 0 "register_operand" "=r")
5637 (match_operand:HF 1 "nonimmediate_operand" "vm")))]
5639 "vcvttsh2<fixsuffix>si\t{%1, %0|%0, %1}"
5640 [(set_attr "type" "sseicvt")
5641 (set_attr "prefix" "evex")
5642 (set_attr "mode" "<MODE>")])
5644 ;; Signed conversion to SImode.
5646 (define_expand "fix_truncxfsi2"
5647 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
5648 (fix:SI (match_operand:XF 1 "register_operand")))
5649 (clobber (reg:CC FLAGS_REG))])]
5654 emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
5659 (define_expand "fix_trunc<mode>si2"
5660 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
5661 (fix:SI (match_operand:MODEF 1 "register_operand")))
5662 (clobber (reg:CC FLAGS_REG))])]
5663 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
5666 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
5668 emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
5671 if (SSE_FLOAT_MODE_P (<MODE>mode))
5673 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
5674 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
5675 if (out != operands[0])
5676 emit_move_insn (operands[0], out);
5681 ;; Signed conversion to HImode.
5683 (define_expand "fix_trunc<mode>hi2"
5684 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
5685 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
5686 (clobber (reg:CC FLAGS_REG))])]
5688 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
5692 emit_insn (gen_fix_trunchi_i387_fisttp (operands[0], operands[1]));
5697 ;; Unsigned conversion to DImode
5699 (define_insn "fixuns_trunc<mode>di2"
5700 [(set (match_operand:DI 0 "register_operand" "=r")
5702 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5703 "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
5704 "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
5705 [(set_attr "type" "sseicvt")
5706 (set_attr "prefix" "evex")
5707 (set_attr "mode" "DI")])
5709 ;; Unsigned conversion to SImode.
5711 (define_expand "fixuns_trunc<mode>si2"
5713 [(set (match_operand:SI 0 "register_operand")
5715 (match_operand:MODEF 1 "nonimmediate_operand")))
5717 (clobber (scratch:<ssevecmode>))
5718 (clobber (scratch:<ssevecmode>))])]
5719 "(!TARGET_64BIT || TARGET_AVX512F) && TARGET_SSE2 && TARGET_SSE_MATH"
5721 machine_mode mode = <MODE>mode;
5722 machine_mode vecmode = <ssevecmode>mode;
5723 REAL_VALUE_TYPE TWO31r;
5728 emit_insn (gen_fixuns_trunc<mode>si2_avx512f (operands[0], operands[1]));
5732 if (optimize_insn_for_size_p ())
5735 real_ldexp (&TWO31r, &dconst1, 31);
5736 two31 = const_double_from_real_value (TWO31r, mode);
5737 two31 = ix86_build_const_vector (vecmode, true, two31);
5738 operands[2] = force_reg (vecmode, two31);
5741 (define_insn "fixuns_trunc<mode>si2_avx512f"
5742 [(set (match_operand:SI 0 "register_operand" "=r")
5744 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5745 "TARGET_AVX512F && TARGET_SSE_MATH"
5746 "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
5747 [(set_attr "type" "sseicvt")
5748 (set_attr "prefix" "evex")
5749 (set_attr "mode" "SI")])
5751 (define_insn "*fixuns_trunchfsi2zext"
5752 [(set (match_operand:DI 0 "register_operand" "=r")
5755 (match_operand:HF 1 "nonimmediate_operand" "vm"))))]
5756 "TARGET_64BIT && TARGET_AVX512FP16"
5757 "vcvttsh2usi\t{%1, %k0|%k0, %1}"
5758 [(set_attr "type" "sseicvt")
5759 (set_attr "prefix" "evex")
5760 (set_attr "mode" "SI")])
5762 (define_insn "*fixuns_trunc<mode>si2_avx512f_zext"
5763 [(set (match_operand:DI 0 "register_operand" "=r")
5766 (match_operand:MODEF 1 "nonimmediate_operand" "vm"))))]
5767 "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
5768 "vcvtt<ssemodesuffix>2usi\t{%1, %k0|%k0, %1}"
5769 [(set_attr "type" "sseicvt")
5770 (set_attr "prefix" "evex")
5771 (set_attr "mode" "SI")])
5773 (define_insn_and_split "*fixuns_trunc<mode>_1"
5774 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
5776 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
5777 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
5778 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
5779 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
5780 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5781 && optimize_function_for_speed_p (cfun)"
5783 "&& reload_completed"
5786 ix86_split_convert_uns_si_sse (operands);
5790 ;; Unsigned conversion to HImode.
5791 ;; Without these patterns, we'll try the unsigned SI conversion which
5792 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
5794 (define_expand "fixuns_trunchfhi2"
5796 (fix:SI (match_operand:HF 1 "nonimmediate_operand")))
5797 (set (match_operand:HI 0 "nonimmediate_operand")
5798 (subreg:HI (match_dup 2) 0))]
5800 "operands[2] = gen_reg_rtx (SImode);")
5802 (define_expand "fixuns_trunc<mode>hi2"
5804 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
5805 (set (match_operand:HI 0 "nonimmediate_operand")
5806 (subreg:HI (match_dup 2) 0))]
5807 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
5808 "operands[2] = gen_reg_rtx (SImode);")
5810 ;; When SSE is available, it is always faster to use it!
5811 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
5812 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
5813 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
5814 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5815 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
5816 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
5817 [(set_attr "type" "sseicvt")
5818 (set_attr "prefix" "maybe_vex")
5819 (set (attr "prefix_rex")
5821 (match_test "<SWI48:MODE>mode == DImode")
5823 (const_string "*")))
5824 (set_attr "mode" "<MODEF:MODE>")
5825 (set_attr "athlon_decode" "double,vector")
5826 (set_attr "amdfam10_decode" "double,double")
5827 (set_attr "bdver1_decode" "double,double")])
5829 ;; Avoid vector decoded forms of the instruction.
5831 [(match_scratch:MODEF 2 "x")
5832 (set (match_operand:SWI48 0 "register_operand")
5833 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
5834 "TARGET_AVOID_VECTOR_DECODE
5835 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5836 && optimize_insn_for_speed_p ()"
5837 [(set (match_dup 2) (match_dup 1))
5838 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
5840 (define_insn "fix_trunc<mode>_i387_fisttp"
5841 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m")
5842 (fix:SWI248x (match_operand 1 "register_operand" "f")))
5843 (clobber (match_scratch:XF 2 "=&f"))]
5844 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5846 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5847 && (TARGET_64BIT || <MODE>mode != DImode))
5848 && TARGET_SSE_MATH)"
5849 "* return output_fix_trunc (insn, operands, true);"
5850 [(set_attr "type" "fisttp")
5851 (set_attr "mode" "<MODE>")])
5853 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5854 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5855 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5856 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5857 ;; function in i386.cc.
5858 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5859 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
5860 (fix:SWI248x (match_operand 1 "register_operand")))
5861 (clobber (reg:CC FLAGS_REG))]
5862 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5864 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5865 && (TARGET_64BIT || <MODE>mode != DImode))
5866 && ix86_pre_reload_split ()"
5871 ix86_optimize_mode_switching[I387_TRUNC] = 1;
5873 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5874 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5876 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5877 operands[2], operands[3]));
5880 [(set_attr "type" "fistp")
5881 (set_attr "i387_cw" "trunc")
5882 (set_attr "mode" "<MODE>")])
5884 (define_insn "fix_truncdi_i387"
5885 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
5886 (fix:DI (match_operand 1 "register_operand" "f")))
5887 (use (match_operand:HI 2 "memory_operand" "m"))
5888 (use (match_operand:HI 3 "memory_operand" "m"))
5889 (clobber (match_scratch:XF 4 "=&f"))]
5890 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5892 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5893 "* return output_fix_trunc (insn, operands, false);"
5894 [(set_attr "type" "fistp")
5895 (set_attr "i387_cw" "trunc")
5896 (set_attr "mode" "DI")])
5898 (define_insn "fix_trunc<mode>_i387"
5899 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
5900 (fix:SWI24 (match_operand 1 "register_operand" "f")))
5901 (use (match_operand:HI 2 "memory_operand" "m"))
5902 (use (match_operand:HI 3 "memory_operand" "m"))]
5903 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5905 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5906 "* return output_fix_trunc (insn, operands, false);"
5907 [(set_attr "type" "fistp")
5908 (set_attr "i387_cw" "trunc")
5909 (set_attr "mode" "<MODE>")])
5911 (define_insn "x86_fnstcw_1"
5912 [(set (match_operand:HI 0 "memory_operand" "=m")
5913 (unspec:HI [(const_int 0)] UNSPEC_FSTCW))]
5916 [(set (attr "length")
5917 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5918 (set_attr "mode" "HI")
5919 (set_attr "unit" "i387")
5920 (set_attr "bdver1_decode" "vector")])
5922 ;; Conversion between fixed point and floating point.
5924 ;; Even though we only accept memory inputs, the backend _really_
5925 ;; wants to be able to do this between registers. Thankfully, LRA
5926 ;; will fix this up for us during register allocation.
5928 (define_insn "floathi<mode>2"
5929 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5930 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
5932 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5933 || TARGET_MIX_SSE_I387)"
5935 [(set_attr "type" "fmov")
5936 (set_attr "mode" "<MODE>")
5937 (set_attr "znver1_decode" "double")
5938 (set_attr "fp_int_src" "true")])
5940 (define_insn "float<SWI48x:mode>xf2"
5941 [(set (match_operand:XF 0 "register_operand" "=f")
5942 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5945 [(set_attr "type" "fmov")
5946 (set_attr "mode" "XF")
5947 (set_attr "znver1_decode" "double")
5948 (set_attr "fp_int_src" "true")])
5950 (define_expand "float<SWI48x:mode><MODEF:mode>2"
5951 [(set (match_operand:MODEF 0 "register_operand")
5952 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand")))]
5953 "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode))
5954 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5955 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT))")
5957 (define_insn "*float<SWI48:mode><MODEF:mode>2"
5958 [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
5960 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
5961 "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
5962 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
5965 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
5966 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5967 [(set_attr "type" "fmov,sseicvt,sseicvt")
5968 (set_attr "avx_partial_xmm_update" "false,true,true")
5969 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5970 (set_attr "mode" "<MODEF:MODE>")
5971 (set (attr "prefix_rex")
5973 (and (eq_attr "prefix" "maybe_vex")
5974 (match_test "<SWI48:MODE>mode == DImode"))
5976 (const_string "*")))
5977 (set_attr "unit" "i387,*,*")
5978 (set_attr "athlon_decode" "*,double,direct")
5979 (set_attr "amdfam10_decode" "*,vector,double")
5980 (set_attr "bdver1_decode" "*,double,direct")
5981 (set_attr "znver1_decode" "double,*,*")
5982 (set_attr "fp_int_src" "true")
5983 (set (attr "enabled")
5985 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
5987 (eq_attr "alternative" "0")
5988 (symbol_ref "TARGET_MIX_SSE_I387
5989 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
5991 (symbol_ref "true"))
5993 (eq_attr "alternative" "0")
5995 (symbol_ref "false"))))
5996 (set (attr "preferred_for_speed")
5997 (cond [(eq_attr "alternative" "1")
5998 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
5999 (symbol_ref "true")))])
6001 (define_insn "float<floatunssuffix><mode>hf2"
6002 [(set (match_operand:HF 0 "register_operand" "=v")
6004 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
6006 "vcvt<floatsuffix>si2sh<rex64suffix>\t{%1, %d0|%d0, %1}"
6007 [(set_attr "type" "sseicvt")
6008 (set_attr "prefix" "evex")
6009 (set_attr "mode" "HF")])
6011 (define_insn "*floatdi<MODEF:mode>2_i387"
6012 [(set (match_operand:MODEF 0 "register_operand" "=f")
6013 (float:MODEF (match_operand:DI 1 "nonimmediate_operand" "m")))]
6015 && TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, DImode)"
6017 [(set_attr "type" "fmov")
6018 (set_attr "mode" "<MODEF:MODE>")
6019 (set_attr "znver1_decode" "double")
6020 (set_attr "fp_int_src" "true")])
6022 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
6023 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
6024 ;; alternative in sse2_loadld.
6026 [(set (match_operand:MODEF 0 "sse_reg_operand")
6027 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
6029 && TARGET_USE_VECTOR_CONVERTS
6030 && optimize_function_for_speed_p (cfun)
6032 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
6033 && (!EXT_REX_SSE_REG_P (operands[0])
6034 || TARGET_AVX512VL)"
6037 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode);
6038 operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode);
6040 emit_insn (gen_sse2_loadld (operands[4],
6041 CONST0_RTX (V4SImode), operands[1]));
6043 if (<ssevecmode>mode == V4SFmode)
6044 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
6046 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
6050 ;; Avoid store forwarding (partial memory) stall penalty
6051 ;; by passing DImode value through XMM registers. */
6054 [(set (match_operand:X87MODEF 0 "register_operand")
6056 (match_operand:DI 1 "register_operand")))]
6057 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
6058 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6059 && TARGET_SSE2 && optimize_function_for_speed_p (cfun)
6060 && can_create_pseudo_p ()"
6063 rtx s = assign_386_stack_local (DImode, SLOT_FLOATxFDI_387);
6064 emit_insn (gen_floatdi<mode>2_i387_with_xmm (operands[0], operands[1], s));
6068 (define_insn_and_split "floatdi<X87MODEF:mode>2_i387_with_xmm"
6069 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
6071 (match_operand:DI 1 "register_operand" "r,r")))
6072 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
6073 (clobber (match_scratch:V4SI 3 "=x,x"))
6074 (clobber (match_scratch:V4SI 4 "=X,x"))]
6075 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
6076 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6077 && TARGET_SSE2 && optimize_function_for_speed_p (cfun)"
6079 "&& reload_completed"
6080 [(set (match_dup 2) (match_dup 3))
6081 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
6083 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
6084 Assemble the 64-bit DImode value in an xmm register. */
6085 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
6086 gen_lowpart (SImode, operands[1])));
6088 emit_insn (gen_sse4_1_pinsrd (operands[3], operands[3],
6089 gen_highpart (SImode, operands[1]),
6093 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
6094 gen_highpart (SImode, operands[1])));
6095 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
6098 operands[3] = gen_lowpart (DImode, operands[3]);
6100 [(set_attr "isa" "sse4,*")
6101 (set_attr "type" "multi")
6102 (set_attr "mode" "<X87MODEF:MODE>")
6103 (set_attr "unit" "i387")
6104 (set_attr "fp_int_src" "true")])
6106 ;; Break partial SSE register dependency stall. This splitter should split
6107 ;; late in the pass sequence (after register rename pass), so allocated
6108 ;; registers won't change anymore
6111 [(set (match_operand:MODEF 0 "sse_reg_operand")
6112 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
6114 && TARGET_SSE_PARTIAL_REG_CONVERTS_DEPENDENCY
6115 && epilogue_completed
6116 && optimize_function_for_speed_p (cfun)
6117 && (!EXT_REX_SSE_REG_P (operands[0])
6118 || TARGET_AVX512VL)"
6120 (vec_merge:<MODEF:ssevecmode>
6121 (vec_duplicate:<MODEF:ssevecmode>
6127 const machine_mode vmode = <MODEF:ssevecmode>mode;
6129 operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode);
6130 emit_move_insn (operands[0], CONST0_RTX (vmode));
6133 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
6134 [(set (match_operand:MODEF 0 "register_operand")
6135 (unsigned_float:MODEF
6136 (match_operand:SWI12 1 "nonimmediate_operand")))]
6138 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
6140 operands[1] = convert_to_mode (SImode, operands[1], 1);
6141 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
6145 (define_insn "*floatuns<SWI48:mode><MODEF:mode>2_avx512"
6146 [(set (match_operand:MODEF 0 "register_operand" "=v")
6147 (unsigned_float:MODEF
6148 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
6149 "TARGET_AVX512F && TARGET_SSE_MATH"
6150 "vcvtusi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %0, %0|%0, %0, %1}"
6151 [(set_attr "type" "sseicvt")
6152 (set_attr "avx_partial_xmm_update" "true")
6153 (set_attr "prefix" "evex")
6154 (set_attr "mode" "<MODEF:MODE>")])
6156 ;; Avoid store forwarding (partial memory) stall penalty by extending
6157 ;; SImode value to DImode through XMM register instead of pushing two
6158 ;; SImode values to stack. Also note that fild loads from memory only.
6160 (define_insn_and_split "floatunssi<mode>2_i387_with_xmm"
6161 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
6162 (unsigned_float:X87MODEF
6163 (match_operand:SI 1 "nonimmediate_operand" "rm")))
6164 (clobber (match_operand:DI 2 "memory_operand" "=m"))
6165 (clobber (match_scratch:DI 3 "=x"))]
6167 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6168 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
6170 "&& reload_completed"
6171 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
6172 (set (match_dup 2) (match_dup 3))
6174 (float:X87MODEF (match_dup 2)))]
6176 [(set_attr "type" "multi")
6177 (set_attr "mode" "<MODE>")])
6179 (define_expand "floatunssi<mode>2"
6180 [(set (match_operand:X87MODEF 0 "register_operand")
6181 (unsigned_float:X87MODEF
6182 (match_operand:SI 1 "nonimmediate_operand")))]
6184 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6185 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
6186 || ((!TARGET_64BIT || TARGET_AVX512F)
6187 && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
6189 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
6191 emit_insn (gen_floatunssi<mode>2_i387_with_xmm
6192 (operands[0], operands[1],
6193 assign_386_stack_local (DImode, SLOT_TEMP)));
6196 if (!TARGET_AVX512F)
6198 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
6203 (define_expand "floatunsdisf2"
6204 [(set (match_operand:SF 0 "register_operand")
6206 (match_operand:DI 1 "nonimmediate_operand")))]
6207 "TARGET_64BIT && TARGET_SSE && TARGET_SSE_MATH"
6209 if (!TARGET_AVX512F)
6211 x86_emit_floatuns (operands);
6216 (define_expand "floatunsdidf2"
6217 [(set (match_operand:DF 0 "register_operand")
6219 (match_operand:DI 1 "nonimmediate_operand")))]
6220 "((TARGET_64BIT && TARGET_AVX512F)
6221 || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
6222 && TARGET_SSE2 && TARGET_SSE_MATH"
6226 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
6229 if (!TARGET_AVX512F)
6231 x86_emit_floatuns (operands);
6236 ;; Load effective address instructions
6238 (define_insn "*lea<mode>"
6239 [(set (match_operand:SWI48 0 "register_operand" "=r")
6240 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
6241 "ix86_hardreg_mov_ok (operands[0], operands[1])"
6243 if (SImode_address_operand (operands[1], VOIDmode))
6245 gcc_assert (TARGET_64BIT);
6246 return "lea{l}\t{%E1, %k0|%k0, %E1}";
6249 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
6251 [(set_attr "type" "lea")
6254 (match_operand 1 "SImode_address_operand")
6256 (const_string "<MODE>")))])
6259 [(set (match_operand:SWI48 0 "register_operand")
6260 (match_operand:SWI48 1 "address_no_seg_operand"))]
6261 "ix86_hardreg_mov_ok (operands[0], operands[1])
6262 && peep2_regno_dead_p (0, FLAGS_REG)
6263 && ix86_avoid_lea_for_addr (peep2_next_insn (0), operands)"
6266 machine_mode mode = <MODE>mode;
6268 /* Emit all operations in SImode for zero-extended addresses. */
6269 if (SImode_address_operand (operands[1], VOIDmode))
6272 ix86_split_lea_for_addr (peep2_next_insn (0), operands, mode);
6274 /* Zero-extend return register to DImode for zero-extended addresses. */
6275 if (mode != <MODE>mode)
6276 emit_insn (gen_zero_extendsidi2 (operands[0],
6277 gen_lowpart (mode, operands[0])));
6282 ;; ix86_split_lea_for_addr emits the shifts as MULT to avoid it from being
6283 ;; peephole2 optimized back into a lea. Split that into the shift during
6284 ;; the following split pass.
6286 [(set (match_operand:SWI48 0 "general_reg_operand")
6287 (mult:SWI48 (match_dup 0) (match_operand:SWI48 1 "const1248_operand")))
6288 (clobber (reg:CC FLAGS_REG))]
6290 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
6291 (clobber (reg:CC FLAGS_REG))])]
6292 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
6296 (define_expand "add<mode>3"
6297 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6298 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6299 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
6302 ix86_expand_binary_operator (PLUS, <MODE>mode, operands, TARGET_APX_NDD);
6306 (define_insn_and_split "*add<dwi>3_doubleword"
6307 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,&r,&r,&r,&r,&r")
6309 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0,ro,r,ro,jO,r")
6310 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o,r,<di>,K,<di>,r")))
6311 (clobber (reg:CC FLAGS_REG))]
6312 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands, TARGET_APX_NDD)"
6314 "&& reload_completed"
6315 [(parallel [(set (reg:CCC FLAGS_REG)
6317 (plus:DWIH (match_dup 1) (match_dup 2))
6320 (plus:DWIH (match_dup 1) (match_dup 2)))])
6321 (parallel [(set (match_dup 3)
6324 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6327 (clobber (reg:CC FLAGS_REG))])]
6329 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6330 if (operands[2] == const0_rtx)
6332 /* Under NDD op0 and op1 may not equal, do not delete insn then. */
6333 bool emit_insn_deleted_note_p = true;
6334 if (!rtx_equal_p (operands[0], operands[1]))
6336 emit_move_insn (operands[0], operands[1]);
6337 emit_insn_deleted_note_p = false;
6339 if (operands[5] != const0_rtx)
6340 ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3],
6342 else if (!rtx_equal_p (operands[3], operands[4]))
6343 emit_move_insn (operands[3], operands[4]);
6344 else if (emit_insn_deleted_note_p)
6345 emit_note (NOTE_INSN_DELETED);
6349 [(set_attr "isa" "*,*,apx_ndd,apx_ndd,apx_ndd,apx_ndd_64,apx_ndd")])
6351 (define_insn_and_split "*add<dwi>3_doubleword_zext"
6352 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,&r,&r")
6355 (match_operand:DWIH 2 "nonimmediate_operand" "rm,r,rm,r"))
6356 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0,r,m")))
6357 (clobber (reg:CC FLAGS_REG))]
6358 "ix86_binary_operator_ok (UNKNOWN, <DWI>mode, operands, TARGET_APX_NDD)"
6360 "&& reload_completed"
6361 [(parallel [(set (reg:CCC FLAGS_REG)
6363 (plus:DWIH (match_dup 1) (match_dup 2))
6366 (plus:DWIH (match_dup 1) (match_dup 2)))])
6367 (parallel [(set (match_dup 3)
6370 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6373 (clobber (reg:CC FLAGS_REG))])]
6374 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[3]);"
6375 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")])
6377 (define_insn_and_split "*add<dwi>3_doubleword_concat"
6378 [(set (match_operand:<DWI> 0 "register_operand" "=&r")
6383 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))
6384 (match_operand:QI 3 "const_int_operand"))
6386 (match_operand:DWIH 4 "nonimmediate_operand" "rm")))
6387 (match_operand:<DWI> 1 "register_operand" "0")))
6388 (clobber (reg:CC FLAGS_REG))]
6389 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
6391 "&& reload_completed"
6392 [(parallel [(set (reg:CCC FLAGS_REG)
6394 (plus:DWIH (match_dup 1) (match_dup 4))
6397 (plus:DWIH (match_dup 1) (match_dup 4)))])
6398 (parallel [(set (match_dup 5)
6401 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6404 (clobber (reg:CC FLAGS_REG))])]
6405 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[5]);")
6407 (define_insn_and_split "*add<dwi>3_doubleword_concat_zext"
6408 [(set (match_operand:<DWI> 0 "register_operand" "=&r")
6413 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))
6414 (match_operand:QI 3 "const_int_operand"))
6416 (match_operand:DWIH 4 "nonimmediate_operand" "rm")))
6418 (match_operand:DWIH 1 "nonimmediate_operand" "rm"))))
6419 (clobber (reg:CC FLAGS_REG))]
6420 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
6422 "&& reload_completed"
6423 [(set (match_dup 0) (match_dup 4))
6424 (parallel [(set (reg:CCC FLAGS_REG)
6426 (plus:DWIH (match_dup 0) (match_dup 1))
6429 (plus:DWIH (match_dup 0) (match_dup 1)))])
6430 (set (match_dup 5) (match_dup 2))
6431 (parallel [(set (match_dup 5)
6434 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6437 (clobber (reg:CC FLAGS_REG))])]
6438 "split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[5]);")
6440 (define_insn "*add<mode>_1"
6441 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,r,r,r,r")
6443 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r,rje,jM,r")
6444 (match_operand:SWI48 2 "x86_64_general_operand" "re,BM,0,le,r,e,BM")))
6445 (clobber (reg:CC FLAGS_REG))]
6446 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)"
6448 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
6449 switch (get_attr_type (insn))
6455 if (operands[2] == const1_rtx)
6456 return use_ndd ? "inc{<imodesuffix>}\t{%1, %0|%0, %1}"
6457 : "inc{<imodesuffix>}\t%0";
6460 gcc_assert (operands[2] == constm1_rtx);
6461 return use_ndd ? "dec{<imodesuffix>}\t{%1, %0|%0, %1}"
6462 : "dec{<imodesuffix>}\t%0";
6466 /* For most processors, ADD is faster than LEA. This alternative
6467 was added to use ADD as much as possible. */
6468 if (which_alternative == 2)
6469 std::swap (operands[1], operands[2]);
6471 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6472 return use_ndd ? "sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
6473 : "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6475 return use_ndd ? "add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
6476 : "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6479 [(set_attr "isa" "*,*,*,*,apx_ndd,apx_ndd,apx_ndd")
6481 (cond [(eq_attr "alternative" "3")
6482 (const_string "lea")
6483 (match_operand:SWI48 2 "incdec_operand")
6484 (const_string "incdec")
6486 (const_string "alu")))
6487 (set (attr "length_immediate")
6489 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6491 (const_string "*")))
6492 (set_attr "mode" "<MODE>")])
6494 ;; It may seem that nonimmediate operand is proper one for operand 1.
6495 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6496 ;; we take care in ix86_binary_operator_ok to not allow two memory
6497 ;; operands so proper swapping will be done in reload. This allow
6498 ;; patterns constructed from addsi_1 to match.
6500 (define_insn "addsi_1_zext"
6501 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r")
6503 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r,r,rm,rjM")
6504 (match_operand:SI 2 "x86_64_general_operand" "rBMe,0,le,rBMe,r,e"))))
6505 (clobber (reg:CC FLAGS_REG))]
6507 && ix86_binary_operator_ok (PLUS, SImode, operands, TARGET_APX_NDD)"
6509 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
6510 switch (get_attr_type (insn))
6516 if (operands[2] == const1_rtx)
6517 return use_ndd ? "inc{l}\t{%1, %k0|%k0, %1}"
6521 gcc_assert (operands[2] == constm1_rtx);
6522 return use_ndd ? "dec{l}\t{%1, %k0|%k0, %1}"
6527 /* For most processors, ADD is faster than LEA. This alternative
6528 was added to use ADD as much as possible. */
6529 if (which_alternative == 1)
6530 std::swap (operands[1], operands[2]);
6532 if (x86_maybe_negate_const_int (&operands[2], SImode))
6533 return use_ndd ? "sub{l}\t{%2 ,%1, %k0|%k0, %1, %2}"
6534 : "sub{l}\t{%2, %k0|%k0, %2}";
6536 return use_ndd ? "add{l}\t{%2 ,%1, %k0|%k0, %1, %2}"
6537 : "add{l}\t{%2, %k0|%k0, %2}";
6540 [(set_attr "isa" "*,*,*,apx_ndd,apx_ndd,apx_ndd")
6542 (cond [(eq_attr "alternative" "2")
6543 (const_string "lea")
6544 (match_operand:SI 2 "incdec_operand")
6545 (const_string "incdec")
6547 (const_string "alu")))
6548 (set (attr "length_immediate")
6550 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6552 (const_string "*")))
6553 (set_attr "mode" "SI")])
6555 (define_insn "*addhi_1"
6556 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp,r,r")
6557 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp,rm,r")
6558 (match_operand:HI 2 "general_operand" "rn,m,0,ln,rn,m")))
6559 (clobber (reg:CC FLAGS_REG))]
6560 "ix86_binary_operator_ok (PLUS, HImode, operands, TARGET_APX_NDD)"
6562 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
6563 switch (get_attr_type (insn))
6569 if (operands[2] == const1_rtx)
6570 return use_ndd ? "inc{w}\t{%1, %0|%0, %1}" : "inc{w}\t%0";
6573 gcc_assert (operands[2] == constm1_rtx);
6574 return use_ndd ? "dec{w}\t{%1, %0|%0, %1}" : "dec{w}\t%0";
6578 /* For most processors, ADD is faster than LEA. This alternative
6579 was added to use ADD as much as possible. */
6580 if (which_alternative == 2)
6581 std::swap (operands[1], operands[2]);
6583 if (x86_maybe_negate_const_int (&operands[2], HImode))
6584 return use_ndd ? "sub{w}\t{%2, %1, %0|%0, %1, %2}"
6585 : "sub{w}\t{%2, %0|%0, %2}";
6587 return use_ndd ? "add{w}\t{%2, %1, %0|%0, %1, %2}"
6588 : "add{w}\t{%2, %0|%0, %2}";
6591 [(set_attr "isa" "*,*,*,*,apx_ndd,apx_ndd")
6593 (cond [(eq_attr "alternative" "3")
6594 (const_string "lea")
6595 (match_operand:HI 2 "incdec_operand")
6596 (const_string "incdec")
6598 (const_string "alu")))
6599 (set (attr "length_immediate")
6601 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6603 (const_string "*")))
6604 (set_attr "mode" "HI,HI,HI,SI,HI,HI")])
6606 (define_insn "*addqi_1"
6607 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp,r,r")
6608 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp,rm,r")
6609 (match_operand:QI 2 "general_operand" "qn,m,0,rn,0,ln,rn,m")))
6610 (clobber (reg:CC FLAGS_REG))]
6611 "ix86_binary_operator_ok (PLUS, QImode, operands, TARGET_APX_NDD)"
6613 bool widen = (get_attr_mode (insn) != MODE_QI);
6614 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
6615 switch (get_attr_type (insn))
6621 if (operands[2] == const1_rtx)
6623 return "inc{b}\t{%1, %0|%0, %1}";
6625 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6628 gcc_assert (operands[2] == constm1_rtx);
6630 return "dec{b}\t{%1, %0|%0, %1}";
6632 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6636 /* For most processors, ADD is faster than LEA. These alternatives
6637 were added to use ADD as much as possible. */
6638 if (which_alternative == 2 || which_alternative == 4)
6639 std::swap (operands[1], operands[2]);
6641 if (x86_maybe_negate_const_int (&operands[2], QImode))
6644 return "sub{b}\t{%2, %1, %0|%0, %1, %2}";
6646 return widen ? "sub{l}\t{%2, %k0|%k0, %2}"
6647 : "sub{b}\t{%2, %0|%0, %2}";
6650 return "add{b}\t{%2, %1, %0|%0, %1, %2}";
6652 return widen ? "add{l}\t{%k2, %k0|%k0, %k2}"
6653 : "add{b}\t{%2, %0|%0, %2}";
6656 [(set_attr "isa" "*,*,*,*,*,*,apx_ndd,apx_ndd")
6658 (cond [(eq_attr "alternative" "5")
6659 (const_string "lea")
6660 (match_operand:QI 2 "incdec_operand")
6661 (const_string "incdec")
6663 (const_string "alu")))
6664 (set (attr "length_immediate")
6666 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6668 (const_string "*")))
6669 (set_attr "mode" "QI,QI,QI,SI,SI,SI,QI,QI")
6670 ;; Potential partial reg stall on alternatives 3 and 4.
6671 (set (attr "preferred_for_speed")
6672 (cond [(eq_attr "alternative" "3,4")
6673 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
6674 (symbol_ref "true")))])
6676 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
6677 (define_insn_and_split "*add<mode>_1_slp"
6678 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
6679 (plus:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0,!<r>")
6680 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
6681 (clobber (reg:CC FLAGS_REG))]
6682 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6684 if (which_alternative)
6687 switch (get_attr_type (insn))
6690 if (operands[2] == const1_rtx)
6691 return "inc{<imodesuffix>}\t%0";
6694 gcc_assert (operands[2] == constm1_rtx);
6695 return "dec{<imodesuffix>}\t%0";
6699 if (x86_maybe_negate_const_int (&operands[2], QImode))
6700 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6702 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6705 "&& reload_completed
6706 && !(rtx_equal_p (operands[0], operands[1])
6707 || rtx_equal_p (operands[0], operands[2]))"
6708 [(set (strict_low_part (match_dup 0)) (match_dup 1))
6710 [(set (strict_low_part (match_dup 0))
6711 (plus:SWI12 (match_dup 0) (match_dup 2)))
6712 (clobber (reg:CC FLAGS_REG))])]
6715 (if_then_else (match_operand:QI 2 "incdec_operand")
6716 (const_string "incdec")
6717 (const_string "alu")))
6718 (set_attr "mode" "<MODE>")])
6720 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
6721 (define_insn_and_split "*addqi_ext<mode>_1_slp"
6722 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+Q,&Q"))
6725 (match_operator:SWI248 3 "extract_operator"
6726 [(match_operand 2 "int248_register_operand" "Q,Q")
6729 (match_operand:QI 1 "nonimmediate_operand" "0,!qm")))
6730 (clobber (reg:CC FLAGS_REG))]
6731 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6733 add{b}\t{%h2, %0|%0, %h2}
6735 "&& reload_completed
6736 && !rtx_equal_p (operands[0], operands[1])"
6737 [(set (strict_low_part (match_dup 0)) (match_dup 1))
6739 [(set (strict_low_part (match_dup 0))
6743 [(match_dup 2) (const_int 8) (const_int 8)]) 0)
6745 (clobber (reg:CC FLAGS_REG))])]
6747 [(set_attr "type" "alu")
6748 (set_attr "mode" "QI")])
6750 (define_insn_and_split "*addqi_ext<mode>_2_slp"
6751 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+&Q"))
6754 (match_operator:SWI248 3 "extract_operator"
6755 [(match_operand 1 "int248_register_operand" "Q")
6759 (match_operator:SWI248 4 "extract_operator"
6760 [(match_operand 2 "int248_register_operand" "Q")
6762 (const_int 8)]) 0)))
6763 (clobber (reg:CC FLAGS_REG))]
6764 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6766 "&& reload_completed"
6767 [(set (strict_low_part (match_dup 0))
6770 [(match_dup 2) (const_int 8) (const_int 8)]) 0))
6772 [(set (strict_low_part (match_dup 0))
6776 [(match_dup 1) (const_int 8) (const_int 8)]) 0)
6778 (clobber (reg:CC FLAGS_REG))])]
6780 [(set_attr "type" "alu")
6781 (set_attr "mode" "QI")])
6783 ;; Split non destructive adds if we cannot use lea.
6785 [(set (match_operand:SWI48 0 "register_operand")
6786 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
6787 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
6788 (clobber (reg:CC FLAGS_REG))]
6789 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
6790 [(set (match_dup 0) (match_dup 1))
6791 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
6792 (clobber (reg:CC FLAGS_REG))])])
6794 ;; Split non destructive adds if we cannot use lea.
6796 [(set (match_operand:DI 0 "register_operand")
6798 (plus:SI (match_operand:SI 1 "register_operand")
6799 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
6800 (clobber (reg:CC FLAGS_REG))]
6802 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
6803 [(set (match_dup 3) (match_dup 1))
6804 (parallel [(set (match_dup 0)
6805 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
6806 (clobber (reg:CC FLAGS_REG))])]
6807 "operands[3] = gen_lowpart (SImode, operands[0]);")
6809 ;; Convert add to the lea pattern to avoid flags dependency.
6811 [(set (match_operand:SWI 0 "register_operand")
6812 (plus:SWI (match_operand:SWI 1 "register_operand")
6813 (match_operand:SWI 2 "<nonmemory_operand>")))
6814 (clobber (reg:CC FLAGS_REG))]
6815 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
6817 (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
6819 if (<MODE>mode != <LEAMODE>mode)
6821 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
6822 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
6823 operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
6827 ;; Convert add to the lea pattern to avoid flags dependency.
6829 [(set (match_operand:DI 0 "register_operand")
6831 (plus:SI (match_operand:SI 1 "register_operand")
6832 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
6833 (clobber (reg:CC FLAGS_REG))]
6834 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
6836 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
6838 (define_insn "*add<mode>_2"
6839 [(set (reg FLAGS_REG)
6842 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>,rm,r")
6843 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,0,r<i>,<m>"))
6845 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,<r>,r,r")
6846 (plus:SWI (match_dup 1) (match_dup 2)))]
6847 "ix86_match_ccmode (insn, CCGOCmode)
6848 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)"
6850 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
6851 switch (get_attr_type (insn))
6854 if (operands[2] == const1_rtx)
6855 return use_ndd ? "inc{<imodesuffix>}\t{%1, %0|%0, %1}"
6856 : "inc{<imodesuffix>}\t%0";
6859 gcc_assert (operands[2] == constm1_rtx);
6860 return use_ndd ? "dec{<imodesuffix>}\t{%1, %0|%0, %1}"
6861 : "dec{<imodesuffix>}\t%0";
6865 if (which_alternative == 2)
6866 std::swap (operands[1], operands[2]);
6868 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6869 return use_ndd ? "sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
6870 : "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6872 return use_ndd ? "add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
6873 : "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6876 [(set_attr "isa" "*,*,*,apx_ndd,apx_ndd")
6878 (if_then_else (match_operand:SWI 2 "incdec_operand")
6879 (const_string "incdec")
6880 (const_string "alu")))
6881 (set (attr "length_immediate")
6883 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6885 (const_string "*")))
6886 (set_attr "mode" "<MODE>")])
6888 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6889 (define_insn "*addsi_2_zext"
6890 [(set (reg FLAGS_REG)
6892 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r,rm")
6893 (match_operand:SI 2 "x86_64_general_operand" "rBMe,0,rBMe,re"))
6895 (set (match_operand:DI 0 "register_operand" "=r,r,r,r")
6896 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6897 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6898 && ix86_binary_operator_ok (PLUS, SImode, operands, TARGET_APX_NDD)"
6900 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
6901 switch (get_attr_type (insn))
6904 if (operands[2] == const1_rtx)
6905 return use_ndd ? "inc{l}\t{%1, %k0|%k0, %1}"
6909 gcc_assert (operands[2] == constm1_rtx);
6910 return use_ndd ? "dec{l}\t{%1, %k0|%k0, %1}"
6915 if (which_alternative == 1)
6916 std::swap (operands[1], operands[2]);
6918 if (x86_maybe_negate_const_int (&operands[2], SImode))
6919 return use_ndd ? "sub{l}\t{%2, %1, %k0|%k0, %1, %2}"
6920 : "sub{l}\t{%2, %k0|%k0, %2}";
6922 return use_ndd ? "add{l}\t{%2, %1, %k0|%k0, %1, %2}"
6923 : "add{l}\t{%2, %k0|%k0, %2}";
6926 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
6928 (if_then_else (match_operand:SI 2 "incdec_operand")
6929 (const_string "incdec")
6930 (const_string "alu")))
6931 (set (attr "length_immediate")
6933 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6935 (const_string "*")))
6936 (set_attr "mode" "SI")])
6938 (define_insn "*add<mode>_3"
6939 [(set (reg FLAGS_REG)
6941 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0,<g>,re"))
6942 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>,r,rm")))
6943 (clobber (match_scratch:SWI 0 "=<r>,<r>,r,r"))]
6944 "ix86_match_ccmode (insn, CCZmode)
6945 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6947 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
6948 switch (get_attr_type (insn))
6951 if (operands[2] == const1_rtx)
6952 return use_ndd ? "inc{<imodesuffix>}\t{%1, %0|%0, %1}"
6953 : "inc{<imodesuffix>}\t%0";
6956 gcc_assert (operands[2] == constm1_rtx);
6957 return use_ndd ? "dec{<imodesuffix>}\t{%1, %0|%0, %1}"
6958 : "dec{<imodesuffix>}\t%0";
6962 if (which_alternative == 1)
6963 std::swap (operands[1], operands[2]);
6965 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6966 return use_ndd ? "sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
6967 : "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6969 return use_ndd ? "add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
6970 : "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6973 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
6975 (if_then_else (match_operand:SWI 2 "incdec_operand")
6976 (const_string "incdec")
6977 (const_string "alu")))
6978 (set (attr "length_immediate")
6980 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6982 (const_string "*")))
6983 (set_attr "mode" "<MODE>")])
6985 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6986 (define_insn "*addsi_3_zext"
6987 [(set (reg FLAGS_REG)
6989 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rBMe,0,rBMe,re"))
6990 (match_operand:SI 1 "nonimmediate_operand" "%0,r,r,rm")))
6991 (set (match_operand:DI 0 "register_operand" "=r,r,r,r")
6992 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6993 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6994 && ix86_binary_operator_ok (PLUS, SImode, operands, TARGET_APX_NDD)"
6996 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
6997 switch (get_attr_type (insn))
7000 if (operands[2] == const1_rtx)
7001 return use_ndd ? "inc{l}\t{%1, %k0|%k0, %1}" : "inc{l}\t%k0";
7004 gcc_assert (operands[2] == constm1_rtx);
7005 return use_ndd ? "dec{l}\t{%1, %k0|%k0, %1}" : "dec{l}\t%k0";
7009 if (which_alternative == 1)
7010 std::swap (operands[1], operands[2]);
7012 if (x86_maybe_negate_const_int (&operands[2], SImode))
7013 return use_ndd ? "sub{l}\t{%2, %1, %k0|%k0, %1, %2}"
7014 : "sub{l}\t{%2, %k0|%k0, %2}";
7016 return use_ndd ? "add{l}\t{%2, %1, %k0|%k0, %1, %2}"
7017 : "add{l}\t{%2, %k0|%k0, %2}";
7020 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
7022 (if_then_else (match_operand:SI 2 "incdec_operand")
7023 (const_string "incdec")
7024 (const_string "alu")))
7025 (set (attr "length_immediate")
7027 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
7029 (const_string "*")))
7030 (set_attr "mode" "SI")])
7032 ; For comparisons against 1, -1 and 128, we may generate better code
7033 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
7034 ; is matched then. We can't accept general immediate, because for
7035 ; case of overflows, the result is messed up.
7036 ; Also carry flag is reversed compared to cmp, so this conversion is valid
7037 ; only for comparisons not depending on it.
7039 (define_insn "*adddi_4"
7040 [(set (reg FLAGS_REG)
7042 (match_operand:DI 1 "nonimmediate_operand" "0,rm")
7043 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
7044 (clobber (match_scratch:DI 0 "=r,r"))]
7046 && ix86_match_ccmode (insn, CCGCmode)"
7048 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
7049 switch (get_attr_type (insn))
7052 if (operands[2] == constm1_rtx)
7053 return use_ndd ? "inc{q}\t{%1, %0|%0, %1}" : "inc{q}\t%0";
7056 gcc_assert (operands[2] == const1_rtx);
7057 return use_ndd ? "dec{q}\t{%1, %0|%0, %1}" : "dec{q}\t%0";
7061 if (x86_maybe_negate_const_int (&operands[2], DImode))
7062 return use_ndd ? "add{q}\t{%2, %1, %0|%0, %1, %2}"
7063 : "add{q}\t{%2, %0|%0, %2}";
7065 return use_ndd ? "sub{q}\t{%2, %1, %0|%0, %1, %2}"
7066 : "sub{q}\t{%2, %0|%0, %2}";
7069 [(set_attr "isa" "*,apx_ndd")
7071 (if_then_else (match_operand:DI 2 "incdec_operand")
7072 (const_string "incdec")
7073 (const_string "alu")))
7074 (set (attr "length_immediate")
7076 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
7078 (const_string "*")))
7079 (set_attr "mode" "DI")])
7081 ; For comparisons against 1, -1 and 128, we may generate better code
7082 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
7083 ; is matched then. We can't accept general immediate, because for
7084 ; case of overflows, the result is messed up.
7085 ; Also carry flag is reversed compared to cmp, so this conversion is valid
7086 ; only for comparisons not depending on it.
7088 (define_insn "*add<mode>_4"
7089 [(set (reg FLAGS_REG)
7091 (match_operand:SWI124 1 "nonimmediate_operand" "0,rm")
7092 (match_operand:SWI124 2 "const_int_operand")))
7093 (clobber (match_scratch:SWI124 0 "=<r>,r"))]
7094 "ix86_match_ccmode (insn, CCGCmode)"
7096 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
7097 switch (get_attr_type (insn))
7100 if (operands[2] == constm1_rtx)
7101 return use_ndd ? "inc{<imodesuffix>}\t{%1, %0|%0, %1}"
7102 : "inc{<imodesuffix>}\t%0";
7105 gcc_assert (operands[2] == const1_rtx);
7106 return use_ndd ? "dec{<imodesuffix>}\t{%1, %0|%0, %1}"
7107 : "dec{<imodesuffix>}\t%0";
7111 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
7112 return use_ndd ? "add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7113 : "add{<imodesuffix>}\t{%2, %0|%0, %2}";
7115 return use_ndd ? "sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7116 : "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
7119 [(set_attr "isa" "*,apx_ndd")
7121 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
7122 (const_string "incdec")
7123 (const_string "alu")))
7124 (set (attr "length_immediate")
7126 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
7128 (const_string "*")))
7129 (set_attr "mode" "<MODE>")])
7131 (define_insn "*add<mode>_5"
7132 [(set (reg FLAGS_REG)
7135 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>,r,rm")
7136 (match_operand:SWI 2 "<general_operand>" "<g>,0,<g>,re"))
7138 (clobber (match_scratch:SWI 0 "=<r>,<r>,r,r"))]
7139 "ix86_match_ccmode (insn, CCGOCmode)
7140 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
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{<imodesuffix>}\t{%1, %0|%0, %1}"
7148 : "inc{<imodesuffix>}\t%0";
7151 gcc_assert (operands[2] == constm1_rtx);
7152 return use_ndd ? "dec{<imodesuffix>}\t{%1, %0|%0, %1}"
7153 : "dec{<imodesuffix>}\t%0";
7157 if (which_alternative == 1)
7158 std::swap (operands[1], operands[2]);
7160 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
7161 return use_ndd ? "sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7162 : "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
7164 return use_ndd ? "add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7165 : "add{<imodesuffix>}\t{%2, %0|%0, %2}";
7168 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
7170 (if_then_else (match_operand:SWI 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" "<MODE>")])
7180 (define_insn "*addqi_ext<mode>_0"
7181 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn")
7184 (match_operator:SWI248 3 "extract_operator"
7185 [(match_operand 2 "int248_register_operand" "Q")
7188 (match_operand:QI 1 "nonimmediate_operand" "0")))
7189 (clobber (reg:CC FLAGS_REG))]
7191 "add{b}\t{%h2, %0|%0, %h2}"
7192 [(set_attr "addr" "gpr8")
7193 (set_attr "type" "alu")
7194 (set_attr "mode" "QI")])
7196 (define_insn_and_split "*addqi_ext2<mode>_0"
7197 [(set (match_operand:QI 0 "register_operand" "=&Q")
7200 (match_operator:SWI248 3 "extract_operator"
7201 [(match_operand 1 "int248_register_operand" "Q")
7205 (match_operator:SWI248 4 "extract_operator"
7206 [(match_operand 2 "int248_register_operand" "Q")
7208 (const_int 8)]) 0)))
7209 (clobber (reg:CC FLAGS_REG))]
7212 "&& reload_completed"
7216 [(match_dup 2) (const_int 8) (const_int 8)]) 0))
7222 [(match_dup 1) (const_int 8) (const_int 8)]) 0)
7224 (clobber (reg:CC FLAGS_REG))])]
7226 [(set_attr "type" "alu")
7227 (set_attr "mode" "QI")])
7229 (define_expand "addqi_ext_1"
7231 [(set (zero_extract:HI (match_operand:HI 0 "register_operand")
7237 (zero_extract:HI (match_operand:HI 1 "register_operand")
7240 (match_operand:QI 2 "const_int_operand")) 0))
7241 (clobber (reg:CC FLAGS_REG))])])
7243 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
7244 (define_insn_and_split "*addqi_ext<mode>_1"
7245 [(set (zero_extract:SWI248
7246 (match_operand 0 "int248_register_operand" "+Q,&Q")
7252 (match_operator:SWI248 3 "extract_operator"
7253 [(match_operand 1 "int248_register_operand" "0,!Q")
7256 (match_operand:QI 2 "general_operand" "QnBn,QnBn")) 0))
7257 (clobber (reg:CC FLAGS_REG))]
7260 if (which_alternative)
7263 switch (get_attr_type (insn))
7266 if (operands[2] == const1_rtx)
7267 return "inc{b}\t%h0";
7270 gcc_assert (operands[2] == constm1_rtx);
7271 return "dec{b}\t%h0";
7275 return "add{b}\t{%2, %h0|%h0, %2}";
7279 && !rtx_equal_p (operands[0], operands[1])"
7280 [(set (zero_extract:SWI248
7281 (match_dup 0) (const_int 8) (const_int 8))
7282 (zero_extract:SWI248
7283 (match_dup 1) (const_int 8) (const_int 8)))
7285 [(set (zero_extract:SWI248
7286 (match_dup 0) (const_int 8) (const_int 8))
7291 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
7293 (clobber (reg:CC FLAGS_REG))])]
7295 [(set_attr "addr" "gpr8")
7297 (if_then_else (match_operand:QI 2 "incdec_operand")
7298 (const_string "incdec")
7299 (const_string "alu")))
7300 (set_attr "mode" "QI")])
7302 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
7303 (define_insn_and_split "*<insn>qi_ext<mode>_2"
7304 [(set (zero_extract:SWI248
7305 (match_operand 0 "int248_register_operand" "+Q,&Q")
7311 (match_operator:SWI248 3 "extract_operator"
7312 [(match_operand 1 "int248_register_operand" "<comm>0,!Q")
7316 (match_operator:SWI248 4 "extract_operator"
7317 [(match_operand 2 "int248_register_operand" "Q,Q")
7319 (const_int 8)]) 0)) 0))
7320 (clobber (reg:CC FLAGS_REG))]
7323 <insn>{b}\t{%h2, %h0|%h0, %h2}
7326 && !(rtx_equal_p (operands[0], operands[1])
7327 || (<CODE> == PLUS && rtx_equal_p (operands[0], operands[2])))"
7328 [(set (zero_extract:SWI248
7329 (match_dup 0) (const_int 8) (const_int 8))
7330 (zero_extract:SWI248
7331 (match_dup 1) (const_int 8) (const_int 8)))
7333 [(set (zero_extract:SWI248
7334 (match_dup 0) (const_int 8) (const_int 8))
7339 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
7342 [(match_dup 2) (const_int 8) (const_int 8)]) 0)) 0))
7343 (clobber (reg:CC FLAGS_REG))])]
7345 [(set_attr "type" "alu")
7346 (set_attr "mode" "QI")])
7348 ;; Like DWI, but use POImode instead of OImode.
7349 (define_mode_attr DPWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI") (TI "POI")])
7351 ;; Add with jump on overflow.
7352 (define_expand "addv<mode>4"
7353 [(parallel [(set (reg:CCO FLAGS_REG)
7357 (match_operand:SWIDWI 1 "nonimmediate_operand"))
7360 (plus:SWIDWI (match_dup 1)
7361 (match_operand:SWIDWI 2
7362 "<general_hilo_operand>")))))
7363 (set (match_operand:SWIDWI 0 "register_operand")
7364 (plus:SWIDWI (match_dup 1) (match_dup 2)))])
7365 (set (pc) (if_then_else
7366 (eq (reg:CCO FLAGS_REG) (const_int 0))
7367 (label_ref (match_operand 3))
7371 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
7372 if (CONST_SCALAR_INT_P (operands[2]))
7373 operands[4] = operands[2];
7375 operands[4] = gen_rtx_SIGN_EXTEND (<DPWI>mode, operands[2]);
7378 (define_insn "*addv<mode>4"
7379 [(set (reg:CCO FLAGS_REG)
7382 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,rm,r"))
7384 (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m,rWe,m")))
7386 (plus:SWI (match_dup 1) (match_dup 2)))))
7387 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r")
7388 (plus:SWI (match_dup 1) (match_dup 2)))]
7389 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)"
7391 add{<imodesuffix>}\t{%2, %0|%0, %2}
7392 add{<imodesuffix>}\t{%2, %0|%0, %2}
7393 add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7394 add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7395 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
7396 (set_attr "type" "alu")
7397 (set_attr "mode" "<MODE>")])
7399 (define_insn "addv<mode>4_1"
7400 [(set (reg:CCO FLAGS_REG)
7403 (match_operand:SWI 1 "nonimmediate_operand" "0,rm"))
7404 (match_operand:<DWI> 3 "const_int_operand"))
7408 (match_operand:SWI 2 "x86_64_immediate_operand" "<i>,<i>")))))
7409 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,r")
7410 (plus:SWI (match_dup 1) (match_dup 2)))]
7411 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)
7412 && CONST_INT_P (operands[2])
7413 && INTVAL (operands[2]) == INTVAL (operands[3])"
7415 add{<imodesuffix>}\t{%2, %0|%0, %2}
7416 add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7417 [(set_attr "isa" "*,apx_ndd")
7418 (set_attr "type" "alu")
7419 (set_attr "mode" "<MODE>")
7420 (set (attr "length_immediate")
7421 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7423 (match_test "<MODE_SIZE> == 8")
7425 (const_string "<MODE_SIZE>")))])
7427 ;; Quad word integer modes as mode attribute.
7428 (define_mode_attr QPWI [(SI "TI") (DI "POI")])
7430 (define_insn_and_split "*addv<dwi>4_doubleword"
7431 [(set (reg:CCO FLAGS_REG)
7435 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0,ro,r"))
7437 (match_operand:<DWI> 2 "nonimmediate_operand" "r,o,r,o")))
7439 (plus:<DWI> (match_dup 1) (match_dup 2)))))
7440 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,&r,&r")
7441 (plus:<DWI> (match_dup 1) (match_dup 2)))]
7442 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands, TARGET_APX_NDD)"
7444 "&& reload_completed"
7445 [(parallel [(set (reg:CCC FLAGS_REG)
7447 (plus:DWIH (match_dup 1) (match_dup 2))
7450 (plus:DWIH (match_dup 1) (match_dup 2)))])
7451 (parallel [(set (reg:CCO FLAGS_REG)
7455 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7456 (sign_extend:<DWI> (match_dup 4)))
7457 (sign_extend:<DWI> (match_dup 5)))
7461 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7467 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7471 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7473 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")])
7475 (define_insn_and_split "*addv<dwi>4_doubleword_1"
7476 [(set (reg:CCO FLAGS_REG)
7480 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,rjM"))
7481 (match_operand:<QPWI> 3 "const_scalar_int_operand" "n,n"))
7485 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>,<di>")))))
7486 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,&r")
7487 (plus:<DWI> (match_dup 1) (match_dup 2)))]
7488 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands, TARGET_APX_NDD)
7489 && CONST_SCALAR_INT_P (operands[2])
7490 && rtx_equal_p (operands[2], operands[3])"
7492 "&& reload_completed"
7493 [(parallel [(set (reg:CCC FLAGS_REG)
7495 (plus:DWIH (match_dup 1) (match_dup 2))
7498 (plus:DWIH (match_dup 1) (match_dup 2)))])
7499 (parallel [(set (reg:CCO FLAGS_REG)
7503 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7504 (sign_extend:<DWI> (match_dup 4)))
7509 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7515 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7519 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7520 if (operands[2] == const0_rtx)
7522 if (!rtx_equal_p (operands[0], operands[1]))
7523 emit_move_insn (operands[0], operands[1]);
7524 emit_insn (gen_addv<mode>4_1 (operands[3], operands[4], operands[5],
7529 [(set_attr "isa" "*,apx_ndd")])
7531 (define_insn "*addv<mode>4_overflow_1"
7532 [(set (reg:CCO FLAGS_REG)
7536 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7537 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7539 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,rm,r")))
7541 (match_operand:SWI 2 "<general_sext_operand>" "rWe,m,rWe,m")))
7545 (match_operator:SWI 5 "ix86_carry_flag_operator"
7546 [(match_dup 3) (const_int 0)])
7549 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r,r,r")
7552 (match_op_dup 5 [(match_dup 3) (const_int 0)])
7555 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)"
7557 adc{<imodesuffix>}\t{%2, %0|%0, %2}
7558 adc{<imodesuffix>}\t{%2, %0|%0, %2}
7559 adc{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7560 adc{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7561 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
7562 (set_attr "type" "alu")
7563 (set_attr "mode" "<MODE>")])
7565 (define_insn "*addv<mode>4_overflow_2"
7566 [(set (reg:CCO FLAGS_REG)
7570 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7571 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7573 (match_operand:SWI 1 "nonimmediate_operand" "%0,rm")))
7574 (match_operand:<DWI> 6 "const_int_operand" "n,n"))
7578 (match_operator:SWI 5 "ix86_carry_flag_operator"
7579 [(match_dup 3) (const_int 0)])
7581 (match_operand:SWI 2 "x86_64_immediate_operand" "e,e")))))
7582 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r")
7585 (match_op_dup 5 [(match_dup 3) (const_int 0)])
7588 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)
7589 && CONST_INT_P (operands[2])
7590 && INTVAL (operands[2]) == INTVAL (operands[6])"
7592 adc{<imodesuffix>}\t{%2, %0|%0, %2}
7593 adc{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7594 [(set_attr "isa" "*,apx_ndd")
7595 (set_attr "type" "alu")
7596 (set_attr "mode" "<MODE>")
7597 (set (attr "length_immediate")
7598 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7600 (const_string "4")))])
7602 (define_expand "uaddv<mode>4"
7603 [(parallel [(set (reg:CCC FLAGS_REG)
7606 (match_operand:SWIDWI 1 "nonimmediate_operand")
7607 (match_operand:SWIDWI 2 "<general_hilo_operand>"))
7609 (set (match_operand:SWIDWI 0 "register_operand")
7610 (plus:SWIDWI (match_dup 1) (match_dup 2)))])
7611 (set (pc) (if_then_else
7612 (ltu (reg:CCC FLAGS_REG) (const_int 0))
7613 (label_ref (match_operand 3))
7616 "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
7618 ;; The lea patterns for modes less than 32 bits need to be matched by
7619 ;; several insns converted to real lea by splitters.
7621 (define_insn_and_split "*lea<mode>_general_1"
7622 [(set (match_operand:SWI12 0 "register_operand" "=r")
7624 (plus:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7625 (match_operand:SWI12 2 "register_operand" "r"))
7626 (match_operand:SWI12 3 "immediate_operand" "i")))]
7627 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7629 "&& reload_completed"
7632 (plus:SI (match_dup 1) (match_dup 2))
7635 operands[0] = gen_lowpart (SImode, operands[0]);
7636 operands[1] = gen_lowpart (SImode, operands[1]);
7637 operands[2] = gen_lowpart (SImode, operands[2]);
7638 operands[3] = gen_lowpart (SImode, operands[3]);
7640 [(set_attr "type" "lea")
7641 (set_attr "mode" "SI")])
7643 (define_insn_and_split "*lea<mode>_general_2"
7644 [(set (match_operand:SWI12 0 "register_operand" "=r")
7646 (mult:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7647 (match_operand 2 "const248_operand" "n"))
7648 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
7649 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7651 "&& reload_completed"
7654 (mult:SI (match_dup 1) (match_dup 2))
7657 operands[0] = gen_lowpart (SImode, operands[0]);
7658 operands[1] = gen_lowpart (SImode, operands[1]);
7659 operands[3] = gen_lowpart (SImode, operands[3]);
7661 [(set_attr "type" "lea")
7662 (set_attr "mode" "SI")])
7664 (define_insn_and_split "*lea<mode>_general_2b"
7665 [(set (match_operand:SWI12 0 "register_operand" "=r")
7667 (ashift:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7668 (match_operand 2 "const123_operand" "n"))
7669 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
7670 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7672 "&& reload_completed"
7675 (ashift:SI (match_dup 1) (match_dup 2))
7678 operands[0] = gen_lowpart (SImode, operands[0]);
7679 operands[1] = gen_lowpart (SImode, operands[1]);
7680 operands[3] = gen_lowpart (SImode, operands[3]);
7682 [(set_attr "type" "lea")
7683 (set_attr "mode" "SI")])
7685 (define_insn_and_split "*lea<mode>_general_3"
7686 [(set (match_operand:SWI12 0 "register_operand" "=r")
7689 (mult:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7690 (match_operand 2 "const248_operand" "n"))
7691 (match_operand:SWI12 3 "register_operand" "r"))
7692 (match_operand:SWI12 4 "immediate_operand" "i")))]
7693 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7695 "&& reload_completed"
7699 (mult:SI (match_dup 1) (match_dup 2))
7703 operands[0] = gen_lowpart (SImode, operands[0]);
7704 operands[1] = gen_lowpart (SImode, operands[1]);
7705 operands[3] = gen_lowpart (SImode, operands[3]);
7706 operands[4] = gen_lowpart (SImode, operands[4]);
7708 [(set_attr "type" "lea")
7709 (set_attr "mode" "SI")])
7711 (define_insn_and_split "*lea<mode>_general_3b"
7712 [(set (match_operand:SWI12 0 "register_operand" "=r")
7715 (ashift:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7716 (match_operand 2 "const123_operand" "n"))
7717 (match_operand:SWI12 3 "register_operand" "r"))
7718 (match_operand:SWI12 4 "immediate_operand" "i")))]
7719 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7721 "&& reload_completed"
7725 (ashift:SI (match_dup 1) (match_dup 2))
7729 operands[0] = gen_lowpart (SImode, operands[0]);
7730 operands[1] = gen_lowpart (SImode, operands[1]);
7731 operands[3] = gen_lowpart (SImode, operands[3]);
7732 operands[4] = gen_lowpart (SImode, operands[4]);
7734 [(set_attr "type" "lea")
7735 (set_attr "mode" "SI")])
7737 (define_insn_and_split "*lea<mode>_general_4"
7738 [(set (match_operand:SWI12 0 "register_operand" "=r")
7741 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7742 (match_operand 2 "const_0_to_3_operand"))
7743 (match_operand 3 "const_int_operand")))]
7744 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7745 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
7746 < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
7748 "&& reload_completed"
7751 (mult:SI (match_dup 1) (match_dup 2))
7754 operands[0] = gen_lowpart (SImode, operands[0]);
7755 operands[1] = gen_lowpart (SImode, operands[1]);
7756 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
7758 [(set_attr "type" "lea")
7759 (set_attr "mode" "SI")])
7761 (define_insn_and_split "*lea<mode>_general_4"
7762 [(set (match_operand:SWI48 0 "register_operand" "=r")
7765 (match_operand:SWI48 1 "register_no_SP_operand" "l")
7766 (match_operand 2 "const_0_to_3_operand"))
7767 (match_operand 3 "const_int_operand")))]
7768 "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
7769 < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
7771 "&& reload_completed"
7774 (mult:SWI48 (match_dup 1) (match_dup 2))
7776 "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
7777 [(set_attr "type" "lea")
7778 (set_attr "mode" "<MODE>")])
7780 ;; Subtract instructions
7782 (define_expand "sub<mode>3"
7783 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
7784 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
7785 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
7788 ix86_expand_binary_operator (MINUS, <MODE>mode, operands, TARGET_APX_NDD);
7792 (define_insn_and_split "*sub<dwi>3_doubleword"
7793 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,&r,&r")
7795 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0,ro,r")
7796 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o,r<di>,o")))
7797 (clobber (reg:CC FLAGS_REG))]
7798 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)"
7800 "&& reload_completed"
7801 [(parallel [(set (reg:CC FLAGS_REG)
7802 (compare:CC (match_dup 1) (match_dup 2)))
7804 (minus:DWIH (match_dup 1) (match_dup 2)))])
7805 (parallel [(set (match_dup 3)
7809 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7811 (clobber (reg:CC FLAGS_REG))])]
7813 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7814 if (operands[2] == const0_rtx)
7816 if (!rtx_equal_p (operands[0], operands[1]))
7817 emit_move_insn (operands[0], operands[1]);
7818 ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3],
7823 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")])
7825 (define_insn_and_split "*sub<dwi>3_doubleword_zext"
7826 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,&r,&r")
7828 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0,r,o")
7830 (match_operand:DWIH 2 "nonimmediate_operand" "rm,r,rm,r"))))
7831 (clobber (reg:CC FLAGS_REG))]
7832 "ix86_binary_operator_ok (UNKNOWN, <DWI>mode, operands, TARGET_APX_NDD)"
7834 "&& reload_completed"
7835 [(parallel [(set (reg:CC FLAGS_REG)
7836 (compare:CC (match_dup 1) (match_dup 2)))
7838 (minus:DWIH (match_dup 1) (match_dup 2)))])
7839 (parallel [(set (match_dup 3)
7843 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7845 (clobber (reg:CC FLAGS_REG))])]
7846 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[3]);"
7847 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")])
7849 (define_insn "*sub<mode>_1"
7850 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r,r")
7852 (match_operand:SWI 1 "nonimmediate_operand" "0,0,rm,rjM,r")
7853 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,r,<i>,<m>")))
7854 (clobber (reg:CC FLAGS_REG))]
7855 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)"
7857 sub{<imodesuffix>}\t{%2, %0|%0, %2}
7858 sub{<imodesuffix>}\t{%2, %0|%0, %2}
7859 sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7860 sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7861 sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7862 [(set_attr "isa" "*,*,apx_ndd,apx_ndd,apx_ndd")
7863 (set_attr "type" "alu")
7864 (set_attr "mode" "<MODE>")])
7866 (define_insn "*subsi_1_zext"
7867 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7869 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,r,rm")
7870 (match_operand:SI 2 "x86_64_general_operand" "rBMe,rBMe,re"))))
7871 (clobber (reg:CC FLAGS_REG))]
7873 && ix86_binary_operator_ok (MINUS, SImode, operands, TARGET_APX_NDD)"
7875 sub{l}\t{%2, %k0|%k0, %2}
7876 sub{l}\t{%2, %1, %k0|%k0, %1, %2}
7877 sub{l}\t{%2, %1, %k0|%k0, %1, %2}"
7878 [(set_attr "isa" "*,apx_ndd,apx_ndd")
7879 (set_attr "type" "alu")
7880 (set_attr "mode" "SI")])
7882 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
7883 (define_insn_and_split "*sub<mode>_1_slp"
7884 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
7885 (minus:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
7886 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
7887 (clobber (reg:CC FLAGS_REG))]
7888 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7890 sub{<imodesuffix>}\t{%2, %0|%0, %2}
7892 "&& reload_completed
7893 && !(rtx_equal_p (operands[0], operands[1]))"
7894 [(set (strict_low_part (match_dup 0)) (match_dup 1))
7896 [(set (strict_low_part (match_dup 0))
7897 (minus:SWI12 (match_dup 0) (match_dup 2)))
7898 (clobber (reg:CC FLAGS_REG))])]
7900 [(set_attr "type" "alu")
7901 (set_attr "mode" "<MODE>")])
7903 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
7904 (define_insn_and_split "*subqi_ext<mode>_1_slp"
7905 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+Q,&Q"))
7907 (match_operand:QI 1 "nonimmediate_operand" "0,!qm")
7909 (match_operator:SWI248 3 "extract_operator"
7910 [(match_operand 2 "int248_register_operand" "Q,Q")
7912 (const_int 8)]) 0)))
7913 (clobber (reg:CC FLAGS_REG))]
7914 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7916 sub{b}\t{%h2, %0|%0, %h2}
7918 "&& reload_completed
7919 && !rtx_equal_p (operands[0], operands[1])"
7920 [(set (strict_low_part (match_dup 0)) (match_dup 1))
7922 [(set (strict_low_part (match_dup 0))
7927 [(match_dup 2) (const_int 8) (const_int 8)]) 0)))
7928 (clobber (reg:CC FLAGS_REG))])]
7930 [(set_attr "type" "alu")
7931 (set_attr "mode" "QI")])
7933 (define_insn_and_split "*subqi_ext<mode>_2_slp"
7934 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+&Q"))
7937 (match_operator:SWI248 3 "extract_operator"
7938 [(match_operand 1 "int248_register_operand" "Q")
7942 (match_operator:SWI248 4 "extract_operator"
7943 [(match_operand 2 "int248_register_operand" "Q")
7945 (const_int 8)]) 0)))
7946 (clobber (reg:CC FLAGS_REG))]
7947 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7949 "&& reload_completed"
7950 [(set (strict_low_part (match_dup 0))
7953 [(match_dup 1) (const_int 8) (const_int 8)]) 0))
7955 [(set (strict_low_part (match_dup 0))
7960 [(match_dup 2) (const_int 8) (const_int 8)]) 0)))
7961 (clobber (reg:CC FLAGS_REG))])]
7963 [(set_attr "type" "alu")
7964 (set_attr "mode" "QI")])
7966 (define_insn "*sub<mode>_2"
7967 [(set (reg FLAGS_REG)
7970 (match_operand:SWI 1 "nonimmediate_operand" "0,0,rm,r")
7971 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,r<i>,<m>"))
7973 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r")
7974 (minus:SWI (match_dup 1) (match_dup 2)))]
7975 "ix86_match_ccmode (insn, CCGOCmode)
7976 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)"
7978 sub{<imodesuffix>}\t{%2, %0|%0, %2}
7979 sub{<imodesuffix>}\t{%2, %0|%0, %2}
7980 sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7981 sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7982 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
7983 (set_attr "type" "alu")
7984 (set_attr "mode" "<MODE>")])
7986 (define_insn "*subsi_2_zext"
7987 [(set (reg FLAGS_REG)
7989 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,r,rm")
7990 (match_operand:SI 2 "x86_64_general_operand" "rBMe,rBMe,re"))
7992 (set (match_operand:DI 0 "register_operand" "=r,r,r")
7994 (minus:SI (match_dup 1)
7996 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7997 && ix86_binary_operator_ok (MINUS, SImode, operands, TARGET_APX_NDD)"
7999 sub{l}\t{%2, %k0|%k0, %2}
8000 sub{l}\t{%2, %1, %k0|%k0, %1, %2}
8001 sub{l}\t{%2, %1, %k0|%k0, %1, %2}"
8002 [(set_attr "isa" "*,apx_ndd,apx_ndd")
8003 (set_attr "type" "alu")
8004 (set_attr "mode" "SI")])
8006 (define_insn "*subqi_ext<mode>_0"
8007 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn")
8009 (match_operand:QI 1 "nonimmediate_operand" "0")
8011 (match_operator:SWI248 3 "extract_operator"
8012 [(match_operand 2 "int248_register_operand" "Q")
8014 (const_int 8)]) 0)))
8015 (clobber (reg:CC FLAGS_REG))]
8017 "sub{b}\t{%h2, %0|%0, %h2}"
8018 [(set_attr "addr" "gpr8")
8019 (set_attr "type" "alu")
8020 (set_attr "mode" "QI")])
8022 (define_insn_and_split "*subqi_ext2<mode>_0"
8023 [(set (match_operand:QI 0 "register_operand" "=&Q")
8026 (match_operator:SWI248 3 "extract_operator"
8027 [(match_operand 1 "int248_register_operand" "Q")
8031 (match_operator:SWI248 4 "extract_operator"
8032 [(match_operand 2 "int248_register_operand" "Q")
8034 (const_int 8)]) 0)))
8035 (clobber (reg:CC FLAGS_REG))]
8038 "&& reload_completed"
8042 [(match_dup 1) (const_int 8) (const_int 8)]) 0))
8049 [(match_dup 2) (const_int 8) (const_int 8)]) 0)))
8050 (clobber (reg:CC FLAGS_REG))])]
8052 [(set_attr "type" "alu")
8053 (set_attr "mode" "QI")])
8055 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
8056 (define_insn_and_split "*subqi_ext<mode>_1"
8057 [(set (zero_extract:SWI248
8058 (match_operand 0 "int248_register_operand" "+Q,&Q")
8064 (match_operator:SWI248 3 "extract_operator"
8065 [(match_operand 1 "int248_register_operand" "0,!Q")
8068 (match_operand:QI 2 "general_operand" "QnBn,QnBn")) 0))
8069 (clobber (reg:CC FLAGS_REG))]
8072 sub{b}\t{%2, %h0|%h0, %2}
8075 && !(rtx_equal_p (operands[0], operands[1]))"
8076 [(set (zero_extract:SWI248
8077 (match_dup 0) (const_int 8) (const_int 8))
8078 (zero_extract:SWI248
8079 (match_dup 1) (const_int 8) (const_int 8)))
8081 [(set (zero_extract:SWI248
8082 (match_dup 0) (const_int 8) (const_int 8))
8087 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
8089 (clobber (reg:CC FLAGS_REG))])]
8091 [(set_attr "addr" "gpr8")
8092 (set_attr "type" "alu")
8093 (set_attr "mode" "QI")])
8095 ;; Subtract with jump on overflow.
8096 (define_expand "subv<mode>4"
8097 [(parallel [(set (reg:CCO FLAGS_REG)
8101 (match_operand:SWIDWI 1 "nonimmediate_operand"))
8104 (minus:SWIDWI (match_dup 1)
8105 (match_operand:SWIDWI 2
8106 "<general_hilo_operand>")))))
8107 (set (match_operand:SWIDWI 0 "register_operand")
8108 (minus:SWIDWI (match_dup 1) (match_dup 2)))])
8109 (set (pc) (if_then_else
8110 (eq (reg:CCO FLAGS_REG) (const_int 0))
8111 (label_ref (match_operand 3))
8115 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands,
8117 if (CONST_SCALAR_INT_P (operands[2]))
8118 operands[4] = operands[2];
8120 operands[4] = gen_rtx_SIGN_EXTEND (<DPWI>mode, operands[2]);
8123 (define_insn "*subv<mode>4"
8124 [(set (reg:CCO FLAGS_REG)
8125 (eq:CCO (minus:<DWI>
8127 (match_operand:SWI 1 "nonimmediate_operand" "0,0,rm,r"))
8129 (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m,rWe,m")))
8131 (minus:SWI (match_dup 1) (match_dup 2)))))
8132 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r")
8133 (minus:SWI (match_dup 1) (match_dup 2)))]
8134 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)"
8136 sub{<imodesuffix>}\t{%2, %0|%0, %2}
8137 sub{<imodesuffix>}\t{%2, %0|%0, %2}
8138 sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
8139 sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
8140 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
8141 (set_attr "type" "alu")
8142 (set_attr "mode" "<MODE>")])
8144 (define_insn "subv<mode>4_1"
8145 [(set (reg:CCO FLAGS_REG)
8146 (eq:CCO (minus:<DWI>
8148 (match_operand:SWI 1 "nonimmediate_operand" "0,rm"))
8149 (match_operand:<DWI> 3 "const_int_operand"))
8153 (match_operand:SWI 2 "x86_64_immediate_operand" "<i>,<i>")))))
8154 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,r")
8155 (minus:SWI (match_dup 1) (match_dup 2)))]
8156 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)
8157 && CONST_INT_P (operands[2])
8158 && INTVAL (operands[2]) == INTVAL (operands[3])"
8160 sub{<imodesuffix>}\t{%2, %0|%0, %2}
8161 sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
8162 [(set_attr "isa" "*,apx_ndd")
8163 (set_attr "type" "alu")
8164 (set_attr "mode" "<MODE>")
8165 (set (attr "length_immediate")
8166 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
8168 (match_test "<MODE_SIZE> == 8")
8170 (const_string "<MODE_SIZE>")))])
8172 (define_insn_and_split "*subv<dwi>4_doubleword"
8173 [(set (reg:CCO FLAGS_REG)
8177 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0,ro,r"))
8179 (match_operand:<DWI> 2 "nonimmediate_operand" "r,o,r,o")))
8181 (minus:<DWI> (match_dup 1) (match_dup 2)))))
8182 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,&r,&r")
8183 (minus:<DWI> (match_dup 1) (match_dup 2)))]
8184 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)"
8186 "&& reload_completed"
8187 [(parallel [(set (reg:CC FLAGS_REG)
8188 (compare:CC (match_dup 1) (match_dup 2)))
8190 (minus:DWIH (match_dup 1) (match_dup 2)))])
8191 (parallel [(set (reg:CCO FLAGS_REG)
8195 (sign_extend:<DWI> (match_dup 4))
8196 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))
8197 (sign_extend:<DWI> (match_dup 5)))
8202 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
8208 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
8211 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
8213 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")])
8215 (define_insn_and_split "*subv<dwi>4_doubleword_1"
8216 [(set (reg:CCO FLAGS_REG)
8220 (match_operand:<DWI> 1 "nonimmediate_operand" "0,ro"))
8221 (match_operand:<QPWI> 3 "const_scalar_int_operand"))
8225 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>,<di>")))))
8226 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,&r")
8227 (minus:<DWI> (match_dup 1) (match_dup 2)))]
8228 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)
8229 && CONST_SCALAR_INT_P (operands[2])
8230 && rtx_equal_p (operands[2], operands[3])"
8232 "&& reload_completed"
8233 [(parallel [(set (reg:CC FLAGS_REG)
8234 (compare:CC (match_dup 1) (match_dup 2)))
8236 (minus:DWIH (match_dup 1) (match_dup 2)))])
8237 (parallel [(set (reg:CCO FLAGS_REG)
8241 (sign_extend:<DWI> (match_dup 4))
8242 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))
8248 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
8254 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
8257 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
8258 if (operands[2] == const0_rtx)
8260 if (!rtx_equal_p (operands[0], operands[1]))
8261 emit_move_insn (operands[0], operands[1]);
8262 emit_insn (gen_subv<mode>4_1 (operands[3], operands[4], operands[5],
8267 [(set_attr "isa" "*,apx_ndd")])
8269 (define_insn "*subv<mode>4_overflow_1"
8270 [(set (reg:CCO FLAGS_REG)
8275 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,rm,r"))
8276 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8277 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
8279 (match_operand:SWI 2 "<general_sext_operand>" "rWe,m,rWe,m")))
8284 (match_operator:SWI 5 "ix86_carry_flag_operator"
8285 [(match_dup 3) (const_int 0)]))
8287 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r,r,r")
8291 (match_op_dup 5 [(match_dup 3) (const_int 0)]))
8293 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)"
8295 sbb{<imodesuffix>}\t{%2, %0|%0, %2}
8296 sbb{<imodesuffix>}\t{%2, %0|%0, %2}
8297 sbb{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
8298 sbb{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
8299 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
8300 (set_attr "type" "alu")
8301 (set_attr "mode" "<MODE>")])
8303 (define_insn "*subv<mode>4_overflow_2"
8304 [(set (reg:CCO FLAGS_REG)
8309 (match_operand:SWI 1 "nonimmediate_operand" "%0,rm"))
8310 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8311 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
8312 (match_operand:<DWI> 6 "const_int_operand" "n,n"))
8317 (match_operator:SWI 5 "ix86_carry_flag_operator"
8318 [(match_dup 3) (const_int 0)]))
8319 (match_operand:SWI 2 "x86_64_immediate_operand" "e,e")))))
8320 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r")
8324 (match_op_dup 5 [(match_dup 3) (const_int 0)]))
8326 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)
8327 && CONST_INT_P (operands[2])
8328 && INTVAL (operands[2]) == INTVAL (operands[6])"
8330 sbb{<imodesuffix>}\t{%2, %0|%0, %2}
8331 sbb{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
8332 [(set_attr "isa" "*,apx_ndd")
8333 (set_attr "type" "alu")
8334 (set_attr "mode" "<MODE>")
8335 (set (attr "length_immediate")
8336 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
8338 (const_string "4")))])
8340 (define_expand "usubv<mode>4"
8341 [(parallel [(set (reg:CC FLAGS_REG)
8343 (match_operand:SWI 1 "nonimmediate_operand")
8344 (match_operand:SWI 2 "<general_operand>")))
8345 (set (match_operand:SWI 0 "register_operand")
8346 (minus:SWI (match_dup 1) (match_dup 2)))])
8347 (set (pc) (if_then_else
8348 (ltu (reg:CC FLAGS_REG) (const_int 0))
8349 (label_ref (match_operand 3))
8352 "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands,
8355 (define_insn "*sub<mode>_3"
8356 [(set (reg FLAGS_REG)
8357 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0,rm,r")
8358 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,r<i>,<m>")))
8359 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>i,r,r")
8360 (minus:SWI (match_dup 1) (match_dup 2)))]
8361 "ix86_match_ccmode (insn, CCmode)
8362 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)"
8364 sub{<imodesuffix>}\t{%2, %0|%0, %2}
8365 sub{<imodesuffix>}\t{%2, %0|%0, %2}
8366 sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
8367 sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
8368 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
8369 (set_attr "type" "alu")
8370 (set_attr "mode" "<MODE>")])
8374 [(set (reg:CC FLAGS_REG)
8375 (compare:CC (match_operand:SWI 0 "general_reg_operand")
8376 (match_operand:SWI 1 "general_gr_operand")))
8378 (minus:SWI (match_dup 0) (match_dup 1)))])]
8379 "find_regno_note (peep2_next_insn (0), REG_UNUSED, REGNO (operands[0])) != 0"
8380 [(set (reg:CC FLAGS_REG)
8381 (compare:CC (match_dup 0) (match_dup 1)))])
8384 [(set (match_operand:SWI 0 "general_reg_operand")
8385 (match_operand:SWI 1 "memory_operand"))
8386 (parallel [(set (reg:CC FLAGS_REG)
8387 (compare:CC (match_dup 0)
8388 (match_operand:SWI 2 "memory_operand")))
8390 (minus:SWI (match_dup 0) (match_dup 2)))])
8391 (set (match_dup 1) (match_dup 0))]
8392 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8393 && peep2_reg_dead_p (3, operands[0])
8394 && !reg_overlap_mentioned_p (operands[0], operands[1])
8395 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8396 [(set (match_dup 0) (match_dup 2))
8397 (parallel [(set (reg:CC FLAGS_REG)
8398 (compare:CC (match_dup 1) (match_dup 0)))
8400 (minus:SWI (match_dup 1) (match_dup 0)))])])
8402 ;; decl %eax; cmpl $-1, %eax; jne .Lxx; can be optimized into
8403 ;; subl $1, %eax; jnc .Lxx;
8406 [(set (match_operand:SWI 0 "general_reg_operand")
8407 (plus:SWI (match_dup 0) (const_int -1)))
8408 (clobber (reg FLAGS_REG))])
8409 (set (reg:CCZ FLAGS_REG)
8410 (compare:CCZ (match_dup 0) (const_int -1)))
8412 (if_then_else (match_operator 1 "bt_comparison_operator"
8413 [(reg:CCZ FLAGS_REG) (const_int 0)])
8416 "peep2_regno_dead_p (3, FLAGS_REG)"
8418 [(set (reg:CC FLAGS_REG)
8419 (compare:CC (match_dup 0) (const_int 1)))
8421 (minus:SWI (match_dup 0) (const_int 1)))])
8423 (if_then_else (match_dup 3)
8427 rtx cc = gen_rtx_REG (CCmode, FLAGS_REG);
8428 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE
8429 ? GEU : LTU, VOIDmode, cc, const0_rtx);
8432 ;; Help combine use borrow flag to test for -1 after dec (add $-1).
8433 (define_insn_and_split "*dec_cmov<mode>"
8434 [(set (match_operand:SWI248 0 "register_operand" "=r")
8435 (if_then_else:SWI248
8436 (match_operator 1 "bt_comparison_operator"
8437 [(match_operand:SWI248 2 "register_operand" "0") (const_int 0)])
8438 (plus:SWI248 (match_dup 2) (const_int -1))
8439 (match_operand:SWI248 3 "nonimmediate_operand" "rm")))
8440 (clobber (reg:CC FLAGS_REG))]
8443 "&& reload_completed"
8444 [(parallel [(set (reg:CC FLAGS_REG)
8445 (compare:CC (match_dup 2) (const_int 1)))
8446 (set (match_dup 0) (minus:SWI248 (match_dup 2) (const_int 1)))])
8448 (if_then_else:SWI248 (match_dup 4) (match_dup 0) (match_dup 3)))]
8450 rtx cc = gen_rtx_REG (CCCmode, FLAGS_REG);
8451 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE
8452 ? GEU : LTU, VOIDmode, cc, const0_rtx);
8455 (define_insn "*subsi_3_zext"
8456 [(set (reg FLAGS_REG)
8457 (compare (match_operand:SI 1 "nonimmediate_operand" "0,r,rm")
8458 (match_operand:SI 2 "x86_64_general_operand" "rBMe,rBMe,re")))
8459 (set (match_operand:DI 0 "register_operand" "=r,r,r")
8461 (minus:SI (match_dup 1)
8463 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
8464 && ix86_binary_operator_ok (MINUS, SImode, operands, TARGET_APX_NDD)"
8466 sub{l}\t{%2, %1|%1, %2}
8467 sub{l}\t{%2, %1, %k0|%k0, %1, %2}
8468 sub{l}\t{%2, %1, %k0|%k0, %1, %2}"
8469 [(set_attr "isa" "*,apx_ndd,apx_ndd")
8470 (set_attr "type" "alu")
8471 (set_attr "mode" "SI")])
8473 ;; Add with carry and subtract with borrow
8475 (define_insn "@add<mode>3_carry"
8476 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r")
8479 (match_operator:SWI 4 "ix86_carry_flag_operator"
8480 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8481 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,rm,r"))
8482 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,r<i>,<m>")))
8483 (clobber (reg:CC FLAGS_REG))]
8484 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)"
8486 adc{<imodesuffix>}\t{%2, %0|%0, %2}
8487 adc{<imodesuffix>}\t{%2, %0|%0, %2}
8488 adc{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
8489 adc{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
8490 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
8491 (set_attr "type" "alu")
8492 (set_attr "use_carry" "1")
8493 (set_attr "pent_pair" "pu")
8494 (set_attr "mode" "<MODE>")])
8497 [(set (match_operand:SWI 0 "general_reg_operand")
8498 (match_operand:SWI 1 "memory_operand"))
8499 (parallel [(set (match_dup 0)
8502 (match_operator:SWI 4 "ix86_carry_flag_operator"
8503 [(match_operand 3 "flags_reg_operand")
8506 (match_operand:SWI 2 "memory_operand")))
8507 (clobber (reg:CC FLAGS_REG))])
8508 (set (match_dup 1) (match_dup 0))]
8509 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8510 && peep2_reg_dead_p (3, operands[0])
8511 && !reg_overlap_mentioned_p (operands[0], operands[1])
8512 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8513 [(set (match_dup 0) (match_dup 2))
8514 (parallel [(set (match_dup 1)
8515 (plus:SWI (plus:SWI (match_op_dup 4
8516 [(match_dup 3) (const_int 0)])
8519 (clobber (reg:CC FLAGS_REG))])])
8522 [(set (match_operand:SWI 0 "general_reg_operand")
8523 (match_operand:SWI 1 "memory_operand"))
8524 (parallel [(set (match_dup 0)
8527 (match_operator:SWI 4 "ix86_carry_flag_operator"
8528 [(match_operand 3 "flags_reg_operand")
8531 (match_operand:SWI 2 "memory_operand")))
8532 (clobber (reg:CC FLAGS_REG))])
8533 (set (match_operand:SWI 5 "general_reg_operand") (match_dup 0))
8534 (set (match_dup 1) (match_dup 5))]
8535 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8536 && peep2_reg_dead_p (3, operands[0])
8537 && peep2_reg_dead_p (4, operands[5])
8538 && !reg_overlap_mentioned_p (operands[0], operands[1])
8539 && !reg_overlap_mentioned_p (operands[0], operands[2])
8540 && !reg_overlap_mentioned_p (operands[5], operands[1])"
8541 [(set (match_dup 0) (match_dup 2))
8542 (parallel [(set (match_dup 1)
8543 (plus:SWI (plus:SWI (match_op_dup 4
8544 [(match_dup 3) (const_int 0)])
8547 (clobber (reg:CC FLAGS_REG))])])
8549 (define_insn "*add<mode>3_carry_0"
8550 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8552 (match_operator:SWI 2 "ix86_carry_flag_operator"
8553 [(reg FLAGS_REG) (const_int 0)])
8554 (match_operand:SWI 1 "nonimmediate_operand" "0")))
8555 (clobber (reg:CC FLAGS_REG))]
8556 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8557 "adc{<imodesuffix>}\t{$0, %0|%0, 0}"
8558 [(set_attr "type" "alu")
8559 (set_attr "use_carry" "1")
8560 (set_attr "pent_pair" "pu")
8561 (set_attr "mode" "<MODE>")])
8563 (define_insn "*add<mode>3_carry_0r"
8564 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8566 (match_operator:SWI 2 "ix86_carry_flag_unset_operator"
8567 [(reg FLAGS_REG) (const_int 0)])
8568 (match_operand:SWI 1 "nonimmediate_operand" "0")))
8569 (clobber (reg:CC FLAGS_REG))]
8570 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8571 "sbb{<imodesuffix>}\t{$-1, %0|%0, -1}"
8572 [(set_attr "type" "alu")
8573 (set_attr "use_carry" "1")
8574 (set_attr "pent_pair" "pu")
8575 (set_attr "mode" "<MODE>")])
8577 (define_insn "*addsi3_carry_zext"
8578 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
8581 (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
8582 [(reg FLAGS_REG) (const_int 0)])
8583 (match_operand:SI 1 "nonimmediate_operand" "%0,r,rm"))
8584 (match_operand:SI 2 "x86_64_general_operand" "rBMe,rBMe,re"))))
8585 (clobber (reg:CC FLAGS_REG))]
8587 && ix86_binary_operator_ok (PLUS, SImode, operands, TARGET_APX_NDD)"
8589 adc{l}\t{%2, %k0|%k0, %2}
8590 adc{l}\t{%2, %1, %k0|%k0, %1, %2}
8591 adc{l}\t{%2, %1, %k0|%k0, %1, %2}"
8592 [(set_attr "isa" "*,apx_ndd,apx_ndd")
8593 (set_attr "type" "alu")
8594 (set_attr "use_carry" "1")
8595 (set_attr "pent_pair" "pu")
8596 (set_attr "mode" "SI")])
8598 (define_insn "*addsi3_carry_zext_0"
8599 [(set (match_operand:DI 0 "register_operand" "=r,r")
8601 (plus:SI (match_operator:SI 2 "ix86_carry_flag_operator"
8602 [(reg FLAGS_REG) (const_int 0)])
8603 (match_operand:SI 1 "nonimmediate_operand" "0,rm"))))
8604 (clobber (reg:CC FLAGS_REG))]
8607 adc{l}\t{$0, %k0|%k0, 0}
8608 adc{l}\t{$0, %1, %k0|%k0, %1, 0}"
8609 [(set_attr "isa" "*,apx_ndd")
8610 (set_attr "type" "alu")
8611 (set_attr "use_carry" "1")
8612 (set_attr "pent_pair" "pu")
8613 (set_attr "mode" "SI")])
8615 (define_insn "*addsi3_carry_zext_0r"
8616 [(set (match_operand:DI 0 "register_operand" "=r,r")
8618 (plus:SI (match_operator:SI 2 "ix86_carry_flag_unset_operator"
8619 [(reg FLAGS_REG) (const_int 0)])
8620 (match_operand:SI 1 "nonimmediate_operand" "0,rm"))))
8621 (clobber (reg:CC FLAGS_REG))]
8624 sbb{l}\t{$-1, %k0|%k0, -1}
8625 sbb{l}\t{$-1, %1, %k0|%k0, %1, -1}"
8626 [(set_attr "isa" "*,apx_ndd")
8627 (set_attr "type" "alu")
8628 (set_attr "use_carry" "1")
8629 (set_attr "pent_pair" "pu")
8630 (set_attr "mode" "SI")])
8632 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
8634 (define_insn "addcarry<mode>"
8635 [(set (reg:CCC FLAGS_REG)
8640 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8641 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8642 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,rm,r"))
8643 (match_operand:SWI48 2 "nonimmediate_operand" "r,rm,r,m")))
8645 (zero_extend:<DWI> (match_dup 2))
8646 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8647 [(match_dup 3) (const_int 0)]))))
8648 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,r")
8649 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8650 [(match_dup 3) (const_int 0)])
8653 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)"
8655 adc{<imodesuffix>}\t{%2, %0|%0, %2}
8656 adc{<imodesuffix>}\t{%2, %0|%0, %2}
8657 adc{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
8658 adc{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
8659 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
8660 (set_attr "type" "alu")
8661 (set_attr "use_carry" "1")
8662 (set_attr "pent_pair" "pu")
8663 (set_attr "mode" "<MODE>")])
8666 [(parallel [(set (reg:CCC FLAGS_REG)
8671 (match_operator:SWI48 4 "ix86_carry_flag_operator"
8672 [(match_operand 2 "flags_reg_operand")
8674 (match_operand:SWI48 0 "general_reg_operand"))
8675 (match_operand:SWI48 1 "memory_operand")))
8677 (zero_extend:<DWI> (match_dup 1))
8678 (match_operator:<DWI> 3 "ix86_carry_flag_operator"
8679 [(match_dup 2) (const_int 0)]))))
8681 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8682 [(match_dup 2) (const_int 0)])
8685 (set (match_dup 1) (match_dup 0))]
8686 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8687 && peep2_reg_dead_p (2, operands[0])
8688 && !reg_overlap_mentioned_p (operands[0], operands[1])"
8689 [(parallel [(set (reg:CCC FLAGS_REG)
8695 [(match_dup 2) (const_int 0)])
8699 (zero_extend:<DWI> (match_dup 0))
8701 [(match_dup 2) (const_int 0)]))))
8703 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8704 [(match_dup 2) (const_int 0)])
8709 [(set (match_operand:SWI48 0 "general_reg_operand")
8710 (match_operand:SWI48 1 "memory_operand"))
8711 (parallel [(set (reg:CCC FLAGS_REG)
8716 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8717 [(match_operand 3 "flags_reg_operand")
8720 (match_operand:SWI48 2 "memory_operand")))
8722 (zero_extend:<DWI> (match_dup 2))
8723 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8724 [(match_dup 3) (const_int 0)]))))
8726 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8727 [(match_dup 3) (const_int 0)])
8730 (set (match_dup 1) (match_dup 0))]
8731 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8732 && peep2_reg_dead_p (3, operands[0])
8733 && !reg_overlap_mentioned_p (operands[0], operands[1])
8734 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8735 [(set (match_dup 0) (match_dup 2))
8736 (parallel [(set (reg:CCC FLAGS_REG)
8742 [(match_dup 3) (const_int 0)])
8746 (zero_extend:<DWI> (match_dup 0))
8748 [(match_dup 3) (const_int 0)]))))
8750 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8751 [(match_dup 3) (const_int 0)])
8756 [(parallel [(set (reg:CCC FLAGS_REG)
8761 (match_operator:SWI48 4 "ix86_carry_flag_operator"
8762 [(match_operand 2 "flags_reg_operand")
8764 (match_operand:SWI48 0 "general_reg_operand"))
8765 (match_operand:SWI48 1 "memory_operand")))
8767 (zero_extend:<DWI> (match_dup 1))
8768 (match_operator:<DWI> 3 "ix86_carry_flag_operator"
8769 [(match_dup 2) (const_int 0)]))))
8771 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8772 [(match_dup 2) (const_int 0)])
8775 (set (match_operand:QI 5 "general_reg_operand")
8776 (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8777 (set (match_operand:SWI48 6 "general_reg_operand")
8778 (zero_extend:SWI48 (match_dup 5)))
8779 (set (match_dup 1) (match_dup 0))]
8780 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8781 && peep2_reg_dead_p (4, operands[0])
8782 && !reg_overlap_mentioned_p (operands[0], operands[1])
8783 && !reg_overlap_mentioned_p (operands[0], operands[5])
8784 && !reg_overlap_mentioned_p (operands[5], operands[1])
8785 && !reg_overlap_mentioned_p (operands[0], operands[6])
8786 && !reg_overlap_mentioned_p (operands[6], operands[1])"
8787 [(parallel [(set (reg:CCC FLAGS_REG)
8793 [(match_dup 2) (const_int 0)])
8797 (zero_extend:<DWI> (match_dup 0))
8799 [(match_dup 2) (const_int 0)]))))
8801 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8802 [(match_dup 2) (const_int 0)])
8805 (set (match_dup 5) (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8806 (set (match_dup 6) (zero_extend:SWI48 (match_dup 5)))])
8808 (define_expand "addcarry<mode>_0"
8810 [(set (reg:CCC FLAGS_REG)
8813 (match_operand:SWI48 1 "nonimmediate_operand")
8814 (match_operand:SWI48 2 "x86_64_general_operand"))
8816 (set (match_operand:SWI48 0 "nonimmediate_operand")
8817 (plus:SWI48 (match_dup 1) (match_dup 2)))])]
8818 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)")
8820 (define_insn "*addcarry<mode>_1"
8821 [(set (reg:CCC FLAGS_REG)
8826 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8827 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8828 (match_operand:SWI48 1 "nonimmediate_operand" "%0,rm"))
8829 (match_operand:SWI48 2 "x86_64_immediate_operand" "e,e")))
8831 (match_operand:<DWI> 6 "const_scalar_int_operand")
8832 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8833 [(match_dup 3) (const_int 0)]))))
8834 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
8835 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8836 [(match_dup 3) (const_int 0)])
8839 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)
8840 && CONST_INT_P (operands[2])
8841 /* Check that operands[6] is operands[2] zero extended from
8842 <MODE>mode to <DWI>mode. */
8843 && ((<MODE>mode == SImode || INTVAL (operands[2]) >= 0)
8844 ? (CONST_INT_P (operands[6])
8845 && UINTVAL (operands[6]) == (UINTVAL (operands[2])
8846 & GET_MODE_MASK (<MODE>mode)))
8847 : (CONST_WIDE_INT_P (operands[6])
8848 && CONST_WIDE_INT_NUNITS (operands[6]) == 2
8849 && ((unsigned HOST_WIDE_INT) CONST_WIDE_INT_ELT (operands[6], 0)
8850 == UINTVAL (operands[2]))
8851 && CONST_WIDE_INT_ELT (operands[6], 1) == 0))"
8853 adc{<imodesuffix>}\t{%2, %0|%0, %2}
8854 adc{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
8855 [(set_attr "isa" "*,apx_ndd")
8856 (set_attr "type" "alu")
8857 (set_attr "use_carry" "1")
8858 (set_attr "pent_pair" "pu")
8859 (set_attr "mode" "<MODE>")
8860 (set (attr "length_immediate")
8861 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
8863 (const_string "4")))])
8865 (define_insn "@sub<mode>3_carry"
8866 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r")
8869 (match_operand:SWI 1 "nonimmediate_operand" "0,0,rm,r")
8870 (match_operator:SWI 4 "ix86_carry_flag_operator"
8871 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
8872 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,r<i>,<m>")))
8873 (clobber (reg:CC FLAGS_REG))]
8874 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)"
8876 sbb{<imodesuffix>}\t{%2, %0|%0, %2}
8877 sbb{<imodesuffix>}\t{%2, %0|%0, %2}
8878 sbb{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
8879 sbb{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
8880 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
8881 (set_attr "type" "alu")
8882 (set_attr "use_carry" "1")
8883 (set_attr "pent_pair" "pu")
8884 (set_attr "mode" "<MODE>")])
8887 [(set (match_operand:SWI 0 "general_reg_operand")
8888 (match_operand:SWI 1 "memory_operand"))
8889 (parallel [(set (match_dup 0)
8893 (match_operator:SWI 4 "ix86_carry_flag_operator"
8894 [(match_operand 3 "flags_reg_operand")
8896 (match_operand:SWI 2 "memory_operand")))
8897 (clobber (reg:CC FLAGS_REG))])
8898 (set (match_dup 1) (match_dup 0))]
8899 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8900 && peep2_reg_dead_p (3, operands[0])
8901 && !reg_overlap_mentioned_p (operands[0], operands[1])
8902 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8903 [(set (match_dup 0) (match_dup 2))
8904 (parallel [(set (match_dup 1)
8905 (minus:SWI (minus:SWI (match_dup 1)
8907 [(match_dup 3) (const_int 0)]))
8909 (clobber (reg:CC FLAGS_REG))])])
8912 [(set (match_operand:SWI 0 "general_reg_operand")
8913 (match_operand:SWI 1 "memory_operand"))
8914 (parallel [(set (match_dup 0)
8918 (match_operator:SWI 4 "ix86_carry_flag_operator"
8919 [(match_operand 3 "flags_reg_operand")
8921 (match_operand:SWI 2 "memory_operand")))
8922 (clobber (reg:CC FLAGS_REG))])
8923 (set (match_operand:SWI 5 "general_reg_operand") (match_dup 0))
8924 (set (match_dup 1) (match_dup 5))]
8925 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8926 && peep2_reg_dead_p (3, operands[0])
8927 && peep2_reg_dead_p (4, operands[5])
8928 && !reg_overlap_mentioned_p (operands[0], operands[1])
8929 && !reg_overlap_mentioned_p (operands[0], operands[2])
8930 && !reg_overlap_mentioned_p (operands[5], operands[1])"
8931 [(set (match_dup 0) (match_dup 2))
8932 (parallel [(set (match_dup 1)
8933 (minus:SWI (minus:SWI (match_dup 1)
8935 [(match_dup 3) (const_int 0)]))
8937 (clobber (reg:CC FLAGS_REG))])])
8939 (define_insn "*sub<mode>3_carry_0"
8940 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8942 (match_operand:SWI 1 "nonimmediate_operand" "0")
8943 (match_operator:SWI 2 "ix86_carry_flag_operator"
8944 [(reg FLAGS_REG) (const_int 0)])))
8945 (clobber (reg:CC FLAGS_REG))]
8946 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8947 "sbb{<imodesuffix>}\t{$0, %0|%0, 0}"
8948 [(set_attr "type" "alu")
8949 (set_attr "use_carry" "1")
8950 (set_attr "pent_pair" "pu")
8951 (set_attr "mode" "<MODE>")])
8953 (define_insn "*sub<mode>3_carry_0r"
8954 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8956 (match_operand:SWI 1 "nonimmediate_operand" "0")
8957 (match_operator:SWI 2 "ix86_carry_flag_unset_operator"
8958 [(reg FLAGS_REG) (const_int 0)])))
8959 (clobber (reg:CC FLAGS_REG))]
8960 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8961 "adc{<imodesuffix>}\t{$-1, %0|%0, -1}"
8962 [(set_attr "type" "alu")
8963 (set_attr "use_carry" "1")
8964 (set_attr "pent_pair" "pu")
8965 (set_attr "mode" "<MODE>")])
8967 (define_insn "*subsi3_carry_zext"
8968 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
8972 (match_operand:SI 1 "nonimmediate_operand" "0,r,rm")
8973 (match_operator:SI 3 "ix86_carry_flag_operator"
8974 [(reg FLAGS_REG) (const_int 0)]))
8975 (match_operand:SI 2 "x86_64_general_operand" "rBMe,rBMe,re"))))
8976 (clobber (reg:CC FLAGS_REG))]
8978 && ix86_binary_operator_ok (MINUS, SImode, operands, TARGET_APX_NDD)"
8980 sbb{l}\t{%2, %k0|%k0, %2}
8981 sbb{l}\t{%2, %1, %k0|%k0, %1, %2}
8982 sbb{l}\t{%2, %1, %k0|%k0, %1, %2}"
8983 [(set_attr "isa" "*,apx_ndd,apx_ndd")
8984 (set_attr "type" "alu")
8985 (set_attr "use_carry" "1")
8986 (set_attr "pent_pair" "pu")
8987 (set_attr "mode" "SI")])
8989 (define_insn "*subsi3_carry_zext_0"
8990 [(set (match_operand:DI 0 "register_operand" "=r")
8993 (match_operand:SI 1 "register_operand" "0")
8994 (match_operator:SI 2 "ix86_carry_flag_operator"
8995 [(reg FLAGS_REG) (const_int 0)]))))
8996 (clobber (reg:CC FLAGS_REG))]
8998 "sbb{l}\t{$0, %k0|%k0, 0}"
8999 [(set_attr "type" "alu")
9000 (set_attr "use_carry" "1")
9001 (set_attr "pent_pair" "pu")
9002 (set_attr "mode" "SI")])
9004 (define_insn "*subsi3_carry_zext_0r"
9005 [(set (match_operand:DI 0 "register_operand" "=r")
9008 (match_operand:SI 1 "register_operand" "0")
9009 (match_operator:SI 2 "ix86_carry_flag_unset_operator"
9010 [(reg FLAGS_REG) (const_int 0)]))))
9011 (clobber (reg:CC FLAGS_REG))]
9013 "adc{l}\t{$-1, %k0|%k0, -1}"
9014 [(set_attr "type" "alu")
9015 (set_attr "use_carry" "1")
9016 (set_attr "pent_pair" "pu")
9017 (set_attr "mode" "SI")])
9019 (define_insn "@sub<mode>3_carry_ccc"
9020 [(set (reg:CCC FLAGS_REG)
9022 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
9024 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
9026 (match_operand:DWIH 2 "x86_64_sext_operand" "rmWe")))))
9027 (clobber (match_scratch:DWIH 0 "=r"))]
9029 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
9030 [(set_attr "type" "alu")
9031 (set_attr "mode" "<MODE>")])
9033 (define_insn "*sub<mode>3_carry_ccc_1"
9034 [(set (reg:CCC FLAGS_REG)
9036 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
9038 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
9039 (match_operand:<DWI> 2 "x86_64_dwzext_immediate_operand" "Wf"))))
9040 (clobber (match_scratch:DWIH 0 "=r"))]
9043 operands[3] = simplify_subreg (<MODE>mode, operands[2], <DWI>mode, 0);
9044 return "sbb{<imodesuffix>}\t{%3, %0|%0, %3}";
9046 [(set_attr "type" "alu")
9047 (set_attr "mode" "<MODE>")])
9049 ;; The sign flag is set from the
9050 ;; (compare (match_dup 1) (plus:DWIH (ltu:DWIH ...) (match_dup 2)))
9051 ;; result, the overflow flag likewise, but the overflow flag is also
9052 ;; set if the (plus:DWIH (ltu:DWIH ...) (match_dup 2)) overflows.
9053 (define_insn "@sub<mode>3_carry_ccgz"
9054 [(set (reg:CCGZ FLAGS_REG)
9055 (unspec:CCGZ [(match_operand:DWIH 1 "register_operand" "0")
9056 (match_operand:DWIH 2 "x86_64_general_operand" "rBMe")
9057 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))]
9059 (clobber (match_scratch:DWIH 0 "=r"))]
9061 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
9062 [(set_attr "type" "alu")
9063 (set_attr "mode" "<MODE>")])
9065 (define_insn "subborrow<mode>"
9066 [(set (reg:CCC FLAGS_REG)
9069 (match_operand:SWI48 1 "nonimmediate_operand" "0,0,r,rm"))
9071 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
9072 [(match_operand 3 "flags_reg_operand") (const_int 0)])
9074 (match_operand:SWI48 2 "nonimmediate_operand" "r,rm,rm,r")))))
9075 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,r")
9076 (minus:SWI48 (minus:SWI48
9078 (match_operator:SWI48 5 "ix86_carry_flag_operator"
9079 [(match_dup 3) (const_int 0)]))
9081 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)"
9083 sbb{<imodesuffix>}\t{%2, %0|%0, %2}
9084 sbb{<imodesuffix>}\t{%2, %0|%0, %2}
9085 sbb{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9086 sbb{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
9087 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
9088 (set_attr "type" "alu")
9089 (set_attr "use_carry" "1")
9090 (set_attr "pent_pair" "pu")
9091 (set_attr "mode" "<MODE>")])
9094 [(set (match_operand:SWI48 0 "general_reg_operand")
9095 (match_operand:SWI48 1 "memory_operand"))
9096 (parallel [(set (reg:CCC FLAGS_REG)
9098 (zero_extend:<DWI> (match_dup 0))
9100 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
9101 [(match_operand 3 "flags_reg_operand") (const_int 0)])
9103 (match_operand:SWI48 2 "memory_operand")))))
9108 (match_operator:SWI48 5 "ix86_carry_flag_operator"
9109 [(match_dup 3) (const_int 0)]))
9111 (set (match_dup 1) (match_dup 0))]
9112 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
9113 && peep2_reg_dead_p (3, operands[0])
9114 && !reg_overlap_mentioned_p (operands[0], operands[1])
9115 && !reg_overlap_mentioned_p (operands[0], operands[2])"
9116 [(set (match_dup 0) (match_dup 2))
9117 (parallel [(set (reg:CCC FLAGS_REG)
9119 (zero_extend:<DWI> (match_dup 1))
9120 (plus:<DWI> (match_op_dup 4
9121 [(match_dup 3) (const_int 0)])
9122 (zero_extend:<DWI> (match_dup 0)))))
9124 (minus:SWI48 (minus:SWI48 (match_dup 1)
9126 [(match_dup 3) (const_int 0)]))
9130 [(set (match_operand:SWI48 6 "general_reg_operand")
9131 (match_operand:SWI48 7 "memory_operand"))
9132 (set (match_operand:SWI48 8 "general_reg_operand")
9133 (match_operand:SWI48 9 "memory_operand"))
9134 (parallel [(set (reg:CCC FLAGS_REG)
9137 (match_operand:SWI48 0 "general_reg_operand"))
9139 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
9140 [(match_operand 3 "flags_reg_operand") (const_int 0)])
9142 (match_operand:SWI48 2 "general_reg_operand")))))
9147 (match_operator:SWI48 5 "ix86_carry_flag_operator"
9148 [(match_dup 3) (const_int 0)]))
9150 (set (match_operand:SWI48 1 "memory_operand") (match_dup 0))]
9151 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
9152 && peep2_reg_dead_p (4, operands[0])
9153 && peep2_reg_dead_p (3, operands[2])
9154 && !reg_overlap_mentioned_p (operands[0], operands[1])
9155 && !reg_overlap_mentioned_p (operands[2], operands[1])
9156 && !reg_overlap_mentioned_p (operands[6], operands[9])
9157 && (rtx_equal_p (operands[6], operands[0])
9158 ? (rtx_equal_p (operands[7], operands[1])
9159 && rtx_equal_p (operands[8], operands[2]))
9160 : (rtx_equal_p (operands[8], operands[0])
9161 && rtx_equal_p (operands[9], operands[1])
9162 && rtx_equal_p (operands[6], operands[2])))"
9163 [(set (match_dup 0) (match_dup 9))
9164 (parallel [(set (reg:CCC FLAGS_REG)
9166 (zero_extend:<DWI> (match_dup 1))
9167 (plus:<DWI> (match_op_dup 4
9168 [(match_dup 3) (const_int 0)])
9169 (zero_extend:<DWI> (match_dup 0)))))
9171 (minus:SWI48 (minus:SWI48 (match_dup 1)
9173 [(match_dup 3) (const_int 0)]))
9176 if (!rtx_equal_p (operands[6], operands[0]))
9177 operands[9] = operands[7];
9181 [(set (match_operand:SWI48 6 "general_reg_operand")
9182 (match_operand:SWI48 7 "memory_operand"))
9183 (set (match_operand:SWI48 8 "general_reg_operand")
9184 (match_operand:SWI48 9 "memory_operand"))
9185 (parallel [(set (reg:CCC FLAGS_REG)
9188 (match_operand:SWI48 0 "general_reg_operand"))
9190 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
9191 [(match_operand 3 "flags_reg_operand") (const_int 0)])
9193 (match_operand:SWI48 2 "general_reg_operand")))))
9198 (match_operator:SWI48 5 "ix86_carry_flag_operator"
9199 [(match_dup 3) (const_int 0)]))
9201 (set (match_operand:QI 10 "general_reg_operand")
9202 (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
9203 (set (match_operand:SWI48 11 "general_reg_operand")
9204 (zero_extend:SWI48 (match_dup 10)))
9205 (set (match_operand:SWI48 1 "memory_operand") (match_dup 0))]
9206 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
9207 && peep2_reg_dead_p (6, operands[0])
9208 && peep2_reg_dead_p (3, operands[2])
9209 && !reg_overlap_mentioned_p (operands[0], operands[1])
9210 && !reg_overlap_mentioned_p (operands[2], operands[1])
9211 && !reg_overlap_mentioned_p (operands[6], operands[9])
9212 && !reg_overlap_mentioned_p (operands[0], operands[10])
9213 && !reg_overlap_mentioned_p (operands[10], operands[1])
9214 && !reg_overlap_mentioned_p (operands[0], operands[11])
9215 && !reg_overlap_mentioned_p (operands[11], operands[1])
9216 && (rtx_equal_p (operands[6], operands[0])
9217 ? (rtx_equal_p (operands[7], operands[1])
9218 && rtx_equal_p (operands[8], operands[2]))
9219 : (rtx_equal_p (operands[8], operands[0])
9220 && rtx_equal_p (operands[9], operands[1])
9221 && rtx_equal_p (operands[6], operands[2])))"
9222 [(set (match_dup 0) (match_dup 9))
9223 (parallel [(set (reg:CCC FLAGS_REG)
9225 (zero_extend:<DWI> (match_dup 1))
9226 (plus:<DWI> (match_op_dup 4
9227 [(match_dup 3) (const_int 0)])
9228 (zero_extend:<DWI> (match_dup 0)))))
9230 (minus:SWI48 (minus:SWI48 (match_dup 1)
9232 [(match_dup 3) (const_int 0)]))
9234 (set (match_dup 10) (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
9235 (set (match_dup 11) (zero_extend:SWI48 (match_dup 10)))]
9237 if (!rtx_equal_p (operands[6], operands[0]))
9238 operands[9] = operands[7];
9241 (define_expand "subborrow<mode>_0"
9243 [(set (reg:CC FLAGS_REG)
9245 (match_operand:SWI48 1 "nonimmediate_operand")
9246 (match_operand:SWI48 2 "<general_operand>")))
9247 (set (match_operand:SWI48 0 "register_operand")
9248 (minus:SWI48 (match_dup 1) (match_dup 2)))])]
9249 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)")
9251 (define_expand "uaddc<mode>5"
9252 [(match_operand:SWI48 0 "register_operand")
9253 (match_operand:SWI48 1 "register_operand")
9254 (match_operand:SWI48 2 "register_operand")
9255 (match_operand:SWI48 3 "register_operand")
9256 (match_operand:SWI48 4 "nonmemory_operand")]
9259 rtx cf = gen_rtx_REG (CCCmode, FLAGS_REG), pat, pat2;
9260 if (operands[4] == const0_rtx)
9261 emit_insn (gen_addcarry<mode>_0 (operands[0], operands[2], operands[3]));
9264 ix86_expand_carry (operands[4]);
9265 pat = gen_rtx_LTU (<DWI>mode, cf, const0_rtx);
9266 pat2 = gen_rtx_LTU (<MODE>mode, cf, const0_rtx);
9267 emit_insn (gen_addcarry<mode> (operands[0], operands[2], operands[3],
9270 rtx cc = gen_reg_rtx (QImode);
9271 pat = gen_rtx_LTU (QImode, cf, const0_rtx);
9272 emit_insn (gen_rtx_SET (cc, pat));
9273 emit_insn (gen_zero_extendqi<mode>2 (operands[1], cc));
9277 (define_expand "usubc<mode>5"
9278 [(match_operand:SWI48 0 "register_operand")
9279 (match_operand:SWI48 1 "register_operand")
9280 (match_operand:SWI48 2 "register_operand")
9281 (match_operand:SWI48 3 "register_operand")
9282 (match_operand:SWI48 4 "nonmemory_operand")]
9286 if (operands[4] == const0_rtx)
9288 cf = gen_rtx_REG (CCmode, FLAGS_REG);
9289 emit_insn (gen_subborrow<mode>_0 (operands[0], operands[2],
9294 cf = gen_rtx_REG (CCCmode, FLAGS_REG);
9295 ix86_expand_carry (operands[4]);
9296 pat = gen_rtx_LTU (<DWI>mode, cf, const0_rtx);
9297 pat2 = gen_rtx_LTU (<MODE>mode, cf, const0_rtx);
9298 emit_insn (gen_subborrow<mode> (operands[0], operands[2], operands[3],
9301 rtx cc = gen_reg_rtx (QImode);
9302 pat = gen_rtx_LTU (QImode, cf, const0_rtx);
9303 emit_insn (gen_rtx_SET (cc, pat));
9304 emit_insn (gen_zero_extendqi<mode>2 (operands[1], cc));
9308 (define_mode_iterator CC_CCC [CC CCC])
9310 ;; Pre-reload splitter to optimize
9311 ;; *setcc_qi followed by *addqi3_cconly_overflow_1 with the same QI
9312 ;; operand and no intervening flags modifications into nothing.
9313 (define_insn_and_split "*setcc_qi_addqi3_cconly_overflow_1_<mode>"
9314 [(set (reg:CCC FLAGS_REG)
9315 (compare:CCC (neg:QI (geu:QI (reg:CC_CCC FLAGS_REG) (const_int 0)))
9316 (ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))))]
9317 "ix86_pre_reload_split ()"
9321 "emit_note (NOTE_INSN_DELETED); DONE;")
9323 ;; Set the carry flag from the carry flag.
9324 (define_insn_and_split "*setccc"
9325 [(set (reg:CCC FLAGS_REG)
9326 (reg:CCC FLAGS_REG))]
9327 "ix86_pre_reload_split ()"
9331 "emit_note (NOTE_INSN_DELETED); DONE;")
9333 ;; Set the carry flag from the carry flag.
9334 (define_insn_and_split "*setcc_qi_negqi_ccc_1_<mode>"
9335 [(set (reg:CCC FLAGS_REG)
9336 (ltu:CCC (reg:CC_CCC FLAGS_REG) (const_int 0)))]
9337 "ix86_pre_reload_split ()"
9341 "emit_note (NOTE_INSN_DELETED); DONE;")
9343 ;; Set the carry flag from the carry flag.
9344 (define_insn_and_split "*setcc_qi_negqi_ccc_2_<mode>"
9345 [(set (reg:CCC FLAGS_REG)
9346 (unspec:CCC [(ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))
9347 (const_int 0)] UNSPEC_CC_NE))]
9348 "ix86_pre_reload_split ()"
9352 "emit_note (NOTE_INSN_DELETED); DONE;")
9354 ;; Overflow setting add instructions
9356 (define_expand "addqi3_cconly_overflow"
9358 [(set (reg:CCC FLAGS_REG)
9361 (match_operand:QI 0 "nonimmediate_operand")
9362 (match_operand:QI 1 "general_operand"))
9364 (clobber (scratch:QI))])]
9365 "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
9367 (define_insn "*add<mode>3_cconly_overflow_1"
9368 [(set (reg:CCC FLAGS_REG)
9371 (match_operand:SWI 1 "nonimmediate_operand" "%0,r,rm")
9372 (match_operand:SWI 2 "<general_operand>" "<g>,<g>,re"))
9374 (clobber (match_scratch:SWI 0 "=<r>,r,r"))]
9375 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9377 add{<imodesuffix>}\t{%2, %0|%0, %2}
9378 add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9379 add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
9380 [(set_attr "isa" "*,apx_ndd,apx_ndd")
9381 (set_attr "type" "alu")
9382 (set_attr "mode" "<MODE>")])
9384 (define_insn "@add<mode>3_cc_overflow_1"
9385 [(set (reg:CCC FLAGS_REG)
9388 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,rm,rjM,r")
9389 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,r,<i>,<m>"))
9391 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r,r")
9392 (plus:SWI (match_dup 1) (match_dup 2)))]
9393 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)"
9395 add{<imodesuffix>}\t{%2, %0|%0, %2}
9396 add{<imodesuffix>}\t{%2, %0|%0, %2}
9397 add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9398 add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9399 add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
9400 [(set_attr "isa" "*,*,apx_ndd,apx_ndd,apx_ndd")
9401 (set_attr "type" "alu")
9402 (set_attr "mode" "<MODE>")])
9405 [(parallel [(set (reg:CCC FLAGS_REG)
9407 (plus:SWI (match_operand:SWI 0 "general_reg_operand")
9408 (match_operand:SWI 1 "memory_operand"))
9410 (set (match_dup 0) (plus:SWI (match_dup 0) (match_dup 1)))])
9411 (set (match_dup 1) (match_dup 0))]
9412 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
9413 && peep2_reg_dead_p (2, operands[0])
9414 && !reg_overlap_mentioned_p (operands[0], operands[1])"
9415 [(parallel [(set (reg:CCC FLAGS_REG)
9417 (plus:SWI (match_dup 1) (match_dup 0))
9419 (set (match_dup 1) (plus:SWI (match_dup 1) (match_dup 0)))])])
9422 [(set (match_operand:SWI 0 "general_reg_operand")
9423 (match_operand:SWI 1 "memory_operand"))
9424 (parallel [(set (reg:CCC FLAGS_REG)
9426 (plus:SWI (match_dup 0)
9427 (match_operand:SWI 2 "memory_operand"))
9429 (set (match_dup 0) (plus:SWI (match_dup 0) (match_dup 2)))])
9430 (set (match_dup 1) (match_dup 0))]
9431 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
9432 && peep2_reg_dead_p (3, operands[0])
9433 && !reg_overlap_mentioned_p (operands[0], operands[1])
9434 && !reg_overlap_mentioned_p (operands[0], operands[2])"
9435 [(set (match_dup 0) (match_dup 2))
9436 (parallel [(set (reg:CCC FLAGS_REG)
9438 (plus:SWI (match_dup 1) (match_dup 0))
9440 (set (match_dup 1) (plus:SWI (match_dup 1) (match_dup 0)))])])
9442 (define_insn "*addsi3_zext_cc_overflow_1"
9443 [(set (reg:CCC FLAGS_REG)
9446 (match_operand:SI 1 "nonimmediate_operand" "%0,r,rm")
9447 (match_operand:SI 2 "x86_64_general_operand" "rBMe,rBMe,re"))
9449 (set (match_operand:DI 0 "register_operand" "=r,r,r")
9450 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
9452 && ix86_binary_operator_ok (PLUS, SImode, operands, TARGET_APX_NDD)"
9454 add{l}\t{%2, %k0|%k0, %2}
9455 add{l}\t{%2, %1, %k0|%k0, %1, %2}
9456 add{l}\t{%2, %1, %k0|%k0, %1, %2}"
9457 [(set_attr "isa" "*,apx_ndd,apx_ndd")
9458 (set_attr "type" "alu")
9459 (set_attr "mode" "SI")])
9461 (define_insn "*add<mode>3_cconly_overflow_2"
9462 [(set (reg:CCC FLAGS_REG)
9465 (match_operand:SWI 1 "nonimmediate_operand" "%0,r,rm")
9466 (match_operand:SWI 2 "<general_operand>" "<g>,<g>,re"))
9468 (clobber (match_scratch:SWI 0 "=<r>,r,r"))]
9469 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9471 add{<imodesuffix>}\t{%2, %0|%0, %2}
9472 add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9473 add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
9474 [(set_attr "isa" "*,apx_ndd,apx_ndd")
9475 (set_attr "type" "alu")
9476 (set_attr "mode" "<MODE>")])
9478 (define_insn "*add<mode>3_cc_overflow_2"
9479 [(set (reg:CCC FLAGS_REG)
9482 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,rm,r")
9483 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,r<i>,<m>"))
9485 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r")
9486 (plus:SWI (match_dup 1) (match_dup 2)))]
9487 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)"
9489 add{<imodesuffix>}\t{%2, %0|%0, %2}
9490 add{<imodesuffix>}\t{%2, %0|%0, %2}
9491 add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9492 add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
9493 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
9494 (set_attr "type" "alu")
9495 (set_attr "mode" "<MODE>")])
9497 (define_insn "*addsi3_zext_cc_overflow_2"
9498 [(set (reg:CCC FLAGS_REG)
9501 (match_operand:SI 1 "nonimmediate_operand" "%0,r,rm")
9502 (match_operand:SI 2 "x86_64_general_operand" "rBMe,rBMe,re"))
9504 (set (match_operand:DI 0 "register_operand" "=r,r,r")
9505 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
9507 && ix86_binary_operator_ok (PLUS, SImode, operands, TARGET_APX_NDD)"
9509 add{l}\t{%2, %k0|%k0, %2}
9510 add{l}\t{%2, %1, %k0|%k0, %1, %2}
9511 add{l}\t{%2, %1, %k0|%k0, %1, %2}"
9512 [(set_attr "isa" "*,apx_ndd,apx_ndd")
9513 (set_attr "type" "alu")
9514 (set_attr "mode" "SI")])
9516 (define_insn_and_split "*add<dwi>3_doubleword_cc_overflow_1"
9517 [(set (reg:CCC FLAGS_REG)
9520 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0,ro,r,ro,jO,r")
9521 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o,r,<di>,K,<di>,o"))
9523 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,&r,&r,&r,&r,&r")
9524 (plus:<DWI> (match_dup 1) (match_dup 2)))]
9525 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands, TARGET_APX_NDD)"
9527 "&& reload_completed"
9528 [(parallel [(set (reg:CCC FLAGS_REG)
9530 (plus:DWIH (match_dup 1) (match_dup 2))
9533 (plus:DWIH (match_dup 1) (match_dup 2)))])
9534 (parallel [(set (reg:CCC FLAGS_REG)
9539 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9544 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))))
9547 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9551 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
9552 if (operands[2] == const0_rtx)
9554 if (!rtx_equal_p (operands[0], operands[1]))
9555 emit_move_insn (operands[0], operands[1]);
9556 emit_insn (gen_addcarry<mode>_0 (operands[3], operands[4], operands[5]));
9559 if (CONST_INT_P (operands[5]))
9560 operands[6] = simplify_unary_operation (ZERO_EXTEND, <DWI>mode,
9561 operands[5], <MODE>mode);
9563 operands[6] = gen_rtx_ZERO_EXTEND (<DWI>mode, operands[5]);
9565 [(set_attr "isa" "*,*,apx_ndd,apx_ndd,apx_ndd,apx_ndd_64,apx_ndd")])
9567 ;; x == 0 with zero flag test can be done also as x < 1U with carry flag
9568 ;; test, where the latter is preferrable if we have some carry consuming
9570 ;; For x != 0, we need to use x < 1U with negation of carry, i.e.
9572 (define_insn_and_split "*add<mode>3_eq"
9573 [(set (match_operand:SWI 0 "nonimmediate_operand")
9576 (eq:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0))
9577 (match_operand:SWI 1 "nonimmediate_operand"))
9578 (match_operand:SWI 2 "<general_operand>")))
9579 (clobber (reg:CC FLAGS_REG))]
9580 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)
9581 && ix86_pre_reload_split ()"
9584 [(set (reg:CC FLAGS_REG)
9585 (compare:CC (match_dup 3) (const_int 1)))
9586 (parallel [(set (match_dup 0)
9588 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9591 (clobber (reg:CC FLAGS_REG))])])
9593 (define_insn_and_split "*add<mode>3_ne"
9594 [(set (match_operand:SWI 0 "nonimmediate_operand")
9597 (ne:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0))
9598 (match_operand:SWI 1 "nonimmediate_operand"))
9599 (match_operand:SWI 2 "<immediate_operand>")))
9600 (clobber (reg:CC FLAGS_REG))]
9601 "CONST_INT_P (operands[2])
9602 && (<MODE>mode != DImode
9603 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
9604 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)
9605 && ix86_pre_reload_split ()"
9608 [(set (reg:CC FLAGS_REG)
9609 (compare:CC (match_dup 3) (const_int 1)))
9610 (parallel [(set (match_dup 0)
9612 (minus:SWI (match_dup 1)
9613 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9615 (clobber (reg:CC FLAGS_REG))])]
9617 operands[2] = gen_int_mode (~INTVAL (operands[2]),
9618 <MODE>mode == DImode ? SImode : <MODE>mode);
9621 (define_insn_and_split "*add<mode>3_eq_0"
9622 [(set (match_operand:SWI 0 "nonimmediate_operand")
9624 (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))
9625 (match_operand:SWI 1 "<general_operand>")))
9626 (clobber (reg:CC FLAGS_REG))]
9627 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)
9628 && ix86_pre_reload_split ()"
9631 [(set (reg:CC FLAGS_REG)
9632 (compare:CC (match_dup 2) (const_int 1)))
9633 (parallel [(set (match_dup 0)
9634 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9636 (clobber (reg:CC FLAGS_REG))])]
9638 if (!nonimmediate_operand (operands[1], <MODE>mode))
9639 operands[1] = force_reg (<MODE>mode, operands[1]);
9642 (define_insn_and_split "*add<mode>3_ne_0"
9643 [(set (match_operand:SWI 0 "nonimmediate_operand")
9645 (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))
9646 (match_operand:SWI 1 "<general_operand>")))
9647 (clobber (reg:CC FLAGS_REG))]
9648 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)
9649 && ix86_pre_reload_split ()"
9652 [(set (reg:CC FLAGS_REG)
9653 (compare:CC (match_dup 2) (const_int 1)))
9654 (parallel [(set (match_dup 0)
9655 (minus:SWI (minus:SWI
9657 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9659 (clobber (reg:CC FLAGS_REG))])]
9661 if (!nonimmediate_operand (operands[1], <MODE>mode))
9662 operands[1] = force_reg (<MODE>mode, operands[1]);
9665 (define_insn_and_split "*sub<mode>3_eq"
9666 [(set (match_operand:SWI 0 "nonimmediate_operand")
9669 (match_operand:SWI 1 "nonimmediate_operand")
9670 (eq:SWI (match_operand 3 "int_nonimmediate_operand")
9672 (match_operand:SWI 2 "<general_operand>")))
9673 (clobber (reg:CC FLAGS_REG))]
9674 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)
9675 && ix86_pre_reload_split ()"
9678 [(set (reg:CC FLAGS_REG)
9679 (compare:CC (match_dup 3) (const_int 1)))
9680 (parallel [(set (match_dup 0)
9682 (minus:SWI (match_dup 1)
9683 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9685 (clobber (reg:CC FLAGS_REG))])])
9687 (define_insn_and_split "*sub<mode>3_ne"
9688 [(set (match_operand:SWI 0 "nonimmediate_operand")
9691 (match_operand:SWI 1 "nonimmediate_operand")
9692 (ne:SWI (match_operand 3 "int_nonimmediate_operand")
9694 (match_operand:SWI 2 "<immediate_operand>")))
9695 (clobber (reg:CC FLAGS_REG))]
9696 "CONST_INT_P (operands[2])
9697 && (<MODE>mode != DImode
9698 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
9699 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)
9700 && ix86_pre_reload_split ()"
9703 [(set (reg:CC FLAGS_REG)
9704 (compare:CC (match_dup 3) (const_int 1)))
9705 (parallel [(set (match_dup 0)
9707 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9710 (clobber (reg:CC FLAGS_REG))])]
9712 operands[2] = gen_int_mode (INTVAL (operands[2]) - 1,
9713 <MODE>mode == DImode ? SImode : <MODE>mode);
9716 (define_insn_and_split "*sub<mode>3_eq_1"
9717 [(set (match_operand:SWI 0 "nonimmediate_operand")
9720 (match_operand:SWI 1 "nonimmediate_operand")
9721 (eq:SWI (match_operand 3 "int_nonimmediate_operand")
9723 (match_operand:SWI 2 "<immediate_operand>")))
9724 (clobber (reg:CC FLAGS_REG))]
9725 "CONST_INT_P (operands[2])
9726 && (<MODE>mode != DImode
9727 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
9728 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)
9729 && ix86_pre_reload_split ()"
9732 [(set (reg:CC FLAGS_REG)
9733 (compare:CC (match_dup 3) (const_int 1)))
9734 (parallel [(set (match_dup 0)
9736 (minus:SWI (match_dup 1)
9737 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9739 (clobber (reg:CC FLAGS_REG))])]
9741 operands[2] = gen_int_mode (-INTVAL (operands[2]),
9742 <MODE>mode == DImode ? SImode : <MODE>mode);
9745 (define_insn_and_split "*sub<mode>3_eq_0"
9746 [(set (match_operand:SWI 0 "nonimmediate_operand")
9748 (match_operand:SWI 1 "<general_operand>")
9749 (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))))
9750 (clobber (reg:CC FLAGS_REG))]
9751 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)
9752 && ix86_pre_reload_split ()"
9755 [(set (reg:CC FLAGS_REG)
9756 (compare:CC (match_dup 2) (const_int 1)))
9757 (parallel [(set (match_dup 0)
9758 (minus:SWI (match_dup 1)
9759 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))))
9760 (clobber (reg:CC FLAGS_REG))])]
9762 if (!nonimmediate_operand (operands[1], <MODE>mode))
9763 operands[1] = force_reg (<MODE>mode, operands[1]);
9766 (define_insn_and_split "*sub<mode>3_ne_0"
9767 [(set (match_operand:SWI 0 "nonimmediate_operand")
9769 (match_operand:SWI 1 "<general_operand>")
9770 (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))))
9771 (clobber (reg:CC FLAGS_REG))]
9772 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)
9773 && ix86_pre_reload_split ()"
9776 [(set (reg:CC FLAGS_REG)
9777 (compare:CC (match_dup 2) (const_int 1)))
9778 (parallel [(set (match_dup 0)
9780 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9783 (clobber (reg:CC FLAGS_REG))])]
9785 if (!nonimmediate_operand (operands[1], <MODE>mode))
9786 operands[1] = force_reg (<MODE>mode, operands[1]);
9789 ;; The patterns that match these are at the end of this file.
9791 (define_expand "<insn>xf3"
9792 [(set (match_operand:XF 0 "register_operand")
9794 (match_operand:XF 1 "register_operand")
9795 (match_operand:XF 2 "register_operand")))]
9798 (define_expand "<insn>hf3"
9799 [(set (match_operand:HF 0 "register_operand")
9801 (match_operand:HF 1 "register_operand")
9802 (match_operand:HF 2 "nonimmediate_operand")))]
9803 "TARGET_AVX512FP16")
9805 (define_expand "<insn><mode>3"
9806 [(set (match_operand:MODEF 0 "register_operand")
9808 (match_operand:MODEF 1 "register_operand")
9809 (match_operand:MODEF 2 "nonimmediate_operand")))]
9810 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
9811 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
9813 ;; Multiply instructions
9815 (define_expand "mul<mode>3"
9816 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
9818 (match_operand:SWIM248 1 "register_operand")
9819 (match_operand:SWIM248 2 "<general_operand>")))
9820 (clobber (reg:CC FLAGS_REG))])])
9822 (define_expand "mulqi3"
9823 [(parallel [(set (match_operand:QI 0 "register_operand")
9825 (match_operand:QI 1 "register_operand")
9826 (match_operand:QI 2 "nonimmediate_operand")))
9827 (clobber (reg:CC FLAGS_REG))])]
9828 "TARGET_QIMODE_MATH")
9831 ;; IMUL reg32/64, reg32/64, imm8 Direct
9832 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
9833 ;; IMUL reg32/64, reg32/64, imm32 Direct
9834 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
9835 ;; IMUL reg32/64, reg32/64 Direct
9836 ;; IMUL reg32/64, mem32/64 Direct
9838 ;; On BDVER1, all above IMULs use DirectPath
9841 ;; IMUL reg16, reg16, imm8 VectorPath
9842 ;; IMUL reg16, mem16, imm8 VectorPath
9843 ;; IMUL reg16, reg16, imm16 VectorPath
9844 ;; IMUL reg16, mem16, imm16 VectorPath
9845 ;; IMUL reg16, reg16 Direct
9846 ;; IMUL reg16, mem16 Direct
9848 ;; On BDVER1, all HI MULs use DoublePath
9850 (define_insn "*mul<mode>3_1"
9851 [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
9853 (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
9854 (match_operand:SWIM248 2 "<general_operand>" "K,<i>,<m>r")))
9855 (clobber (reg:CC FLAGS_REG))]
9856 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9858 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9859 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9860 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
9861 [(set_attr "type" "imul")
9862 (set_attr "prefix_0f" "0,0,1")
9863 (set (attr "athlon_decode")
9864 (cond [(eq_attr "cpu" "athlon")
9865 (const_string "vector")
9866 (eq_attr "alternative" "1")
9867 (const_string "vector")
9868 (and (eq_attr "alternative" "2")
9869 (ior (match_test "<MODE>mode == HImode")
9870 (match_operand 1 "memory_operand")))
9871 (const_string "vector")]
9872 (const_string "direct")))
9873 (set (attr "amdfam10_decode")
9874 (cond [(and (eq_attr "alternative" "0,1")
9875 (ior (match_test "<MODE>mode == HImode")
9876 (match_operand 1 "memory_operand")))
9877 (const_string "vector")]
9878 (const_string "direct")))
9879 (set (attr "bdver1_decode")
9881 (match_test "<MODE>mode == HImode")
9882 (const_string "double")
9883 (const_string "direct")))
9884 (set_attr "mode" "<MODE>")])
9886 (define_insn "*mulsi3_1_zext"
9887 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9889 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
9890 (match_operand:SI 2 "x86_64_general_operand" "K,e,BMr"))))
9891 (clobber (reg:CC FLAGS_REG))]
9893 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9895 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
9896 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
9897 imul{l}\t{%2, %k0|%k0, %2}"
9898 [(set_attr "type" "imul")
9899 (set_attr "prefix_0f" "0,0,1")
9900 (set (attr "athlon_decode")
9901 (cond [(eq_attr "cpu" "athlon")
9902 (const_string "vector")
9903 (eq_attr "alternative" "1")
9904 (const_string "vector")
9905 (and (eq_attr "alternative" "2")
9906 (match_operand 1 "memory_operand"))
9907 (const_string "vector")]
9908 (const_string "direct")))
9909 (set (attr "amdfam10_decode")
9910 (cond [(and (eq_attr "alternative" "0,1")
9911 (match_operand 1 "memory_operand"))
9912 (const_string "vector")]
9913 (const_string "direct")))
9914 (set_attr "bdver1_decode" "direct")
9915 (set_attr "mode" "SI")])
9917 ;;On AMDFAM10 and BDVER1
9921 (define_insn "*mulqi3_1"
9922 [(set (match_operand:QI 0 "register_operand" "=a")
9923 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9924 (match_operand:QI 2 "nonimmediate_operand" "qm")))
9925 (clobber (reg:CC FLAGS_REG))]
9927 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9929 [(set_attr "type" "imul")
9930 (set_attr "length_immediate" "0")
9931 (set (attr "athlon_decode")
9932 (if_then_else (eq_attr "cpu" "athlon")
9933 (const_string "vector")
9934 (const_string "direct")))
9935 (set_attr "amdfam10_decode" "direct")
9936 (set_attr "bdver1_decode" "direct")
9937 (set_attr "mode" "QI")])
9939 ;; Multiply with jump on overflow.
9940 (define_expand "mulv<mode>4"
9941 [(parallel [(set (reg:CCO FLAGS_REG)
9944 (match_operand:SWI248 1 "register_operand"))
9947 (mult:SWI248 (match_dup 1)
9948 (match_operand:SWI248 2
9949 "<general_operand>")))))
9950 (set (match_operand:SWI248 0 "register_operand")
9951 (mult:SWI248 (match_dup 1) (match_dup 2)))])
9952 (set (pc) (if_then_else
9953 (eq (reg:CCO FLAGS_REG) (const_int 0))
9954 (label_ref (match_operand 3))
9958 if (CONST_INT_P (operands[2]))
9959 operands[4] = operands[2];
9961 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
9964 (define_insn "*mulv<mode>4"
9965 [(set (reg:CCO FLAGS_REG)
9968 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
9970 (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
9972 (mult:SWI48 (match_dup 1) (match_dup 2)))))
9973 (set (match_operand:SWI48 0 "register_operand" "=r,r")
9974 (mult:SWI48 (match_dup 1) (match_dup 2)))]
9975 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9977 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9978 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
9979 [(set_attr "type" "imul")
9980 (set_attr "prefix_0f" "0,1")
9981 (set (attr "athlon_decode")
9982 (cond [(eq_attr "cpu" "athlon")
9983 (const_string "vector")
9984 (eq_attr "alternative" "0")
9985 (const_string "vector")
9986 (and (eq_attr "alternative" "1")
9987 (match_operand 1 "memory_operand"))
9988 (const_string "vector")]
9989 (const_string "direct")))
9990 (set (attr "amdfam10_decode")
9991 (cond [(and (eq_attr "alternative" "1")
9992 (match_operand 1 "memory_operand"))
9993 (const_string "vector")]
9994 (const_string "direct")))
9995 (set_attr "bdver1_decode" "direct")
9996 (set_attr "mode" "<MODE>")])
9998 (define_insn "*mulvhi4"
9999 [(set (reg:CCO FLAGS_REG)
10002 (match_operand:HI 1 "nonimmediate_operand" "%0"))
10004 (match_operand:HI 2 "nonimmediate_operand" "mr")))
10006 (mult:HI (match_dup 1) (match_dup 2)))))
10007 (set (match_operand:HI 0 "register_operand" "=r")
10008 (mult:HI (match_dup 1) (match_dup 2)))]
10009 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
10010 "imul{w}\t{%2, %0|%0, %2}"
10011 [(set_attr "type" "imul")
10012 (set_attr "prefix_0f" "1")
10013 (set_attr "athlon_decode" "vector")
10014 (set_attr "amdfam10_decode" "direct")
10015 (set_attr "bdver1_decode" "double")
10016 (set_attr "mode" "HI")])
10018 (define_insn "*mulv<mode>4_1"
10019 [(set (reg:CCO FLAGS_REG)
10020 (eq:CCO (mult:<DWI>
10022 (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
10023 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
10025 (mult:SWI248 (match_dup 1)
10026 (match_operand:SWI248 2
10027 "<immediate_operand>" "K,<i>")))))
10028 (set (match_operand:SWI248 0 "register_operand" "=r,r")
10029 (mult:SWI248 (match_dup 1) (match_dup 2)))]
10030 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
10031 && CONST_INT_P (operands[2])
10032 && INTVAL (operands[2]) == INTVAL (operands[3])"
10033 "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
10034 [(set_attr "type" "imul")
10035 (set (attr "prefix_0f")
10037 (match_test "<MODE>mode == HImode")
10039 (const_string "*")))
10040 (set (attr "athlon_decode")
10041 (cond [(eq_attr "cpu" "athlon")
10042 (const_string "vector")
10043 (eq_attr "alternative" "1")
10044 (const_string "vector")]
10045 (const_string "direct")))
10046 (set (attr "amdfam10_decode")
10047 (cond [(ior (match_test "<MODE>mode == HImode")
10048 (match_operand 1 "memory_operand"))
10049 (const_string "vector")]
10050 (const_string "direct")))
10051 (set (attr "bdver1_decode")
10053 (match_test "<MODE>mode == HImode")
10054 (const_string "double")
10055 (const_string "direct")))
10056 (set_attr "mode" "<MODE>")
10057 (set (attr "length_immediate")
10058 (cond [(eq_attr "alternative" "0")
10060 (match_test "<MODE_SIZE> == 8")
10061 (const_string "4")]
10062 (const_string "<MODE_SIZE>")))])
10064 (define_expand "umulv<mode>4"
10065 [(parallel [(set (reg:CCO FLAGS_REG)
10066 (eq:CCO (mult:<DWI>
10068 (match_operand:SWI248 1
10069 "nonimmediate_operand"))
10071 (match_operand:SWI248 2
10072 "nonimmediate_operand")))
10074 (mult:SWI248 (match_dup 1) (match_dup 2)))))
10075 (set (match_operand:SWI248 0 "register_operand")
10076 (mult:SWI248 (match_dup 1) (match_dup 2)))
10077 (clobber (scratch:SWI248))])
10078 (set (pc) (if_then_else
10079 (eq (reg:CCO FLAGS_REG) (const_int 0))
10080 (label_ref (match_operand 3))
10084 if (MEM_P (operands[1]) && MEM_P (operands[2]))
10085 operands[1] = force_reg (<MODE>mode, operands[1]);
10088 (define_insn "*umulv<mode>4"
10089 [(set (reg:CCO FLAGS_REG)
10090 (eq:CCO (mult:<DWI>
10092 (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
10094 (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
10096 (mult:SWI248 (match_dup 1) (match_dup 2)))))
10097 (set (match_operand:SWI248 0 "register_operand" "=a")
10098 (mult:SWI248 (match_dup 1) (match_dup 2)))
10099 (clobber (match_scratch:SWI248 3 "=d"))]
10100 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
10101 "mul{<imodesuffix>}\t%2"
10102 [(set_attr "type" "imul")
10103 (set_attr "length_immediate" "0")
10104 (set (attr "athlon_decode")
10105 (if_then_else (eq_attr "cpu" "athlon")
10106 (const_string "vector")
10107 (const_string "double")))
10108 (set_attr "amdfam10_decode" "double")
10109 (set_attr "bdver1_decode" "direct")
10110 (set_attr "mode" "<MODE>")])
10112 (define_expand "<u>mulvqi4"
10113 [(parallel [(set (reg:CCO FLAGS_REG)
10116 (match_operand:QI 1 "nonimmediate_operand"))
10118 (match_operand:QI 2 "nonimmediate_operand")))
10120 (mult:QI (match_dup 1) (match_dup 2)))))
10121 (set (match_operand:QI 0 "register_operand")
10122 (mult:QI (match_dup 1) (match_dup 2)))])
10123 (set (pc) (if_then_else
10124 (eq (reg:CCO FLAGS_REG) (const_int 0))
10125 (label_ref (match_operand 3))
10127 "TARGET_QIMODE_MATH"
10129 if (MEM_P (operands[1]) && MEM_P (operands[2]))
10130 operands[1] = force_reg (QImode, operands[1]);
10133 (define_insn "*<u>mulvqi4"
10134 [(set (reg:CCO FLAGS_REG)
10137 (match_operand:QI 1 "nonimmediate_operand" "%0"))
10139 (match_operand:QI 2 "nonimmediate_operand" "qm")))
10141 (mult:QI (match_dup 1) (match_dup 2)))))
10142 (set (match_operand:QI 0 "register_operand" "=a")
10143 (mult:QI (match_dup 1) (match_dup 2)))]
10144 "TARGET_QIMODE_MATH
10145 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10146 "<sgnprefix>mul{b}\t%2"
10147 [(set_attr "type" "imul")
10148 (set_attr "length_immediate" "0")
10149 (set (attr "athlon_decode")
10150 (if_then_else (eq_attr "cpu" "athlon")
10151 (const_string "vector")
10152 (const_string "direct")))
10153 (set_attr "amdfam10_decode" "direct")
10154 (set_attr "bdver1_decode" "direct")
10155 (set_attr "mode" "QI")])
10157 (define_expand "<u>mul<mode><dwi>3"
10158 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
10161 (match_operand:DWIH 1 "register_operand"))
10163 (match_operand:DWIH 2 "nonimmediate_operand"))))
10164 (clobber (reg:CC FLAGS_REG))])])
10166 (define_expand "<u>mulqihi3"
10167 [(parallel [(set (match_operand:HI 0 "register_operand")
10170 (match_operand:QI 1 "register_operand"))
10172 (match_operand:QI 2 "nonimmediate_operand"))))
10173 (clobber (reg:CC FLAGS_REG))])]
10174 "TARGET_QIMODE_MATH")
10176 (define_insn "*bmi2_umul<mode><dwi>3_1"
10177 [(set (match_operand:DWIH 0 "register_operand" "=r")
10179 (match_operand:DWIH 2 "register_operand" "%d")
10180 (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
10181 (set (match_operand:DWIH 1 "register_operand" "=r")
10182 (umul_highpart:DWIH (match_dup 2) (match_dup 3)))]
10184 "mulx\t{%3, %0, %1|%1, %0, %3}"
10185 [(set_attr "type" "imulx")
10186 (set_attr "prefix" "vex")
10187 (set_attr "mode" "<MODE>")])
10189 ;; Tweak *bmi2_umul<mode><dwi>3_1 to eliminate following mov.
10191 [(parallel [(set (match_operand:DWIH 0 "general_reg_operand")
10192 (mult:DWIH (match_operand:DWIH 2 "register_operand")
10193 (match_operand:DWIH 3 "nonimmediate_operand")))
10194 (set (match_operand:DWIH 1 "general_reg_operand")
10195 (umul_highpart:DWIH (match_dup 2) (match_dup 3)))])
10196 (set (match_operand:DWIH 4 "general_reg_operand")
10197 (match_operand:DWIH 5 "general_reg_operand"))]
10199 && ((REGNO (operands[5]) == REGNO (operands[0])
10200 && REGNO (operands[1]) != REGNO (operands[4]))
10201 || (REGNO (operands[5]) == REGNO (operands[1])
10202 && REGNO (operands[0]) != REGNO (operands[4])))
10203 && peep2_reg_dead_p (2, operands[5])"
10204 [(parallel [(set (match_dup 0) (mult:DWIH (match_dup 2) (match_dup 3)))
10206 (umul_highpart:DWIH (match_dup 2) (match_dup 3)))])]
10208 if (REGNO (operands[5]) == REGNO (operands[0]))
10209 operands[0] = operands[4];
10211 operands[1] = operands[4];
10214 (define_insn "*umul<mode><dwi>3_1"
10215 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
10218 (match_operand:DWIH 1 "register_operand" "%d,a"))
10220 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
10221 (clobber (reg:CC FLAGS_REG))]
10222 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
10225 mul{<imodesuffix>}\t%2"
10226 [(set_attr "isa" "bmi2,*")
10227 (set_attr "type" "imulx,imul")
10228 (set_attr "length_immediate" "*,0")
10229 (set (attr "athlon_decode")
10230 (cond [(eq_attr "alternative" "1")
10231 (if_then_else (eq_attr "cpu" "athlon")
10232 (const_string "vector")
10233 (const_string "double"))]
10234 (const_string "*")))
10235 (set_attr "amdfam10_decode" "*,double")
10236 (set_attr "bdver1_decode" "*,direct")
10237 (set_attr "prefix" "vex,orig")
10238 (set_attr "mode" "<MODE>")])
10240 ;; Convert mul to the mulx pattern to avoid flags dependency.
10242 [(set (match_operand:<DWI> 0 "register_operand")
10245 (match_operand:DWIH 1 "register_operand"))
10247 (match_operand:DWIH 2 "nonimmediate_operand"))))
10248 (clobber (reg:CC FLAGS_REG))]
10249 "TARGET_BMI2 && reload_completed
10250 && REGNO (operands[1]) == DX_REG"
10251 [(parallel [(set (match_dup 3)
10252 (mult:DWIH (match_dup 1) (match_dup 2)))
10254 (umul_highpart:DWIH (match_dup 1) (match_dup 2)))])]
10256 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
10258 operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
10261 (define_insn "*mul<mode><dwi>3_1"
10262 [(set (match_operand:<DWI> 0 "register_operand" "=A")
10265 (match_operand:DWIH 1 "register_operand" "%a"))
10267 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
10268 (clobber (reg:CC FLAGS_REG))]
10269 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
10270 "imul{<imodesuffix>}\t%2"
10271 [(set_attr "type" "imul")
10272 (set_attr "length_immediate" "0")
10273 (set (attr "athlon_decode")
10274 (if_then_else (eq_attr "cpu" "athlon")
10275 (const_string "vector")
10276 (const_string "double")))
10277 (set_attr "amdfam10_decode" "double")
10278 (set_attr "bdver1_decode" "direct")
10279 (set_attr "mode" "<MODE>")])
10281 (define_insn "*<u>mulqihi3_1"
10282 [(set (match_operand:HI 0 "register_operand" "=a")
10285 (match_operand:QI 1 "register_operand" "%0"))
10287 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
10288 (clobber (reg:CC FLAGS_REG))]
10289 "TARGET_QIMODE_MATH
10290 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10291 "<sgnprefix>mul{b}\t%2"
10292 [(set_attr "type" "imul")
10293 (set_attr "length_immediate" "0")
10294 (set (attr "athlon_decode")
10295 (if_then_else (eq_attr "cpu" "athlon")
10296 (const_string "vector")
10297 (const_string "direct")))
10298 (set_attr "amdfam10_decode" "direct")
10299 (set_attr "bdver1_decode" "direct")
10300 (set_attr "mode" "QI")])
10302 ;; Widening multiplication peephole2s to tweak register allocation.
10303 ;; mov imm,%rdx; mov %rdi,%rax; mulq %rdx -> mov imm,%rax; mulq %rdi
10305 [(set (match_operand:DWIH 0 "general_reg_operand")
10306 (match_operand:DWIH 1 "immediate_operand"))
10307 (set (match_operand:DWIH 2 "general_reg_operand")
10308 (match_operand:DWIH 3 "general_reg_operand"))
10309 (parallel [(set (match_operand:<DWI> 4 "general_reg_operand")
10310 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
10311 (zero_extend:<DWI> (match_dup 0))))
10312 (clobber (reg:CC FLAGS_REG))])]
10313 "REGNO (operands[3]) != AX_REG
10314 && REGNO (operands[0]) != REGNO (operands[2])
10315 && REGNO (operands[0]) != REGNO (operands[3])
10316 && (REGNO (operands[0]) == REGNO (operands[4])
10317 || REGNO (operands[0]) == DX_REG
10318 || peep2_reg_dead_p (3, operands[0]))"
10319 [(set (match_dup 2) (match_dup 1))
10320 (parallel [(set (match_dup 4)
10321 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
10322 (zero_extend:<DWI> (match_dup 3))))
10323 (clobber (reg:CC FLAGS_REG))])])
10325 ;; mov imm,%rax; mov %rdi,%rdx; mulx %rax -> mov imm,%rdx; mulx %rdi
10327 [(set (match_operand:DWIH 0 "general_reg_operand")
10328 (match_operand:DWIH 1 "immediate_operand"))
10329 (set (match_operand:DWIH 2 "general_reg_operand")
10330 (match_operand:DWIH 3 "general_reg_operand"))
10331 (parallel [(set (match_operand:DWIH 4 "general_reg_operand")
10332 (mult:DWIH (match_dup 2) (match_dup 0)))
10333 (set (match_operand:DWIH 5 "general_reg_operand")
10334 (umul_highpart:DWIH (match_dup 2) (match_dup 0)))])]
10335 "REGNO (operands[3]) != DX_REG
10336 && REGNO (operands[0]) != REGNO (operands[2])
10337 && REGNO (operands[0]) != REGNO (operands[3])
10338 && (REGNO (operands[0]) == REGNO (operands[4])
10339 || REGNO (operands[0]) == REGNO (operands[5])
10340 || peep2_reg_dead_p (3, operands[0]))
10341 && (REGNO (operands[2]) == REGNO (operands[4])
10342 || REGNO (operands[2]) == REGNO (operands[5])
10343 || peep2_reg_dead_p (3, operands[2]))"
10344 [(set (match_dup 2) (match_dup 1))
10345 (parallel [(set (match_dup 4)
10346 (mult:DWIH (match_dup 2) (match_dup 3)))
10348 (umul_highpart:DWIH (match_dup 2) (match_dup 3)))])])
10350 ;; Highpart multiplication patterns
10351 (define_insn "<s>mul<mode>3_highpart"
10352 [(set (match_operand:DWIH 0 "register_operand" "=d")
10353 (any_mul_highpart:DWIH
10354 (match_operand:DWIH 1 "register_operand" "%a")
10355 (match_operand:DWIH 2 "nonimmediate_operand" "rm")))
10356 (clobber (match_scratch:DWIH 3 "=1"))
10357 (clobber (reg:CC FLAGS_REG))]
10359 "<sgnprefix>mul{<imodesuffix>}\t%2"
10360 [(set_attr "type" "imul")
10361 (set_attr "length_immediate" "0")
10362 (set (attr "athlon_decode")
10363 (if_then_else (eq_attr "cpu" "athlon")
10364 (const_string "vector")
10365 (const_string "double")))
10366 (set_attr "amdfam10_decode" "double")
10367 (set_attr "bdver1_decode" "direct")
10368 (set_attr "mode" "<MODE>")])
10370 (define_insn "*<s>mulsi3_highpart_zext"
10371 [(set (match_operand:DI 0 "register_operand" "=d")
10373 (any_mul_highpart:SI
10374 (match_operand:SI 1 "register_operand" "%a")
10375 (match_operand:SI 2 "nonimmediate_operand" "rm"))))
10376 (clobber (match_scratch:SI 3 "=1"))
10377 (clobber (reg:CC FLAGS_REG))]
10379 "<sgnprefix>mul{l}\t%2"
10380 [(set_attr "type" "imul")
10381 (set_attr "length_immediate" "0")
10382 (set (attr "athlon_decode")
10383 (if_then_else (eq_attr "cpu" "athlon")
10384 (const_string "vector")
10385 (const_string "double")))
10386 (set_attr "amdfam10_decode" "double")
10387 (set_attr "bdver1_decode" "direct")
10388 (set_attr "mode" "SI")])
10390 (define_insn "*<s>muldi3_highpart_1"
10391 [(set (match_operand:DI 0 "register_operand" "=d")
10396 (match_operand:DI 1 "nonimmediate_operand" "%a"))
10398 (match_operand:DI 2 "nonimmediate_operand" "rm")))
10400 (clobber (match_scratch:DI 3 "=1"))
10401 (clobber (reg:CC FLAGS_REG))]
10403 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10404 "<sgnprefix>mul{q}\t%2"
10405 [(set_attr "type" "imul")
10406 (set_attr "length_immediate" "0")
10407 (set (attr "athlon_decode")
10408 (if_then_else (eq_attr "cpu" "athlon")
10409 (const_string "vector")
10410 (const_string "double")))
10411 (set_attr "amdfam10_decode" "double")
10412 (set_attr "bdver1_decode" "direct")
10413 (set_attr "mode" "DI")])
10415 (define_insn "*<s>mulsi3_highpart_zext"
10416 [(set (match_operand:DI 0 "register_operand" "=d")
10417 (zero_extend:DI (truncate:SI
10419 (mult:DI (any_extend:DI
10420 (match_operand:SI 1 "nonimmediate_operand" "%a"))
10422 (match_operand:SI 2 "nonimmediate_operand" "rm")))
10424 (clobber (match_scratch:SI 3 "=1"))
10425 (clobber (reg:CC FLAGS_REG))]
10427 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10428 "<sgnprefix>mul{l}\t%2"
10429 [(set_attr "type" "imul")
10430 (set_attr "length_immediate" "0")
10431 (set (attr "athlon_decode")
10432 (if_then_else (eq_attr "cpu" "athlon")
10433 (const_string "vector")
10434 (const_string "double")))
10435 (set_attr "amdfam10_decode" "double")
10436 (set_attr "bdver1_decode" "direct")
10437 (set_attr "mode" "SI")])
10439 (define_insn "*<s>mulsi3_highpart_1"
10440 [(set (match_operand:SI 0 "register_operand" "=d")
10445 (match_operand:SI 1 "nonimmediate_operand" "%a"))
10447 (match_operand:SI 2 "nonimmediate_operand" "rm")))
10449 (clobber (match_scratch:SI 3 "=1"))
10450 (clobber (reg:CC FLAGS_REG))]
10451 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
10452 "<sgnprefix>mul{l}\t%2"
10453 [(set_attr "type" "imul")
10454 (set_attr "length_immediate" "0")
10455 (set (attr "athlon_decode")
10456 (if_then_else (eq_attr "cpu" "athlon")
10457 (const_string "vector")
10458 (const_string "double")))
10459 (set_attr "amdfam10_decode" "double")
10460 (set_attr "bdver1_decode" "direct")
10461 (set_attr "mode" "SI")])
10463 ;; Highpart multiplication peephole2s to tweak register allocation.
10464 ;; mov imm,%rdx; mov %rdi,%rax; imulq %rdx -> mov imm,%rax; imulq %rdi
10466 [(set (match_operand:SWI48 0 "general_reg_operand")
10467 (match_operand:SWI48 1 "immediate_operand"))
10468 (set (match_operand:SWI48 2 "general_reg_operand")
10469 (match_operand:SWI48 3 "general_reg_operand"))
10470 (parallel [(set (match_operand:SWI48 4 "general_reg_operand")
10471 (any_mul_highpart:SWI48 (match_dup 2) (match_dup 0)))
10472 (clobber (match_dup 2))
10473 (clobber (reg:CC FLAGS_REG))])]
10474 "REGNO (operands[3]) != AX_REG
10475 && REGNO (operands[0]) != REGNO (operands[2])
10476 && REGNO (operands[0]) != REGNO (operands[3])
10477 && (REGNO (operands[0]) == REGNO (operands[4])
10478 || peep2_reg_dead_p (3, operands[0]))"
10479 [(set (match_dup 2) (match_dup 1))
10480 (parallel [(set (match_dup 4)
10481 (any_mul_highpart:SWI48 (match_dup 2) (match_dup 3)))
10482 (clobber (match_dup 2))
10483 (clobber (reg:CC FLAGS_REG))])])
10486 [(set (match_operand:SI 0 "general_reg_operand")
10487 (match_operand:SI 1 "immediate_operand"))
10488 (set (match_operand:SI 2 "general_reg_operand")
10489 (match_operand:SI 3 "general_reg_operand"))
10490 (parallel [(set (match_operand:DI 4 "general_reg_operand")
10492 (any_mul_highpart:SI (match_dup 2) (match_dup 0))))
10493 (clobber (match_dup 2))
10494 (clobber (reg:CC FLAGS_REG))])]
10496 && REGNO (operands[3]) != AX_REG
10497 && REGNO (operands[0]) != REGNO (operands[2])
10498 && REGNO (operands[2]) != REGNO (operands[3])
10499 && REGNO (operands[0]) != REGNO (operands[3])
10500 && (REGNO (operands[0]) == REGNO (operands[4])
10501 || peep2_reg_dead_p (3, operands[0]))"
10502 [(set (match_dup 2) (match_dup 1))
10503 (parallel [(set (match_dup 4)
10505 (any_mul_highpart:SI (match_dup 2) (match_dup 3))))
10506 (clobber (match_dup 2))
10507 (clobber (reg:CC FLAGS_REG))])])
10509 ;; The patterns that match these are at the end of this file.
10511 (define_expand "mulxf3"
10512 [(set (match_operand:XF 0 "register_operand")
10513 (mult:XF (match_operand:XF 1 "register_operand")
10514 (match_operand:XF 2 "register_operand")))]
10517 (define_expand "mulhf3"
10518 [(set (match_operand:HF 0 "register_operand")
10519 (mult:HF (match_operand:HF 1 "register_operand")
10520 (match_operand:HF 2 "nonimmediate_operand")))]
10521 "TARGET_AVX512FP16")
10523 (define_expand "mul<mode>3"
10524 [(set (match_operand:MODEF 0 "register_operand")
10525 (mult:MODEF (match_operand:MODEF 1 "register_operand")
10526 (match_operand:MODEF 2 "nonimmediate_operand")))]
10527 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
10528 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
10530 ;; Divide instructions
10532 ;; The patterns that match these are at the end of this file.
10534 (define_expand "divxf3"
10535 [(set (match_operand:XF 0 "register_operand")
10536 (div:XF (match_operand:XF 1 "register_operand")
10537 (match_operand:XF 2 "register_operand")))]
10540 /* There is no more precision loss than Newton-Rhapson approximation
10541 when using HFmode rcp/rsqrt, so do the transformation directly under
10542 TARGET_RECIP_DIV and fast-math. */
10543 (define_expand "divhf3"
10544 [(set (match_operand:HF 0 "register_operand")
10545 (div:HF (match_operand:HF 1 "register_operand")
10546 (match_operand:HF 2 "nonimmediate_operand")))]
10547 "TARGET_AVX512FP16"
10549 if (TARGET_RECIP_DIV
10550 && optimize_insn_for_speed_p ()
10551 && flag_finite_math_only && !flag_trapping_math
10552 && flag_unsafe_math_optimizations)
10554 rtx op = gen_reg_rtx (HFmode);
10555 operands[2] = force_reg (HFmode, operands[2]);
10556 emit_insn (gen_rcphf2 (op, operands[2]));
10557 emit_insn (gen_mulhf3 (operands[0], operands[1], op));
10562 (define_expand "div<mode>3"
10563 [(set (match_operand:MODEF 0 "register_operand")
10564 (div:MODEF (match_operand:MODEF 1 "register_operand")
10565 (match_operand:MODEF 2 "nonimmediate_operand")))]
10566 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
10567 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10569 if (<MODE>mode == SFmode
10570 && TARGET_SSE && TARGET_SSE_MATH
10571 && TARGET_RECIP_DIV
10572 && optimize_insn_for_speed_p ()
10573 && flag_finite_math_only && !flag_trapping_math
10574 && flag_unsafe_math_optimizations)
10576 ix86_emit_swdivsf (operands[0], operands[1],
10577 operands[2], SFmode);
10582 ;; Divmod instructions.
10584 (define_code_iterator any_div [div udiv])
10585 (define_code_attr paired_mod [(div "mod") (udiv "umod")])
10587 (define_expand "<u>divmod<mode>4"
10588 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
10590 (match_operand:SWIM248 1 "register_operand")
10591 (match_operand:SWIM248 2 "nonimmediate_operand")))
10592 (set (match_operand:SWIM248 3 "register_operand")
10593 (<paired_mod>:SWIM248 (match_dup 1) (match_dup 2)))
10594 (clobber (reg:CC FLAGS_REG))])])
10596 ;; Split with 8bit unsigned divide:
10597 ;; if (dividend an divisor are in [0-255])
10598 ;; use 8bit unsigned integer divide
10600 ;; use original integer divide
10602 [(set (match_operand:SWI48 0 "register_operand")
10603 (any_div:SWI48 (match_operand:SWI48 2 "register_operand")
10604 (match_operand:SWI48 3 "nonimmediate_operand")))
10605 (set (match_operand:SWI48 1 "register_operand")
10606 (<paired_mod>:SWI48 (match_dup 2) (match_dup 3)))
10607 (clobber (reg:CC FLAGS_REG))]
10608 "TARGET_USE_8BIT_IDIV
10609 && TARGET_QIMODE_MATH
10610 && can_create_pseudo_p ()
10611 && !optimize_insn_for_size_p ()"
10613 "ix86_split_idivmod (<MODE>mode, operands, <u_bool>); DONE;")
10616 [(set (match_operand:DI 0 "register_operand")
10618 (any_div:SI (match_operand:SI 2 "register_operand")
10619 (match_operand:SI 3 "nonimmediate_operand"))))
10620 (set (match_operand:SI 1 "register_operand")
10621 (<paired_mod>:SI (match_dup 2) (match_dup 3)))
10622 (clobber (reg:CC FLAGS_REG))]
10624 && TARGET_USE_8BIT_IDIV
10625 && TARGET_QIMODE_MATH
10626 && can_create_pseudo_p ()
10627 && !optimize_insn_for_size_p ()"
10629 "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
10632 [(set (match_operand:DI 1 "register_operand")
10634 (<paired_mod>:SI (match_operand:SI 2 "register_operand")
10635 (match_operand:SI 3 "nonimmediate_operand"))))
10636 (set (match_operand:SI 0 "register_operand")
10637 (any_div:SI (match_dup 2) (match_dup 3)))
10638 (clobber (reg:CC FLAGS_REG))]
10640 && TARGET_USE_8BIT_IDIV
10641 && TARGET_QIMODE_MATH
10642 && can_create_pseudo_p ()
10643 && !optimize_insn_for_size_p ()"
10645 "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
10647 (define_insn_and_split "divmod<mode>4_1"
10648 [(set (match_operand:SWI48 0 "register_operand" "=a")
10649 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
10650 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
10651 (set (match_operand:SWI48 1 "register_operand" "=&d")
10652 (mod:SWI48 (match_dup 2) (match_dup 3)))
10653 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10654 (clobber (reg:CC FLAGS_REG))]
10658 [(parallel [(set (match_dup 1)
10659 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
10660 (clobber (reg:CC FLAGS_REG))])
10661 (parallel [(set (match_dup 0)
10662 (div:SWI48 (match_dup 2) (match_dup 3)))
10664 (mod:SWI48 (match_dup 2) (match_dup 3)))
10665 (use (match_dup 1))
10666 (clobber (reg:CC FLAGS_REG))])]
10668 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
10670 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10671 operands[4] = operands[2];
10674 /* Avoid use of cltd in favor of a mov+shift. */
10675 emit_move_insn (operands[1], operands[2]);
10676 operands[4] = operands[1];
10679 [(set_attr "type" "multi")
10680 (set_attr "mode" "<MODE>")])
10682 (define_insn_and_split "udivmod<mode>4_1"
10683 [(set (match_operand:SWI48 0 "register_operand" "=a")
10684 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
10685 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
10686 (set (match_operand:SWI48 1 "register_operand" "=&d")
10687 (umod:SWI48 (match_dup 2) (match_dup 3)))
10688 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10689 (clobber (reg:CC FLAGS_REG))]
10693 [(set (match_dup 1) (const_int 0))
10694 (parallel [(set (match_dup 0)
10695 (udiv:SWI48 (match_dup 2) (match_dup 3)))
10697 (umod:SWI48 (match_dup 2) (match_dup 3)))
10698 (use (match_dup 1))
10699 (clobber (reg:CC FLAGS_REG))])]
10701 [(set_attr "type" "multi")
10702 (set_attr "mode" "<MODE>")])
10704 (define_insn_and_split "divmodsi4_zext_1"
10705 [(set (match_operand:DI 0 "register_operand" "=a")
10707 (div:SI (match_operand:SI 2 "register_operand" "0")
10708 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10709 (set (match_operand:SI 1 "register_operand" "=&d")
10710 (mod:SI (match_dup 2) (match_dup 3)))
10711 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10712 (clobber (reg:CC FLAGS_REG))]
10715 "&& reload_completed"
10716 [(parallel [(set (match_dup 1)
10717 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10718 (clobber (reg:CC FLAGS_REG))])
10719 (parallel [(set (match_dup 0)
10720 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
10722 (mod:SI (match_dup 2) (match_dup 3)))
10723 (use (match_dup 1))
10724 (clobber (reg:CC FLAGS_REG))])]
10726 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10728 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10729 operands[4] = operands[2];
10732 /* Avoid use of cltd in favor of a mov+shift. */
10733 emit_move_insn (operands[1], operands[2]);
10734 operands[4] = operands[1];
10737 [(set_attr "type" "multi")
10738 (set_attr "mode" "SI")])
10740 (define_insn_and_split "udivmodsi4_zext_1"
10741 [(set (match_operand:DI 0 "register_operand" "=a")
10743 (udiv:SI (match_operand:SI 2 "register_operand" "0")
10744 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10745 (set (match_operand:SI 1 "register_operand" "=&d")
10746 (umod:SI (match_dup 2) (match_dup 3)))
10747 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10748 (clobber (reg:CC FLAGS_REG))]
10751 "&& reload_completed"
10752 [(set (match_dup 1) (const_int 0))
10753 (parallel [(set (match_dup 0)
10754 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
10756 (umod:SI (match_dup 2) (match_dup 3)))
10757 (use (match_dup 1))
10758 (clobber (reg:CC FLAGS_REG))])]
10760 [(set_attr "type" "multi")
10761 (set_attr "mode" "SI")])
10763 (define_insn_and_split "divmodsi4_zext_2"
10764 [(set (match_operand:DI 1 "register_operand" "=&d")
10766 (mod:SI (match_operand:SI 2 "register_operand" "0")
10767 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10768 (set (match_operand:SI 0 "register_operand" "=a")
10769 (div:SI (match_dup 2) (match_dup 3)))
10770 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10771 (clobber (reg:CC FLAGS_REG))]
10774 "&& reload_completed"
10775 [(parallel [(set (match_dup 6)
10776 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10777 (clobber (reg:CC FLAGS_REG))])
10778 (parallel [(set (match_dup 1)
10779 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
10781 (div:SI (match_dup 2) (match_dup 3)))
10782 (use (match_dup 6))
10783 (clobber (reg:CC FLAGS_REG))])]
10785 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10786 operands[6] = gen_lowpart (SImode, operands[1]);
10788 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10789 operands[4] = operands[2];
10792 /* Avoid use of cltd in favor of a mov+shift. */
10793 emit_move_insn (operands[6], operands[2]);
10794 operands[4] = operands[6];
10797 [(set_attr "type" "multi")
10798 (set_attr "mode" "SI")])
10800 (define_insn_and_split "udivmodsi4_zext_2"
10801 [(set (match_operand:DI 1 "register_operand" "=&d")
10803 (umod:SI (match_operand:SI 2 "register_operand" "0")
10804 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10805 (set (match_operand:SI 0 "register_operand" "=a")
10806 (udiv:SI (match_dup 2) (match_dup 3)))
10807 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10808 (clobber (reg:CC FLAGS_REG))]
10811 "&& reload_completed"
10812 [(set (match_dup 4) (const_int 0))
10813 (parallel [(set (match_dup 1)
10814 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
10816 (udiv:SI (match_dup 2) (match_dup 3)))
10817 (use (match_dup 4))
10818 (clobber (reg:CC FLAGS_REG))])]
10819 "operands[4] = gen_lowpart (SImode, operands[1]);"
10820 [(set_attr "type" "multi")
10821 (set_attr "mode" "SI")])
10823 (define_insn_and_split "*divmod<mode>4"
10824 [(set (match_operand:SWIM248 0 "register_operand" "=a")
10825 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
10826 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
10827 (set (match_operand:SWIM248 1 "register_operand" "=&d")
10828 (mod:SWIM248 (match_dup 2) (match_dup 3)))
10829 (clobber (reg:CC FLAGS_REG))]
10833 [(parallel [(set (match_dup 1)
10834 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
10835 (clobber (reg:CC FLAGS_REG))])
10836 (parallel [(set (match_dup 0)
10837 (div:SWIM248 (match_dup 2) (match_dup 3)))
10839 (mod:SWIM248 (match_dup 2) (match_dup 3)))
10840 (use (match_dup 1))
10841 (clobber (reg:CC FLAGS_REG))])]
10843 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
10845 if (<MODE>mode != HImode
10846 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
10847 operands[4] = operands[2];
10850 /* Avoid use of cltd in favor of a mov+shift. */
10851 emit_move_insn (operands[1], operands[2]);
10852 operands[4] = operands[1];
10855 [(set_attr "type" "multi")
10856 (set_attr "mode" "<MODE>")])
10858 (define_insn_and_split "*udivmod<mode>4"
10859 [(set (match_operand:SWIM248 0 "register_operand" "=a")
10860 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
10861 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
10862 (set (match_operand:SWIM248 1 "register_operand" "=&d")
10863 (umod:SWIM248 (match_dup 2) (match_dup 3)))
10864 (clobber (reg:CC FLAGS_REG))]
10868 [(set (match_dup 1) (const_int 0))
10869 (parallel [(set (match_dup 0)
10870 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
10872 (umod:SWIM248 (match_dup 2) (match_dup 3)))
10873 (use (match_dup 1))
10874 (clobber (reg:CC FLAGS_REG))])]
10876 [(set_attr "type" "multi")
10877 (set_attr "mode" "<MODE>")])
10879 ;; Optimize division or modulo by constant power of 2, if the constant
10880 ;; materializes only after expansion.
10881 (define_insn_and_split "*udivmod<mode>4_pow2"
10882 [(set (match_operand:SWI48 0 "register_operand" "=r")
10883 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
10884 (match_operand:SWI48 3 "const_int_operand")))
10885 (set (match_operand:SWI48 1 "register_operand" "=r")
10886 (umod:SWI48 (match_dup 2) (match_dup 3)))
10887 (clobber (reg:CC FLAGS_REG))]
10888 "IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
10890 "&& reload_completed"
10891 [(set (match_dup 1) (match_dup 2))
10892 (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
10893 (clobber (reg:CC FLAGS_REG))])
10894 (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
10895 (clobber (reg:CC FLAGS_REG))])]
10897 int v = exact_log2 (UINTVAL (operands[3]));
10898 operands[4] = GEN_INT (v);
10899 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
10901 [(set_attr "type" "multi")
10902 (set_attr "mode" "<MODE>")])
10904 (define_insn_and_split "*divmodsi4_zext_1"
10905 [(set (match_operand:DI 0 "register_operand" "=a")
10907 (div:SI (match_operand:SI 2 "register_operand" "0")
10908 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10909 (set (match_operand:SI 1 "register_operand" "=&d")
10910 (mod:SI (match_dup 2) (match_dup 3)))
10911 (clobber (reg:CC FLAGS_REG))]
10914 "&& reload_completed"
10915 [(parallel [(set (match_dup 1)
10916 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10917 (clobber (reg:CC FLAGS_REG))])
10918 (parallel [(set (match_dup 0)
10919 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
10921 (mod:SI (match_dup 2) (match_dup 3)))
10922 (use (match_dup 1))
10923 (clobber (reg:CC FLAGS_REG))])]
10925 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10927 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10928 operands[4] = operands[2];
10931 /* Avoid use of cltd in favor of a mov+shift. */
10932 emit_move_insn (operands[1], operands[2]);
10933 operands[4] = operands[1];
10936 [(set_attr "type" "multi")
10937 (set_attr "mode" "SI")])
10939 (define_insn_and_split "*udivmodsi4_zext_1"
10940 [(set (match_operand:DI 0 "register_operand" "=a")
10942 (udiv:SI (match_operand:SI 2 "register_operand" "0")
10943 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10944 (set (match_operand:SI 1 "register_operand" "=&d")
10945 (umod:SI (match_dup 2) (match_dup 3)))
10946 (clobber (reg:CC FLAGS_REG))]
10949 "&& reload_completed"
10950 [(set (match_dup 1) (const_int 0))
10951 (parallel [(set (match_dup 0)
10952 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
10954 (umod:SI (match_dup 2) (match_dup 3)))
10955 (use (match_dup 1))
10956 (clobber (reg:CC FLAGS_REG))])]
10958 [(set_attr "type" "multi")
10959 (set_attr "mode" "SI")])
10961 (define_insn_and_split "*udivmodsi4_pow2_zext_1"
10962 [(set (match_operand:DI 0 "register_operand" "=r")
10964 (udiv:SI (match_operand:SI 2 "register_operand" "0")
10965 (match_operand:SI 3 "const_int_operand"))))
10966 (set (match_operand:SI 1 "register_operand" "=r")
10967 (umod:SI (match_dup 2) (match_dup 3)))
10968 (clobber (reg:CC FLAGS_REG))]
10970 && IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
10972 "&& reload_completed"
10973 [(set (match_dup 1) (match_dup 2))
10974 (parallel [(set (match_dup 0)
10975 (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4))))
10976 (clobber (reg:CC FLAGS_REG))])
10977 (parallel [(set (match_dup 1) (and:SI (match_dup 1) (match_dup 5)))
10978 (clobber (reg:CC FLAGS_REG))])]
10980 int v = exact_log2 (UINTVAL (operands[3]));
10981 operands[4] = GEN_INT (v);
10982 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
10984 [(set_attr "type" "multi")
10985 (set_attr "mode" "SI")])
10987 (define_insn_and_split "*divmodsi4_zext_2"
10988 [(set (match_operand:DI 1 "register_operand" "=&d")
10990 (mod:SI (match_operand:SI 2 "register_operand" "0")
10991 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10992 (set (match_operand:SI 0 "register_operand" "=a")
10993 (div:SI (match_dup 2) (match_dup 3)))
10994 (clobber (reg:CC FLAGS_REG))]
10997 "&& reload_completed"
10998 [(parallel [(set (match_dup 6)
10999 (ashiftrt:SI (match_dup 4) (match_dup 5)))
11000 (clobber (reg:CC FLAGS_REG))])
11001 (parallel [(set (match_dup 1)
11002 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
11004 (div:SI (match_dup 2) (match_dup 3)))
11005 (use (match_dup 6))
11006 (clobber (reg:CC FLAGS_REG))])]
11008 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
11009 operands[6] = gen_lowpart (SImode, operands[1]);
11011 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
11012 operands[4] = operands[2];
11015 /* Avoid use of cltd in favor of a mov+shift. */
11016 emit_move_insn (operands[6], operands[2]);
11017 operands[4] = operands[6];
11020 [(set_attr "type" "multi")
11021 (set_attr "mode" "SI")])
11023 (define_insn_and_split "*udivmodsi4_zext_2"
11024 [(set (match_operand:DI 1 "register_operand" "=&d")
11026 (umod:SI (match_operand:SI 2 "register_operand" "0")
11027 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
11028 (set (match_operand:SI 0 "register_operand" "=a")
11029 (udiv:SI (match_dup 2) (match_dup 3)))
11030 (clobber (reg:CC FLAGS_REG))]
11033 "&& reload_completed"
11034 [(set (match_dup 4) (const_int 0))
11035 (parallel [(set (match_dup 1)
11036 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
11038 (udiv:SI (match_dup 2) (match_dup 3)))
11039 (use (match_dup 4))
11040 (clobber (reg:CC FLAGS_REG))])]
11041 "operands[4] = gen_lowpart (SImode, operands[1]);"
11042 [(set_attr "type" "multi")
11043 (set_attr "mode" "SI")])
11045 (define_insn_and_split "*udivmodsi4_pow2_zext_2"
11046 [(set (match_operand:DI 1 "register_operand" "=r")
11048 (umod:SI (match_operand:SI 2 "register_operand" "0")
11049 (match_operand:SI 3 "const_int_operand"))))
11050 (set (match_operand:SI 0 "register_operand" "=r")
11051 (udiv:SI (match_dup 2) (match_dup 3)))
11052 (clobber (reg:CC FLAGS_REG))]
11054 && IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
11056 "&& reload_completed"
11057 [(set (match_dup 1) (match_dup 2))
11058 (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4)))
11059 (clobber (reg:CC FLAGS_REG))])
11060 (parallel [(set (match_dup 1)
11061 (zero_extend:DI (and:SI (match_dup 1) (match_dup 5))))
11062 (clobber (reg:CC FLAGS_REG))])]
11064 int v = exact_log2 (UINTVAL (operands[3]));
11065 operands[4] = GEN_INT (v);
11066 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
11068 [(set_attr "type" "multi")
11069 (set_attr "mode" "SI")])
11071 (define_insn "*<u>divmod<mode>4_noext"
11072 [(set (match_operand:SWIM248 0 "register_operand" "=a")
11074 (match_operand:SWIM248 2 "register_operand" "0")
11075 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
11076 (set (match_operand:SWIM248 1 "register_operand" "=d")
11077 (<paired_mod>:SWIM248 (match_dup 2) (match_dup 3)))
11078 (use (match_operand:SWIM248 4 "register_operand" "1"))
11079 (clobber (reg:CC FLAGS_REG))]
11081 "<sgnprefix>div{<imodesuffix>}\t%3"
11082 [(set_attr "type" "idiv")
11083 (set_attr "mode" "<MODE>")])
11085 (define_insn "*<u>divmodsi4_noext_zext_1"
11086 [(set (match_operand:DI 0 "register_operand" "=a")
11088 (any_div:SI (match_operand:SI 2 "register_operand" "0")
11089 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
11090 (set (match_operand:SI 1 "register_operand" "=d")
11091 (<paired_mod>:SI (match_dup 2) (match_dup 3)))
11092 (use (match_operand:SI 4 "register_operand" "1"))
11093 (clobber (reg:CC FLAGS_REG))]
11095 "<sgnprefix>div{l}\t%3"
11096 [(set_attr "type" "idiv")
11097 (set_attr "mode" "SI")])
11099 (define_insn "*<u>divmodsi4_noext_zext_2"
11100 [(set (match_operand:DI 1 "register_operand" "=d")
11102 (<paired_mod>:SI (match_operand:SI 2 "register_operand" "0")
11103 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
11104 (set (match_operand:SI 0 "register_operand" "=a")
11105 (any_div:SI (match_dup 2) (match_dup 3)))
11106 (use (match_operand:SI 4 "register_operand" "1"))
11107 (clobber (reg:CC FLAGS_REG))]
11109 "<sgnprefix>div{l}\t%3"
11110 [(set_attr "type" "idiv")
11111 (set_attr "mode" "SI")])
11113 ;; Avoid sign-extension (using cdq) for constant numerators.
11114 (define_insn_and_split "*divmodsi4_const"
11115 [(set (match_operand:SI 0 "register_operand" "=&a")
11116 (div:SI (match_operand:SI 2 "const_int_operand")
11117 (match_operand:SI 3 "nonimmediate_operand" "rm")))
11118 (set (match_operand:SI 1 "register_operand" "=&d")
11119 (mod:SI (match_dup 2) (match_dup 3)))
11120 (clobber (reg:CC FLAGS_REG))]
11121 "!optimize_function_for_size_p (cfun)"
11123 "&& reload_completed"
11124 [(set (match_dup 0) (match_dup 2))
11125 (set (match_dup 1) (match_dup 4))
11126 (parallel [(set (match_dup 0)
11127 (div:SI (match_dup 0) (match_dup 3)))
11129 (mod:SI (match_dup 0) (match_dup 3)))
11130 (use (match_dup 1))
11131 (clobber (reg:CC FLAGS_REG))])]
11133 operands[4] = INTVAL (operands[2]) < 0 ? constm1_rtx : const0_rtx;
11135 [(set_attr "type" "multi")
11136 (set_attr "mode" "SI")])
11138 (define_expand "divmodqi4"
11139 [(parallel [(set (match_operand:QI 0 "register_operand")
11141 (match_operand:QI 1 "register_operand")
11142 (match_operand:QI 2 "nonimmediate_operand")))
11143 (set (match_operand:QI 3 "register_operand")
11144 (mod:QI (match_dup 1) (match_dup 2)))
11145 (clobber (reg:CC FLAGS_REG))])]
11146 "TARGET_QIMODE_MATH"
11151 tmp0 = gen_reg_rtx (HImode);
11152 tmp1 = gen_reg_rtx (HImode);
11154 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
11155 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
11156 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
11158 /* Extract remainder from AH. */
11159 tmp1 = gen_rtx_ZERO_EXTRACT (HImode, tmp0, GEN_INT (8), GEN_INT (8));
11160 tmp1 = lowpart_subreg (QImode, tmp1, HImode);
11161 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
11163 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
11164 set_unique_reg_note (insn, REG_EQUAL, mod);
11166 /* Extract quotient from AL. */
11167 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
11169 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
11170 set_unique_reg_note (insn, REG_EQUAL, div);
11175 (define_expand "udivmodqi4"
11176 [(parallel [(set (match_operand:QI 0 "register_operand")
11178 (match_operand:QI 1 "register_operand")
11179 (match_operand:QI 2 "nonimmediate_operand")))
11180 (set (match_operand:QI 3 "register_operand")
11181 (umod:QI (match_dup 1) (match_dup 2)))
11182 (clobber (reg:CC FLAGS_REG))])]
11183 "TARGET_QIMODE_MATH"
11188 tmp0 = gen_reg_rtx (HImode);
11189 tmp1 = gen_reg_rtx (HImode);
11191 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
11192 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
11193 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
11195 /* Extract remainder from AH. */
11196 tmp1 = gen_rtx_ZERO_EXTRACT (HImode, tmp0, GEN_INT (8), GEN_INT (8));
11197 tmp1 = lowpart_subreg (QImode, tmp1, HImode);
11198 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
11200 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
11201 set_unique_reg_note (insn, REG_EQUAL, mod);
11203 /* Extract quotient from AL. */
11204 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
11206 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
11207 set_unique_reg_note (insn, REG_EQUAL, div);
11212 ;; Divide AX by r/m8, with result stored in
11215 ;; Change div/mod to HImode and extend the second argument to HImode
11216 ;; so that mode of div/mod matches with mode of arguments. Otherwise
11217 ;; combine may fail.
11218 (define_insn "<u>divmodhiqi3"
11219 [(set (match_operand:HI 0 "register_operand" "=a")
11224 (mod:HI (match_operand:HI 1 "register_operand" "0")
11226 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
11230 (div:HI (match_dup 1) (any_extend:HI (match_dup 2)))))))
11231 (clobber (reg:CC FLAGS_REG))]
11232 "TARGET_QIMODE_MATH"
11233 "<sgnprefix>div{b}\t%2"
11234 [(set_attr "type" "idiv")
11235 (set_attr "mode" "QI")])
11237 ;; We cannot use div/idiv for double division, because it causes
11238 ;; "division by zero" on the overflow and that's not what we expect
11239 ;; from truncate. Because true (non truncating) double division is
11240 ;; never generated, we can't create this insn anyway.
11243 ; [(set (match_operand:SI 0 "register_operand" "=a")
11245 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
11247 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
11248 ; (set (match_operand:SI 3 "register_operand" "=d")
11250 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
11251 ; (clobber (reg:CC FLAGS_REG))]
11253 ; "div{l}\t{%2, %0|%0, %2}"
11254 ; [(set_attr "type" "idiv")])
11256 ;;- Logical AND instructions
11258 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
11259 ;; Note that this excludes ah.
11261 (define_expand "@test<mode>_ccno_1"
11262 [(set (reg:CCNO FLAGS_REG)
11265 (match_operand:SWI48 0 "nonimmediate_operand")
11266 (match_operand:SWI48 1 "<nonmemory_szext_operand>"))
11269 (define_expand "testqi_ccz_1"
11270 [(set (reg:CCZ FLAGS_REG)
11273 (match_operand:QI 0 "nonimmediate_operand")
11274 (match_operand:QI 1 "nonmemory_operand"))
11277 (define_insn "*testdi_1"
11278 [(set (reg FLAGS_REG)
11281 (match_operand:DI 0 "nonimmediate_operand" "%r,rm")
11282 (match_operand:DI 1 "x86_64_szext_nonmemory_operand" "Z,re"))
11285 && ix86_match_ccmode
11287 /* If we are going to emit testl instead of testq, and the operands[1]
11288 constant might have the SImode sign bit set, make sure the sign
11289 flag isn't tested, because the instruction will set the sign flag
11290 based on bit 31 rather than bit 63. If it isn't CONST_INT,
11291 conservatively assume it might have bit 31 set. */
11292 (satisfies_constraint_Z (operands[1])
11293 && (!CONST_INT_P (operands[1])
11294 || val_signbit_known_set_p (SImode, INTVAL (operands[1]))))
11295 ? CCZmode : CCNOmode)"
11297 test{l}\t{%k1, %k0|%k0, %k1}
11298 test{q}\t{%1, %0|%0, %1}"
11299 [(set_attr "type" "test")
11300 (set_attr "mode" "SI,DI")])
11302 (define_insn "*testqi_1_maybe_si"
11303 [(set (reg FLAGS_REG)
11306 (match_operand:QI 0 "nonimmediate_operand" "%qm,qm,r")
11307 (match_operand:QI 1 "nonmemory_operand" "q,n,n"))
11309 "ix86_match_ccmode (insn,
11310 CONST_INT_P (operands[1])
11311 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
11313 if (get_attr_mode (insn) == MODE_SI)
11315 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
11316 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
11317 return "test{l}\t{%1, %k0|%k0, %1}";
11319 return "test{b}\t{%1, %0|%0, %1}";
11321 [(set_attr "type" "test")
11323 (cond [(eq_attr "alternative" "2")
11324 (const_string "SI")
11325 (and (match_test "optimize_insn_for_size_p ()")
11326 (and (match_operand 0 "ext_QIreg_operand")
11327 (match_operand 1 "const_0_to_127_operand")))
11328 (const_string "SI")
11330 (const_string "QI")))
11331 (set_attr "pent_pair" "uv,np,np")])
11333 (define_insn "*test<mode>_1"
11334 [(set (reg FLAGS_REG)
11337 (match_operand:SWI124 0 "nonimmediate_operand" "%<r>m,*a,<r>m")
11338 (match_operand:SWI124 1 "<nonmemory_szext_operand>" "<r>,<i>,<i>"))
11340 "ix86_match_ccmode (insn, CCNOmode)"
11341 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
11342 [(set_attr "type" "test")
11343 (set_attr "mode" "<MODE>")
11344 (set_attr "pent_pair" "uv,uv,np")])
11346 (define_expand "testqi_ext_1_ccno"
11347 [(set (reg:CCNO FLAGS_REG)
11352 (match_operand:HI 0 "register_operand")
11355 (match_operand:QI 1 "const_int_operand"))
11358 (define_insn "*testqi_ext<mode>_1"
11359 [(set (reg FLAGS_REG)
11363 (match_operator:SWI248 2 "extract_operator"
11364 [(match_operand 0 "int248_register_operand" "Q")
11367 (match_operand:QI 1 "general_operand" "QnBn"))
11369 "ix86_match_ccmode (insn, CCNOmode)"
11370 "test{b}\t{%1, %h0|%h0, %1}"
11371 [(set_attr "addr" "gpr8")
11372 (set_attr "type" "test")
11373 (set_attr "mode" "QI")])
11375 (define_insn "*testqi_ext<mode>_2"
11376 [(set (reg FLAGS_REG)
11380 (match_operator:SWI248 2 "extract_operator"
11381 [(match_operand 0 "int248_register_operand" "Q")
11385 (match_operator:SWI248 3 "extract_operator"
11386 [(match_operand 1 "int248_register_operand" "Q")
11388 (const_int 8)]) 0))
11390 "ix86_match_ccmode (insn, CCNOmode)"
11391 "test{b}\t{%h1, %h0|%h0, %h1}"
11392 [(set_attr "type" "test")
11393 (set_attr "mode" "QI")])
11395 ;; Provide a *testti instruction that STV can implement using ptest.
11396 ;; This pattern splits into *andti3_doubleword and *cmpti_doubleword.
11397 (define_insn_and_split "*testti_doubleword"
11398 [(set (reg:CCZ FLAGS_REG)
11400 (and:TI (match_operand:TI 0 "register_operand")
11401 (match_operand:TI 1 "general_operand"))
11404 && ix86_pre_reload_split ()"
11407 [(parallel [(set (match_dup 2) (and:TI (match_dup 0) (match_dup 1)))
11408 (clobber (reg:CC FLAGS_REG))])
11409 (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 2) (const_int 0)))]
11411 operands[2] = gen_reg_rtx (TImode);
11412 if (!x86_64_hilo_general_operand (operands[1], TImode))
11413 operands[1] = force_reg (TImode, operands[1]);
11416 ;; Combine likes to form bit extractions for some tests. Humor it.
11417 (define_insn_and_split "*testqi_ext_3"
11418 [(set (match_operand 0 "flags_reg_operand")
11419 (match_operator 1 "compare_operator"
11420 [(zero_extract:SWI248
11421 (match_operand 2 "int_nonimmediate_operand" "rm")
11422 (match_operand:QI 3 "const_int_operand")
11423 (match_operand:QI 4 "const_int_operand"))
11425 "/* Ensure that resulting mask is zero or sign extended operand. */
11426 INTVAL (operands[4]) >= 0
11427 && ((INTVAL (operands[3]) > 0
11428 && INTVAL (operands[3]) + INTVAL (operands[4]) <= 32)
11429 || (<MODE>mode == DImode
11430 && INTVAL (operands[3]) > 32
11431 && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))
11432 && ix86_match_ccmode (insn,
11433 /* If zero_extract mode precision is the same
11434 as len, the SF of the zero_extract
11435 comparison will be the most significant
11436 extracted bit, but this could be matched
11437 after splitting only for pos 0 len all bits
11438 trivial extractions. Require CCZmode. */
11439 (GET_MODE_PRECISION (<MODE>mode)
11440 == INTVAL (operands[3]))
11441 /* Otherwise, require CCZmode if we'd use a mask
11442 with the most significant bit set and can't
11443 widen it to wider mode. *testdi_1 also
11444 requires CCZmode if the mask has bit
11445 31 set and all bits above it clear. */
11446 || (INTVAL (operands[3]) + INTVAL (operands[4])
11448 /* We can't widen also if val is not a REG. */
11449 || (INTVAL (operands[3]) + INTVAL (operands[4])
11450 == GET_MODE_PRECISION (GET_MODE (operands[2]))
11451 && !register_operand (operands[2],
11452 GET_MODE (operands[2])))
11453 /* And we shouldn't widen if
11454 TARGET_PARTIAL_REG_STALL. */
11455 || (TARGET_PARTIAL_REG_STALL
11456 && (INTVAL (operands[3]) + INTVAL (operands[4])
11457 >= (paradoxical_subreg_p (operands[2])
11459 (GET_MODE (SUBREG_REG (operands[2])))
11461 ? GET_MODE_PRECISION
11462 (GET_MODE (SUBREG_REG (operands[2])))
11463 : GET_MODE_PRECISION
11464 (GET_MODE (operands[2])))))
11465 ? CCZmode : CCNOmode)"
11468 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11470 rtx val = operands[2];
11471 HOST_WIDE_INT len = INTVAL (operands[3]);
11472 HOST_WIDE_INT pos = INTVAL (operands[4]);
11473 machine_mode mode = GET_MODE (val);
11475 if (SUBREG_P (val))
11477 machine_mode submode = GET_MODE (SUBREG_REG (val));
11479 /* Narrow paradoxical subregs to prevent partial register stalls. */
11480 if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)
11481 && GET_MODE_CLASS (submode) == MODE_INT
11482 && (GET_MODE (operands[0]) == CCZmode
11483 || pos + len < GET_MODE_PRECISION (submode)
11484 || REG_P (SUBREG_REG (val))))
11486 val = SUBREG_REG (val);
11491 /* Small HImode tests can be converted to QImode. */
11493 && register_operand (val, HImode))
11495 rtx nval = gen_lowpart (QImode, val);
11497 || GET_MODE (operands[0]) == CCZmode
11505 gcc_assert (pos + len <= GET_MODE_PRECISION (mode));
11507 /* If the mask is going to have the sign bit set in the mode
11508 we want to do the comparison in and user isn't interested just
11509 in the zero flag, then we must widen the target mode. */
11510 if (pos + len == GET_MODE_PRECISION (mode)
11511 && GET_MODE (operands[0]) != CCZmode)
11513 gcc_assert (pos + len < 32 && !MEM_P (val));
11515 val = gen_lowpart (mode, val);
11519 = wi::shifted_mask (pos, len, false, GET_MODE_PRECISION (mode));
11521 operands[2] = gen_rtx_AND (mode, val, immed_wide_int_const (mask, mode));
11524 ;; Split and;cmp (as optimized by combine) into not;test
11525 ;; Except when TARGET_BMI provides andn (*andn_<mode>_ccno).
11526 (define_insn_and_split "*test<mode>_not"
11527 [(set (reg:CCZ FLAGS_REG)
11530 (not:SWI (match_operand:SWI 0 "register_operand"))
11531 (match_operand:SWI 1 "<nonmemory_szext_operand>"))
11533 "ix86_pre_reload_split ()
11534 && (!TARGET_BMI || !REG_P (operands[1]))"
11537 [(set (match_dup 2) (not:SWI (match_dup 0)))
11538 (set (reg:CCZ FLAGS_REG)
11539 (compare:CCZ (and:SWI (match_dup 2) (match_dup 1))
11541 "operands[2] = gen_reg_rtx (<MODE>mode);")
11543 ;; Split and;cmp (as optimized by combine) into andn;cmp $0
11544 (define_insn_and_split "*test<mode>_not_doubleword"
11545 [(set (reg:CCZ FLAGS_REG)
11548 (not:DWI (match_operand:DWI 0 "nonimmediate_operand"))
11549 (match_operand:DWI 1 "nonimmediate_operand"))
11551 "ix86_pre_reload_split ()"
11555 [(set (match_dup 2) (and:DWI (not:DWI (match_dup 0)) (match_dup 1)))
11556 (clobber (reg:CC FLAGS_REG))])
11557 (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 2) (const_int 0)))]
11559 operands[0] = force_reg (<MODE>mode, operands[0]);
11560 operands[2] = gen_reg_rtx (<MODE>mode);
11563 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
11564 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
11565 ;; this is relatively important trick.
11566 ;; Do the conversion only post-reload to avoid limiting of the register class
11569 [(set (match_operand 0 "flags_reg_operand")
11570 (match_operator 1 "compare_operator"
11571 [(and (match_operand 2 "QIreg_operand")
11572 (match_operand 3 "const_int_operand"))
11575 && GET_MODE (operands[2]) != QImode
11576 && ((ix86_match_ccmode (insn, CCZmode)
11577 && !(INTVAL (operands[3]) & ~(255 << 8)))
11578 || (ix86_match_ccmode (insn, CCNOmode)
11579 && !(INTVAL (operands[3]) & ~(127 << 8))))"
11580 [(set (match_dup 0)
11584 (zero_extract:HI (match_dup 2)
11590 operands[2] = gen_lowpart (HImode, operands[2]);
11591 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, QImode);
11595 [(set (match_operand 0 "flags_reg_operand")
11596 (match_operator 1 "compare_operator"
11597 [(and (match_operand 2 "nonimmediate_operand")
11598 (match_operand 3 "const_int_operand"))
11601 && GET_MODE (operands[2]) != QImode
11602 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
11603 && ((ix86_match_ccmode (insn, CCZmode)
11604 && !(INTVAL (operands[3]) & ~255))
11605 || (ix86_match_ccmode (insn, CCNOmode)
11606 && !(INTVAL (operands[3]) & ~127)))"
11607 [(set (match_dup 0)
11608 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
11611 operands[2] = gen_lowpart (QImode, operands[2]);
11612 operands[3] = gen_int_mode (INTVAL (operands[3]), QImode);
11615 ;; Narrow test instructions with immediate operands that test
11616 ;; memory locations for zero. E.g. testl $0x00aa0000, mem can be
11617 ;; converted to testb $0xaa, mem+2. Reject volatile locations and
11618 ;; targets where reading (possibly unaligned) part of memory
11619 ;; location after a large write to the same address causes
11620 ;; store-to-load forwarding stall.
11622 [(set (reg:CCZ FLAGS_REG)
11624 (and:SWI248 (match_operand:SWI248 0 "memory_operand")
11625 (match_operand 1 "const_int_operand"))
11627 "!TARGET_PARTIAL_MEMORY_READ_STALL && !MEM_VOLATILE_P (operands[0])"
11628 [(set (reg:CCZ FLAGS_REG)
11629 (compare:CCZ (match_dup 2) (const_int 0)))]
11631 unsigned HOST_WIDE_INT ival = UINTVAL (operands[1]);
11632 int first_nonzero_byte, bitsize;
11633 rtx new_addr, new_const;
11634 machine_mode new_mode;
11639 /* Clear bits outside mode width. */
11640 ival &= GET_MODE_MASK (<MODE>mode);
11642 first_nonzero_byte = ctz_hwi (ival) / BITS_PER_UNIT;
11644 ival >>= first_nonzero_byte * BITS_PER_UNIT;
11646 bitsize = sizeof (ival) * BITS_PER_UNIT - clz_hwi (ival);
11648 if (bitsize <= GET_MODE_BITSIZE (QImode))
11650 else if (bitsize <= GET_MODE_BITSIZE (HImode))
11652 else if (bitsize <= GET_MODE_BITSIZE (SImode))
11657 if (GET_MODE_SIZE (new_mode) >= GET_MODE_SIZE (<MODE>mode))
11660 new_addr = adjust_address (operands[0], new_mode, first_nonzero_byte);
11661 new_const = gen_int_mode (ival, new_mode);
11663 operands[2] = gen_rtx_AND (new_mode, new_addr, new_const);
11666 ;; %%% This used to optimize known byte-wide and operations to memory,
11667 ;; and sometimes to QImode registers. If this is considered useful,
11668 ;; it should be done with splitters.
11670 (define_expand "and<mode>3"
11671 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
11672 (and:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
11673 (match_operand:SDWIM 2 "<general_szext_operand>")))]
11676 machine_mode mode = <MODE>mode;
11678 if (GET_MODE_SIZE (<MODE>mode) > UNITS_PER_WORD
11679 && !x86_64_hilo_general_operand (operands[2], <MODE>mode))
11680 operands[2] = force_reg (<MODE>mode, operands[2]);
11682 if (GET_MODE_SIZE (<MODE>mode) <= UNITS_PER_WORD
11683 && const_int_operand (operands[2], <MODE>mode)
11684 && register_operand (operands[0], <MODE>mode)
11685 && !(TARGET_ZERO_EXTEND_WITH_AND
11686 && optimize_function_for_speed_p (cfun)))
11688 unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
11690 if (ival == GET_MODE_MASK (SImode))
11692 else if (ival == GET_MODE_MASK (HImode))
11694 else if (ival == GET_MODE_MASK (QImode))
11698 if (mode != <MODE>mode)
11699 emit_insn (gen_extend_insn
11700 (operands[0], gen_lowpart (mode, operands[1]),
11701 <MODE>mode, mode, 1));
11703 ix86_expand_binary_operator (AND, <MODE>mode, operands, TARGET_APX_NDD);
11708 (define_insn_and_split "*and<dwi>3_doubleword"
11709 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,&r,&r,&r,&r,&r")
11711 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0,ro,r,ro,jO,r")
11712 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o,r,<di>,K,<di>,o")))
11713 (clobber (reg:CC FLAGS_REG))]
11714 "ix86_binary_operator_ok (AND, <DWI>mode, operands, TARGET_APX_NDD)"
11716 "&& reload_completed"
11717 [(const_int:DWIH 0)]
11719 bool emit_insn_deleted_note_p = false;
11721 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
11723 if (operands[2] == const0_rtx)
11724 emit_move_insn (operands[0], const0_rtx);
11725 else if (operands[2] == constm1_rtx)
11727 if (!rtx_equal_p (operands[0], operands[1]))
11728 emit_move_insn (operands[0], operands[1]);
11730 emit_insn_deleted_note_p = true;
11733 ix86_expand_binary_operator (AND, <MODE>mode, &operands[0], TARGET_APX_NDD);
11735 if (operands[5] == const0_rtx)
11736 emit_move_insn (operands[3], const0_rtx);
11737 else if (operands[5] == constm1_rtx)
11739 if (!rtx_equal_p (operands[3], operands[4]))
11740 emit_move_insn (operands[3], operands[4]);
11741 else if (emit_insn_deleted_note_p)
11742 emit_note (NOTE_INSN_DELETED);
11745 ix86_expand_binary_operator (AND, <MODE>mode, &operands[3], TARGET_APX_NDD);
11749 [(set_attr "isa" "*,*,apx_ndd,apx_ndd,apx_ndd,apx_ndd_64,apx_ndd")])
11751 (define_insn "*anddi_1"
11752 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm,r,r,r,r,r,?k")
11754 (match_operand:DI 1 "nonimmediate_operand" "%0,r,0,0,rm,rjM,r,qm,k")
11755 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,Z,re,m,r,e,m,L,k")))
11756 (clobber (reg:CC FLAGS_REG))]
11758 && ix86_binary_operator_ok (AND, DImode, operands, TARGET_APX_NDD)"
11760 and{l}\t{%k2, %k0|%k0, %k2}
11761 and{l}\t{%k2, %k1, %k0|%k0, %k1, %k2}
11762 and{q}\t{%2, %0|%0, %2}
11763 and{q}\t{%2, %0|%0, %2}
11764 and{q}\t{%2, %1, %0|%0, %1, %2}
11765 and{q}\t{%2, %1, %0|%0, %1, %2}
11766 and{q}\t{%2, %1, %0|%0, %1, %2}
11769 [(set_attr "isa" "x64,apx_ndd,x64,x64,apx_ndd,apx_ndd,apx_ndd,x64,avx512bw")
11770 (set_attr "type" "alu,alu,alu,alu,alu,alu,alu,imovx,msklog")
11771 (set_attr "length_immediate" "*,*,*,*,*,*,*,0,*")
11772 (set (attr "prefix_rex")
11774 (and (eq_attr "type" "imovx")
11775 (and (match_test "INTVAL (operands[2]) == 0xff")
11776 (match_operand 1 "ext_QIreg_operand")))
11778 (const_string "*")))
11779 (set_attr "mode" "SI,SI,DI,DI,DI,DI,DI,SI,DI")])
11781 (define_insn_and_split "*anddi_1_btr"
11782 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11784 (match_operand:DI 1 "nonimmediate_operand" "%0")
11785 (match_operand:DI 2 "const_int_operand" "n")))
11786 (clobber (reg:CC FLAGS_REG))]
11787 "TARGET_64BIT && TARGET_USE_BT
11788 && ix86_binary_operator_ok (AND, DImode, operands)
11789 && IN_RANGE (exact_log2 (~INTVAL (operands[2])), 31, 63)"
11791 "&& reload_completed"
11792 [(parallel [(set (zero_extract:DI (match_dup 0)
11796 (clobber (reg:CC FLAGS_REG))])]
11797 "operands[3] = GEN_INT (exact_log2 (~INTVAL (operands[2])));"
11798 [(set_attr "type" "alu1")
11799 (set_attr "prefix_0f" "1")
11800 (set_attr "znver1_decode" "double")
11801 (set_attr "mode" "DI")])
11803 ;; Turn *anddi_1 into *andsi_1_zext if possible.
11805 [(set (match_operand:DI 0 "register_operand")
11806 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
11807 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
11808 (clobber (reg:CC FLAGS_REG))]
11810 [(parallel [(set (match_dup 0)
11811 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
11812 (clobber (reg:CC FLAGS_REG))])]
11814 if (GET_CODE (operands[2]) == SYMBOL_REF
11815 || GET_CODE (operands[2]) == LABEL_REF)
11817 operands[2] = shallow_copy_rtx (operands[2]);
11818 PUT_MODE (operands[2], SImode);
11820 else if (GET_CODE (operands[2]) == CONST)
11822 /* (const:DI (plus:DI (symbol_ref:DI ("...")) (const_int N))) */
11823 operands[2] = copy_rtx (operands[2]);
11824 PUT_MODE (operands[2], SImode);
11825 PUT_MODE (XEXP (operands[2], 0), SImode);
11826 PUT_MODE (XEXP (XEXP (operands[2], 0), 0), SImode);
11829 operands[2] = gen_lowpart (SImode, operands[2]);
11832 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
11833 (define_insn "*andsi_1_zext"
11834 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
11836 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,rm,rjM,r")
11837 (match_operand:SI 2 "x86_64_general_operand" "rBMe,r,e,BM"))))
11838 (clobber (reg:CC FLAGS_REG))]
11840 && ix86_binary_operator_ok (AND, SImode, operands, TARGET_APX_NDD)"
11842 and{l}\t{%2, %k0|%k0, %2}
11843 and{l}\t{%2, %1, %k0|%k0, %1, %2}
11844 and{l}\t{%2, %1, %k0|%k0, %1, %2}
11845 and{l}\t{%2, %1, %k0|%k0, %1, %2}"
11846 [(set_attr "type" "alu")
11847 (set_attr "isa" "*,apx_ndd,apx_ndd,apx_ndd")
11848 (set_attr "mode" "SI")])
11850 (define_insn "*and<mode>_1"
11851 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,r,r,r,Ya,?k")
11852 (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,rm,rjM,r,qm,k")
11853 (match_operand:SWI24 2 "<general_operand>" "r<i>,<m>,r,<i>,<m>,L,k")))
11854 (clobber (reg:CC FLAGS_REG))]
11855 "ix86_binary_operator_ok (AND, <MODE>mode, operands, TARGET_APX_NDD)"
11857 and{<imodesuffix>}\t{%2, %0|%0, %2}
11858 and{<imodesuffix>}\t{%2, %0|%0, %2}
11859 and{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
11860 and{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
11861 and{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
11865 (cond [(eq_attr "alternative" "2,3,4")
11866 (const_string "apx_ndd")
11867 (eq_attr "alternative" "6")
11868 (if_then_else (eq_attr "mode" "SI")
11869 (const_string "avx512bw")
11870 (const_string "avx512f"))
11872 (const_string "*")))
11873 (set_attr "type" "alu,alu,alu,alu,alu,imovx,msklog")
11874 (set_attr "length_immediate" "*,*,*,*,*,0,*")
11875 (set (attr "prefix_rex")
11877 (and (eq_attr "type" "imovx")
11878 (and (match_test "INTVAL (operands[2]) == 0xff")
11879 (match_operand 1 "ext_QIreg_operand")))
11881 (const_string "*")))
11882 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<MODE>,SI,<MODE>")])
11884 (define_insn "*andqi_1"
11885 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r,r,?k")
11886 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,rm,r,k")
11887 (match_operand:QI 2 "general_operand" "qn,m,rn,rn,m,k")))
11888 (clobber (reg:CC FLAGS_REG))]
11889 "ix86_binary_operator_ok (AND, QImode, operands, TARGET_APX_NDD)"
11891 and{b}\t{%2, %0|%0, %2}
11892 and{b}\t{%2, %0|%0, %2}
11893 and{l}\t{%k2, %k0|%k0, %k2}
11894 and{b}\t{%2, %1, %0|%0, %1, %2}
11895 and{b}\t{%2, %1, %0|%0, %1, %2}
11897 [(set_attr "type" "alu,alu,alu,alu,alu,msklog")
11898 (set_attr "isa" "*,*,*,apx_ndd,apx_ndd,*")
11900 (cond [(eq_attr "alternative" "2")
11901 (const_string "SI")
11902 (and (eq_attr "alternative" "5")
11903 (match_test "!TARGET_AVX512DQ"))
11904 (const_string "HI")
11906 (const_string "QI")))
11907 ;; Potential partial reg stall on alternative 2.
11908 (set (attr "preferred_for_speed")
11909 (cond [(eq_attr "alternative" "2")
11910 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
11911 (symbol_ref "true")))])
11913 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
11914 (define_insn_and_split "*<code><mode>_1_slp"
11915 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
11916 (any_logic:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0,!<r>")
11917 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
11918 (clobber (reg:CC FLAGS_REG))]
11919 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
11921 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
11923 "&& reload_completed
11924 && !(rtx_equal_p (operands[0], operands[1])
11925 || rtx_equal_p (operands[0], operands[2]))"
11926 [(set (strict_low_part (match_dup 0)) (match_dup 1))
11928 [(set (strict_low_part (match_dup 0))
11929 (any_logic:SWI12 (match_dup 0) (match_dup 2)))
11930 (clobber (reg:CC FLAGS_REG))])]
11932 [(set_attr "type" "alu")
11933 (set_attr "mode" "<MODE>")])
11935 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
11936 (define_insn_and_split "*<code>qi_ext<mode>_1_slp"
11937 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+Q,&Q"))
11940 (match_operator:SWI248 3 "extract_operator"
11941 [(match_operand 2 "int248_register_operand" "Q,Q")
11944 (match_operand:QI 1 "nonimmediate_operand" "0,!qm")))
11945 (clobber (reg:CC FLAGS_REG))]
11946 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
11948 <logic>{b}\t{%h2, %0|%0, %h2}
11950 "&& reload_completed
11951 && !rtx_equal_p (operands[0], operands[1])"
11952 [(set (strict_low_part (match_dup 0)) (match_dup 1))
11954 [(set (strict_low_part (match_dup 0))
11958 [(match_dup 2) (const_int 8) (const_int 8)]) 0)
11960 (clobber (reg:CC FLAGS_REG))])]
11962 [(set_attr "type" "alu")
11963 (set_attr "mode" "QI")])
11965 (define_insn_and_split "*<code>qi_ext<mode>_2_slp"
11966 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+&Q"))
11969 (match_operator:SWI248 3 "extract_operator"
11970 [(match_operand 1 "int248_register_operand" "Q")
11974 (match_operator:SWI248 4 "extract_operator"
11975 [(match_operand 2 "int248_register_operand" "Q")
11977 (const_int 8)]) 0)))
11978 (clobber (reg:CC FLAGS_REG))]
11979 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
11981 "&& reload_completed"
11982 [(set (strict_low_part (match_dup 0))
11985 [(match_dup 2) (const_int 8) (const_int 8)]) 0))
11987 [(set (strict_low_part (match_dup 0))
11991 [(match_dup 1) (const_int 8) (const_int 8)]) 0)
11993 (clobber (reg:CC FLAGS_REG))])]
11995 [(set_attr "type" "alu")
11996 (set_attr "mode" "QI")])
11999 [(set (match_operand:SWI248 0 "register_operand")
12000 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
12001 (match_operand:SWI248 2 "const_int_operand")))
12002 (clobber (reg:CC FLAGS_REG))]
12004 && (!REG_P (operands[1])
12005 || REGNO (operands[0]) != REGNO (operands[1]))
12006 && (UINTVAL (operands[2]) == GET_MODE_MASK (SImode)
12007 || UINTVAL (operands[2]) == GET_MODE_MASK (HImode)
12008 || UINTVAL (operands[2]) == GET_MODE_MASK (QImode))"
12011 unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
12014 if (ival == GET_MODE_MASK (SImode))
12016 else if (ival == GET_MODE_MASK (HImode))
12018 else if (ival == GET_MODE_MASK (QImode))
12021 gcc_unreachable ();
12023 /* Zero extend to SImode to avoid partial register stalls. */
12024 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
12025 operands[0] = gen_lowpart (SImode, operands[0]);
12027 emit_insn (gen_extend_insn
12028 (operands[0], gen_lowpart (mode, operands[1]),
12029 GET_MODE (operands[0]), mode, 1));
12034 [(set (match_operand:SWI48 0 "register_operand")
12035 (and:SWI48 (match_dup 0)
12036 (const_int -65536)))
12037 (clobber (reg:CC FLAGS_REG))]
12038 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
12039 || optimize_function_for_size_p (cfun)"
12040 [(set (strict_low_part (match_dup 1)) (const_int 0))]
12041 "operands[1] = gen_lowpart (HImode, operands[0]);")
12044 [(set (match_operand:SWI248 0 "any_QIreg_operand")
12045 (and:SWI248 (match_dup 0)
12047 (clobber (reg:CC FLAGS_REG))]
12048 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12049 && reload_completed"
12050 [(set (strict_low_part (match_dup 1)) (const_int 0))]
12051 "operands[1] = gen_lowpart (QImode, operands[0]);")
12054 [(set (match_operand:SWI248 0 "QIreg_operand")
12055 (and:SWI248 (match_dup 0)
12056 (const_int -65281)))
12057 (clobber (reg:CC FLAGS_REG))]
12058 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12059 && reload_completed"
12061 [(set (zero_extract:HI (match_dup 0)
12067 (zero_extract:HI (match_dup 0)
12071 (zero_extract:HI (match_dup 0)
12073 (const_int 8)) 0)) 0))
12074 (clobber (reg:CC FLAGS_REG))])]
12075 "operands[0] = gen_lowpart (HImode, operands[0]);")
12077 (define_insn "*anddi_2"
12078 [(set (reg FLAGS_REG)
12081 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,r,rm,r")
12082 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m,Z,re,m"))
12084 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,r,r")
12085 (and:DI (match_dup 1) (match_dup 2)))]
12087 && ix86_match_ccmode
12089 /* If we are going to emit andl instead of andq, and the operands[2]
12090 constant might have the SImode sign bit set, make sure the sign
12091 flag isn't tested, because the instruction will set the sign flag
12092 based on bit 31 rather than bit 63. If it isn't CONST_INT,
12093 conservatively assume it might have bit 31 set. */
12094 (satisfies_constraint_Z (operands[2])
12095 && (!CONST_INT_P (operands[2])
12096 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
12097 ? CCZmode : CCNOmode)
12098 && ix86_binary_operator_ok (AND, DImode, operands, TARGET_APX_NDD)"
12100 and{l}\t{%k2, %k0|%k0, %k2}
12101 and{q}\t{%2, %0|%0, %2}
12102 and{q}\t{%2, %0|%0, %2}
12103 and{l}\t{%k2, %k1, %k0|%k0, %k1, %k2}
12104 and{q}\t{%2, %1, %0|%0, %1, %2}
12105 and{q}\t{%2, %1, %0|%0, %1, %2}"
12106 [(set_attr "type" "alu")
12107 (set_attr "isa" "*,*,*,apx_ndd,apx_ndd,apx_ndd")
12108 (set_attr "mode" "SI,DI,DI,SI,DI,DI")])
12110 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
12111 (define_insn "*andsi_2_zext"
12112 [(set (reg FLAGS_REG)
12114 (match_operand:SI 1 "nonimmediate_operand" "%0,rm,r")
12115 (match_operand:SI 2 "x86_64_general_operand" "rBMe,re,BM"))
12117 (set (match_operand:DI 0 "register_operand" "=r,r,r")
12118 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
12119 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
12120 && ix86_binary_operator_ok (AND, SImode, operands, TARGET_APX_NDD)"
12122 and{l}\t{%2, %k0|%k0, %2}
12123 and{l}\t{%2, %1, %k0|%k0, %1, %2}
12124 and{l}\t{%2, %1, %k0|%k0, %1, %2}"
12125 [(set_attr "type" "alu")
12126 (set_attr "isa" "*,apx_ndd,apx_ndd")
12127 (set_attr "mode" "SI")])
12129 (define_insn "*andqi_2_maybe_si"
12130 [(set (reg FLAGS_REG)
12132 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,rm,r")
12133 (match_operand:QI 2 "general_operand" "qn,m,n,rn,m"))
12135 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r,r")
12136 (and:QI (match_dup 1) (match_dup 2)))]
12137 "ix86_binary_operator_ok (AND, QImode, operands, TARGET_APX_NDD)
12138 && ix86_match_ccmode (insn,
12139 CONST_INT_P (operands[2])
12140 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
12142 if (get_attr_mode (insn) == MODE_SI)
12144 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
12145 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
12146 return "and{l}\t{%2, %k0|%k0, %2}";
12148 if (which_alternative > 2)
12149 return "and{b}\t{%2, %1, %0|%0, %1, %2}";
12150 return "and{b}\t{%2, %0|%0, %2}";
12152 [(set_attr "type" "alu")
12153 (set_attr "isa" "*,*,*,apx_ndd,apx_ndd")
12155 (cond [(eq_attr "alternative" "3,4")
12156 (const_string "QI")
12157 (eq_attr "alternative" "2")
12158 (const_string "SI")
12159 (and (match_test "optimize_insn_for_size_p ()")
12160 (and (match_operand 0 "ext_QIreg_operand")
12161 (match_operand 2 "const_0_to_127_operand")))
12162 (const_string "SI")
12164 (const_string "QI")))
12165 ;; Potential partial reg stall on alternative 2.
12166 (set (attr "preferred_for_speed")
12167 (cond [(eq_attr "alternative" "2")
12168 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
12169 (symbol_ref "true")))])
12171 (define_insn "*and<mode>_2"
12172 [(set (reg FLAGS_REG)
12173 (compare (and:SWI124
12174 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0,rm,r")
12175 (match_operand:SWI124 2 "<general_operand>" "<r><i>,<m>,r<i>,<m>"))
12177 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>m,<r>,r,r")
12178 (and:SWI124 (match_dup 1) (match_dup 2)))]
12179 "ix86_match_ccmode (insn, CCNOmode)
12180 && ix86_binary_operator_ok (AND, <MODE>mode, operands, TARGET_APX_NDD)"
12182 and{<imodesuffix>}\t{%2, %0|%0, %2}
12183 and{<imodesuffix>}\t{%2, %0|%0, %2}
12184 and{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
12185 and{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
12186 [(set_attr "type" "alu")
12187 (set_attr "isa" "*,*,apx_ndd,apx_ndd")
12188 (set_attr "mode" "<MODE>")])
12190 (define_insn "*<code>qi_ext<mode>_0"
12191 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn")
12194 (match_operator:SWI248 3 "extract_operator"
12195 [(match_operand 2 "int248_register_operand" "Q")
12198 (match_operand:QI 1 "nonimmediate_operand" "0")))
12199 (clobber (reg:CC FLAGS_REG))]
12201 "<logic>{b}\t{%h2, %0|%0, %h2}"
12202 [(set_attr "addr" "gpr8")
12203 (set_attr "type" "alu")
12204 (set_attr "mode" "QI")])
12206 (define_insn_and_split "*<code>qi_ext2<mode>_0"
12207 [(set (match_operand:QI 0 "register_operand" "=&Q")
12210 (match_operator:SWI248 3 "extract_operator"
12211 [(match_operand 1 "int248_register_operand" "Q")
12215 (match_operator:SWI248 4 "extract_operator"
12216 [(match_operand 2 "int248_register_operand" "Q")
12218 (const_int 8)]) 0)))
12219 (clobber (reg:CC FLAGS_REG))]
12222 "&& reload_completed"
12223 [(set (match_dup 0)
12226 [(match_dup 2) (const_int 8) (const_int 8)]) 0))
12228 [(set (match_dup 0)
12232 [(match_dup 1) (const_int 8) (const_int 8)]) 0)
12234 (clobber (reg:CC FLAGS_REG))])]
12236 [(set_attr "type" "alu")
12237 (set_attr "mode" "QI")])
12239 (define_expand "andqi_ext_1"
12241 [(set (zero_extract:HI (match_operand:HI 0 "register_operand")
12247 (zero_extract:HI (match_operand:HI 1 "register_operand")
12250 (match_operand:QI 2 "const_int_operand")) 0))
12251 (clobber (reg:CC FLAGS_REG))])])
12253 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
12254 (define_insn_and_split "*<code>qi_ext<mode>_1"
12255 [(set (zero_extract:SWI248
12256 (match_operand 0 "int248_register_operand" "+Q,&Q")
12262 (match_operator:SWI248 3 "extract_operator"
12263 [(match_operand 1 "int248_register_operand" "0,!Q")
12266 (match_operand:QI 2 "general_operand" "QnBn,QnBn")) 0))
12267 (clobber (reg:CC FLAGS_REG))]
12270 <logic>{b}\t{%2, %h0|%h0, %2}
12273 && !(rtx_equal_p (operands[0], operands[1]))"
12274 [(set (zero_extract:SWI248
12275 (match_dup 0) (const_int 8) (const_int 8))
12276 (zero_extract:SWI248
12277 (match_dup 1) (const_int 8) (const_int 8)))
12279 [(set (zero_extract:SWI248
12280 (match_dup 0) (const_int 8) (const_int 8))
12285 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
12287 (clobber (reg:CC FLAGS_REG))])]
12289 [(set_attr "addr" "gpr8")
12290 (set_attr "type" "alu")
12291 (set_attr "mode" "QI")])
12293 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
12294 (define_insn_and_split "*<code>qi_ext<mode>_1_cc"
12295 [(set (match_operand 4 "flags_reg_operand")
12296 (match_operator 5 "compare_operator"
12299 (match_operator:SWI248 3 "extract_operator"
12300 [(match_operand 1 "int248_register_operand" "0,!Q")
12303 (match_operand:QI 2 "general_operand" "QnBn,QnBn"))
12305 (set (zero_extract:SWI248
12306 (match_operand 0 "int248_register_operand" "+Q,&Q")
12313 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
12314 (match_dup 2)) 0))]
12315 "ix86_match_ccmode (insn, CCNOmode)"
12317 <logic>{b}\t{%2, %h0|%h0, %2}
12319 "&& reload_completed
12320 && !(rtx_equal_p (operands[0], operands[1]))"
12321 [(set (zero_extract:SWI248
12322 (match_dup 0) (const_int 8) (const_int 8))
12323 (zero_extract:SWI248
12324 (match_dup 1) (const_int 8) (const_int 8)))
12326 [(set (match_dup 4)
12331 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
12334 (set (zero_extract:SWI248
12335 (match_dup 0) (const_int 8) (const_int 8))
12340 [(match_dup 1) (const_int 8) (const_int 8)]) 0)
12341 (match_dup 2)) 0))])]
12343 [(set_attr "addr" "gpr8")
12344 (set_attr "type" "alu")
12345 (set_attr "mode" "QI")])
12347 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
12348 (define_insn_and_split "*<code>qi_ext<mode>_2"
12349 [(set (zero_extract:SWI248
12350 (match_operand 0 "int248_register_operand" "+Q,&Q")
12356 (match_operator:SWI248 3 "extract_operator"
12357 [(match_operand 1 "int248_register_operand" "%0,!Q")
12361 (match_operator:SWI248 4 "extract_operator"
12362 [(match_operand 2 "int248_register_operand" "Q,Q")
12364 (const_int 8)]) 0)) 0))
12365 (clobber (reg:CC FLAGS_REG))]
12368 <logic>{b}\t{%h2, %h0|%h0, %h2}
12371 && !(rtx_equal_p (operands[0], operands[1])
12372 || rtx_equal_p (operands[0], operands[2]))"
12373 [(set (zero_extract:SWI248
12374 (match_dup 0) (const_int 8) (const_int 8))
12375 (zero_extract:SWI248
12376 (match_dup 1) (const_int 8) (const_int 8)))
12378 [(set (zero_extract:SWI248
12379 (match_dup 0) (const_int 8) (const_int 8))
12384 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
12387 [(match_dup 2) (const_int 8) (const_int 8)]) 0)) 0))
12388 (clobber (reg:CC FLAGS_REG))])]
12390 [(set_attr "type" "alu")
12391 (set_attr "mode" "QI")])
12393 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
12394 (define_insn_and_split "*<code>qi_ext<mode>_3"
12395 [(set (zero_extract:SWI248
12396 (match_operand 0 "int248_register_operand" "+Q,&Q")
12399 (match_operator:SWI248 3 "extract_operator"
12401 (match_operand 1 "int248_register_operand" "%0,!Q")
12402 (match_operand 2 "int248_register_operand" "Q,Q"))
12405 (clobber (reg:CC FLAGS_REG))]
12406 "GET_MODE (operands[1]) == GET_MODE (operands[2])"
12408 <logic>{b}\t{%h2, %h0|%h0, %h2}
12410 "&& reload_completed
12411 && !(rtx_equal_p (operands[0], operands[1])
12412 || rtx_equal_p (operands[0], operands[2]))"
12413 [(set (zero_extract:SWI248
12414 (match_dup 0) (const_int 8) (const_int 8))
12415 (zero_extract:SWI248
12416 (match_dup 1) (const_int 8) (const_int 8)))
12418 [(set (zero_extract:SWI248
12419 (match_dup 0) (const_int 8) (const_int 8))
12421 [(any_logic (match_dup 4) (match_dup 2))
12422 (const_int 8) (const_int 8)]))
12423 (clobber (reg:CC FLAGS_REG))])]
12424 "operands[4] = gen_lowpart (GET_MODE (operands[1]), operands[0]);"
12425 [(set_attr "type" "alu")
12426 (set_attr "mode" "QI")])
12428 ;; Convert wide AND instructions with immediate operand to shorter QImode
12429 ;; equivalents when possible.
12430 ;; Don't do the splitting with memory operands, since it introduces risk
12431 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
12432 ;; for size, but that can (should?) be handled by generic code instead.
12433 ;; Don't do the splitting for APX NDD as NDD does not support *h registers.
12435 [(set (match_operand:SWI248 0 "QIreg_operand")
12436 (and:SWI248 (match_operand:SWI248 1 "register_operand")
12437 (match_operand:SWI248 2 "const_int_operand")))
12438 (clobber (reg:CC FLAGS_REG))]
12440 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12441 && !(~INTVAL (operands[2]) & ~(255 << 8))
12442 && !(TARGET_APX_NDD && REGNO (operands[0]) != REGNO (operands[1]))"
12444 [(set (zero_extract:HI (match_dup 0)
12450 (zero_extract:HI (match_dup 1)
12454 (clobber (reg:CC FLAGS_REG))])]
12456 operands[0] = gen_lowpart (HImode, operands[0]);
12457 operands[1] = gen_lowpart (HImode, operands[1]);
12458 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
12461 ;; Since AND can be encoded with sign extended immediate, this is only
12462 ;; profitable when 7th bit is not set.
12464 [(set (match_operand:SWI248 0 "any_QIreg_operand")
12465 (and:SWI248 (match_operand:SWI248 1 "general_operand")
12466 (match_operand:SWI248 2 "const_int_operand")))
12467 (clobber (reg:CC FLAGS_REG))]
12469 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12470 && !(~INTVAL (operands[2]) & ~255)
12471 && !(INTVAL (operands[2]) & 128)
12472 && !(TARGET_APX_NDD
12473 && !rtx_equal_p (operands[0], operands[1]))"
12474 [(parallel [(set (strict_low_part (match_dup 0))
12475 (and:QI (match_dup 1)
12477 (clobber (reg:CC FLAGS_REG))])]
12479 operands[0] = gen_lowpart (QImode, operands[0]);
12480 operands[1] = gen_lowpart (QImode, operands[1]);
12481 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
12484 (define_insn_and_split "*andn<dwi>3_doubleword_bmi"
12485 [(set (match_operand:<DWI> 0 "register_operand" "=&r,&r,r,r")
12487 (not:<DWI> (match_operand:<DWI> 1 "register_operand" "r,r,0,r"))
12488 (match_operand:<DWI> 2 "nonimmediate_operand" "r,o,ro,0")))
12489 (clobber (reg:CC FLAGS_REG))]
12492 "&& reload_completed"
12493 [(parallel [(set (match_dup 0)
12494 (and:DWIH (not:DWIH (match_dup 1)) (match_dup 2)))
12495 (clobber (reg:CC FLAGS_REG))])
12496 (parallel [(set (match_dup 3)
12497 (and:DWIH (not:DWIH (match_dup 4)) (match_dup 5)))
12498 (clobber (reg:CC FLAGS_REG))])]
12499 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);"
12500 [(set_attr "isa" "x64,*,*,*")])
12502 (define_insn_and_split "*andn<mode>3_doubleword"
12503 [(set (match_operand:DWI 0 "register_operand")
12505 (not:DWI (match_operand:DWI 1 "register_operand"))
12506 (match_operand:DWI 2 "nonimmediate_operand")))
12507 (clobber (reg:CC FLAGS_REG))]
12509 && ix86_pre_reload_split ()"
12512 [(set (match_dup 3) (not:DWI (match_dup 1)))
12513 (parallel [(set (match_dup 0)
12514 (and:DWI (match_dup 3) (match_dup 2)))
12515 (clobber (reg:CC FLAGS_REG))])]
12516 "operands[3] = gen_reg_rtx (<MODE>mode);")
12518 (define_insn "*andn<mode>_1"
12519 [(set (match_operand:SWI48 0 "register_operand" "=r,r,?k")
12521 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r,k"))
12522 (match_operand:SWI48 2 "nonimmediate_operand" "r,m,k")))
12523 (clobber (reg:CC FLAGS_REG))]
12524 "TARGET_BMI || TARGET_AVX512BW"
12526 andn\t{%2, %1, %0|%0, %1, %2}
12527 andn\t{%2, %1, %0|%0, %1, %2}
12529 [(set_attr "isa" "bmi,bmi,avx512bw")
12530 (set_attr "type" "bitmanip,bitmanip,msklog")
12531 (set_attr "btver2_decode" "direct, double,*")
12532 (set_attr "mode" "<MODE>")])
12534 (define_insn "*andn<mode>_1"
12535 [(set (match_operand:SWI12 0 "register_operand" "=r,?k")
12537 (not:SWI12 (match_operand:SWI12 1 "register_operand" "r,k"))
12538 (match_operand:SWI12 2 "register_operand" "r,k")))
12539 (clobber (reg:CC FLAGS_REG))]
12540 "TARGET_BMI || TARGET_AVX512BW"
12542 andn\t{%k2, %k1, %k0|%k0, %k1, %k2}
12544 [(set_attr "isa" "bmi,avx512f")
12545 (set_attr "type" "bitmanip,msklog")
12546 (set_attr "btver2_decode" "direct,*")
12548 (cond [(eq_attr "alternative" "0")
12549 (const_string "SI")
12550 (and (eq_attr "alternative" "1")
12551 (match_test "!TARGET_AVX512DQ"))
12552 (const_string "HI")
12554 (const_string "<MODE>")))])
12556 (define_insn "*andn_<mode>_ccno"
12557 [(set (reg FLAGS_REG)
12560 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
12561 (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
12563 (clobber (match_scratch:SWI48 0 "=r,r"))]
12564 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
12565 "andn\t{%2, %1, %0|%0, %1, %2}"
12566 [(set_attr "type" "bitmanip")
12567 (set_attr "btver2_decode" "direct, double")
12568 (set_attr "mode" "<MODE>")])
12570 ;; Split *andnsi_1 after reload with -Oz when not;and is shorter.
12572 [(set (match_operand:SI 0 "register_operand")
12573 (and:SI (not:SI (match_operand:SI 1 "register_operand"))
12574 (match_operand:SI 2 "nonimmediate_operand")))
12575 (clobber (reg:CC FLAGS_REG))]
12577 && optimize_insn_for_size_p () && optimize_size > 1
12578 && REGNO (operands[0]) == REGNO (operands[1])
12579 && LEGACY_INT_REG_P (operands[0])
12580 && !REX_INT_REG_P (operands[2])
12581 && !reg_overlap_mentioned_p (operands[0], operands[2])"
12582 [(set (match_dup 0) (not:SI (match_dup 1)))
12583 (parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
12584 (clobber (reg:CC FLAGS_REG))])])
12586 ;; Split *andn_si_ccno with -Oz when not;test is shorter.
12588 [(set (match_operand 0 "flags_reg_operand")
12589 (match_operator 1 "compare_operator"
12590 [(and:SI (not:SI (match_operand:SI 2 "general_reg_operand"))
12591 (match_operand:SI 3 "nonimmediate_operand"))
12593 (clobber (match_dup 2))]
12595 && optimize_insn_for_size_p () && optimize_size > 1
12596 && LEGACY_INT_REG_P (operands[2])
12597 && !REX_INT_REG_P (operands[3])
12598 && !reg_overlap_mentioned_p (operands[2], operands[3])"
12599 [(set (match_dup 2) (not:SI (match_dup 2)))
12600 (set (match_dup 0) (match_op_dup 1
12601 [(and:SI (match_dup 3) (match_dup 2))
12604 ;; Variant 1 of 4: Split ((A | B) ^ A) ^ C as (B & ~A) ^ C.
12606 [(set (match_operand:SWI48 0 "register_operand")
12609 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
12610 (match_operand:SWI48 2 "nonimmediate_operand"))
12612 (match_operand:SWI48 3 "nonimmediate_operand")))
12613 (clobber (reg:CC FLAGS_REG))]
12616 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 1)) (match_dup 2)))
12617 (clobber (reg:CC FLAGS_REG))])
12619 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
12620 (clobber (reg:CC FLAGS_REG))])]
12621 "operands[4] = gen_reg_rtx (<MODE>mode);")
12623 ;; Variant 2 of 4: Split ((A | B) ^ B) ^ C as (A & ~B) ^ C.
12625 [(set (match_operand:SWI48 0 "register_operand")
12628 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
12629 (match_operand:SWI48 2 "register_operand"))
12631 (match_operand:SWI48 3 "nonimmediate_operand")))
12632 (clobber (reg:CC FLAGS_REG))]
12635 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 2)) (match_dup 1)))
12636 (clobber (reg:CC FLAGS_REG))])
12638 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
12639 (clobber (reg:CC FLAGS_REG))])]
12640 "operands[4] = gen_reg_rtx (<MODE>mode);")
12642 ;; Variant 3 of 4: Split ((A | B) ^ C) ^ A as (B & ~A) ^ C.
12644 [(set (match_operand:SWI48 0 "register_operand")
12647 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
12648 (match_operand:SWI48 2 "nonimmediate_operand"))
12649 (match_operand:SWI48 3 "nonimmediate_operand"))
12651 (clobber (reg:CC FLAGS_REG))]
12654 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 1)) (match_dup 2)))
12655 (clobber (reg:CC FLAGS_REG))])
12657 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
12658 (clobber (reg:CC FLAGS_REG))])]
12659 "operands[4] = gen_reg_rtx (<MODE>mode);")
12661 ;; Variant 4 of 4: Split ((A | B) ^ C) ^ B as (A & ~B) ^ C.
12663 [(set (match_operand:SWI48 0 "register_operand")
12666 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
12667 (match_operand:SWI48 2 "register_operand"))
12668 (match_operand:SWI48 3 "nonimmediate_operand"))
12670 (clobber (reg:CC FLAGS_REG))]
12673 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 2)) (match_dup 1)))
12674 (clobber (reg:CC FLAGS_REG))])
12676 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
12677 (clobber (reg:CC FLAGS_REG))])]
12678 "operands[4] = gen_reg_rtx (<MODE>mode);")
12680 ;; Logical inclusive and exclusive OR instructions
12682 ;; %%% This used to optimize known byte-wide and operations to memory.
12683 ;; If this is considered useful, it should be done with splitters.
12685 (define_expand "<code><mode>3"
12686 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
12687 (any_or:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
12688 (match_operand:SDWIM 2 "<general_operand>")))]
12691 if (GET_MODE_SIZE (<MODE>mode) > UNITS_PER_WORD
12692 && !x86_64_hilo_general_operand (operands[2], <MODE>mode))
12693 operands[2] = force_reg (<MODE>mode, operands[2]);
12695 ix86_expand_binary_operator (<CODE>, <MODE>mode, operands, TARGET_APX_NDD);
12699 (define_insn_and_split "*<code><dwi>3_doubleword"
12700 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,&r,&r,&r,&r,&r")
12702 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0,ro,r,ro,jO,r")
12703 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o,r,<di>,K,<di>,o")))
12704 (clobber (reg:CC FLAGS_REG))]
12705 "ix86_binary_operator_ok (<CODE>, <DWI>mode, operands, TARGET_APX_NDD)"
12707 "&& reload_completed"
12708 [(const_int:DWIH 0)]
12710 /* This insn may disappear completely when operands[2] == const0_rtx
12711 and operands[0] == operands[1], which requires a NOTE_INSN_DELETED. */
12712 bool emit_insn_deleted_note_p = false;
12714 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
12716 if (operands[2] == const0_rtx)
12718 if (!rtx_equal_p (operands[0], operands[1]))
12719 emit_move_insn (operands[0], operands[1]);
12721 emit_insn_deleted_note_p = true;
12723 else if (operands[2] == constm1_rtx)
12726 emit_move_insn (operands[0], constm1_rtx);
12728 ix86_expand_unary_operator (NOT, <MODE>mode, &operands[0],
12732 ix86_expand_binary_operator (<CODE>, <MODE>mode, &operands[0],
12735 if (operands[5] == const0_rtx)
12737 if (!rtx_equal_p (operands[3], operands[4]))
12738 emit_move_insn (operands[3], operands[4]);
12739 else if (emit_insn_deleted_note_p)
12740 emit_note (NOTE_INSN_DELETED);
12742 else if (operands[5] == constm1_rtx)
12745 emit_move_insn (operands[3], constm1_rtx);
12747 ix86_expand_unary_operator (NOT, <MODE>mode, &operands[3],
12751 ix86_expand_binary_operator (<CODE>, <MODE>mode, &operands[3],
12756 [(set_attr "isa" "*,*,apx_ndd,apx_ndd,apx_ndd,apx_ndd_64,apx_ndd")])
12758 (define_insn "*<code><mode>_1"
12759 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,r,r,r,?k")
12761 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,rm,rjM,r,k")
12762 (match_operand:SWI248 2 "<general_operand>" "r<i>,<m>,r,<i>,<m>,k")))
12763 (clobber (reg:CC FLAGS_REG))]
12764 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands, TARGET_APX_NDD)"
12766 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
12767 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
12768 <logic>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
12769 <logic>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
12770 <logic>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
12772 [(set_attr "isa" "*,*,apx_ndd,apx_ndd,apx_ndd,<kmov_isa>")
12773 (set_attr "type" "alu, alu, alu, alu, alu, msklog")
12774 (set_attr "mode" "<MODE>")])
12776 (define_insn_and_split "*notxor<mode>_1"
12777 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,r,r,?k")
12780 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,rm,r,k")
12781 (match_operand:SWI248 2 "<general_operand>" "r<i>,<m>,r<i>,<m>,k"))))
12782 (clobber (reg:CC FLAGS_REG))]
12783 "ix86_binary_operator_ok (XOR, <MODE>mode, operands, TARGET_APX_NDD)"
12785 "&& reload_completed"
12787 [(set (match_dup 0)
12788 (xor:SWI248 (match_dup 1) (match_dup 2)))
12789 (clobber (reg:CC FLAGS_REG))])
12791 (not:SWI248 (match_dup 0)))]
12793 if (MASK_REG_P (operands[0]))
12795 emit_insn (gen_kxnor<mode> (operands[0], operands[1], operands[2]));
12799 [(set_attr "isa" "*,*,apx_ndd,apx_ndd,<kmov_isa>")
12800 (set_attr "type" "alu, alu, alu, alu, msklog")
12801 (set_attr "mode" "<MODE>")])
12803 (define_insn_and_split "*iordi_1_bts"
12804 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12806 (match_operand:DI 1 "nonimmediate_operand" "%0")
12807 (match_operand:DI 2 "const_int_operand" "n")))
12808 (clobber (reg:CC FLAGS_REG))]
12809 "TARGET_64BIT && TARGET_USE_BT
12810 && ix86_binary_operator_ok (IOR, DImode, operands)
12811 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
12813 "&& reload_completed"
12814 [(parallel [(set (zero_extract:DI (match_dup 0)
12818 (clobber (reg:CC FLAGS_REG))])]
12819 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
12820 [(set_attr "type" "alu1")
12821 (set_attr "prefix_0f" "1")
12822 (set_attr "znver1_decode" "double")
12823 (set_attr "mode" "DI")])
12825 (define_insn_and_split "*xordi_1_btc"
12826 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12828 (match_operand:DI 1 "nonimmediate_operand" "%0")
12829 (match_operand:DI 2 "const_int_operand" "n")))
12830 (clobber (reg:CC FLAGS_REG))]
12831 "TARGET_64BIT && TARGET_USE_BT
12832 && ix86_binary_operator_ok (XOR, DImode, operands)
12833 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
12835 "&& reload_completed"
12836 [(parallel [(set (zero_extract:DI (match_dup 0)
12839 (not:DI (zero_extract:DI (match_dup 0)
12842 (clobber (reg:CC FLAGS_REG))])]
12843 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
12844 [(set_attr "type" "alu1")
12845 (set_attr "prefix_0f" "1")
12846 (set_attr "znver1_decode" "double")
12847 (set_attr "mode" "DI")])
12849 ;; Optimize a ^ ((a ^ b) & mask) to (~mask & a) | (b & mask)
12850 (define_insn_and_split "*xor2andn"
12851 [(set (match_operand:SWI248 0 "register_operand")
12855 (match_operand:SWI248 1 "nonimmediate_operand")
12856 (match_operand:SWI248 2 "nonimmediate_operand"))
12857 (match_operand:SWI248 3 "nonimmediate_operand"))
12859 (clobber (reg:CC FLAGS_REG))]
12860 "TARGET_BMI && ix86_pre_reload_split ()"
12863 [(parallel [(set (match_dup 4)
12868 (clobber (reg:CC FLAGS_REG))])
12869 (parallel [(set (match_dup 5)
12873 (clobber (reg:CC FLAGS_REG))])
12874 (parallel [(set (match_dup 0)
12878 (clobber (reg:CC FLAGS_REG))])]
12880 operands[1] = force_reg (<MODE>mode, operands[1]);
12881 operands[3] = force_reg (<MODE>mode, operands[3]);
12882 operands[4] = gen_reg_rtx (<MODE>mode);
12883 operands[5] = gen_reg_rtx (<MODE>mode);
12886 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
12887 (define_insn "*<code>si_1_zext"
12888 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
12890 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0,rm,rjM,r")
12891 (match_operand:SI 2 "x86_64_general_operand" "rBMe,r,e,BM"))))
12892 (clobber (reg:CC FLAGS_REG))]
12894 && ix86_binary_operator_ok (<CODE>, SImode, operands, TARGET_APX_NDD)"
12896 <logic>{l}\t{%2, %k0|%k0, %2}
12897 <logic>{l}\t{%2, %1, %k0|%k0, %1, %2}
12898 <logic>{l}\t{%2, %1, %k0|%k0, %1, %2}
12899 <logic>{l}\t{%2, %1, %k0|%k0, %1, %2}"
12900 [(set_attr "type" "alu")
12901 (set_attr "isa" "*,apx_ndd,apx_ndd,apx_ndd")
12902 (set_attr "mode" "SI")])
12904 (define_insn "*<code>si_1_zext_imm"
12905 [(set (match_operand:DI 0 "register_operand" "=r,r")
12907 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0,rm"))
12908 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z,Z")))
12909 (clobber (reg:CC FLAGS_REG))]
12911 && ix86_binary_operator_ok (<CODE>, SImode, operands, TARGET_APX_NDD)"
12913 <logic>{l}\t{%2, %k0|%k0, %2}
12914 <logic>{l}\t{%2, %1, %k0|%k0, %1, %2}"
12915 [(set_attr "type" "alu")
12916 (set_attr "isa" "*,apx_ndd")
12917 (set_attr "mode" "SI")])
12919 (define_insn "*<code>qi_1"
12920 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r,r,?k")
12921 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,rm,r,k")
12922 (match_operand:QI 2 "general_operand" "qn,m,rn,rn,m,k")))
12923 (clobber (reg:CC FLAGS_REG))]
12924 "ix86_binary_operator_ok (<CODE>, QImode, operands, TARGET_APX_NDD)"
12926 <logic>{b}\t{%2, %0|%0, %2}
12927 <logic>{b}\t{%2, %0|%0, %2}
12928 <logic>{l}\t{%k2, %k0|%k0, %k2}
12929 <logic>{b}\t{%2, %1, %0|%0, %1, %2}
12930 <logic>{b}\t{%2, %1, %0|%0, %1, %2}
12932 [(set_attr "isa" "*,*,*,apx_ndd,apx_ndd,avx512f")
12933 (set_attr "type" "alu,alu,alu,alu,alu,msklog")
12935 (cond [(eq_attr "alternative" "2")
12936 (const_string "SI")
12937 (and (eq_attr "alternative" "5")
12938 (match_test "!TARGET_AVX512DQ"))
12939 (const_string "HI")
12941 (const_string "QI")))
12942 ;; Potential partial reg stall on alternative 2.
12943 (set (attr "preferred_for_speed")
12944 (cond [(eq_attr "alternative" "2")
12945 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
12946 (symbol_ref "true")))])
12948 (define_insn_and_split "*notxorqi_1"
12949 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r,r,?k")
12951 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,rm,r,k")
12952 (match_operand:QI 2 "general_operand" "qn,m,rn,rn,m,k"))))
12953 (clobber (reg:CC FLAGS_REG))]
12954 "ix86_binary_operator_ok (XOR, QImode, operands, TARGET_APX_NDD)"
12956 "&& reload_completed"
12958 [(set (match_dup 0)
12959 (xor:QI (match_dup 1) (match_dup 2)))
12960 (clobber (reg:CC FLAGS_REG))])
12962 (not:QI (match_dup 0)))]
12964 if (mask_reg_operand (operands[0], QImode))
12966 emit_insn (gen_kxnorqi (operands[0], operands[1], operands[2]));
12970 [(set_attr "isa" "*,*,*,apx_ndd,apx_ndd,avx512f")
12971 (set_attr "type" "alu,alu,alu,alu,alu,msklog")
12973 (cond [(eq_attr "alternative" "2")
12974 (const_string "SI")
12975 (and (eq_attr "alternative" "5")
12976 (match_test "!TARGET_AVX512DQ"))
12977 (const_string "HI")
12979 (const_string "QI")))
12980 ;; Potential partial reg stall on alternative 2.
12981 (set (attr "preferred_for_speed")
12982 (cond [(eq_attr "alternative" "2")
12983 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
12984 (symbol_ref "true")))])
12986 ;; convert (sign_extend:WIDE (any_logic:NARROW (memory, immediate)))
12987 ;; to (any_logic:WIDE (sign_extend (memory)), (sign_extend (immediate))).
12988 ;; This eliminates sign extension after logic operation.
12991 [(set (match_operand:SWI248 0 "register_operand")
12992 (sign_extend:SWI248
12993 (any_logic:QI (match_operand:QI 1 "memory_operand")
12994 (match_operand:QI 2 "const_int_operand"))))]
12996 [(set (match_dup 3) (sign_extend:SWI248 (match_dup 1)))
12997 (set (match_dup 0) (any_logic:SWI248 (match_dup 3) (match_dup 2)))]
12998 "operands[3] = gen_reg_rtx (<MODE>mode);")
13001 [(set (match_operand:SWI48 0 "register_operand")
13003 (any_logic:HI (match_operand:HI 1 "memory_operand")
13004 (match_operand:HI 2 "const_int_operand"))))]
13006 [(set (match_dup 3) (sign_extend:SWI48 (match_dup 1)))
13007 (set (match_dup 0) (any_logic:SWI48 (match_dup 3) (match_dup 2)))]
13008 "operands[3] = gen_reg_rtx (<MODE>mode);")
13011 [(set (match_operand:DI 0 "register_operand")
13013 (any_logic:SI (match_operand:SI 1 "memory_operand")
13014 (match_operand:SI 2 "const_int_operand"))))]
13016 [(set (match_dup 3) (sign_extend:DI (match_dup 1)))
13017 (set (match_dup 0) (any_logic:DI (match_dup 3) (match_dup 2)))]
13018 "operands[3] = gen_reg_rtx (DImode);")
13020 (define_insn "*<code><mode>_2"
13021 [(set (reg FLAGS_REG)
13022 (compare (any_or:SWI
13023 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,rm,r")
13024 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,r<i>,<m>"))
13026 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r")
13027 (any_or:SWI (match_dup 1) (match_dup 2)))]
13028 "ix86_match_ccmode (insn, CCNOmode)
13029 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands, TARGET_APX_NDD)"
13031 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
13032 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
13033 <logic>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
13034 <logic>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
13035 [(set_attr "type" "alu")
13036 (set_attr "isa" "*,*,apx_ndd,apx_ndd")
13037 (set_attr "mode" "<MODE>")])
13039 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
13040 ;; ??? Special case for immediate operand is missing - it is tricky.
13041 (define_insn "*<code>si_2_zext"
13042 [(set (reg FLAGS_REG)
13043 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0,rm,r")
13044 (match_operand:SI 2 "x86_64_general_operand" "rBMe,re,BM"))
13046 (set (match_operand:DI 0 "register_operand" "=r,r,r")
13047 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
13048 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
13049 && ix86_binary_operator_ok (<CODE>, SImode, operands, TARGET_APX_NDD)"
13051 <logic>{l}\t{%2, %k0|%k0, %2}
13052 <logic>{l}\t{%2, %1, %k0|%k0, %1, %2}
13053 <logic>{l}\t{%2, %1, %k0|%k0, %1, %2}"
13054 [(set_attr "type" "alu")
13055 (set_attr "isa" "*,apx_ndd,apx_ndd")
13056 (set_attr "mode" "SI")])
13058 (define_insn "*<code>si_2_zext_imm"
13059 [(set (reg FLAGS_REG)
13060 (compare (any_or:SI
13061 (match_operand:SI 1 "nonimmediate_operand" "%0,rm")
13062 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z,Z"))
13064 (set (match_operand:DI 0 "register_operand" "=r,r")
13065 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13066 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
13067 && ix86_binary_operator_ok (<CODE>, SImode, operands, TARGET_APX_NDD)"
13069 <logic>{l}\t{%2, %k0|%k0, %2}
13070 <logic>{l}\t{%2, %1, %k0|%k0, %1, %2}"
13071 [(set_attr "type" "alu")
13072 (set_attr "isa" "*,apx_ndd")
13073 (set_attr "mode" "SI")])
13075 (define_insn "*<code><mode>_3"
13076 [(set (reg FLAGS_REG)
13077 (compare (any_or:SWI
13078 (match_operand:SWI 1 "nonimmediate_operand" "%0")
13079 (match_operand:SWI 2 "<general_operand>" "<g>"))
13081 (clobber (match_scratch:SWI 0 "=<r>"))]
13082 "ix86_match_ccmode (insn, CCNOmode)
13083 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13084 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
13085 [(set_attr "type" "alu")
13086 (set_attr "mode" "<MODE>")])
13088 ;; Convert wide OR instructions with immediate operand to shorter QImode
13089 ;; equivalents when possible.
13090 ;; Don't do the splitting with memory operands, since it introduces risk
13091 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
13092 ;; for size, but that can (should?) be handled by generic code instead.
13093 ;; Don't do the splitting for APX NDD as NDD does not support *h registers.
13095 [(set (match_operand:SWI248 0 "QIreg_operand")
13096 (any_or:SWI248 (match_operand:SWI248 1 "register_operand")
13097 (match_operand:SWI248 2 "const_int_operand")))
13098 (clobber (reg:CC FLAGS_REG))]
13100 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13101 && !(INTVAL (operands[2]) & ~(255 << 8))
13102 && !(TARGET_APX_NDD && REGNO (operands[0]) != REGNO (operands[1]))"
13104 [(set (zero_extract:HI (match_dup 0)
13110 (zero_extract:HI (match_dup 1)
13114 (clobber (reg:CC FLAGS_REG))])]
13116 /* Handle the case where INTVAL (operands[2]) == 0. */
13117 if (operands[2] == const0_rtx)
13119 if (!rtx_equal_p (operands[0], operands[1]))
13120 emit_move_insn (operands[0], operands[1]);
13122 emit_note (NOTE_INSN_DELETED);
13125 operands[0] = gen_lowpart (HImode, operands[0]);
13126 operands[1] = gen_lowpart (HImode, operands[1]);
13127 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
13130 ;; Since OR can be encoded with sign extended immediate, this is only
13131 ;; profitable when 7th bit is set.
13133 [(set (match_operand:SWI248 0 "any_QIreg_operand")
13134 (any_or:SWI248 (match_operand:SWI248 1 "general_operand")
13135 (match_operand:SWI248 2 "const_int_operand")))
13136 (clobber (reg:CC FLAGS_REG))]
13138 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13139 && !(INTVAL (operands[2]) & ~255)
13140 && (INTVAL (operands[2]) & 128)
13141 && !(TARGET_APX_NDD
13142 && !rtx_equal_p (operands[0], operands[1]))"
13143 [(parallel [(set (strict_low_part (match_dup 0))
13144 (any_or:QI (match_dup 1)
13146 (clobber (reg:CC FLAGS_REG))])]
13148 operands[0] = gen_lowpart (QImode, operands[0]);
13149 operands[1] = gen_lowpart (QImode, operands[1]);
13150 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
13153 (define_expand "xorqi_ext_1_cc"
13155 [(set (reg:CCNO FLAGS_REG)
13159 (zero_extract:HI (match_operand:HI 1 "register_operand")
13162 (match_operand:QI 2 "const_int_operand"))
13164 (set (zero_extract:HI (match_operand:HI 0 "register_operand")
13170 (zero_extract:HI (match_dup 1)
13173 (match_dup 2)) 0))])])
13175 ;; Peephole2 rega = 0; rega op= regb into rega = regb.
13177 [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
13179 (clobber (reg:CC FLAGS_REG))])
13180 (parallel [(set (match_dup 0)
13181 (any_or_plus:SWI (match_dup 0)
13182 (match_operand:SWI 1 "<general_operand>")))
13183 (clobber (reg:CC FLAGS_REG))])]
13184 "!reg_mentioned_p (operands[0], operands[1])"
13185 [(set (match_dup 0) (match_dup 1))])
13187 ;; Peephole2 dead instruction in rega = 0; rega op= rega.
13189 [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
13191 (clobber (reg:CC FLAGS_REG))])
13192 (parallel [(set (match_dup 0)
13193 (any_or_plus:SWI (match_dup 0) (match_dup 0)))
13194 (clobber (reg:CC FLAGS_REG))])]
13196 [(parallel [(set (match_dup 0) (const_int 0))
13197 (clobber (reg:CC FLAGS_REG))])])
13199 ;; Split DST = (HI<<32)|LO early to minimize register usage.
13200 (define_insn_and_split "*concat<mode><dwi>3_1"
13201 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
13203 (ashift:<DWI> (match_operand:<DWI> 1 "register_operand" "r,r")
13204 (match_operand:QI 2 "const_int_operand"))
13206 (match_operand:DWIH 3 "nonimmediate_operand" "r,m"))))]
13207 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT"
13209 "&& reload_completed"
13212 split_double_concat (<DWI>mode, operands[0], operands[3],
13213 gen_lowpart (<MODE>mode, operands[1]));
13217 (define_insn_and_split "*concat<mode><dwi>3_2"
13218 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
13221 (match_operand:DWIH 1 "nonimmediate_operand" "r,m"))
13222 (ashift:<DWI> (match_operand:<DWI> 2 "register_operand" "r,r")
13223 (match_operand:QI 3 "const_int_operand"))))]
13224 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13226 "&& reload_completed"
13229 split_double_concat (<DWI>mode, operands[0], operands[1],
13230 gen_lowpart (<MODE>mode, operands[2]));
13234 (define_insn_and_split "*concat<mode><dwi>3_3"
13235 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,r,&r,x")
13239 (match_operand:DWIH 1 "nonimmediate_operand" "r,m,r,m,x"))
13240 (match_operand:QI 2 "const_int_operand"))
13242 (match_operand:DWIH 3 "nonimmediate_operand" "r,r,m,m,0"))))]
13243 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT"
13245 "&& reload_completed"
13248 if (SSE_REG_P (operands[0]))
13250 rtx tmp = gen_rtx_REG (V2DImode, REGNO (operands[0]));
13251 emit_insn (gen_vec_concatv2di (tmp, operands[3], operands[1]));
13254 split_double_concat (<DWI>mode, operands[0], operands[3], operands[1]);
13257 [(set_attr "isa" "*,*,*,x64,x64")])
13259 (define_insn_and_split "*concat<mode><dwi>3_4"
13260 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,r,&r")
13263 (match_operand:DWIH 1 "nonimmediate_operand" "r,m,r,m"))
13266 (match_operand:DWIH 2 "nonimmediate_operand" "r,r,m,m"))
13267 (match_operand:QI 3 "const_int_operand"))))]
13268 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13270 "&& reload_completed"
13273 split_double_concat (<DWI>mode, operands[0], operands[1], operands[2]);
13276 [(set_attr "isa" "*,*,*,x64")])
13278 (define_insn_and_split "*concat<half><mode>3_5"
13279 [(set (match_operand:DWI 0 "nonimmediate_operand" "=r,o,o")
13281 (ashift:DWI (match_operand:DWI 1 "register_operand" "r,r,r")
13282 (match_operand:QI 2 "const_int_operand"))
13283 (match_operand:DWI 3 "const_scalar_int_operand" "n,n,Wd")))]
13284 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT / 2
13285 && (<MODE>mode == DImode
13286 ? CONST_INT_P (operands[3])
13287 && (UINTVAL (operands[3]) & ~GET_MODE_MASK (SImode)) == 0
13288 : CONST_INT_P (operands[3])
13289 ? INTVAL (operands[3]) >= 0
13290 : CONST_WIDE_INT_NUNITS (operands[3]) == 2
13291 && CONST_WIDE_INT_ELT (operands[3], 1) == 0)
13292 && !(CONST_INT_P (operands[3])
13293 ? ix86_endbr_immediate_operand (operands[3], VOIDmode)
13294 : ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[3],
13298 "&& reload_completed"
13301 rtx op3 = simplify_subreg (<HALF>mode, operands[3], <MODE>mode, 0);
13302 split_double_concat (<MODE>mode, operands[0], op3,
13303 gen_lowpart (<HALF>mode, operands[1]));
13306 [(set_attr "isa" "*,nox64,x64")])
13308 (define_insn_and_split "*concat<mode><dwi>3_6"
13309 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,o,r")
13313 (match_operand:DWIH 1 "nonimmediate_operand" "r,r,r,m"))
13314 (match_operand:QI 2 "const_int_operand"))
13315 (match_operand:<DWI> 3 "const_scalar_int_operand" "n,n,Wd,n")))]
13316 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT
13317 && (<DWI>mode == DImode
13318 ? CONST_INT_P (operands[3])
13319 && (UINTVAL (operands[3]) & ~GET_MODE_MASK (SImode)) == 0
13320 : CONST_INT_P (operands[3])
13321 ? INTVAL (operands[3]) >= 0
13322 : CONST_WIDE_INT_NUNITS (operands[3]) == 2
13323 && CONST_WIDE_INT_ELT (operands[3], 1) == 0)
13324 && !(CONST_INT_P (operands[3])
13325 ? ix86_endbr_immediate_operand (operands[3], VOIDmode)
13326 : ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[3],
13330 "&& reload_completed"
13333 rtx op3 = simplify_subreg (<MODE>mode, operands[3], <DWI>mode, 0);
13334 split_double_concat (<DWI>mode, operands[0], op3, operands[1]);
13337 [(set_attr "isa" "*,nox64,x64,*")])
13339 (define_insn_and_split "*concat<mode><dwi>3_7"
13340 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,o,r")
13343 (match_operand:DWIH 1 "nonimmediate_operand" "r,r,r,m"))
13344 (match_operand:<DWI> 2 "const_scalar_int_operand" "n,n,Wd,n")))]
13345 "<DWI>mode == DImode
13346 ? CONST_INT_P (operands[2])
13347 && (UINTVAL (operands[2]) & GET_MODE_MASK (SImode)) == 0
13348 && !ix86_endbr_immediate_operand (operands[2], VOIDmode)
13349 : CONST_WIDE_INT_P (operands[2])
13350 && CONST_WIDE_INT_NUNITS (operands[2]) == 2
13351 && CONST_WIDE_INT_ELT (operands[2], 0) == 0
13352 && !ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[2],
13356 "&& reload_completed"
13360 if (<DWI>mode == DImode)
13361 op2 = gen_int_mode (INTVAL (operands[2]) >> 32, <MODE>mode);
13363 op2 = gen_int_mode (CONST_WIDE_INT_ELT (operands[2], 1), <MODE>mode);
13364 split_double_concat (<DWI>mode, operands[0], operands[1], op2);
13367 [(set_attr "isa" "*,nox64,x64,*")])
13369 ;; Negation instructions
13371 (define_expand "neg<mode>2"
13372 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
13373 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
13376 ix86_expand_unary_operator (NEG, <MODE>mode, operands, TARGET_APX_NDD);
13380 (define_insn_and_split "*neg<dwi>2_doubleword"
13381 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,&r")
13382 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0,ro")))
13383 (clobber (reg:CC FLAGS_REG))]
13384 "ix86_unary_operator_ok (NEG, <DWI>mode, operands, TARGET_APX_NDD)"
13386 "&& reload_completed"
13388 [(set (reg:CCC FLAGS_REG)
13389 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
13390 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
13392 [(set (match_dup 2)
13393 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
13396 (clobber (reg:CC FLAGS_REG))])
13398 [(set (match_dup 2)
13399 (neg:DWIH (match_dup 2)))
13400 (clobber (reg:CC FLAGS_REG))])]
13401 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);"
13402 [(set_attr "isa" "*,apx_ndd")])
13415 [(set (match_operand:SWI48 0 "general_reg_operand")
13416 (match_operand:SWI48 1 "nonimmediate_gr_operand"))
13418 [(set (reg:CCC FLAGS_REG)
13419 (unspec:CCC [(match_operand:SWI48 2 "general_reg_operand")
13420 (const_int 0)] UNSPEC_CC_NE))
13421 (set (match_dup 2) (neg:SWI48 (match_dup 2)))])
13423 [(set (match_dup 0)
13424 (plus:SWI48 (plus:SWI48
13425 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
13428 (clobber (reg:CC FLAGS_REG))])
13430 [(set (match_dup 0)
13431 (neg:SWI48 (match_dup 0)))
13432 (clobber (reg:CC FLAGS_REG))])]
13433 "REGNO (operands[0]) != REGNO (operands[2])
13434 && !reg_mentioned_p (operands[0], operands[1])
13435 && !reg_mentioned_p (operands[2], operands[1])"
13437 [(set (reg:CCC FLAGS_REG)
13438 (unspec:CCC [(match_dup 2) (const_int 0)] UNSPEC_CC_NE))
13439 (set (match_dup 2) (neg:SWI48 (match_dup 2)))])
13441 [(set (match_dup 0)
13442 (minus:SWI48 (minus:SWI48
13444 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0)))
13446 (clobber (reg:CC FLAGS_REG))])]
13447 "ix86_expand_clear (operands[0]);")
13456 ;; sbbl %edx, %edx // *x86_mov<mode>cc_0_m1
13460 [(set (match_operand:SWI48 0 "general_reg_operand") (const_int 0))
13461 (clobber (reg:CC FLAGS_REG))])
13463 [(set (reg:CCC FLAGS_REG)
13464 (unspec:CCC [(match_operand:SWI48 1 "general_reg_operand")
13465 (const_int 0)] UNSPEC_CC_NE))
13466 (set (match_dup 1) (neg:SWI48 (match_dup 1)))])
13468 [(set (match_dup 0)
13469 (plus:SWI48 (plus:SWI48
13470 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
13473 (clobber (reg:CC FLAGS_REG))])
13475 [(set (match_dup 0)
13476 (neg:SWI48 (match_dup 0)))
13477 (clobber (reg:CC FLAGS_REG))])]
13478 "REGNO (operands[0]) != REGNO (operands[1])"
13480 [(set (reg:CCC FLAGS_REG)
13481 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
13482 (set (match_dup 1) (neg:SWI48 (match_dup 1)))])
13484 [(set (match_dup 0)
13485 (if_then_else:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
13488 (clobber (reg:CC FLAGS_REG))])])
13490 (define_insn "*neg<mode>_1"
13491 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,r")
13492 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0,rm")))
13493 (clobber (reg:CC FLAGS_REG))]
13494 "ix86_unary_operator_ok (NEG, <MODE>mode, operands, TARGET_APX_NDD)"
13496 neg{<imodesuffix>}\t%0
13497 neg{<imodesuffix>}\t{%1, %0|%0, %1}"
13498 [(set_attr "type" "negnot")
13499 (set_attr "isa" "*,apx_ndd")
13500 (set_attr "mode" "<MODE>")])
13502 (define_insn "*negsi_1_zext"
13503 [(set (match_operand:DI 0 "register_operand" "=r,r")
13505 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm"))))
13506 (clobber (reg:CC FLAGS_REG))]
13508 && ix86_unary_operator_ok (NEG, SImode, operands, TARGET_APX_NDD)"
13511 neg{l}\t{%k1, %k0|%k0, %k1}"
13512 [(set_attr "type" "negnot")
13513 (set_attr "isa" "*,apx_ndd")
13514 (set_attr "mode" "SI")])
13516 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
13517 (define_insn_and_split "*neg<mode>_1_slp"
13518 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
13519 (neg:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")))
13520 (clobber (reg:CC FLAGS_REG))]
13521 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
13523 neg{<imodesuffix>}\t%0
13525 "&& reload_completed
13526 && !(rtx_equal_p (operands[0], operands[1]))"
13527 [(set (strict_low_part (match_dup 0)) (match_dup 1))
13529 [(set (strict_low_part (match_dup 0))
13530 (neg:SWI12 (match_dup 0)))
13531 (clobber (reg:CC FLAGS_REG))])]
13533 [(set_attr "type" "negnot")
13534 (set_attr "mode" "<MODE>")])
13536 (define_insn "*neg<mode>_2"
13537 [(set (reg FLAGS_REG)
13539 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0,rm"))
13541 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,r")
13542 (neg:SWI (match_dup 1)))]
13543 "ix86_match_ccmode (insn, CCGOCmode)
13544 && ix86_unary_operator_ok (NEG, <MODE>mode, operands, TARGET_APX_NDD)"
13546 neg{<imodesuffix>}\t%0
13547 neg{<imodesuffix>}\t{%1, %0|%0, %1}"
13548 [(set_attr "type" "negnot")
13549 (set_attr "isa" "*,apx_ndd")
13550 (set_attr "mode" "<MODE>")])
13552 (define_insn "*negsi_2_zext"
13553 [(set (reg FLAGS_REG)
13555 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm"))
13557 (set (match_operand:DI 0 "register_operand" "=r,r")
13559 (neg:SI (match_dup 1))))]
13560 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
13561 && ix86_unary_operator_ok (NEG, SImode, operands, TARGET_APX_NDD)"
13564 neg{l}\t{%1, %k0|%k0, %1}"
13565 [(set_attr "type" "negnot")
13566 (set_attr "isa" "*,apx_ndd")
13567 (set_attr "mode" "SI")])
13569 (define_insn "*neg<mode>_ccc_1"
13570 [(set (reg:CCC FLAGS_REG)
13572 [(match_operand:SWI 1 "nonimmediate_operand" "0,rm")
13573 (const_int 0)] UNSPEC_CC_NE))
13574 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,r")
13575 (neg:SWI (match_dup 1)))]
13578 neg{<imodesuffix>}\t%0
13579 neg{<imodesuffix>}\t{%1, %0|%0, %1}"
13580 [(set_attr "type" "negnot")
13581 (set_attr "isa" "*,apx_ndd")
13582 (set_attr "mode" "<MODE>")])
13584 (define_insn "*neg<mode>_ccc_2"
13585 [(set (reg:CCC FLAGS_REG)
13587 [(match_operand:SWI 1 "nonimmediate_operand" "0,rm")
13588 (const_int 0)] UNSPEC_CC_NE))
13589 (clobber (match_scratch:SWI 0 "=<r>,r"))]
13592 neg{<imodesuffix>}\t%0
13593 neg{<imodesuffix>}\t{%1, %0|%0, %1}"
13594 [(set_attr "type" "negnot")
13595 (set_attr "isa" "*,apx_ndd")
13596 (set_attr "mode" "<MODE>")])
13598 (define_expand "x86_neg<mode>_ccc"
13600 [(set (reg:CCC FLAGS_REG)
13601 (unspec:CCC [(match_operand:SWI48 1 "register_operand")
13602 (const_int 0)] UNSPEC_CC_NE))
13603 (set (match_operand:SWI48 0 "register_operand")
13604 (neg:SWI48 (match_dup 1)))])])
13606 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
13607 (define_insn_and_split "*negqi_ext<mode>_1"
13608 [(set (zero_extract:SWI248
13609 (match_operand 0 "int248_register_operand" "+Q,&Q")
13615 (match_operator:SWI248 2 "extract_operator"
13616 [(match_operand 1 "int248_register_operand" "0,!Q")
13618 (const_int 8)]) 0)) 0))
13619 (clobber (reg:CC FLAGS_REG))]
13625 && !(rtx_equal_p (operands[0], operands[1]))"
13626 [(set (zero_extract:SWI248
13627 (match_dup 0) (const_int 8) (const_int 8))
13628 (zero_extract:SWI248
13629 (match_dup 1) (const_int 8) (const_int 8)))
13631 [(set (zero_extract:SWI248
13632 (match_dup 0) (const_int 8) (const_int 8))
13637 [(match_dup 0) (const_int 8) (const_int 8)]) 0)) 0))
13638 (clobber (reg:CC FLAGS_REG))])]
13640 [(set_attr "type" "negnot")
13641 (set_attr "mode" "QI")])
13643 ;; Negate with jump on overflow.
13644 (define_expand "negv<mode>3"
13645 [(parallel [(set (reg:CCO FLAGS_REG)
13647 [(match_operand:SWI 1 "register_operand")
13648 (match_dup 3)] UNSPEC_CC_NE))
13649 (set (match_operand:SWI 0 "register_operand")
13650 (neg:SWI (match_dup 1)))])
13651 (set (pc) (if_then_else
13652 (eq (reg:CCO FLAGS_REG) (const_int 0))
13653 (label_ref (match_operand 2))
13658 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
13662 (define_insn "*negv<mode>3"
13663 [(set (reg:CCO FLAGS_REG)
13664 (unspec:CCO [(match_operand:SWI 1 "nonimmediate_operand" "0")
13665 (match_operand:SWI 2 "const_int_operand")]
13667 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
13668 (neg:SWI (match_dup 1)))]
13669 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
13670 && mode_signbit_p (<MODE>mode, operands[2])"
13671 "neg{<imodesuffix>}\t%0"
13672 [(set_attr "type" "negnot")
13673 (set_attr "mode" "<MODE>")])
13675 ;; Optimize *negsi_1 followed by *cmpsi_ccno_1 (PR target/91384)
13677 [(set (match_operand:SWI 0 "general_reg_operand")
13678 (match_operand:SWI 1 "general_reg_operand"))
13679 (parallel [(set (match_dup 0) (neg:SWI (match_dup 0)))
13680 (clobber (reg:CC FLAGS_REG))])
13681 (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))]
13683 [(set (match_dup 0) (match_dup 1))
13684 (parallel [(set (reg:CCZ FLAGS_REG)
13685 (compare:CCZ (neg:SWI (match_dup 0)) (const_int 0)))
13686 (set (match_dup 0) (neg:SWI (match_dup 0)))])])
13688 ;; Special expand pattern to handle integer mode abs
13690 (define_expand "abs<mode>2"
13692 [(set (match_operand:SDWIM 0 "register_operand")
13694 (match_operand:SDWIM 1 "general_operand")))
13695 (clobber (reg:CC FLAGS_REG))])]
13697 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)"
13699 if (TARGET_EXPAND_ABS)
13701 machine_mode mode = <MODE>mode;
13702 operands[1] = force_reg (mode, operands[1]);
13704 /* Generate rtx abs using:
13705 abs (x) = (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)) */
13707 rtx shift_amount = gen_int_mode (GET_MODE_PRECISION (mode) - 1, QImode);
13708 rtx shift_dst = expand_simple_binop (mode, ASHIFTRT, operands[1],
13709 shift_amount, NULL_RTX,
13711 rtx xor_dst = expand_simple_binop (mode, XOR, shift_dst, operands[1],
13712 operands[0], 0, OPTAB_DIRECT);
13713 rtx minus_dst = expand_simple_binop (mode, MINUS, xor_dst, shift_dst,
13714 operands[0], 0, OPTAB_DIRECT);
13715 if (!rtx_equal_p (minus_dst, operands[0]))
13716 emit_move_insn (operands[0], minus_dst);
13721 (define_insn_and_split "*abs<dwi>2_doubleword"
13722 [(set (match_operand:<DWI> 0 "register_operand")
13724 (match_operand:<DWI> 1 "general_operand")))
13725 (clobber (reg:CC FLAGS_REG))]
13727 && ix86_pre_reload_split ()"
13731 [(set (reg:CCC FLAGS_REG)
13732 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
13733 (set (match_dup 2) (neg:DWIH (match_dup 1)))])
13735 [(set (match_dup 5)
13736 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
13739 (clobber (reg:CC FLAGS_REG))])
13741 [(set (reg:CCGOC FLAGS_REG)
13743 (neg:DWIH (match_dup 5))
13746 (neg:DWIH (match_dup 5)))])
13749 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
13754 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
13758 operands[1] = force_reg (<DWI>mode, operands[1]);
13759 operands[2] = gen_reg_rtx (<DWI>mode);
13761 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
13764 (define_insn_and_split "*nabs<dwi>2_doubleword"
13765 [(set (match_operand:<DWI> 0 "register_operand")
13768 (match_operand:<DWI> 1 "general_operand"))))
13769 (clobber (reg:CC FLAGS_REG))]
13771 && ix86_pre_reload_split ()"
13775 [(set (reg:CCC FLAGS_REG)
13776 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
13777 (set (match_dup 2) (neg:DWIH (match_dup 1)))])
13779 [(set (match_dup 5)
13780 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
13783 (clobber (reg:CC FLAGS_REG))])
13785 [(set (reg:CCGOC FLAGS_REG)
13787 (neg:DWIH (match_dup 5))
13790 (neg:DWIH (match_dup 5)))])
13793 (lt (reg:CCGOC FLAGS_REG) (const_int 0))
13798 (lt (reg:CCGOC FLAGS_REG) (const_int 0))
13802 operands[1] = force_reg (<DWI>mode, operands[1]);
13803 operands[2] = gen_reg_rtx (<DWI>mode);
13805 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
13808 (define_insn_and_split "*abs<mode>2_1"
13809 [(set (match_operand:SWI 0 "register_operand")
13811 (match_operand:SWI 1 "general_operand")))
13812 (clobber (reg:CC FLAGS_REG))]
13814 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
13815 && ix86_pre_reload_split ()"
13819 [(set (reg:CCGOC FLAGS_REG)
13821 (neg:SWI (match_dup 1))
13824 (neg:SWI (match_dup 1)))])
13827 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
13831 operands[1] = force_reg (<MODE>mode, operands[1]);
13832 operands[2] = gen_reg_rtx (<MODE>mode);
13835 (define_insn_and_split "*nabs<mode>2_1"
13836 [(set (match_operand:SWI 0 "register_operand")
13839 (match_operand:SWI 1 "general_operand"))))
13840 (clobber (reg:CC FLAGS_REG))]
13842 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
13843 && ix86_pre_reload_split ()"
13847 [(set (reg:CCGOC FLAGS_REG)
13849 (neg:SWI (match_dup 1))
13852 (neg:SWI (match_dup 1)))])
13855 (lt (reg:CCGOC FLAGS_REG) (const_int 0))
13859 operands[1] = force_reg (<MODE>mode, operands[1]);
13860 operands[2] = gen_reg_rtx (<MODE>mode);
13863 (define_expand "<code>tf2"
13864 [(set (match_operand:TF 0 "register_operand")
13865 (absneg:TF (match_operand:TF 1 "register_operand")))]
13867 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
13869 (define_insn_and_split "*<code>tf2_1"
13870 [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
13872 (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m")))
13873 (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))]
13876 "&& reload_completed"
13877 [(set (match_dup 0)
13878 (<absneg_op>:TF (match_dup 1) (match_dup 2)))]
13882 if (MEM_P (operands[1]))
13883 std::swap (operands[1], operands[2]);
13887 if (operands_match_p (operands[0], operands[2]))
13888 std::swap (operands[1], operands[2]);
13891 [(set_attr "isa" "noavx,noavx,avx,avx")])
13893 (define_insn_and_split "*nabstf2_1"
13894 [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
13897 (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m"))))
13898 (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))]
13901 "&& reload_completed"
13902 [(set (match_dup 0)
13903 (ior:TF (match_dup 1) (match_dup 2)))]
13907 if (MEM_P (operands[1]))
13908 std::swap (operands[1], operands[2]);
13912 if (operands_match_p (operands[0], operands[2]))
13913 std::swap (operands[1], operands[2]);
13916 [(set_attr "isa" "noavx,noavx,avx,avx")])
13918 (define_expand "<code>hf2"
13919 [(set (match_operand:HF 0 "register_operand")
13920 (absneg:HF (match_operand:HF 1 "register_operand")))]
13921 "TARGET_AVX512FP16"
13922 "ix86_expand_fp_absneg_operator (<CODE>, HFmode, operands); DONE;")
13924 (define_expand "<code><mode>2"
13925 [(set (match_operand:X87MODEF 0 "register_operand")
13926 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
13927 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13928 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
13930 ;; Changing of sign for FP values is doable using integer unit too.
13931 (define_insn "*<code><mode>2_i387_1"
13932 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
13934 (match_operand:X87MODEF 1 "register_operand" "0,0")))
13935 (clobber (reg:CC FLAGS_REG))]
13936 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13940 [(set (match_operand:X87MODEF 0 "fp_register_operand")
13941 (absneg:X87MODEF (match_operand:X87MODEF 1 "fp_register_operand")))
13942 (clobber (reg:CC FLAGS_REG))]
13943 "TARGET_80387 && reload_completed"
13944 [(set (match_dup 0) (absneg:X87MODEF (match_dup 1)))])
13947 [(set (match_operand:X87MODEF 0 "general_reg_operand")
13948 (absneg:X87MODEF (match_operand:X87MODEF 1 "general_reg_operand")))
13949 (clobber (reg:CC FLAGS_REG))]
13950 "TARGET_80387 && reload_completed"
13952 "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
13954 (define_insn_and_split "*<code>hf2_1"
13955 [(set (match_operand:HF 0 "register_operand" "=Yv")
13957 (match_operand:HF 1 "register_operand" "Yv")))
13958 (use (match_operand:V8HF 2 "vector_operand" "Yvm"))
13959 (clobber (reg:CC FLAGS_REG))]
13960 "TARGET_AVX512FP16"
13962 "&& reload_completed"
13963 [(set (match_dup 0)
13964 (<absneg_op>:V8HF (match_dup 1) (match_dup 2)))]
13966 operands[0] = lowpart_subreg (V8HFmode, operands[0], HFmode);
13967 operands[1] = lowpart_subreg (V8HFmode, operands[1], HFmode);
13970 (define_insn "*<code><mode>2_1"
13971 [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv,f,!r")
13973 (match_operand:MODEF 1 "register_operand" "0,x,Yv,0,0")))
13974 (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm,X,X"))
13975 (clobber (reg:CC FLAGS_REG))]
13976 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13978 [(set_attr "isa" "noavx,noavx,avx,*,*")
13979 (set (attr "enabled")
13981 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
13983 (eq_attr "alternative" "3,4")
13984 (symbol_ref "TARGET_MIX_SSE_I387")
13985 (const_string "*"))
13987 (eq_attr "alternative" "3,4")
13988 (symbol_ref "true")
13989 (symbol_ref "false"))))])
13992 [(set (match_operand:MODEF 0 "sse_reg_operand")
13994 (match_operand:MODEF 1 "sse_reg_operand")))
13995 (use (match_operand:<ssevecmodef> 2 "vector_operand"))
13996 (clobber (reg:CC FLAGS_REG))]
13997 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13998 && reload_completed"
13999 [(set (match_dup 0)
14000 (<absneg_op>:<ssevecmodef> (match_dup 1) (match_dup 2)))]
14002 machine_mode mode = <MODE>mode;
14003 machine_mode vmode = <ssevecmodef>mode;
14005 operands[0] = lowpart_subreg (vmode, operands[0], mode);
14006 operands[1] = lowpart_subreg (vmode, operands[1], mode);
14008 if (!TARGET_AVX && operands_match_p (operands[0], operands[2]))
14009 std::swap (operands[1], operands[2]);
14013 [(set (match_operand:MODEF 0 "fp_register_operand")
14014 (absneg:MODEF (match_operand:MODEF 1 "fp_register_operand")))
14015 (use (match_operand 2))
14016 (clobber (reg:CC FLAGS_REG))]
14017 "TARGET_80387 && reload_completed"
14018 [(set (match_dup 0) (absneg:MODEF (match_dup 1)))])
14021 [(set (match_operand:MODEF 0 "general_reg_operand")
14022 (absneg:MODEF (match_operand:MODEF 1 "general_reg_operand")))
14023 (use (match_operand 2))
14024 (clobber (reg:CC FLAGS_REG))]
14025 "TARGET_80387 && reload_completed"
14027 "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
14029 (define_insn_and_split "*nabs<mode>2_1"
14030 [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv")
14033 (match_operand:MODEF 1 "register_operand" "0,x,Yv"))))
14034 (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm"))]
14035 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
14037 "&& reload_completed"
14038 [(set (match_dup 0)
14039 (ior:<ssevecmodef> (match_dup 1) (match_dup 2)))]
14041 machine_mode mode = <MODE>mode;
14042 machine_mode vmode = <ssevecmodef>mode;
14044 operands[0] = lowpart_subreg (vmode, operands[0], mode);
14045 operands[1] = lowpart_subreg (vmode, operands[1], mode);
14047 if (!TARGET_AVX && operands_match_p (operands[0], operands[2]))
14048 std::swap (operands[1], operands[2]);
14050 [(set_attr "isa" "noavx,noavx,avx")])
14052 ;; Conditionalize these after reload. If they match before reload, we
14053 ;; lose the clobber and ability to use integer instructions.
14055 (define_insn "*<code><mode>2_i387"
14056 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
14057 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
14058 "TARGET_80387 && reload_completed"
14059 "<absneg_mnemonic>"
14060 [(set_attr "type" "fsgn")
14061 (set_attr "mode" "<MODE>")])
14063 ;; Copysign instructions
14065 (define_expand "copysign<mode>3"
14066 [(match_operand:SSEMODEF 0 "register_operand")
14067 (match_operand:SSEMODEF 1 "nonmemory_operand")
14068 (match_operand:SSEMODEF 2 "register_operand")]
14069 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14070 || (TARGET_SSE && (<MODE>mode == TFmode))
14071 || (TARGET_AVX512FP16 && (<MODE>mode ==HFmode))"
14072 "ix86_expand_copysign (operands); DONE;")
14074 (define_expand "xorsign<mode>3"
14075 [(match_operand:MODEFH 0 "register_operand")
14076 (match_operand:MODEFH 1 "register_operand")
14077 (match_operand:MODEFH 2 "register_operand")]
14078 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14079 || <MODE>mode == HFmode"
14081 if (rtx_equal_p (operands[1], operands[2]))
14082 emit_insn (gen_abs<mode>2 (operands[0], operands[1]));
14084 ix86_expand_xorsign (operands);
14088 ;; One complement instructions
14090 (define_expand "one_cmpl<mode>2"
14091 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
14092 (not:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
14095 ix86_expand_unary_operator (NOT, <MODE>mode, operands, TARGET_APX_NDD);
14099 (define_insn_and_split "*one_cmpl<dwi>2_doubleword"
14100 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,&r")
14101 (not:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0,ro")))]
14102 "ix86_unary_operator_ok (NOT, <DWI>mode, operands, TARGET_APX_NDD)"
14104 "&& reload_completed"
14105 [(set (match_dup 0)
14106 (not:DWIH (match_dup 1)))
14108 (not:DWIH (match_dup 3)))]
14109 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);"
14110 [(set_attr "isa" "*,apx_ndd")])
14112 (define_insn "*one_cmpl<mode>2_1"
14113 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,?k")
14114 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0,rm,k")))]
14115 "ix86_unary_operator_ok (NOT, <MODE>mode, operands, TARGET_APX_NDD)"
14117 not{<imodesuffix>}\t%0
14118 not{<imodesuffix>}\t{%1, %0|%0, %1}
14120 [(set_attr "isa" "*,apx_ndd,<kmov_isa>")
14121 (set_attr "type" "negnot,negnot,msklog")
14122 (set_attr "mode" "<MODE>")])
14124 (define_insn "*one_cmplsi2_1_zext"
14125 [(set (match_operand:DI 0 "register_operand" "=r,r,?k")
14127 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm,k"))))]
14129 && ix86_unary_operator_ok (NOT, SImode, operands, TARGET_APX_NDD)"
14132 not{l}\t{%1, %k0|%k0, %1}
14134 [(set_attr "isa" "x64,apx_ndd,avx512bw")
14135 (set_attr "type" "negnot,negnot,msklog")
14136 (set_attr "mode" "SI,SI,SI")])
14138 (define_insn "*one_cmplqi2_1"
14139 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r,?k")
14140 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,rm,k")))]
14141 "ix86_unary_operator_ok (NOT, QImode, operands, TARGET_APX_NDD)"
14145 not{b}\t{%1, %0|%0, %1}
14147 [(set_attr "isa" "*,*,apx_ndd,avx512f")
14148 (set_attr "type" "negnot,negnot,negnot,msklog")
14150 (cond [(eq_attr "alternative" "1")
14151 (const_string "SI")
14152 (and (eq_attr "alternative" "3")
14153 (match_test "!TARGET_AVX512DQ"))
14154 (const_string "HI")
14156 (const_string "QI")))
14157 ;; Potential partial reg stall on alternative 1.
14158 (set (attr "preferred_for_speed")
14159 (cond [(eq_attr "alternative" "1")
14160 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
14161 (symbol_ref "true")))])
14163 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
14164 (define_insn_and_split "*one_cmpl<mode>_1_slp"
14165 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
14166 (not:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")))]
14167 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
14169 not{<imodesuffix>}\t%0
14171 "&& reload_completed
14172 && !(rtx_equal_p (operands[0], operands[1]))"
14173 [(set (strict_low_part (match_dup 0)) (match_dup 1))
14174 (set (strict_low_part (match_dup 0))
14175 (not:SWI12 (match_dup 0)))]
14177 [(set_attr "type" "negnot")
14178 (set_attr "mode" "<MODE>")])
14180 (define_insn "*one_cmpl<mode>2_2"
14181 [(set (reg FLAGS_REG)
14182 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0,rm"))
14184 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,r")
14185 (not:SWI (match_dup 1)))]
14186 "ix86_match_ccmode (insn, CCNOmode)
14187 && ix86_unary_operator_ok (NOT, <MODE>mode, operands, TARGET_APX_NDD)"
14189 [(set_attr "type" "alu1")
14190 (set_attr "isa" "*,apx_ndd")
14191 (set_attr "mode" "<MODE>")])
14194 [(set (match_operand 0 "flags_reg_operand")
14195 (match_operator 2 "compare_operator"
14196 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
14198 (set (match_operand:SWI 1 "nonimmediate_operand")
14199 (not:SWI (match_dup 3)))]
14200 "ix86_match_ccmode (insn, CCNOmode)"
14201 [(parallel [(set (match_dup 0)
14202 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
14205 (xor:SWI (match_dup 3) (const_int -1)))])])
14207 (define_insn "*one_cmplsi2_2_zext"
14208 [(set (reg FLAGS_REG)
14209 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm"))
14211 (set (match_operand:DI 0 "register_operand" "=r,r")
14212 (zero_extend:DI (not:SI (match_dup 1))))]
14213 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
14214 && ix86_unary_operator_ok (NOT, SImode, operands, TARGET_APX_NDD)"
14216 [(set_attr "type" "alu1")
14217 (set_attr "isa" "*,apx_ndd")
14218 (set_attr "mode" "SI")])
14221 [(set (match_operand 0 "flags_reg_operand")
14222 (match_operator 2 "compare_operator"
14223 [(not:SI (match_operand:SI 3 "nonimmediate_operand"))
14225 (set (match_operand:DI 1 "register_operand")
14226 (zero_extend:DI (not:SI (match_dup 3))))]
14227 "ix86_match_ccmode (insn, CCNOmode)"
14228 [(parallel [(set (match_dup 0)
14229 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
14232 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
14234 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
14235 (define_insn_and_split "*one_cmplqi_ext<mode>_1"
14236 [(set (zero_extract:SWI248
14237 (match_operand 0 "int248_register_operand" "+Q,&Q")
14243 (match_operator:SWI248 2 "extract_operator"
14244 [(match_operand 1 "int248_register_operand" "0,!Q")
14246 (const_int 8)]) 0)) 0))]
14252 && !(rtx_equal_p (operands[0], operands[1]))"
14253 [(set (zero_extract:SWI248
14254 (match_dup 0) (const_int 8) (const_int 8))
14255 (zero_extract:SWI248
14256 (match_dup 1) (const_int 8) (const_int 8)))
14257 (set (zero_extract:SWI248
14258 (match_dup 0) (const_int 8) (const_int 8))
14263 [(match_dup 0) (const_int 8) (const_int 8)]) 0)) 0))]
14265 [(set_attr "type" "negnot")
14266 (set_attr "mode" "QI")])
14268 ;; Shift instructions
14270 ;; DImode shifts are implemented using the i386 "shift double" opcode,
14271 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
14272 ;; is variable, then the count is in %cl and the "imm" operand is dropped
14273 ;; from the assembler input.
14275 ;; This instruction shifts the target reg/mem as usual, but instead of
14276 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
14277 ;; is a left shift double, bits are taken from the high order bits of
14278 ;; reg, else if the insn is a shift right double, bits are taken from the
14279 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
14280 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
14282 ;; Since sh[lr]d does not change the `reg' operand, that is done
14283 ;; separately, making all shifts emit pairs of shift double and normal
14284 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
14285 ;; support a 63 bit shift, each shift where the count is in a reg expands
14286 ;; to a pair of shifts, a branch, a shift by 32 and a label.
14288 ;; If the shift count is a constant, we need never emit more than one
14289 ;; shift pair, instead using moves and sign extension for counts greater
14292 (define_expand "ashl<mode>3"
14293 [(set (match_operand:SDWIM 0 "<shift_operand>")
14294 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
14295 (match_operand:QI 2 "nonmemory_operand")))]
14298 ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands, TARGET_APX_NDD);
14302 (define_insn_and_split "*ashl<dwi>3_doubleword_mask"
14303 [(set (match_operand:<DWI> 0 "register_operand")
14305 (match_operand:<DWI> 1 "register_operand")
14308 (match_operand 2 "int248_register_operand" "c")
14309 (match_operand 3 "const_int_operand")) 0)))
14310 (clobber (reg:CC FLAGS_REG))]
14311 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
14312 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
14313 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
14314 && ix86_pre_reload_split ()"
14318 [(set (match_dup 6)
14319 (ior:DWIH (ashift:DWIH (match_dup 6)
14320 (and:QI (match_dup 2) (match_dup 8)))
14322 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
14323 (minus:QI (match_dup 9)
14324 (and:QI (match_dup 2) (match_dup 8)))) 0)))
14325 (clobber (reg:CC FLAGS_REG))])
14327 [(set (match_dup 4)
14328 (ashift:DWIH (match_dup 5) (match_dup 2)))
14329 (clobber (reg:CC FLAGS_REG))])]
14331 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
14333 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14334 operands[2] = gen_lowpart (QImode, operands[2]);
14335 emit_insn (gen_ashl<dwi>3_doubleword (operands[0], operands[1],
14340 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
14342 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
14343 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
14345 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14346 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14349 xops[0] = gen_reg_rtx (GET_MODE (operands[2]));
14350 xops[1] = operands[2];
14351 xops[2] = GEN_INT (INTVAL (operands[3])
14352 & ((<MODE_SIZE> * BITS_PER_UNIT) - 1));
14353 ix86_expand_binary_operator (AND, GET_MODE (operands[2]), xops);
14354 operands[2] = xops[0];
14357 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14358 operands[2] = gen_lowpart (QImode, operands[2]);
14360 if (!rtx_equal_p (operands[6], operands[7]))
14361 emit_move_insn (operands[6], operands[7]);
14364 (define_insn_and_split "*ashl<dwi>3_doubleword_mask_1"
14365 [(set (match_operand:<DWI> 0 "register_operand")
14367 (match_operand:<DWI> 1 "register_operand")
14369 (match_operand:QI 2 "register_operand" "c")
14370 (match_operand:QI 3 "const_int_operand"))))
14371 (clobber (reg:CC FLAGS_REG))]
14372 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
14373 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
14374 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
14375 && ix86_pre_reload_split ()"
14379 [(set (match_dup 6)
14380 (ior:DWIH (ashift:DWIH (match_dup 6)
14381 (and:QI (match_dup 2) (match_dup 8)))
14383 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
14384 (minus:QI (match_dup 9)
14385 (and:QI (match_dup 2) (match_dup 8)))) 0)))
14386 (clobber (reg:CC FLAGS_REG))])
14388 [(set (match_dup 4)
14389 (ashift:DWIH (match_dup 5) (match_dup 2)))
14390 (clobber (reg:CC FLAGS_REG))])]
14392 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
14394 emit_insn (gen_ashl<dwi>3_doubleword (operands[0], operands[1],
14399 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
14401 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
14402 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
14404 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14405 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14407 rtx tem = gen_reg_rtx (QImode);
14408 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
14412 if (!rtx_equal_p (operands[6], operands[7]))
14413 emit_move_insn (operands[6], operands[7]);
14416 (define_insn "ashl<mode>3_doubleword"
14417 [(set (match_operand:DWI 0 "register_operand" "=&r,&r")
14418 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n,r")
14419 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
14420 (clobber (reg:CC FLAGS_REG))]
14423 [(set_attr "type" "multi")
14424 (set_attr "isa" "*,apx_ndd")])
14427 [(set (match_operand:DWI 0 "register_operand")
14428 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
14429 (match_operand:QI 2 "nonmemory_operand")))
14430 (clobber (reg:CC FLAGS_REG))]
14431 "epilogue_completed"
14435 && !rtx_equal_p (operands[0], operands[1])
14436 && REG_P (operands[1]))
14437 ix86_split_ashl_ndd (operands, NULL_RTX);
14439 ix86_split_ashl (operands, NULL_RTX, <MODE>mode);
14443 ;; By default we don't ask for a scratch register, because when DWImode
14444 ;; values are manipulated, registers are already at a premium. But if
14445 ;; we have one handy, we won't turn it away.
14448 [(match_scratch:DWIH 3 "r")
14449 (parallel [(set (match_operand:<DWI> 0 "register_operand")
14451 (match_operand:<DWI> 1 "nonmemory_operand")
14452 (match_operand:QI 2 "nonmemory_operand")))
14453 (clobber (reg:CC FLAGS_REG))])
14459 && !rtx_equal_p (operands[0], operands[1])
14460 && (REG_P (operands[1])))
14461 ix86_split_ashl_ndd (operands, operands[3]);
14463 ix86_split_ashl (operands, operands[3], <DWI>mode);
14467 (define_insn_and_split "*ashl<dwi>3_doubleword_highpart"
14468 [(set (match_operand:<DWI> 0 "register_operand" "=r")
14470 (any_extend:<DWI> (match_operand:DWIH 1 "nonimmediate_operand" "rm"))
14471 (match_operand:QI 2 "const_int_operand")))
14472 (clobber (reg:CC FLAGS_REG))]
14473 "INTVAL (operands[2]) >= <MODE_SIZE> * BITS_PER_UNIT
14474 && INTVAL (operands[2]) < <MODE_SIZE> * BITS_PER_UNIT * 2"
14476 "&& reload_completed"
14479 split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[3]);
14480 int bits = INTVAL (operands[2]) - (<MODE_SIZE> * BITS_PER_UNIT);
14481 bool op_equal_p = rtx_equal_p (operands[3], operands[1]);
14485 emit_move_insn (operands[3], operands[1]);
14489 if (!op_equal_p && !TARGET_APX_NDD)
14490 emit_move_insn (operands[3], operands[1]);
14491 rtx op_tmp = TARGET_APX_NDD ? operands[1] : operands[3];
14492 emit_insn (gen_ashl<mode>3 (operands[3], op_tmp, GEN_INT (bits)));
14494 ix86_expand_clear (operands[0]);
14498 (define_insn "x86_64_shld"
14499 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
14500 (ior:DI (ashift:DI (match_dup 0)
14501 (and:QI (match_operand:QI 2 "nonmemory_operand" "Jc")
14506 (match_operand:DI 1 "register_operand" "r"))
14507 (minus:QI (const_int 64)
14508 (and:QI (match_dup 2) (const_int 63)))) 0)))
14509 (clobber (reg:CC FLAGS_REG))]
14511 "shld{q}\t{%2, %1, %0|%0, %1, %2}"
14512 [(set_attr "type" "ishift")
14513 (set_attr "prefix_0f" "1")
14514 (set_attr "mode" "DI")
14515 (set_attr "athlon_decode" "vector")
14516 (set_attr "amdfam10_decode" "vector")
14517 (set_attr "bdver1_decode" "vector")])
14519 (define_insn "x86_64_shld_ndd"
14520 [(set (match_operand:DI 0 "register_operand" "=r")
14521 (ior:DI (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "rm")
14522 (and:QI (match_operand:QI 3 "nonmemory_operand" "Jc")
14527 (match_operand:DI 2 "register_operand" "r"))
14528 (minus:QI (const_int 64)
14529 (and:QI (match_dup 3) (const_int 63)))) 0)))
14530 (clobber (reg:CC FLAGS_REG))]
14532 "shld{q}\t{%3, %2, %1, %0|%0, %1, %2, %3}"
14533 [(set_attr "type" "ishift")
14534 (set_attr "mode" "DI")])
14536 (define_insn "x86_64_shld_1"
14537 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
14538 (ior:DI (ashift:DI (match_dup 0)
14539 (match_operand:QI 2 "const_0_to_63_operand"))
14543 (match_operand:DI 1 "register_operand" "r"))
14544 (match_operand:QI 3 "const_0_to_255_operand")) 0)))
14545 (clobber (reg:CC FLAGS_REG))]
14547 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])"
14548 "shld{q}\t{%2, %1, %0|%0, %1, %2}"
14549 [(set_attr "type" "ishift")
14550 (set_attr "prefix_0f" "1")
14551 (set_attr "mode" "DI")
14552 (set_attr "length_immediate" "1")
14553 (set_attr "athlon_decode" "vector")
14554 (set_attr "amdfam10_decode" "vector")
14555 (set_attr "bdver1_decode" "vector")])
14557 (define_insn "x86_64_shld_ndd_1"
14558 [(set (match_operand:DI 0 "register_operand" "=r")
14559 (ior:DI (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "rm")
14560 (match_operand:QI 3 "const_0_to_63_operand"))
14564 (match_operand:DI 2 "register_operand" "r"))
14565 (match_operand:QI 4 "const_0_to_255_operand")) 0)))
14566 (clobber (reg:CC FLAGS_REG))]
14568 && INTVAL (operands[4]) == 64 - INTVAL (operands[3])"
14569 "shld{q}\t{%3, %2, %1, %0|%0, %1, %2, %3}"
14570 [(set_attr "type" "ishift")
14571 (set_attr "mode" "DI")
14572 (set_attr "length_immediate" "1")])
14575 (define_insn_and_split "*x86_64_shld_shrd_1_nozext"
14576 [(set (match_operand:DI 0 "nonimmediate_operand")
14577 (ior:DI (ashift:DI (match_operand:DI 4 "nonimmediate_operand")
14578 (match_operand:QI 2 "const_0_to_63_operand"))
14580 (match_operand:DI 1 "nonimmediate_operand")
14581 (match_operand:QI 3 "const_0_to_63_operand"))))
14582 (clobber (reg:CC FLAGS_REG))]
14584 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])
14585 && ix86_pre_reload_split ()"
14590 if (rtx_equal_p (operands[4], operands[0]))
14592 operands[1] = force_reg (DImode, operands[1]);
14593 emit_insn (gen_x86_64_shld_1 (operands[0], operands[1], operands[2], operands[3]));
14595 else if (rtx_equal_p (operands[1], operands[0]))
14597 operands[4] = force_reg (DImode, operands[4]);
14598 emit_insn (gen_x86_64_shrd_1 (operands[0], operands[4], operands[3], operands[2]));
14600 else if (TARGET_APX_NDD)
14602 rtx tmp = gen_reg_rtx (DImode);
14603 if (MEM_P (operands[4]))
14605 operands[1] = force_reg (DImode, operands[1]);
14606 emit_insn (gen_x86_64_shld_ndd_1 (tmp, operands[4], operands[1],
14607 operands[2], operands[3]));
14609 else if (MEM_P (operands[1]))
14610 emit_insn (gen_x86_64_shrd_ndd_1 (tmp, operands[1], operands[4],
14611 operands[3], operands[2]));
14613 emit_insn (gen_x86_64_shld_ndd_1 (tmp, operands[4], operands[1],
14614 operands[2], operands[3]));
14615 emit_move_insn (operands[0], tmp);
14619 operands[1] = force_reg (DImode, operands[1]);
14620 rtx tmp = gen_reg_rtx (DImode);
14621 emit_move_insn (tmp, operands[4]);
14622 emit_insn (gen_x86_64_shld_1 (tmp, operands[1], operands[2], operands[3]));
14623 emit_move_insn (operands[0], tmp);
14628 (define_insn_and_split "*x86_64_shld_2"
14629 [(set (match_operand:DI 0 "nonimmediate_operand")
14630 (ior:DI (ashift:DI (match_dup 0)
14631 (match_operand:QI 2 "nonmemory_operand"))
14632 (lshiftrt:DI (match_operand:DI 1 "register_operand")
14633 (minus:QI (const_int 64) (match_dup 2)))))
14634 (clobber (reg:CC FLAGS_REG))]
14635 "TARGET_64BIT && ix86_pre_reload_split ()"
14638 [(parallel [(set (match_dup 0)
14639 (ior:DI (ashift:DI (match_dup 0)
14640 (and:QI (match_dup 2) (const_int 63)))
14643 (zero_extend:TI (match_dup 1))
14644 (minus:QI (const_int 64)
14645 (and:QI (match_dup 2)
14646 (const_int 63)))) 0)))
14647 (clobber (reg:CC FLAGS_REG))])])
14649 (define_insn_and_split "*x86_64_shld_ndd_2"
14650 [(set (match_operand:DI 0 "nonimmediate_operand")
14651 (ior:DI (ashift:DI (match_operand:DI 1 "nonimmediate_operand")
14652 (match_operand:QI 3 "nonmemory_operand"))
14653 (lshiftrt:DI (match_operand:DI 2 "register_operand")
14654 (minus:QI (const_int 64) (match_dup 3)))))
14655 (clobber (reg:CC FLAGS_REG))]
14657 && ix86_pre_reload_split ()"
14660 [(parallel [(set (match_dup 4)
14661 (ior:DI (ashift:DI (match_dup 1)
14662 (and:QI (match_dup 3) (const_int 63)))
14665 (zero_extend:TI (match_dup 2))
14666 (minus:QI (const_int 64)
14667 (and:QI (match_dup 3)
14668 (const_int 63)))) 0)))
14669 (clobber (reg:CC FLAGS_REG))
14670 (set (match_dup 0) (match_dup 4))])]
14672 operands[4] = gen_reg_rtx (DImode);
14673 emit_move_insn (operands[4], operands[0]);
14676 (define_insn "x86_shld"
14677 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
14678 (ior:SI (ashift:SI (match_dup 0)
14679 (and:QI (match_operand:QI 2 "nonmemory_operand" "Ic")
14684 (match_operand:SI 1 "register_operand" "r"))
14685 (minus:QI (const_int 32)
14686 (and:QI (match_dup 2) (const_int 31)))) 0)))
14687 (clobber (reg:CC FLAGS_REG))]
14689 "shld{l}\t{%2, %1, %0|%0, %1, %2}"
14690 [(set_attr "type" "ishift")
14691 (set_attr "prefix_0f" "1")
14692 (set_attr "mode" "SI")
14693 (set_attr "pent_pair" "np")
14694 (set_attr "athlon_decode" "vector")
14695 (set_attr "amdfam10_decode" "vector")
14696 (set_attr "bdver1_decode" "vector")])
14698 (define_insn "x86_shld_ndd"
14699 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14700 (ior:SI (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
14701 (and:QI (match_operand:QI 3 "nonmemory_operand" "Ic")
14706 (match_operand:SI 2 "register_operand" "r"))
14707 (minus:QI (const_int 32)
14708 (and:QI (match_dup 3) (const_int 31)))) 0)))
14709 (clobber (reg:CC FLAGS_REG))]
14711 "shld{l}\t{%3, %2, %1, %0|%0, %1, %2, %3}"
14712 [(set_attr "type" "ishift")
14713 (set_attr "mode" "SI")])
14716 (define_insn "x86_shld_1"
14717 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
14718 (ior:SI (ashift:SI (match_dup 0)
14719 (match_operand:QI 2 "const_0_to_31_operand"))
14723 (match_operand:SI 1 "register_operand" "r"))
14724 (match_operand:QI 3 "const_0_to_63_operand")) 0)))
14725 (clobber (reg:CC FLAGS_REG))]
14726 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])"
14727 "shld{l}\t{%2, %1, %0|%0, %1, %2}"
14728 [(set_attr "type" "ishift")
14729 (set_attr "prefix_0f" "1")
14730 (set_attr "length_immediate" "1")
14731 (set_attr "mode" "SI")
14732 (set_attr "pent_pair" "np")
14733 (set_attr "athlon_decode" "vector")
14734 (set_attr "amdfam10_decode" "vector")
14735 (set_attr "bdver1_decode" "vector")])
14737 (define_insn "x86_shld_ndd_1"
14738 [(set (match_operand:SI 0 "register_operand" "=r")
14739 (ior:SI (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
14740 (match_operand:QI 3 "const_0_to_31_operand"))
14744 (match_operand:SI 2 "register_operand" "r"))
14745 (match_operand:QI 4 "const_0_to_63_operand")) 0)))
14746 (clobber (reg:CC FLAGS_REG))]
14748 && INTVAL (operands[4]) == 32 - INTVAL (operands[3])"
14749 "shld{l}\t{%3, %2, %1, %0|%0, %1, %2, %3}"
14750 [(set_attr "type" "ishift")
14751 (set_attr "length_immediate" "1")
14752 (set_attr "mode" "SI")])
14755 (define_insn_and_split "*x86_shld_shrd_1_nozext"
14756 [(set (match_operand:SI 0 "nonimmediate_operand")
14757 (ior:SI (ashift:SI (match_operand:SI 4 "nonimmediate_operand")
14758 (match_operand:QI 2 "const_0_to_31_operand"))
14760 (match_operand:SI 1 "nonimmediate_operand")
14761 (match_operand:QI 3 "const_0_to_31_operand"))))
14762 (clobber (reg:CC FLAGS_REG))]
14763 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])
14764 && ix86_pre_reload_split ()"
14769 if (rtx_equal_p (operands[4], operands[0]))
14771 operands[1] = force_reg (SImode, operands[1]);
14772 emit_insn (gen_x86_shld_1 (operands[0], operands[1], operands[2], operands[3]));
14774 else if (rtx_equal_p (operands[1], operands[0]))
14776 operands[4] = force_reg (SImode, operands[4]);
14777 emit_insn (gen_x86_shrd_1 (operands[0], operands[4], operands[3], operands[2]));
14779 else if (TARGET_APX_NDD)
14781 rtx tmp = gen_reg_rtx (SImode);
14782 if (MEM_P (operands[4]))
14784 operands[1] = force_reg (SImode, operands[1]);
14785 emit_insn (gen_x86_shld_ndd_1 (tmp, operands[4], operands[1],
14786 operands[2], operands[3]));
14788 else if (MEM_P (operands[1]))
14789 emit_insn (gen_x86_shrd_ndd_1 (tmp, operands[1], operands[4],
14790 operands[3], operands[2]));
14792 emit_insn (gen_x86_shld_ndd_1 (tmp, operands[4], operands[1],
14793 operands[2], operands[3]));
14794 emit_move_insn (operands[0], tmp);
14798 operands[1] = force_reg (SImode, operands[1]);
14799 rtx tmp = gen_reg_rtx (SImode);
14800 emit_move_insn (tmp, operands[4]);
14801 emit_insn (gen_x86_shld_1 (tmp, operands[1], operands[2], operands[3]));
14802 emit_move_insn (operands[0], tmp);
14807 (define_insn_and_split "*x86_shld_2"
14808 [(set (match_operand:SI 0 "nonimmediate_operand")
14809 (ior:SI (ashift:SI (match_dup 0)
14810 (match_operand:QI 2 "nonmemory_operand"))
14811 (lshiftrt:SI (match_operand:SI 1 "register_operand")
14812 (minus:QI (const_int 32) (match_dup 2)))))
14813 (clobber (reg:CC FLAGS_REG))]
14814 "TARGET_64BIT && ix86_pre_reload_split ()"
14817 [(parallel [(set (match_dup 0)
14818 (ior:SI (ashift:SI (match_dup 0)
14819 (and:QI (match_dup 2) (const_int 31)))
14822 (zero_extend:DI (match_dup 1))
14823 (minus:QI (const_int 32)
14824 (and:QI (match_dup 2)
14825 (const_int 31)))) 0)))
14826 (clobber (reg:CC FLAGS_REG))])])
14828 (define_insn_and_split "*x86_shld_ndd_2"
14829 [(set (match_operand:SI 0 "nonimmediate_operand")
14830 (ior:SI (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
14831 (match_operand:QI 3 "nonmemory_operand"))
14832 (lshiftrt:SI (match_operand:SI 2 "register_operand")
14833 (minus:QI (const_int 32) (match_dup 3)))))
14834 (clobber (reg:CC FLAGS_REG))]
14836 && ix86_pre_reload_split ()"
14839 [(parallel [(set (match_dup 4)
14840 (ior:SI (ashift:SI (match_dup 1)
14841 (and:QI (match_dup 3) (const_int 31)))
14844 (zero_extend:DI (match_dup 2))
14845 (minus:QI (const_int 32)
14846 (and:QI (match_dup 3)
14847 (const_int 31)))) 0)))
14848 (clobber (reg:CC FLAGS_REG))
14849 (set (match_dup 0) (match_dup 4))])]
14851 operands[4] = gen_reg_rtx (SImode);
14852 emit_move_insn (operands[4], operands[0]);
14855 (define_expand "@x86_shift<mode>_adj_1"
14856 [(set (reg:CCZ FLAGS_REG)
14857 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
14860 (set (match_operand:SWI48 0 "register_operand")
14861 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
14862 (match_operand:SWI48 1 "register_operand")
14865 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
14866 (match_operand:SWI48 3 "register_operand")
14869 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
14871 (define_expand "@x86_shift<mode>_adj_2"
14872 [(use (match_operand:SWI48 0 "register_operand"))
14873 (use (match_operand:SWI48 1 "register_operand"))
14874 (use (match_operand:QI 2 "register_operand"))]
14877 rtx_code_label *label = gen_label_rtx ();
14880 emit_insn (gen_testqi_ccz_1 (operands[2],
14881 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
14883 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
14884 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
14885 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
14886 gen_rtx_LABEL_REF (VOIDmode, label),
14888 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
14889 JUMP_LABEL (tmp) = label;
14891 emit_move_insn (operands[0], operands[1]);
14892 ix86_expand_clear (operands[1]);
14894 emit_label (label);
14895 LABEL_NUSES (label) = 1;
14900 ;; Avoid useless masking of count operand.
14901 (define_insn_and_split "*ashl<mode>3_mask"
14902 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14904 (match_operand:SWI48 1 "nonimmediate_operand")
14907 (match_operand 2 "int248_register_operand" "c,r")
14908 (match_operand 3 "const_int_operand")) 0)))
14909 (clobber (reg:CC FLAGS_REG))]
14910 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
14911 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
14912 == GET_MODE_BITSIZE (<MODE>mode)-1
14913 && ix86_pre_reload_split ()"
14917 [(set (match_dup 0)
14918 (ashift:SWI48 (match_dup 1)
14920 (clobber (reg:CC FLAGS_REG))])]
14922 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14923 operands[2] = gen_lowpart (QImode, operands[2]);
14925 [(set_attr "isa" "*,bmi2")])
14927 (define_insn_and_split "*ashl<mode>3_mask_1"
14928 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14930 (match_operand:SWI48 1 "nonimmediate_operand")
14932 (match_operand:QI 2 "register_operand" "c,r")
14933 (match_operand:QI 3 "const_int_operand"))))
14934 (clobber (reg:CC FLAGS_REG))]
14935 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
14936 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
14937 == GET_MODE_BITSIZE (<MODE>mode)-1
14938 && ix86_pre_reload_split ()"
14942 [(set (match_dup 0)
14943 (ashift:SWI48 (match_dup 1)
14945 (clobber (reg:CC FLAGS_REG))])]
14947 [(set_attr "isa" "*,bmi2")])
14949 (define_insn "*bmi2_ashl<mode>3_1"
14950 [(set (match_operand:SWI48 0 "register_operand" "=r")
14951 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14952 (match_operand:SWI48 2 "register_operand" "r")))]
14954 "shlx\t{%2, %1, %0|%0, %1, %2}"
14955 [(set_attr "type" "ishiftx")
14956 (set_attr "mode" "<MODE>")])
14958 (define_insn "*ashl<mode>3_1"
14959 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,?k,r")
14960 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm,k,rm")
14961 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r,<KS>,c<S>")))
14962 (clobber (reg:CC FLAGS_REG))]
14963 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands, TARGET_APX_NDD)"
14965 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
14966 switch (get_attr_type (insn))
14974 gcc_assert (operands[2] == const1_rtx);
14975 gcc_assert (rtx_equal_p (operands[0], operands[1]));
14976 return "add{<imodesuffix>}\t%0, %0";
14979 if (operands[2] == const1_rtx
14980 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14981 /* For NDD form instructions related to TARGET_SHIFT1, the $1
14982 immediate do not need to be omitted as assembler will map it
14983 to use shorter encoding. */
14985 return "sal{<imodesuffix>}\t%0";
14987 return use_ndd ? "sal{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
14988 : "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14991 [(set_attr "isa" "*,*,bmi2,avx512bw,apx_ndd")
14993 (cond [(eq_attr "alternative" "1")
14994 (const_string "lea")
14995 (eq_attr "alternative" "2")
14996 (const_string "ishiftx")
14997 (eq_attr "alternative" "4")
14998 (const_string "ishift")
14999 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
15000 (match_operand 0 "register_operand"))
15001 (match_operand 2 "const1_operand"))
15002 (const_string "alu")
15003 (eq_attr "alternative" "3")
15004 (const_string "msklog")
15006 (const_string "ishift")))
15007 (set (attr "length_immediate")
15009 (ior (eq_attr "type" "alu")
15010 (and (eq_attr "type" "ishift")
15011 (and (match_operand 2 "const1_operand")
15012 (ior (match_test "TARGET_SHIFT1")
15013 (match_test "optimize_function_for_size_p (cfun)")))))
15015 (const_string "*")))
15016 (set_attr "mode" "<MODE>")])
15018 ;; Convert shift to the shiftx pattern to avoid flags dependency.
15020 [(set (match_operand:SWI48 0 "register_operand")
15021 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
15022 (match_operand:QI 2 "register_operand")))
15023 (clobber (reg:CC FLAGS_REG))]
15024 "TARGET_BMI2 && reload_completed"
15025 [(set (match_dup 0)
15026 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
15027 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
15029 (define_insn "*bmi2_ashlsi3_1_zext"
15030 [(set (match_operand:DI 0 "register_operand" "=r")
15032 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
15033 (match_operand:SI 2 "register_operand" "r"))))]
15034 "TARGET_64BIT && TARGET_BMI2"
15035 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
15036 [(set_attr "type" "ishiftx")
15037 (set_attr "mode" "SI")])
15039 (define_insn "*ashlsi3_1_zext"
15040 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
15042 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm,rm")
15043 (match_operand:QI 2 "nonmemory_operand" "cI,M,r,cI"))))
15044 (clobber (reg:CC FLAGS_REG))]
15046 && ix86_binary_operator_ok (ASHIFT, SImode, operands, TARGET_APX_NDD)"
15048 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
15049 switch (get_attr_type (insn))
15056 gcc_assert (operands[2] == const1_rtx);
15057 return "add{l}\t%k0, %k0";
15060 if (operands[2] == const1_rtx
15061 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
15063 return "sal{l}\t%k0";
15065 return use_ndd ? "sal{l}\t{%2, %1, %k0|%k0, %1, %2}"
15066 : "sal{l}\t{%2, %k0|%k0, %2}";
15069 [(set_attr "isa" "*,*,bmi2,apx_ndd")
15071 (cond [(eq_attr "alternative" "1")
15072 (const_string "lea")
15073 (eq_attr "alternative" "2")
15074 (const_string "ishiftx")
15075 (eq_attr "alternative" "3")
15076 (const_string "ishift")
15077 (and (match_test "TARGET_DOUBLE_WITH_ADD")
15078 (match_operand 2 "const1_operand"))
15079 (const_string "alu")
15081 (const_string "ishift")))
15082 (set (attr "length_immediate")
15084 (ior (eq_attr "type" "alu")
15085 (and (eq_attr "type" "ishift")
15086 (and (match_operand 2 "const1_operand")
15087 (ior (match_test "TARGET_SHIFT1")
15088 (match_test "optimize_function_for_size_p (cfun)")))))
15090 (const_string "*")))
15091 (set_attr "mode" "SI")])
15093 ;; Convert shift to the shiftx pattern to avoid flags dependency.
15095 [(set (match_operand:DI 0 "register_operand")
15097 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
15098 (match_operand:QI 2 "register_operand"))))
15099 (clobber (reg:CC FLAGS_REG))]
15100 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
15101 [(set (match_dup 0)
15102 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
15103 "operands[2] = gen_lowpart (SImode, operands[2]);")
15105 (define_insn "*ashlhi3_1"
15106 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp,?k,r")
15107 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l,k,rm")
15108 (match_operand:QI 2 "nonmemory_operand" "cI,M,Ww,cI")))
15109 (clobber (reg:CC FLAGS_REG))]
15110 "ix86_binary_operator_ok (ASHIFT, HImode, operands, TARGET_APX_NDD)"
15112 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
15113 switch (get_attr_type (insn))
15120 gcc_assert (operands[2] == const1_rtx);
15121 return "add{w}\t%0, %0";
15124 if (operands[2] == const1_rtx
15125 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
15127 return "sal{w}\t%0";
15129 return use_ndd ? "sal{w}\t{%2, %1, %0|%0, %1, %2}"
15130 : "sal{w}\t{%2, %0|%0, %2}";
15133 [(set_attr "isa" "*,*,avx512f,apx_ndd")
15135 (cond [(eq_attr "alternative" "1")
15136 (const_string "lea")
15137 (eq_attr "alternative" "2")
15138 (const_string "msklog")
15139 (eq_attr "alternative" "3")
15140 (const_string "ishift")
15141 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
15142 (match_operand 0 "register_operand"))
15143 (match_operand 2 "const1_operand"))
15144 (const_string "alu")
15146 (const_string "ishift")))
15147 (set (attr "length_immediate")
15149 (ior (eq_attr "type" "alu")
15150 (and (eq_attr "type" "ishift")
15151 (and (match_operand 2 "const1_operand")
15152 (ior (match_test "TARGET_SHIFT1")
15153 (match_test "optimize_function_for_size_p (cfun)")))))
15155 (const_string "*")))
15156 (set_attr "mode" "HI,SI,HI,HI")])
15158 (define_insn "*ashlqi3_1"
15159 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp,?k,r")
15160 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l,k,rm")
15161 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M,Wb,cI")))
15162 (clobber (reg:CC FLAGS_REG))]
15163 "ix86_binary_operator_ok (ASHIFT, QImode, operands, TARGET_APX_NDD)"
15165 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
15166 switch (get_attr_type (insn))
15173 gcc_assert (operands[2] == const1_rtx);
15174 if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
15175 return "add{l}\t%k0, %k0";
15177 return "add{b}\t%0, %0";
15180 if (operands[2] == const1_rtx
15181 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
15184 if (get_attr_mode (insn) == MODE_SI)
15185 return "sal{l}\t%k0";
15187 return "sal{b}\t%0";
15191 if (get_attr_mode (insn) == MODE_SI)
15192 return "sal{l}\t{%2, %k0|%k0, %2}";
15194 return use_ndd ? "sal{b}\t{%2, %1, %0|%0, %1, %2}"
15195 : "sal{b}\t{%2, %0|%0, %2}";
15199 [(set_attr "isa" "*,*,*,avx512dq,apx_ndd")
15201 (cond [(eq_attr "alternative" "2")
15202 (const_string "lea")
15203 (eq_attr "alternative" "3")
15204 (const_string "msklog")
15205 (eq_attr "alternative" "4")
15206 (const_string "ishift")
15207 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
15208 (match_operand 0 "register_operand"))
15209 (match_operand 2 "const1_operand"))
15210 (const_string "alu")
15212 (const_string "ishift")))
15213 (set (attr "length_immediate")
15215 (ior (eq_attr "type" "alu")
15216 (and (eq_attr "type" "ishift")
15217 (and (match_operand 2 "const1_operand")
15218 (ior (match_test "TARGET_SHIFT1")
15219 (match_test "optimize_function_for_size_p (cfun)")))))
15221 (const_string "*")))
15222 (set_attr "mode" "QI,SI,SI,QI,QI")
15223 ;; Potential partial reg stall on alternative 1.
15224 (set (attr "preferred_for_speed")
15225 (cond [(eq_attr "alternative" "1,4")
15226 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
15227 (symbol_ref "true")))])
15229 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
15230 (define_insn_and_split "*ashl<mode>3_1_slp"
15231 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
15232 (ashift:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
15233 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
15234 (clobber (reg:CC FLAGS_REG))]
15235 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
15237 if (which_alternative)
15240 switch (get_attr_type (insn))
15243 gcc_assert (operands[2] == const1_rtx);
15244 return "add{<imodesuffix>}\t%0, %0";
15247 if (operands[2] == const1_rtx
15248 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15249 return "sal{<imodesuffix>}\t%0";
15251 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
15254 "&& reload_completed
15255 && !(rtx_equal_p (operands[0], operands[1]))"
15256 [(set (strict_low_part (match_dup 0)) (match_dup 1))
15258 [(set (strict_low_part (match_dup 0))
15259 (ashift:SWI12 (match_dup 0) (match_dup 2)))
15260 (clobber (reg:CC FLAGS_REG))])]
15262 [(set (attr "type")
15263 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
15264 (match_operand 2 "const1_operand"))
15265 (const_string "alu")
15267 (const_string "ishift")))
15268 (set (attr "length_immediate")
15270 (ior (eq_attr "type" "alu")
15271 (and (eq_attr "type" "ishift")
15272 (and (match_operand 2 "const1_operand")
15273 (ior (match_test "TARGET_SHIFT1")
15274 (match_test "optimize_function_for_size_p (cfun)")))))
15276 (const_string "*")))
15277 (set_attr "mode" "<MODE>")])
15279 ;; Convert ashift to the lea pattern to avoid flags dependency.
15281 [(set (match_operand:SWI 0 "general_reg_operand")
15282 (ashift:SWI (match_operand:SWI 1 "index_reg_operand")
15283 (match_operand 2 "const_0_to_3_operand")))
15284 (clobber (reg:CC FLAGS_REG))]
15286 && REGNO (operands[0]) != REGNO (operands[1])"
15287 [(set (match_dup 0)
15288 (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
15290 if (<MODE>mode != <LEAMODE>mode)
15292 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
15293 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
15295 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
15298 ;; Convert ashift to the lea pattern to avoid flags dependency.
15300 [(set (match_operand:DI 0 "general_reg_operand")
15302 (ashift:SI (match_operand:SI 1 "index_reg_operand")
15303 (match_operand 2 "const_0_to_3_operand"))))
15304 (clobber (reg:CC FLAGS_REG))]
15305 "TARGET_64BIT && reload_completed
15306 && REGNO (operands[0]) != REGNO (operands[1])"
15307 [(set (match_dup 0)
15308 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
15310 operands[1] = gen_lowpart (SImode, operands[1]);
15311 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
15314 ;; This pattern can't accept a variable shift count, since shifts by
15315 ;; zero don't affect the flags. We assume that shifts by constant
15316 ;; zero are optimized away.
15317 (define_insn "*ashl<mode>3_cmp"
15318 [(set (reg FLAGS_REG)
15320 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0,rm")
15321 (match_operand:QI 2 "<shift_immediate_operand>" "<S>,<S>"))
15323 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,r")
15324 (ashift:SWI (match_dup 1) (match_dup 2)))]
15325 "(optimize_function_for_size_p (cfun)
15326 || !TARGET_PARTIAL_FLAG_REG_STALL
15327 || (operands[2] == const1_rtx
15329 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
15330 && ix86_match_ccmode (insn, CCGOCmode)
15331 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands, TARGET_APX_NDD)"
15333 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
15334 switch (get_attr_type (insn))
15337 gcc_assert (operands[2] == const1_rtx);
15338 return "add{<imodesuffix>}\t%0, %0";
15341 if (operands[2] == const1_rtx
15342 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
15344 return "sal{<imodesuffix>}\t%0";
15346 return use_ndd ? "sal{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
15347 : "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
15350 [(set_attr "isa" "*,apx_ndd")
15352 (cond [(eq_attr "alternative" "1")
15353 (const_string "ishift")
15354 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
15355 (match_operand 0 "register_operand"))
15356 (match_operand 2 "const1_operand"))
15357 (const_string "alu")
15359 (const_string "ishift")))
15360 (set (attr "length_immediate")
15362 (ior (eq_attr "type" "alu")
15363 (and (eq_attr "type" "ishift")
15364 (and (match_operand 2 "const1_operand")
15365 (ior (match_test "TARGET_SHIFT1")
15366 (match_test "optimize_function_for_size_p (cfun)")))))
15368 (const_string "*")))
15369 (set_attr "mode" "<MODE>")])
15371 (define_insn "*ashlsi3_cmp_zext"
15372 [(set (reg FLAGS_REG)
15374 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
15375 (match_operand:QI 2 "const_1_to_31_operand"))
15377 (set (match_operand:DI 0 "register_operand" "=r,r")
15378 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
15380 && (optimize_function_for_size_p (cfun)
15381 || !TARGET_PARTIAL_FLAG_REG_STALL
15382 || (operands[2] == const1_rtx
15384 || TARGET_DOUBLE_WITH_ADD)))
15385 && ix86_match_ccmode (insn, CCGOCmode)
15386 && ix86_binary_operator_ok (ASHIFT, SImode, operands, TARGET_APX_NDD)"
15388 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
15389 switch (get_attr_type (insn))
15392 gcc_assert (operands[2] == const1_rtx);
15393 return "add{l}\t%k0, %k0";
15396 if (operands[2] == const1_rtx
15397 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
15399 return "sal{l}\t%k0";
15401 return use_ndd ? "sal{l}\t{%2, %1, %k0|%k0, %1, %2}"
15402 : "sal{l}\t{%2, %k0|%k0, %2}";
15405 [(set_attr "isa" "*,apx_ndd")
15407 (cond [(eq_attr "alternative" "1")
15408 (const_string "ishift")
15409 (and (match_test "TARGET_DOUBLE_WITH_ADD")
15410 (match_operand 2 "const1_operand"))
15411 (const_string "alu")
15413 (const_string "ishift")))
15414 (set (attr "length_immediate")
15416 (ior (eq_attr "type" "alu")
15417 (and (eq_attr "type" "ishift")
15418 (and (match_operand 2 "const1_operand")
15419 (ior (match_test "TARGET_SHIFT1")
15420 (match_test "optimize_function_for_size_p (cfun)")))))
15422 (const_string "*")))
15423 (set_attr "mode" "SI")])
15425 (define_insn "*ashl<mode>3_cconly"
15426 [(set (reg FLAGS_REG)
15428 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0,rm")
15429 (match_operand:QI 2 "<shift_immediate_operand>" "<S>,<S>"))
15431 (clobber (match_scratch:SWI 0 "=<r>,r"))]
15432 "(optimize_function_for_size_p (cfun)
15433 || !TARGET_PARTIAL_FLAG_REG_STALL
15434 || (operands[2] == const1_rtx
15436 || TARGET_DOUBLE_WITH_ADD)))
15437 && ix86_match_ccmode (insn, CCGOCmode)"
15439 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
15440 switch (get_attr_type (insn))
15443 gcc_assert (operands[2] == const1_rtx);
15444 return "add{<imodesuffix>}\t%0, %0";
15447 if (operands[2] == const1_rtx
15448 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
15450 return "sal{<imodesuffix>}\t%0";
15452 return use_ndd ? "sal{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
15453 : "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
15456 [(set_attr "isa" "*,apx_ndd")
15458 (cond [(eq_attr "alternative" "1")
15459 (const_string "ishift")
15460 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
15461 (match_operand 0 "register_operand"))
15462 (match_operand 2 "const1_operand"))
15463 (const_string "alu")
15465 (const_string "ishift")))
15466 (set (attr "length_immediate")
15468 (ior (eq_attr "type" "alu")
15469 (and (eq_attr "type" "ishift")
15470 (and (match_operand 2 "const1_operand")
15471 (ior (match_test "TARGET_SHIFT1")
15472 (match_test "optimize_function_for_size_p (cfun)")))))
15474 (const_string "*")))
15475 (set_attr "mode" "<MODE>")])
15477 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
15478 (define_insn_and_split "*ashlqi_ext<mode>_1"
15479 [(set (zero_extract:SWI248
15480 (match_operand 0 "int248_register_operand" "+Q,&Q")
15486 (match_operator:SWI248 3 "extract_operator"
15487 [(match_operand 1 "int248_register_operand" "0,!Q")
15490 (match_operand:QI 2 "nonmemory_operand" "cI,cI")) 0))
15491 (clobber (reg:CC FLAGS_REG))]
15494 if (which_alternative)
15497 switch (get_attr_type (insn))
15500 gcc_assert (operands[2] == const1_rtx);
15501 return "add{b}\t%h0, %h0";
15504 if (operands[2] == const1_rtx
15505 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15506 return "sal{b}\t%h0";
15508 return "sal{b}\t{%2, %h0|%h0, %2}";
15512 && !(rtx_equal_p (operands[0], operands[1]))"
15513 [(set (zero_extract:SWI248
15514 (match_dup 0) (const_int 8) (const_int 8))
15515 (zero_extract:SWI248
15516 (match_dup 1) (const_int 8) (const_int 8)))
15518 [(set (zero_extract:SWI248
15519 (match_dup 0) (const_int 8) (const_int 8))
15524 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
15526 (clobber (reg:CC FLAGS_REG))])]
15528 [(set (attr "type")
15529 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
15530 (match_operand 2 "const1_operand"))
15531 (const_string "alu")
15533 (const_string "ishift")))
15534 (set (attr "length_immediate")
15536 (ior (eq_attr "type" "alu")
15537 (and (eq_attr "type" "ishift")
15538 (and (match_operand 2 "const1_operand")
15539 (ior (match_test "TARGET_SHIFT1")
15540 (match_test "optimize_function_for_size_p (cfun)")))))
15542 (const_string "*")))
15543 (set_attr "mode" "QI")])
15545 ;; See comment above `ashl<mode>3' about how this works.
15547 (define_expand "<insn><mode>3"
15548 [(set (match_operand:SDWIM 0 "<shift_operand>")
15549 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
15550 (match_operand:QI 2 "nonmemory_operand")))]
15553 ix86_expand_binary_operator (<CODE>, <MODE>mode, operands, TARGET_APX_NDD);
15557 ;; Avoid useless masking of count operand.
15558 (define_insn_and_split "*<insn><mode>3_mask"
15559 [(set (match_operand:SWI48 0 "nonimmediate_operand")
15561 (match_operand:SWI48 1 "nonimmediate_operand")
15564 (match_operand 2 "int248_register_operand" "c,r")
15565 (match_operand 3 "const_int_operand")) 0)))
15566 (clobber (reg:CC FLAGS_REG))]
15567 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
15568 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15569 == GET_MODE_BITSIZE (<MODE>mode)-1
15570 && ix86_pre_reload_split ()"
15574 [(set (match_dup 0)
15575 (any_shiftrt:SWI48 (match_dup 1)
15577 (clobber (reg:CC FLAGS_REG))])]
15579 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
15580 operands[2] = gen_lowpart (QImode, operands[2]);
15582 [(set_attr "isa" "*,bmi2")])
15584 (define_insn_and_split "*<insn><mode>3_mask_1"
15585 [(set (match_operand:SWI48 0 "nonimmediate_operand")
15587 (match_operand:SWI48 1 "nonimmediate_operand")
15589 (match_operand:QI 2 "register_operand" "c,r")
15590 (match_operand:QI 3 "const_int_operand"))))
15591 (clobber (reg:CC FLAGS_REG))]
15592 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
15593 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15594 == GET_MODE_BITSIZE (<MODE>mode)-1
15595 && ix86_pre_reload_split ()"
15599 [(set (match_dup 0)
15600 (any_shiftrt:SWI48 (match_dup 1)
15602 (clobber (reg:CC FLAGS_REG))])]
15604 [(set_attr "isa" "*,bmi2")])
15606 (define_insn_and_split "*<insn><dwi>3_doubleword_mask"
15607 [(set (match_operand:<DWI> 0 "register_operand")
15609 (match_operand:<DWI> 1 "register_operand")
15612 (match_operand 2 "int248_register_operand" "c")
15613 (match_operand 3 "const_int_operand")) 0)))
15614 (clobber (reg:CC FLAGS_REG))]
15615 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
15616 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
15617 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
15618 && ix86_pre_reload_split ()"
15622 [(set (match_dup 4)
15623 (ior:DWIH (lshiftrt:DWIH (match_dup 4)
15624 (and:QI (match_dup 2) (match_dup 8)))
15626 (ashift:<DWI> (zero_extend:<DWI> (match_dup 7))
15627 (minus:QI (match_dup 9)
15628 (and:QI (match_dup 2) (match_dup 8)))) 0)))
15629 (clobber (reg:CC FLAGS_REG))])
15631 [(set (match_dup 6)
15632 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
15633 (clobber (reg:CC FLAGS_REG))])]
15635 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
15637 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
15638 operands[2] = gen_lowpart (QImode, operands[2]);
15639 emit_insn (gen_<insn><dwi>3_doubleword (operands[0], operands[1],
15644 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
15646 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
15647 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
15649 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
15650 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
15653 xops[0] = gen_reg_rtx (GET_MODE (operands[2]));
15654 xops[1] = operands[2];
15655 xops[2] = GEN_INT (INTVAL (operands[3])
15656 & ((<MODE_SIZE> * BITS_PER_UNIT) - 1));
15657 ix86_expand_binary_operator (AND, GET_MODE (operands[2]), xops);
15658 operands[2] = xops[0];
15661 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
15662 operands[2] = gen_lowpart (QImode, operands[2]);
15664 if (!rtx_equal_p (operands[4], operands[5]))
15665 emit_move_insn (operands[4], operands[5]);
15668 (define_insn_and_split "*<insn><dwi>3_doubleword_mask_1"
15669 [(set (match_operand:<DWI> 0 "register_operand")
15671 (match_operand:<DWI> 1 "register_operand")
15673 (match_operand:QI 2 "register_operand" "c")
15674 (match_operand:QI 3 "const_int_operand"))))
15675 (clobber (reg:CC FLAGS_REG))]
15676 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
15677 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
15678 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
15679 && ix86_pre_reload_split ()"
15683 [(set (match_dup 4)
15684 (ior:DWIH (lshiftrt:DWIH (match_dup 4)
15685 (and:QI (match_dup 2) (match_dup 8)))
15687 (ashift:<DWI> (zero_extend:<DWI> (match_dup 7))
15688 (minus:QI (match_dup 9)
15689 (and:QI (match_dup 2) (match_dup 8)))) 0)))
15690 (clobber (reg:CC FLAGS_REG))])
15692 [(set (match_dup 6)
15693 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
15694 (clobber (reg:CC FLAGS_REG))])]
15696 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
15698 emit_insn (gen_<insn><dwi>3_doubleword (operands[0], operands[1],
15703 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
15705 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
15706 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
15708 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
15709 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
15711 rtx tem = gen_reg_rtx (QImode);
15712 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
15716 if (!rtx_equal_p (operands[4], operands[5]))
15717 emit_move_insn (operands[4], operands[5]);
15720 (define_insn_and_split "<insn><mode>3_doubleword"
15721 [(set (match_operand:DWI 0 "register_operand" "=&r,&r")
15722 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0,r")
15723 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
15724 (clobber (reg:CC FLAGS_REG))]
15727 "epilogue_completed"
15731 && !rtx_equal_p (operands[0], operands[1]))
15732 ix86_split_rshift_ndd (<CODE>, operands, NULL_RTX);
15734 ix86_split_<insn> (operands, NULL_RTX, <MODE>mode);
15737 [(set_attr "type" "multi")
15738 (set_attr "isa" "*,apx_ndd")])
15740 ;; By default we don't ask for a scratch register, because when DWImode
15741 ;; values are manipulated, registers are already at a premium. But if
15742 ;; we have one handy, we won't turn it away.
15745 [(match_scratch:DWIH 3 "r")
15746 (parallel [(set (match_operand:<DWI> 0 "register_operand")
15748 (match_operand:<DWI> 1 "register_operand")
15749 (match_operand:QI 2 "nonmemory_operand")))
15750 (clobber (reg:CC FLAGS_REG))])
15756 && !rtx_equal_p (operands[0], operands[1]))
15757 ix86_split_rshift_ndd (<CODE>, operands, operands[3]);
15759 ix86_split_<insn> (operands, operands[3], <DWI>mode);
15763 ;; Split truncations of double word right shifts into x86_shrd_1.
15764 (define_insn_and_split "<insn><dwi>3_doubleword_lowpart"
15765 [(set (match_operand:DWIH 0 "register_operand" "=&r")
15767 (any_shiftrt:<DWI> (match_operand:<DWI> 1 "register_operand" "r")
15768 (match_operand:QI 2 "const_int_operand")) 0))
15769 (clobber (reg:CC FLAGS_REG))]
15770 "UINTVAL (operands[2]) < <MODE_SIZE> * BITS_PER_UNIT"
15772 "&& reload_completed"
15774 [(set (match_dup 0)
15775 (ior:DWIH (lshiftrt:DWIH (match_dup 0) (match_dup 2))
15777 (ashift:<DWI> (zero_extend:<DWI> (match_dup 3))
15778 (match_dup 4)) 0)))
15779 (clobber (reg:CC FLAGS_REG))])]
15781 split_double_mode (<DWI>mode, &operands[1], 1, &operands[1], &operands[3]);
15782 operands[4] = GEN_INT ((<MODE_SIZE> * BITS_PER_UNIT) - INTVAL (operands[2]));
15783 if (!rtx_equal_p (operands[0], operands[1]))
15784 emit_move_insn (operands[0], operands[1]);
15787 (define_insn "x86_64_shrd"
15788 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
15789 (ior:DI (lshiftrt:DI (match_dup 0)
15790 (and:QI (match_operand:QI 2 "nonmemory_operand" "Jc")
15795 (match_operand:DI 1 "register_operand" "r"))
15796 (minus:QI (const_int 64)
15797 (and:QI (match_dup 2) (const_int 63)))) 0)))
15798 (clobber (reg:CC FLAGS_REG))]
15800 "shrd{q}\t{%2, %1, %0|%0, %1, %2}"
15801 [(set_attr "type" "ishift")
15802 (set_attr "prefix_0f" "1")
15803 (set_attr "mode" "DI")
15804 (set_attr "athlon_decode" "vector")
15805 (set_attr "amdfam10_decode" "vector")
15806 (set_attr "bdver1_decode" "vector")])
15808 (define_insn "x86_64_shrd_ndd"
15809 [(set (match_operand:DI 0 "register_operand" "=r")
15810 (ior:DI (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "rm")
15811 (and:QI (match_operand:QI 3 "nonmemory_operand" "Jc")
15816 (match_operand:DI 2 "register_operand" "r"))
15817 (minus:QI (const_int 64)
15818 (and:QI (match_dup 3) (const_int 63)))) 0)))
15819 (clobber (reg:CC FLAGS_REG))]
15821 "shrd{q}\t{%3, %2, %1, %0|%0, %1, %2, %3}"
15822 [(set_attr "type" "ishift")
15823 (set_attr "mode" "DI")])
15826 (define_insn "x86_64_shrd_1"
15827 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
15828 (ior:DI (lshiftrt:DI (match_dup 0)
15829 (match_operand:QI 2 "const_0_to_63_operand"))
15833 (match_operand:DI 1 "register_operand" "r"))
15834 (match_operand:QI 3 "const_0_to_255_operand")) 0)))
15835 (clobber (reg:CC FLAGS_REG))]
15837 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])"
15838 "shrd{q}\t{%2, %1, %0|%0, %1, %2}"
15839 [(set_attr "type" "ishift")
15840 (set_attr "prefix_0f" "1")
15841 (set_attr "length_immediate" "1")
15842 (set_attr "mode" "DI")
15843 (set_attr "athlon_decode" "vector")
15844 (set_attr "amdfam10_decode" "vector")
15845 (set_attr "bdver1_decode" "vector")])
15847 (define_insn "x86_64_shrd_ndd_1"
15848 [(set (match_operand:DI 0 "register_operand" "=r")
15849 (ior:DI (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "rm")
15850 (match_operand:QI 3 "const_0_to_63_operand"))
15854 (match_operand:DI 2 "register_operand" "r"))
15855 (match_operand:QI 4 "const_0_to_255_operand")) 0)))
15856 (clobber (reg:CC FLAGS_REG))]
15858 && INTVAL (operands[4]) == 64 - INTVAL (operands[3])"
15859 "shrd{q}\t{%3, %2, %1, %0|%0, %1, %2, %3}"
15860 [(set_attr "type" "ishift")
15861 (set_attr "length_immediate" "1")
15862 (set_attr "mode" "DI")])
15865 (define_insn_and_split "*x86_64_shrd_shld_1_nozext"
15866 [(set (match_operand:DI 0 "nonimmediate_operand")
15867 (ior:DI (lshiftrt:DI (match_operand:DI 4 "nonimmediate_operand")
15868 (match_operand:QI 2 "const_0_to_63_operand"))
15870 (match_operand:DI 1 "nonimmediate_operand")
15871 (match_operand:QI 3 "const_0_to_63_operand"))))
15872 (clobber (reg:CC FLAGS_REG))]
15874 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])
15875 && ix86_pre_reload_split ()"
15880 if (rtx_equal_p (operands[4], operands[0]))
15882 operands[1] = force_reg (DImode, operands[1]);
15883 emit_insn (gen_x86_64_shrd_1 (operands[0], operands[1], operands[2], operands[3]));
15885 else if (rtx_equal_p (operands[1], operands[0]))
15887 operands[4] = force_reg (DImode, operands[4]);
15888 emit_insn (gen_x86_64_shld_1 (operands[0], operands[4], operands[3], operands[2]));
15890 else if (TARGET_APX_NDD)
15892 rtx tmp = gen_reg_rtx (DImode);
15893 if (MEM_P (operands[4]))
15895 operands[1] = force_reg (DImode, operands[1]);
15896 emit_insn (gen_x86_64_shrd_ndd_1 (tmp, operands[4], operands[1],
15897 operands[2], operands[3]));
15899 else if (MEM_P (operands[1]))
15900 emit_insn (gen_x86_64_shld_ndd_1 (tmp, operands[1], operands[4],
15901 operands[3], operands[2]));
15903 emit_insn (gen_x86_64_shrd_ndd_1 (tmp, operands[4], operands[1],
15904 operands[2], operands[3]));
15905 emit_move_insn (operands[0], tmp);
15909 operands[1] = force_reg (DImode, operands[1]);
15910 rtx tmp = gen_reg_rtx (DImode);
15911 emit_move_insn (tmp, operands[4]);
15912 emit_insn (gen_x86_64_shrd_1 (tmp, operands[1], operands[2], operands[3]));
15913 emit_move_insn (operands[0], tmp);
15918 (define_insn_and_split "*x86_64_shrd_2"
15919 [(set (match_operand:DI 0 "nonimmediate_operand")
15920 (ior:DI (lshiftrt:DI (match_dup 0)
15921 (match_operand:QI 2 "nonmemory_operand"))
15922 (ashift:DI (match_operand:DI 1 "register_operand")
15923 (minus:QI (const_int 64) (match_dup 2)))))
15924 (clobber (reg:CC FLAGS_REG))]
15925 "TARGET_64BIT && ix86_pre_reload_split ()"
15928 [(parallel [(set (match_dup 0)
15929 (ior:DI (lshiftrt:DI (match_dup 0)
15930 (and:QI (match_dup 2) (const_int 63)))
15933 (zero_extend:TI (match_dup 1))
15934 (minus:QI (const_int 64)
15935 (and:QI (match_dup 2)
15936 (const_int 63)))) 0)))
15937 (clobber (reg:CC FLAGS_REG))])])
15939 (define_insn_and_split "*x86_64_shrd_ndd_2"
15940 [(set (match_operand:DI 0 "nonimmediate_operand")
15941 (ior:DI (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand")
15942 (match_operand:QI 3 "nonmemory_operand"))
15943 (ashift:DI (match_operand:DI 2 "register_operand")
15944 (minus:QI (const_int 64) (match_dup 2)))))
15945 (clobber (reg:CC FLAGS_REG))]
15947 && ix86_pre_reload_split ()"
15950 [(parallel [(set (match_dup 4)
15951 (ior:DI (lshiftrt:DI (match_dup 1)
15952 (and:QI (match_dup 3) (const_int 63)))
15955 (zero_extend:TI (match_dup 2))
15956 (minus:QI (const_int 64)
15957 (and:QI (match_dup 3)
15958 (const_int 63)))) 0)))
15959 (clobber (reg:CC FLAGS_REG))
15960 (set (match_dup 0) (match_dup 4))])]
15962 operands[4] = gen_reg_rtx (DImode);
15963 emit_move_insn (operands[4], operands[0]);
15966 (define_insn "x86_shrd"
15967 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
15968 (ior:SI (lshiftrt:SI (match_dup 0)
15969 (and:QI (match_operand:QI 2 "nonmemory_operand" "Ic")
15974 (match_operand:SI 1 "register_operand" "r"))
15975 (minus:QI (const_int 32)
15976 (and:QI (match_dup 2) (const_int 31)))) 0)))
15977 (clobber (reg:CC FLAGS_REG))]
15979 "shrd{l}\t{%2, %1, %0|%0, %1, %2}"
15980 [(set_attr "type" "ishift")
15981 (set_attr "prefix_0f" "1")
15982 (set_attr "mode" "SI")
15983 (set_attr "pent_pair" "np")
15984 (set_attr "athlon_decode" "vector")
15985 (set_attr "amdfam10_decode" "vector")
15986 (set_attr "bdver1_decode" "vector")])
15988 (define_insn "x86_shrd_ndd"
15989 [(set (match_operand:SI 0 "register_operand" "=r")
15990 (ior:SI (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
15991 (and:QI (match_operand:QI 3 "nonmemory_operand" "Ic")
15996 (match_operand:SI 2 "register_operand" "r"))
15997 (minus:QI (const_int 32)
15998 (and:QI (match_dup 3) (const_int 31)))) 0)))
15999 (clobber (reg:CC FLAGS_REG))]
16001 "shrd{l}\t{%3, %2, %1, %0|%0, %1, %2, %3}"
16002 [(set_attr "type" "ishift")
16003 (set_attr "mode" "SI")])
16005 (define_insn "x86_shrd_1"
16006 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
16007 (ior:SI (lshiftrt:SI (match_dup 0)
16008 (match_operand:QI 2 "const_0_to_31_operand"))
16012 (match_operand:SI 1 "register_operand" "r"))
16013 (match_operand:QI 3 "const_0_to_63_operand")) 0)))
16014 (clobber (reg:CC FLAGS_REG))]
16015 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])"
16016 "shrd{l}\t{%2, %1, %0|%0, %1, %2}"
16017 [(set_attr "type" "ishift")
16018 (set_attr "prefix_0f" "1")
16019 (set_attr "length_immediate" "1")
16020 (set_attr "mode" "SI")
16021 (set_attr "pent_pair" "np")
16022 (set_attr "athlon_decode" "vector")
16023 (set_attr "amdfam10_decode" "vector")
16024 (set_attr "bdver1_decode" "vector")])
16026 (define_insn "x86_shrd_ndd_1"
16027 [(set (match_operand:SI 0 "register_operand" "=r")
16028 (ior:SI (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
16029 (match_operand:QI 3 "const_0_to_31_operand"))
16033 (match_operand:SI 2 "register_operand" "r"))
16034 (match_operand:QI 4 "const_0_to_63_operand")) 0)))
16035 (clobber (reg:CC FLAGS_REG))]
16037 && (INTVAL (operands[4]) == 32 - INTVAL (operands[3]))"
16038 "shrd{l}\t{%3, %2, %1, %0|%0, %1, %2, %3}"
16039 [(set_attr "type" "ishift")
16040 (set_attr "length_immediate" "1")
16041 (set_attr "mode" "SI")])
16044 (define_insn_and_split "*x86_shrd_shld_1_nozext"
16045 [(set (match_operand:SI 0 "nonimmediate_operand")
16046 (ior:SI (lshiftrt:SI (match_operand:SI 4 "nonimmediate_operand")
16047 (match_operand:QI 2 "const_0_to_31_operand"))
16049 (match_operand:SI 1 "nonimmediate_operand")
16050 (match_operand:QI 3 "const_0_to_31_operand"))))
16051 (clobber (reg:CC FLAGS_REG))]
16052 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])
16053 && ix86_pre_reload_split ()"
16058 if (rtx_equal_p (operands[4], operands[0]))
16060 operands[1] = force_reg (SImode, operands[1]);
16061 emit_insn (gen_x86_shrd_1 (operands[0], operands[1], operands[2], operands[3]));
16063 else if (rtx_equal_p (operands[1], operands[0]))
16065 operands[4] = force_reg (SImode, operands[4]);
16066 emit_insn (gen_x86_shld_1 (operands[0], operands[4], operands[3], operands[2]));
16068 else if (TARGET_APX_NDD)
16070 rtx tmp = gen_reg_rtx (SImode);
16071 if (MEM_P (operands[4]))
16073 operands[1] = force_reg (SImode, operands[1]);
16074 emit_insn (gen_x86_shrd_ndd_1 (tmp, operands[4], operands[1],
16075 operands[2], operands[3]));
16077 else if (MEM_P (operands[1]))
16078 emit_insn (gen_x86_shld_ndd_1 (tmp, operands[1], operands[4],
16079 operands[3], operands[2]));
16081 emit_insn (gen_x86_shrd_ndd_1 (tmp, operands[4], operands[1],
16082 operands[2], operands[3]));
16083 emit_move_insn (operands[0], tmp);
16087 operands[1] = force_reg (SImode, operands[1]);
16088 rtx tmp = gen_reg_rtx (SImode);
16089 emit_move_insn (tmp, operands[4]);
16090 emit_insn (gen_x86_shrd_1 (tmp, operands[1], operands[2], operands[3]));
16091 emit_move_insn (operands[0], tmp);
16096 (define_insn_and_split "*x86_shrd_2"
16097 [(set (match_operand:SI 0 "nonimmediate_operand")
16098 (ior:SI (lshiftrt:SI (match_dup 0)
16099 (match_operand:QI 2 "nonmemory_operand"))
16100 (ashift:SI (match_operand:SI 1 "register_operand")
16101 (minus:QI (const_int 32) (match_dup 2)))))
16102 (clobber (reg:CC FLAGS_REG))]
16103 "TARGET_64BIT && ix86_pre_reload_split ()"
16106 [(parallel [(set (match_dup 0)
16107 (ior:SI (lshiftrt:SI (match_dup 0)
16108 (and:QI (match_dup 2) (const_int 31)))
16111 (zero_extend:DI (match_dup 1))
16112 (minus:QI (const_int 32)
16113 (and:QI (match_dup 2)
16114 (const_int 31)))) 0)))
16115 (clobber (reg:CC FLAGS_REG))])])
16117 (define_insn_and_split "*x86_shrd_ndd_2"
16118 [(set (match_operand:SI 0 "nonimmediate_operand")
16119 (ior:SI (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
16120 (match_operand:QI 3 "nonmemory_operand"))
16121 (ashift:SI (match_operand:SI 2 "register_operand")
16122 (minus:QI (const_int 32) (match_dup 3)))))
16123 (clobber (reg:CC FLAGS_REG))]
16125 && ix86_pre_reload_split ()"
16128 [(parallel [(set (match_dup 4)
16129 (ior:SI (lshiftrt:SI (match_dup 1)
16130 (and:QI (match_dup 3) (const_int 31)))
16133 (zero_extend:DI (match_dup 2))
16134 (minus:QI (const_int 32)
16135 (and:QI (match_dup 3)
16136 (const_int 31)))) 0)))
16137 (clobber (reg:CC FLAGS_REG))
16138 (set (match_dup 0) (match_dup 4))])]
16140 operands[4] = gen_reg_rtx (SImode);
16141 emit_move_insn (operands[4], operands[0]);
16144 ;; Base name for insn mnemonic.
16145 (define_mode_attr cvt_mnemonic
16146 [(SI "{cltd|cdq}") (DI "{cqto|cqo}")])
16148 (define_insn "ashr<mode>3_cvt"
16149 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=*d,rm,r")
16151 (match_operand:SWI48 1 "nonimmediate_operand" "*a,0,rm")
16152 (match_operand:QI 2 "const_int_operand")))
16153 (clobber (reg:CC FLAGS_REG))]
16154 "INTVAL (operands[2]) == GET_MODE_BITSIZE (<MODE>mode)-1
16155 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
16156 && ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands, TARGET_APX_NDD)"
16159 sar{<imodesuffix>}\t{%2, %0|%0, %2}
16160 sar{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
16161 [(set_attr "isa" "*,*,apx_ndd")
16162 (set_attr "type" "imovx,ishift,ishift")
16163 (set_attr "prefix_0f" "0,*,*")
16164 (set_attr "length_immediate" "0,*,*")
16165 (set_attr "modrm" "0,1,1")
16166 (set_attr "mode" "<MODE>")])
16168 (define_insn "*ashrsi3_cvt_zext"
16169 [(set (match_operand:DI 0 "register_operand" "=*d,r,r")
16171 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0,rm")
16172 (match_operand:QI 2 "const_int_operand"))))
16173 (clobber (reg:CC FLAGS_REG))]
16174 "TARGET_64BIT && INTVAL (operands[2]) == 31
16175 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
16176 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands, TARGET_APX_NDD)"
16179 sar{l}\t{%2, %k0|%k0, %2}
16180 sar{l}\t{%2, %1, %k0|%k0, %1, %2}"
16181 [(set_attr "isa" "*,*,apx_ndd")
16182 (set_attr "type" "imovx,ishift,ishift")
16183 (set_attr "prefix_0f" "0,*,*")
16184 (set_attr "length_immediate" "0,*,*")
16185 (set_attr "modrm" "0,1,1")
16186 (set_attr "mode" "SI")])
16188 (define_expand "@x86_shift<mode>_adj_3"
16189 [(use (match_operand:SWI48 0 "register_operand"))
16190 (use (match_operand:SWI48 1 "register_operand"))
16191 (use (match_operand:QI 2 "register_operand"))]
16194 rtx_code_label *label = gen_label_rtx ();
16197 emit_insn (gen_testqi_ccz_1 (operands[2],
16198 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
16200 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
16201 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
16202 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
16203 gen_rtx_LABEL_REF (VOIDmode, label),
16205 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
16206 JUMP_LABEL (tmp) = label;
16208 emit_move_insn (operands[0], operands[1]);
16209 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
16210 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
16211 emit_label (label);
16212 LABEL_NUSES (label) = 1;
16217 (define_insn "*bmi2_<insn><mode>3_1"
16218 [(set (match_operand:SWI48 0 "register_operand" "=r")
16219 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
16220 (match_operand:SWI48 2 "register_operand" "r")))]
16222 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
16223 [(set_attr "type" "ishiftx")
16224 (set_attr "mode" "<MODE>")])
16226 (define_insn "*ashr<mode>3_1"
16227 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
16229 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm,rm")
16230 (match_operand:QI 2 "nonmemory_operand" "c<S>,r,c<S>")))
16231 (clobber (reg:CC FLAGS_REG))]
16232 "ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands, TARGET_APX_NDD)"
16234 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
16235 switch (get_attr_type (insn))
16241 if (operands[2] == const1_rtx
16242 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
16244 return "sar{<imodesuffix>}\t%0";
16246 return use_ndd ? "sar{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
16247 : "sar{<imodesuffix>}\t{%2, %0|%0, %2}";
16250 [(set_attr "isa" "*,bmi2,apx_ndd")
16251 (set_attr "type" "ishift,ishiftx,ishift")
16252 (set (attr "length_immediate")
16254 (and (match_operand 2 "const1_operand")
16255 (ior (match_test "TARGET_SHIFT1")
16256 (match_test "optimize_function_for_size_p (cfun)")))
16258 (const_string "*")))
16259 (set_attr "mode" "<MODE>")])
16261 ;; Specialization of *lshr<mode>3_1 below, extracting the SImode
16262 ;; highpart of a DI to be extracted, but allowing it to be clobbered.
16263 (define_insn_and_split "*highpartdisi2"
16264 [(set (subreg:DI (match_operand:SI 0 "register_operand" "=r,x,?k,r") 0)
16265 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0,k,rm")
16267 (clobber (reg:CC FLAGS_REG))]
16270 "&& reload_completed"
16272 [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 32)))
16273 (clobber (reg:CC FLAGS_REG))])]
16275 if (SSE_REG_P (operands[0]))
16277 rtx tmp = gen_rtx_REG (V4SImode, REGNO (operands[0]));
16278 emit_insn (gen_sse_shufps_v4si (tmp, tmp, tmp,
16279 const1_rtx, const1_rtx,
16280 GEN_INT (5), GEN_INT (5)));
16283 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
16285 [(set_attr "isa" "*,*,*,apx_ndd")])
16288 (define_insn "*lshr<mode>3_1"
16289 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,?k,r")
16291 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm,k,rm")
16292 (match_operand:QI 2 "nonmemory_operand" "c<S>,r,<KS>,c<S>")))
16293 (clobber (reg:CC FLAGS_REG))]
16294 "ix86_binary_operator_ok (LSHIFTRT, <MODE>mode, operands, TARGET_APX_NDD)"
16296 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
16297 switch (get_attr_type (insn))
16304 if (operands[2] == const1_rtx
16305 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
16307 return "shr{<imodesuffix>}\t%0";
16309 return use_ndd ? "shr{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
16310 : "shr{<imodesuffix>}\t{%2, %0|%0, %2}";
16313 [(set_attr "isa" "*,bmi2,avx512bw,apx_ndd")
16314 (set_attr "type" "ishift,ishiftx,msklog,ishift")
16315 (set (attr "length_immediate")
16317 (and (and (match_operand 2 "const1_operand")
16318 (eq_attr "alternative" "0"))
16319 (ior (match_test "TARGET_SHIFT1")
16320 (match_test "optimize_function_for_size_p (cfun)")))
16322 (const_string "*")))
16323 (set_attr "mode" "<MODE>")])
16325 ;; Convert shift to the shiftx pattern to avoid flags dependency.
16327 [(set (match_operand:SWI48 0 "register_operand")
16328 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
16329 (match_operand:QI 2 "register_operand")))
16330 (clobber (reg:CC FLAGS_REG))]
16331 "TARGET_BMI2 && reload_completed"
16332 [(set (match_dup 0)
16333 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
16334 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
16336 (define_insn "*bmi2_<insn>si3_1_zext"
16337 [(set (match_operand:DI 0 "register_operand" "=r")
16339 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
16340 (match_operand:SI 2 "register_operand" "r"))))]
16341 "TARGET_64BIT && TARGET_BMI2"
16342 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
16343 [(set_attr "type" "ishiftx")
16344 (set_attr "mode" "SI")])
16346 (define_insn "*<insn>si3_1_zext"
16347 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
16349 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm,rm")
16350 (match_operand:QI 2 "nonmemory_operand" "cI,r,cI"))))
16351 (clobber (reg:CC FLAGS_REG))]
16353 && ix86_binary_operator_ok (<CODE>, SImode, operands, TARGET_APX_NDD)"
16355 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
16356 switch (get_attr_type (insn))
16362 if (operands[2] == const1_rtx
16363 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
16365 return "<shift>{l}\t%k0";
16367 return use_ndd ? "<shift>{l}\t{%2, %1, %k0|%k0, %1, %2}"
16368 : "<shift>{l}\t{%2, %k0|%k0, %2}";
16371 [(set_attr "isa" "*,bmi2,apx_ndd")
16372 (set_attr "type" "ishift,ishiftx,ishift")
16373 (set (attr "length_immediate")
16375 (and (match_operand 2 "const1_operand")
16376 (ior (match_test "TARGET_SHIFT1")
16377 (match_test "optimize_function_for_size_p (cfun)")))
16379 (const_string "*")))
16380 (set_attr "mode" "SI")])
16382 ;; Convert shift to the shiftx pattern to avoid flags dependency.
16384 [(set (match_operand:DI 0 "register_operand")
16386 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
16387 (match_operand:QI 2 "register_operand"))))
16388 (clobber (reg:CC FLAGS_REG))]
16389 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
16390 [(set (match_dup 0)
16391 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
16392 "operands[2] = gen_lowpart (SImode, operands[2]);")
16394 (define_insn "*ashr<mode>3_1"
16395 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m, r")
16397 (match_operand:SWI12 1 "nonimmediate_operand" "0, rm")
16398 (match_operand:QI 2 "nonmemory_operand" "c<S>, c<S>")))
16399 (clobber (reg:CC FLAGS_REG))]
16400 "ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands, TARGET_APX_NDD)"
16402 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
16403 if (operands[2] == const1_rtx
16404 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
16406 return "sar{<imodesuffix>}\t%0";
16408 return use_ndd ? "sar{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
16409 : "sar{<imodesuffix>}\t{%2, %0|%0, %2}";
16411 [(set_attr "isa" "*, apx_ndd")
16412 (set_attr "type" "ishift")
16413 (set (attr "length_immediate")
16415 (and (match_operand 2 "const1_operand")
16416 (ior (match_test "TARGET_SHIFT1")
16417 (match_test "optimize_function_for_size_p (cfun)")))
16419 (const_string "*")))
16420 (set_attr "mode" "<MODE>")])
16422 (define_insn "*lshrqi3_1"
16423 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,?k,r")
16425 (match_operand:QI 1 "nonimmediate_operand" "0, k, rm")
16426 (match_operand:QI 2 "nonmemory_operand" "cI,Wb,cI")))
16427 (clobber (reg:CC FLAGS_REG))]
16428 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands, TARGET_APX_NDD)"
16430 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
16431 switch (get_attr_type (insn))
16434 if (operands[2] == const1_rtx
16435 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
16437 return "shr{b}\t%0";
16439 return use_ndd ? "shr{b}\t{%2, %1, %0|%0, %1, %2}"
16440 : "shr{b}\t{%2, %0|%0, %2}";
16444 gcc_unreachable ();
16447 [(set_attr "isa" "*,avx512dq,apx_ndd")
16448 (set_attr "type" "ishift,msklog,ishift")
16449 (set (attr "length_immediate")
16451 (and (and (match_operand 2 "const1_operand")
16452 (eq_attr "alternative" "0"))
16453 (ior (match_test "TARGET_SHIFT1")
16454 (match_test "optimize_function_for_size_p (cfun)")))
16456 (const_string "*")))
16457 (set_attr "mode" "QI")])
16459 (define_insn "*lshrhi3_1"
16460 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm, ?k, r")
16462 (match_operand:HI 1 "nonimmediate_operand" "0, k, rm")
16463 (match_operand:QI 2 "nonmemory_operand" "cI, Ww, cI")))
16464 (clobber (reg:CC FLAGS_REG))]
16465 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands, TARGET_APX_NDD)"
16467 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
16468 switch (get_attr_type (insn))
16471 if (operands[2] == const1_rtx
16472 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
16474 return "shr{w}\t%0";
16476 return use_ndd ? "shr{w}\t{%2, %1, %0|%0, %1, %2}"
16477 : "shr{w}\t{%2, %0|%0, %2}";
16481 gcc_unreachable ();
16484 [(set_attr "isa" "*, avx512f, apx_ndd")
16485 (set_attr "type" "ishift,msklog,ishift")
16486 (set (attr "length_immediate")
16488 (and (and (match_operand 2 "const1_operand")
16489 (eq_attr "alternative" "0"))
16490 (ior (match_test "TARGET_SHIFT1")
16491 (match_test "optimize_function_for_size_p (cfun)")))
16493 (const_string "*")))
16494 (set_attr "mode" "HI")])
16496 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
16497 (define_insn_and_split "*<insn><mode>3_1_slp"
16498 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
16499 (any_shiftrt:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
16500 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
16501 (clobber (reg:CC FLAGS_REG))]
16502 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
16504 if (which_alternative)
16507 if (operands[2] == const1_rtx
16508 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
16509 return "<shift>{<imodesuffix>}\t%0";
16511 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
16513 "&& reload_completed
16514 && !(rtx_equal_p (operands[0], operands[1]))"
16515 [(set (strict_low_part (match_dup 0)) (match_dup 1))
16517 [(set (strict_low_part (match_dup 0))
16518 (any_shiftrt:SWI12 (match_dup 0) (match_dup 2)))
16519 (clobber (reg:CC FLAGS_REG))])]
16521 [(set_attr "type" "ishift")
16522 (set (attr "length_immediate")
16524 (and (match_operand 2 "const1_operand")
16525 (ior (match_test "TARGET_SHIFT1")
16526 (match_test "optimize_function_for_size_p (cfun)")))
16528 (const_string "*")))
16529 (set_attr "mode" "<MODE>")])
16531 ;; This pattern can't accept a variable shift count, since shifts by
16532 ;; zero don't affect the flags. We assume that shifts by constant
16533 ;; zero are optimized away.
16534 (define_insn "*<insn><mode>3_cmp"
16535 [(set (reg FLAGS_REG)
16538 (match_operand:SWI 1 "nonimmediate_operand" "0,rm")
16539 (match_operand:QI 2 "<shift_immediate_operand>" "<S>,<S>"))
16541 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,r")
16542 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
16543 "(optimize_function_for_size_p (cfun)
16544 || !TARGET_PARTIAL_FLAG_REG_STALL
16545 || (operands[2] == const1_rtx
16547 && ix86_match_ccmode (insn, CCGOCmode)
16548 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands, TARGET_APX_NDD)"
16550 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
16551 if (operands[2] == const1_rtx
16552 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
16554 return "<shift>{<imodesuffix>}\t%0";
16556 return use_ndd ? "<shift>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
16557 : "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
16559 [(set_attr "isa" "*,apx_ndd")
16560 (set_attr "type" "ishift")
16561 (set (attr "length_immediate")
16563 (and (match_operand 2 "const1_operand")
16564 (ior (match_test "TARGET_SHIFT1")
16565 (match_test "optimize_function_for_size_p (cfun)")))
16567 (const_string "*")))
16568 (set_attr "mode" "<MODE>")])
16570 (define_insn "*<insn>si3_cmp_zext"
16571 [(set (reg FLAGS_REG)
16573 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
16574 (match_operand:QI 2 "const_1_to_31_operand"))
16576 (set (match_operand:DI 0 "register_operand" "=r,r")
16577 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
16579 && (optimize_function_for_size_p (cfun)
16580 || !TARGET_PARTIAL_FLAG_REG_STALL
16581 || (operands[2] == const1_rtx
16583 && ix86_match_ccmode (insn, CCGOCmode)
16584 && ix86_binary_operator_ok (<CODE>, SImode, operands, TARGET_APX_NDD)"
16586 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
16587 if (operands[2] == const1_rtx
16588 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
16590 return "<shift>{l}\t%k0";
16592 return use_ndd ? "<shift>{l}\t{%2, %1, %k0|%k0, %1, %2}"
16593 : "<shift>{l}\t{%2, %k0|%k0, %2}";
16595 [(set_attr "isa" "*,apx_ndd")
16596 (set_attr "type" "ishift")
16597 (set (attr "length_immediate")
16599 (and (match_operand 2 "const1_operand")
16600 (ior (match_test "TARGET_SHIFT1")
16601 (match_test "optimize_function_for_size_p (cfun)")))
16603 (const_string "*")))
16604 (set_attr "mode" "SI")])
16606 (define_insn "*<insn><mode>3_cconly"
16607 [(set (reg FLAGS_REG)
16610 (match_operand:SWI 1 "nonimmediate_operand" "0,rm")
16611 (match_operand:QI 2 "<shift_immediate_operand>" "<S>,<S>"))
16613 (clobber (match_scratch:SWI 0 "=<r>,r"))]
16614 "(optimize_function_for_size_p (cfun)
16615 || !TARGET_PARTIAL_FLAG_REG_STALL
16616 || (operands[2] == const1_rtx
16618 && ix86_match_ccmode (insn, CCGOCmode)"
16620 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
16621 if (operands[2] == const1_rtx
16622 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
16624 return "<shift>{<imodesuffix>}\t%0";
16627 ? "<shift>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
16628 : "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
16630 [(set_attr "isa" "*,apx_ndd")
16631 (set_attr "type" "ishift")
16632 (set (attr "length_immediate")
16634 (and (match_operand 2 "const1_operand")
16635 (ior (match_test "TARGET_SHIFT1")
16636 (match_test "optimize_function_for_size_p (cfun)")))
16638 (const_string "*")))
16639 (set_attr "mode" "<MODE>")])
16641 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
16642 (define_insn_and_split "*<insn>qi_ext<mode>_1"
16643 [(set (zero_extract:SWI248
16644 (match_operand 0 "int248_register_operand" "+Q,&Q")
16650 (match_operator:SWI248 3 "extract_operator"
16651 [(match_operand 1 "int248_register_operand" "0,!Q")
16654 (match_operand:QI 2 "nonmemory_operand" "cI,cI")) 0))
16655 (clobber (reg:CC FLAGS_REG))]
16658 if (which_alternative)
16661 if (operands[2] == const1_rtx
16662 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
16663 return "<shift>{b}\t%h0";
16665 return "<shift>{b}\t{%2, %h0|%h0, %2}";
16668 && !(rtx_equal_p (operands[0], operands[1]))"
16669 [(set (zero_extract:SWI248
16670 (match_dup 0) (const_int 8) (const_int 8))
16671 (zero_extract:SWI248
16672 (match_dup 1) (const_int 8) (const_int 8)))
16674 [(set (zero_extract:SWI248
16675 (match_dup 0) (const_int 8) (const_int 8))
16680 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
16682 (clobber (reg:CC FLAGS_REG))])]
16684 [(set_attr "type" "ishift")
16685 (set (attr "length_immediate")
16687 (and (match_operand 2 "const1_operand")
16688 (ior (match_test "TARGET_SHIFT1")
16689 (match_test "optimize_function_for_size_p (cfun)")))
16691 (const_string "*")))
16692 (set_attr "mode" "QI")])
16694 (define_insn_and_split "*extend<dwi>2_doubleword_highpart"
16695 [(set (match_operand:<DWI> 0 "register_operand" "=r")
16697 (ashift:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")
16698 (match_operand:QI 2 "const_int_operand"))
16699 (match_operand:QI 3 "const_int_operand")))
16700 (clobber (reg:CC FLAGS_REG))]
16701 "INTVAL (operands[2]) == INTVAL (operands[3])
16702 && UINTVAL (operands[2]) < <MODE_SIZE> * BITS_PER_UNIT"
16704 "&& reload_completed"
16705 [(parallel [(set (match_dup 4)
16706 (ashift:DWIH (match_dup 4) (match_dup 2)))
16707 (clobber (reg:CC FLAGS_REG))])
16708 (parallel [(set (match_dup 4)
16709 (ashiftrt:DWIH (match_dup 4) (match_dup 2)))
16710 (clobber (reg:CC FLAGS_REG))])]
16711 "split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[4]);")
16713 (define_insn_and_split "*extendv2di2_highpart_stv"
16714 [(set (match_operand:V2DI 0 "register_operand" "=v")
16716 (ashift:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "vm")
16717 (match_operand:QI 2 "const_int_operand"))
16718 (match_operand:QI 3 "const_int_operand")))]
16719 "!TARGET_64BIT && TARGET_STV && TARGET_AVX512VL
16720 && INTVAL (operands[2]) == INTVAL (operands[3])
16721 && UINTVAL (operands[2]) < 32"
16723 "&& reload_completed"
16724 [(set (match_dup 0)
16725 (ashift:V2DI (match_dup 1) (match_dup 2)))
16727 (ashiftrt:V2DI (match_dup 0) (match_dup 2)))])
16729 ;; Rotate instructions
16731 (define_expand "<insn>ti3"
16732 [(set (match_operand:TI 0 "register_operand")
16733 (any_rotate:TI (match_operand:TI 1 "register_operand")
16734 (match_operand:QI 2 "nonmemory_operand")))]
16737 if (const_1_to_63_operand (operands[2], VOIDmode))
16738 emit_insn (gen_ix86_<insn>ti3_doubleword
16739 (operands[0], operands[1], operands[2]));
16740 else if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 64)
16742 operands[1] = force_reg (TImode, operands[1]);
16743 emit_insn (gen_<insn>64ti2_doubleword (operands[0], operands[1]));
16747 rtx amount = force_reg (QImode, operands[2]);
16748 rtx src_lo = gen_lowpart (DImode, operands[1]);
16749 rtx src_hi = gen_highpart (DImode, operands[1]);
16750 rtx tmp_lo = gen_reg_rtx (DImode);
16751 rtx tmp_hi = gen_reg_rtx (DImode);
16752 emit_move_insn (tmp_lo, src_lo);
16753 emit_move_insn (tmp_hi, src_hi);
16754 rtx (*shiftd) (rtx, rtx, rtx)
16755 = (<CODE> == ROTATE) ? gen_x86_64_shld : gen_x86_64_shrd;
16756 emit_insn (shiftd (tmp_lo, src_hi, amount));
16757 emit_insn (shiftd (tmp_hi, src_lo, amount));
16758 rtx dst_lo = gen_lowpart (DImode, operands[0]);
16759 rtx dst_hi = gen_highpart (DImode, operands[0]);
16760 emit_move_insn (dst_lo, tmp_lo);
16761 emit_move_insn (dst_hi, tmp_hi);
16762 emit_insn (gen_x86_shiftdi_adj_1 (dst_lo, dst_hi, amount, tmp_lo));
16767 (define_expand "<insn>di3"
16768 [(set (match_operand:DI 0 "shiftdi_operand")
16769 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
16770 (match_operand:QI 2 "nonmemory_operand")))]
16774 ix86_expand_binary_operator (<CODE>, DImode, operands, TARGET_APX_NDD);
16775 else if (const_1_to_31_operand (operands[2], VOIDmode))
16776 emit_insn (gen_ix86_<insn>di3_doubleword
16777 (operands[0], operands[1], operands[2]));
16778 else if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 32)
16780 operands[1] = force_reg (DImode, operands[1]);
16781 emit_insn (gen_<insn>32di2_doubleword (operands[0], operands[1]));
16789 (define_expand "<insn><mode>3"
16790 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
16791 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
16792 (match_operand:QI 2 "nonmemory_operand")))]
16795 ix86_expand_binary_operator (<CODE>, <MODE>mode, operands, TARGET_APX_NDD);
16799 ;; Avoid useless masking of count operand.
16800 (define_insn_and_split "*<insn><mode>3_mask"
16801 [(set (match_operand:SWI 0 "nonimmediate_operand")
16803 (match_operand:SWI 1 "nonimmediate_operand")
16806 (match_operand 2 "int248_register_operand" "c")
16807 (match_operand 3 "const_int_operand")) 0)))
16808 (clobber (reg:CC FLAGS_REG))]
16809 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
16810 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16811 == GET_MODE_BITSIZE (<MODE>mode)-1
16812 && ix86_pre_reload_split ()"
16816 [(set (match_dup 0)
16817 (any_rotate:SWI (match_dup 1)
16819 (clobber (reg:CC FLAGS_REG))])]
16821 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
16822 operands[2] = gen_lowpart (QImode, operands[2]);
16826 [(set (match_operand:SWI 0 "register_operand")
16828 (match_operand:SWI 1 "const_int_operand")
16831 (match_operand 2 "int248_register_operand")
16832 (match_operand 3 "const_int_operand")) 0)))]
16833 "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode) - 1))
16834 == GET_MODE_BITSIZE (<MODE>mode) - 1"
16835 [(set (match_dup 4) (match_dup 1))
16837 (any_rotate:SWI (match_dup 4)
16838 (subreg:QI (match_dup 2) 0)))]
16839 "operands[4] = gen_reg_rtx (<MODE>mode);")
16841 (define_insn_and_split "*<insn><mode>3_mask_1"
16842 [(set (match_operand:SWI 0 "nonimmediate_operand")
16844 (match_operand:SWI 1 "nonimmediate_operand")
16846 (match_operand:QI 2 "register_operand" "c")
16847 (match_operand:QI 3 "const_int_operand"))))
16848 (clobber (reg:CC FLAGS_REG))]
16849 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
16850 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16851 == GET_MODE_BITSIZE (<MODE>mode)-1
16852 && ix86_pre_reload_split ()"
16856 [(set (match_dup 0)
16857 (any_rotate:SWI (match_dup 1)
16859 (clobber (reg:CC FLAGS_REG))])])
16862 [(set (match_operand:SWI 0 "register_operand")
16864 (match_operand:SWI 1 "const_int_operand")
16866 (match_operand:QI 2 "register_operand")
16867 (match_operand:QI 3 "const_int_operand"))))]
16868 "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode) - 1))
16869 == GET_MODE_BITSIZE (<MODE>mode) - 1"
16870 [(set (match_dup 4) (match_dup 1))
16872 (any_rotate:SWI (match_dup 4) (match_dup 2)))]
16873 "operands[4] = gen_reg_rtx (<MODE>mode);")
16875 ;; Implement rotation using two double-precision
16876 ;; shift instructions and a scratch register.
16878 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
16879 [(set (match_operand:<DWI> 0 "register_operand" "=r")
16880 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
16881 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
16882 (clobber (reg:CC FLAGS_REG))
16883 (clobber (match_scratch:DWIH 3 "=&r"))]
16887 [(set (match_dup 3) (match_dup 4))
16889 [(set (match_dup 4)
16890 (ior:DWIH (ashift:DWIH (match_dup 4)
16891 (and:QI (match_dup 2) (match_dup 6)))
16893 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
16894 (minus:QI (match_dup 7)
16895 (and:QI (match_dup 2)
16896 (match_dup 6)))) 0)))
16897 (clobber (reg:CC FLAGS_REG))])
16899 [(set (match_dup 5)
16900 (ior:DWIH (ashift:DWIH (match_dup 5)
16901 (and:QI (match_dup 2) (match_dup 6)))
16903 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 3))
16904 (minus:QI (match_dup 7)
16905 (and:QI (match_dup 2)
16906 (match_dup 6)))) 0)))
16907 (clobber (reg:CC FLAGS_REG))])]
16909 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
16910 operands[7] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
16912 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
16915 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
16916 [(set (match_operand:<DWI> 0 "register_operand" "=r")
16917 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
16918 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
16919 (clobber (reg:CC FLAGS_REG))
16920 (clobber (match_scratch:DWIH 3 "=&r"))]
16924 [(set (match_dup 3) (match_dup 4))
16926 [(set (match_dup 4)
16927 (ior:DWIH (lshiftrt:DWIH (match_dup 4)
16928 (and:QI (match_dup 2) (match_dup 6)))
16930 (ashift:<DWI> (zero_extend:<DWI> (match_dup 5))
16931 (minus:QI (match_dup 7)
16932 (and:QI (match_dup 2)
16933 (match_dup 6)))) 0)))
16934 (clobber (reg:CC FLAGS_REG))])
16936 [(set (match_dup 5)
16937 (ior:DWIH (lshiftrt:DWIH (match_dup 5)
16938 (and:QI (match_dup 2) (match_dup 6)))
16940 (ashift:<DWI> (zero_extend:<DWI> (match_dup 3))
16941 (minus:QI (match_dup 7)
16942 (and:QI (match_dup 2)
16943 (match_dup 6)))) 0)))
16944 (clobber (reg:CC FLAGS_REG))])]
16946 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
16947 operands[7] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
16949 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
16952 (define_insn_and_split "<insn>32di2_doubleword"
16953 [(set (match_operand:DI 0 "register_operand" "=r,r")
16954 (any_rotate:DI (match_operand:DI 1 "register_operand" "0,r")
16958 "&& reload_completed"
16959 [(set (match_dup 0) (match_dup 3))
16960 (set (match_dup 2) (match_dup 1))]
16962 split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);
16963 if (rtx_equal_p (operands[0], operands[1]))
16965 emit_insn (gen_swapsi (operands[0], operands[2]));
16970 (define_insn_and_split "<insn>64ti2_doubleword"
16971 [(set (match_operand:TI 0 "register_operand" "=r,r")
16972 (any_rotate:TI (match_operand:TI 1 "register_operand" "0,r")
16976 "&& reload_completed"
16977 [(set (match_dup 0) (match_dup 3))
16978 (set (match_dup 2) (match_dup 1))]
16980 split_double_mode (TImode, &operands[0], 2, &operands[0], &operands[2]);
16981 if (rtx_equal_p (operands[0], operands[1]))
16983 emit_insn (gen_swapdi (operands[0], operands[2]));
16988 (define_mode_attr rorx_immediate_operand
16989 [(SI "const_0_to_31_operand")
16990 (DI "const_0_to_63_operand")])
16992 (define_insn "*bmi2_rorx<mode>3_1"
16993 [(set (match_operand:SWI48 0 "register_operand" "=r")
16995 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
16996 (match_operand:QI 2 "<rorx_immediate_operand>" "<S>")))]
16997 "TARGET_BMI2 && !optimize_function_for_size_p (cfun)"
16998 "rorx\t{%2, %1, %0|%0, %1, %2}"
16999 [(set_attr "type" "rotatex")
17000 (set_attr "mode" "<MODE>")])
17002 (define_insn "*<insn><mode>3_1"
17003 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
17005 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm,rm")
17006 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>,c<S>")))
17007 (clobber (reg:CC FLAGS_REG))]
17008 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands, TARGET_APX_NDD)"
17010 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
17011 switch (get_attr_type (insn))
17017 if (operands[2] == const1_rtx
17018 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
17020 return "<rotate>{<imodesuffix>}\t%0";
17022 return use_ndd ? "<rotate>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
17023 : "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
17026 [(set_attr "isa" "*,bmi2,apx_ndd")
17027 (set_attr "type" "rotate,rotatex,rotate")
17028 (set (attr "preferred_for_size")
17029 (cond [(eq_attr "alternative" "0")
17030 (symbol_ref "true")]
17031 (symbol_ref "false")))
17032 (set (attr "length_immediate")
17034 (and (eq_attr "type" "rotate")
17035 (and (match_operand 2 "const1_operand")
17036 (ior (match_test "TARGET_SHIFT1")
17037 (match_test "optimize_function_for_size_p (cfun)"))))
17039 (const_string "*")))
17040 (set_attr "mode" "<MODE>")])
17042 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
17044 [(set (match_operand:SWI48 0 "register_operand")
17045 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17046 (match_operand:QI 2 "const_int_operand")))
17047 (clobber (reg:CC FLAGS_REG))]
17048 "TARGET_BMI2 && reload_completed && !optimize_function_for_size_p (cfun)"
17049 [(set (match_dup 0)
17050 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
17052 int bitsize = GET_MODE_BITSIZE (<MODE>mode);
17054 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
17058 [(set (match_operand:SWI48 0 "register_operand")
17059 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17060 (match_operand:QI 2 "const_int_operand")))
17061 (clobber (reg:CC FLAGS_REG))]
17062 "TARGET_BMI2 && reload_completed && !optimize_function_for_size_p (cfun)"
17063 [(set (match_dup 0)
17064 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
17066 (define_insn "*bmi2_rorxsi3_1_zext"
17067 [(set (match_operand:DI 0 "register_operand" "=r")
17069 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
17070 (match_operand:QI 2 "const_0_to_31_operand"))))]
17071 "TARGET_64BIT && TARGET_BMI2 && !optimize_function_for_size_p (cfun)"
17072 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
17073 [(set_attr "type" "rotatex")
17074 (set_attr "mode" "SI")])
17076 (define_insn "*<insn>si3_1_zext"
17077 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
17079 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm,rm")
17080 (match_operand:QI 2 "nonmemory_operand" "cI,I,cI"))))
17081 (clobber (reg:CC FLAGS_REG))]
17082 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
17084 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
17085 switch (get_attr_type (insn))
17091 if (operands[2] == const1_rtx
17092 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
17094 return "<rotate>{l}\t%k0";
17096 return use_ndd ? "<rotate>{l}\t{%2, %1, %k0|%k0, %1, %2}"
17097 : "<rotate>{l}\t{%2, %k0|%k0, %2}";
17100 [(set_attr "isa" "*,bmi2,apx_ndd")
17101 (set_attr "type" "rotate,rotatex,rotate")
17102 (set (attr "preferred_for_size")
17103 (cond [(eq_attr "alternative" "0")
17104 (symbol_ref "true")]
17105 (symbol_ref "false")))
17106 (set (attr "length_immediate")
17108 (and (eq_attr "type" "rotate")
17109 (and (match_operand 2 "const1_operand")
17110 (ior (match_test "TARGET_SHIFT1")
17111 (match_test "optimize_function_for_size_p (cfun)"))))
17113 (const_string "*")))
17114 (set_attr "mode" "SI")])
17116 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
17118 [(set (match_operand:DI 0 "register_operand")
17120 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
17121 (match_operand:QI 2 "const_int_operand"))))
17122 (clobber (reg:CC FLAGS_REG))]
17123 "TARGET_64BIT && TARGET_BMI2 && reload_completed
17124 && !optimize_function_for_size_p (cfun)"
17125 [(set (match_dup 0)
17126 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
17128 int bitsize = GET_MODE_BITSIZE (SImode);
17130 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
17134 [(set (match_operand:DI 0 "register_operand")
17136 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
17137 (match_operand:QI 2 "const_int_operand"))))
17138 (clobber (reg:CC FLAGS_REG))]
17139 "TARGET_64BIT && TARGET_BMI2 && reload_completed
17140 && !optimize_function_for_size_p (cfun)"
17141 [(set (match_dup 0)
17142 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
17144 (define_insn "*<insn><mode>3_1"
17145 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m,r")
17146 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0,rm")
17147 (match_operand:QI 2 "nonmemory_operand" "c<S>,c<S>")))
17148 (clobber (reg:CC FLAGS_REG))]
17149 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands, TARGET_APX_NDD)"
17151 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
17152 if (operands[2] == const1_rtx
17153 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
17155 return "<rotate>{<imodesuffix>}\t%0";
17158 ? "<rotate>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
17159 : "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
17161 [(set_attr "isa" "*,apx_ndd")
17162 (set_attr "type" "rotate")
17163 (set (attr "length_immediate")
17165 (and (match_operand 2 "const1_operand")
17166 (ior (match_test "TARGET_SHIFT1")
17167 (match_test "optimize_function_for_size_p (cfun)")))
17169 (const_string "*")))
17170 (set_attr "mode" "<MODE>")])
17172 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
17173 (define_insn_and_split "*<insn><mode>3_1_slp"
17174 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
17175 (any_rotate:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
17176 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
17177 (clobber (reg:CC FLAGS_REG))]
17178 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
17180 if (which_alternative)
17183 if (operands[2] == const1_rtx
17184 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
17185 return "<rotate>{<imodesuffix>}\t%0";
17187 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
17189 "&& reload_completed
17190 && !(rtx_equal_p (operands[0], operands[1]))"
17191 [(set (strict_low_part (match_dup 0)) (match_dup 1))
17193 [(set (strict_low_part (match_dup 0))
17194 (any_rotate:SWI12 (match_dup 0) (match_dup 2)))
17195 (clobber (reg:CC FLAGS_REG))])]
17197 [(set_attr "type" "rotate")
17198 (set (attr "length_immediate")
17200 (and (match_operand 2 "const1_operand")
17201 (ior (match_test "TARGET_SHIFT1")
17202 (match_test "optimize_function_for_size_p (cfun)")))
17204 (const_string "*")))
17205 (set_attr "mode" "<MODE>")])
17208 [(set (match_operand:HI 0 "QIreg_operand")
17209 (any_rotate:HI (match_dup 0) (const_int 8)))
17210 (clobber (reg:CC FLAGS_REG))]
17212 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
17213 [(parallel [(set (strict_low_part (match_dup 0))
17214 (bswap:HI (match_dup 0)))
17215 (clobber (reg:CC FLAGS_REG))])])
17217 ;; Rotations through carry flag
17218 (define_insn "rcrsi2"
17219 [(set (match_operand:SI 0 "register_operand" "=r,r")
17221 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
17223 (ashift:SI (ltu:SI (reg:CCC FLAGS_REG) (const_int 0))
17225 (clobber (reg:CC FLAGS_REG))]
17229 rcr{l}\t{%1, %0|%0, %1}"
17230 [(set_attr "isa" "*,apx_ndd")
17231 (set_attr "type" "ishift1")
17232 (set_attr "memory" "none")
17233 (set_attr "length_immediate" "0")
17234 (set_attr "mode" "SI")])
17236 (define_insn "rcrdi2"
17237 [(set (match_operand:DI 0 "register_operand" "=r,r")
17239 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,rm")
17241 (ashift:DI (ltu:DI (reg:CCC FLAGS_REG) (const_int 0))
17243 (clobber (reg:CC FLAGS_REG))]
17247 rcr{q}\t{%1, %0|%0, %1}"
17248 [(set_attr "isa" "*,apx_ndd")
17249 (set_attr "type" "ishift1")
17250 (set_attr "length_immediate" "0")
17251 (set_attr "mode" "DI")])
17253 ;; Versions of sar and shr that set the carry flag.
17254 (define_insn "<insn><mode>3_carry"
17255 [(set (reg:CCC FLAGS_REG)
17256 (unspec:CCC [(and:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
17258 (const_int 0)] UNSPEC_CC_NE))
17259 (set (match_operand:SWI48 0 "register_operand" "=r,r")
17260 (any_shiftrt:SWI48 (match_dup 1) (const_int 1)))]
17263 bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
17264 if ((TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
17266 return "<shift>{<imodesuffix>}\t%0";
17267 return use_ndd ? "<shift>{<imodesuffix>}\t{$1, %1, %0|%0, %1, 1}"
17268 : "<shift>{<imodesuffix>}\t{$1, %0|%0, 1}";
17270 [(set_attr "isa" "*, apx_ndd")
17271 (set_attr "type" "ishift1")
17272 (set (attr "length_immediate")
17274 (ior (match_test "TARGET_SHIFT1")
17275 (match_test "optimize_function_for_size_p (cfun)"))
17277 (const_string "*")))
17278 (set_attr "mode" "<MODE>")])
17280 ;; Bit set / bit test instructions
17282 ;; %%% bts, btr, btc
17284 ;; These instructions are *slow* when applied to memory.
17286 (define_code_attr btsc [(ior "bts") (xor "btc")])
17288 (define_insn "*<btsc><mode>"
17289 [(set (match_operand:SWI48 0 "register_operand" "=r")
17291 (ashift:SWI48 (const_int 1)
17292 (match_operand:QI 2 "register_operand" "r"))
17293 (match_operand:SWI48 1 "register_operand" "0")))
17294 (clobber (reg:CC FLAGS_REG))]
17296 "<btsc>{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
17297 [(set_attr "type" "alu1")
17298 (set_attr "prefix_0f" "1")
17299 (set_attr "znver1_decode" "double")
17300 (set_attr "mode" "<MODE>")])
17302 ;; Avoid useless masking of count operand.
17303 (define_insn_and_split "*<btsc><mode>_mask"
17304 [(set (match_operand:SWI48 0 "register_operand")
17310 (match_operand 1 "int248_register_operand")
17311 (match_operand 2 "const_int_operand")) 0))
17312 (match_operand:SWI48 3 "register_operand")))
17313 (clobber (reg:CC FLAGS_REG))]
17315 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
17316 == GET_MODE_BITSIZE (<MODE>mode)-1
17317 && ix86_pre_reload_split ()"
17321 [(set (match_dup 0)
17323 (ashift:SWI48 (const_int 1)
17326 (clobber (reg:CC FLAGS_REG))])]
17328 operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
17329 operands[1] = gen_lowpart (QImode, operands[1]);
17332 (define_insn_and_split "*<btsc><mode>_mask_1"
17333 [(set (match_operand:SWI48 0 "register_operand")
17338 (match_operand:QI 1 "register_operand")
17339 (match_operand:QI 2 "const_int_operand")))
17340 (match_operand:SWI48 3 "register_operand")))
17341 (clobber (reg:CC FLAGS_REG))]
17343 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
17344 == GET_MODE_BITSIZE (<MODE>mode)-1
17345 && ix86_pre_reload_split ()"
17349 [(set (match_dup 0)
17351 (ashift:SWI48 (const_int 1)
17354 (clobber (reg:CC FLAGS_REG))])])
17356 (define_insn "*btr<mode>"
17357 [(set (match_operand:SWI48 0 "register_operand" "=r")
17359 (rotate:SWI48 (const_int -2)
17360 (match_operand:QI 2 "register_operand" "r"))
17361 (match_operand:SWI48 1 "register_operand" "0")))
17362 (clobber (reg:CC FLAGS_REG))]
17364 "btr{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
17365 [(set_attr "type" "alu1")
17366 (set_attr "prefix_0f" "1")
17367 (set_attr "znver1_decode" "double")
17368 (set_attr "mode" "<MODE>")])
17370 ;; Avoid useless masking of count operand.
17371 (define_insn_and_split "*btr<mode>_mask"
17372 [(set (match_operand:SWI48 0 "register_operand")
17378 (match_operand 1 "int248_register_operand")
17379 (match_operand 2 "const_int_operand")) 0))
17380 (match_operand:SWI48 3 "register_operand")))
17381 (clobber (reg:CC FLAGS_REG))]
17383 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
17384 == GET_MODE_BITSIZE (<MODE>mode)-1
17385 && ix86_pre_reload_split ()"
17389 [(set (match_dup 0)
17391 (rotate:SWI48 (const_int -2)
17394 (clobber (reg:CC FLAGS_REG))])]
17396 operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
17397 operands[1] = gen_lowpart (QImode, operands[1]);
17400 (define_insn_and_split "*btr<mode>_mask_1"
17401 [(set (match_operand:SWI48 0 "register_operand")
17406 (match_operand:QI 1 "register_operand")
17407 (match_operand:QI 2 "const_int_operand")))
17408 (match_operand:SWI48 3 "register_operand")))
17409 (clobber (reg:CC FLAGS_REG))]
17411 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
17412 == GET_MODE_BITSIZE (<MODE>mode)-1
17413 && ix86_pre_reload_split ()"
17417 [(set (match_dup 0)
17419 (rotate:SWI48 (const_int -2)
17422 (clobber (reg:CC FLAGS_REG))])])
17424 (define_insn_and_split "*btr<mode>_1"
17425 [(set (match_operand:SWI12 0 "register_operand")
17428 (rotate:SI (const_int -2)
17429 (match_operand:QI 2 "register_operand")) 0)
17430 (match_operand:SWI12 1 "nonimmediate_operand")))
17431 (clobber (reg:CC FLAGS_REG))]
17432 "TARGET_USE_BT && ix86_pre_reload_split ()"
17436 [(set (match_dup 0)
17437 (and:SI (rotate:SI (const_int -2) (match_dup 2))
17439 (clobber (reg:CC FLAGS_REG))])]
17441 operands[0] = lowpart_subreg (SImode, operands[0], <MODE>mode);
17442 operands[1] = force_reg (<MODE>mode, operands[1]);
17443 operands[1] = lowpart_subreg (SImode, operands[1], <MODE>mode);
17446 (define_insn_and_split "*btr<mode>_2"
17447 [(set (zero_extract:HI
17448 (match_operand:SWI12 0 "nonimmediate_operand")
17450 (match_operand:QI 1 "register_operand"))
17452 (clobber (reg:CC FLAGS_REG))]
17453 "TARGET_USE_BT && ix86_pre_reload_split ()"
17455 "&& MEM_P (operands[0])"
17456 [(set (match_dup 2) (match_dup 0))
17458 [(set (match_dup 3)
17459 (and:SI (rotate:SI (const_int -2) (match_dup 1))
17461 (clobber (reg:CC FLAGS_REG))])
17462 (set (match_dup 0) (match_dup 5))]
17464 operands[2] = gen_reg_rtx (<MODE>mode);
17465 operands[5] = gen_reg_rtx (<MODE>mode);
17466 operands[3] = lowpart_subreg (SImode, operands[5], <MODE>mode);
17467 operands[4] = lowpart_subreg (SImode, operands[2], <MODE>mode);
17471 [(set (zero_extract:HI
17472 (match_operand:SWI12 0 "register_operand")
17474 (match_operand:QI 1 "register_operand"))
17476 (clobber (reg:CC FLAGS_REG))]
17477 "TARGET_USE_BT && ix86_pre_reload_split ()"
17479 [(set (match_dup 0)
17480 (and:SI (rotate:SI (const_int -2) (match_dup 1))
17482 (clobber (reg:CC FLAGS_REG))])]
17484 operands[2] = lowpart_subreg (SImode, operands[0], <MODE>mode);
17485 operands[0] = lowpart_subreg (SImode, operands[0], <MODE>mode);
17488 ;; These instructions are never faster than the corresponding
17489 ;; and/ior/xor operations when using immediate operand, so with
17490 ;; 32-bit there's no point. But in 64-bit, we can't hold the
17491 ;; relevant immediates within the instruction itself, so operating
17492 ;; on bits in the high 32-bits of a register becomes easier.
17494 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
17495 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
17496 ;; negdf respectively, so they can never be disabled entirely.
17498 (define_insn "*btsq_imm"
17499 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
17501 (match_operand:QI 1 "const_0_to_63_operand"))
17503 (clobber (reg:CC FLAGS_REG))]
17504 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
17505 "bts{q}\t{%1, %0|%0, %1}"
17506 [(set_attr "type" "alu1")
17507 (set_attr "prefix_0f" "1")
17508 (set_attr "znver1_decode" "double")
17509 (set_attr "mode" "DI")])
17511 (define_insn "*btrq_imm"
17512 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
17514 (match_operand:QI 1 "const_0_to_63_operand"))
17516 (clobber (reg:CC FLAGS_REG))]
17517 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
17518 "btr{q}\t{%1, %0|%0, %1}"
17519 [(set_attr "type" "alu1")
17520 (set_attr "prefix_0f" "1")
17521 (set_attr "znver1_decode" "double")
17522 (set_attr "mode" "DI")])
17524 (define_insn "*btcq_imm"
17525 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
17527 (match_operand:QI 1 "const_0_to_63_operand"))
17528 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
17529 (clobber (reg:CC FLAGS_REG))]
17530 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
17531 "btc{q}\t{%1, %0|%0, %1}"
17532 [(set_attr "type" "alu1")
17533 (set_attr "prefix_0f" "1")
17534 (set_attr "znver1_decode" "double")
17535 (set_attr "mode" "DI")])
17537 ;; Allow Nocona to avoid these instructions if a register is available.
17540 [(match_scratch:DI 2 "r")
17541 (parallel [(set (zero_extract:DI
17542 (match_operand:DI 0 "nonimmediate_operand")
17544 (match_operand:QI 1 "const_0_to_63_operand"))
17546 (clobber (reg:CC FLAGS_REG))])]
17547 "TARGET_64BIT && !TARGET_USE_BT"
17548 [(parallel [(set (match_dup 0)
17549 (ior:DI (match_dup 0) (match_dup 3)))
17550 (clobber (reg:CC FLAGS_REG))])]
17552 int i = INTVAL (operands[1]);
17554 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
17556 if (!x86_64_immediate_operand (operands[3], DImode))
17558 emit_move_insn (operands[2], operands[3]);
17559 operands[3] = operands[2];
17564 [(match_scratch:DI 2 "r")
17565 (parallel [(set (zero_extract:DI
17566 (match_operand:DI 0 "nonimmediate_operand")
17568 (match_operand:QI 1 "const_0_to_63_operand"))
17570 (clobber (reg:CC FLAGS_REG))])]
17571 "TARGET_64BIT && !TARGET_USE_BT"
17572 [(parallel [(set (match_dup 0)
17573 (and:DI (match_dup 0) (match_dup 3)))
17574 (clobber (reg:CC FLAGS_REG))])]
17576 int i = INTVAL (operands[1]);
17578 operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
17580 if (!x86_64_immediate_operand (operands[3], DImode))
17582 emit_move_insn (operands[2], operands[3]);
17583 operands[3] = operands[2];
17588 [(match_scratch:DI 2 "r")
17589 (parallel [(set (zero_extract:DI
17590 (match_operand:DI 0 "nonimmediate_operand")
17592 (match_operand:QI 1 "const_0_to_63_operand"))
17593 (not:DI (zero_extract:DI
17594 (match_dup 0) (const_int 1) (match_dup 1))))
17595 (clobber (reg:CC FLAGS_REG))])]
17596 "TARGET_64BIT && !TARGET_USE_BT"
17597 [(parallel [(set (match_dup 0)
17598 (xor:DI (match_dup 0) (match_dup 3)))
17599 (clobber (reg:CC FLAGS_REG))])]
17601 int i = INTVAL (operands[1]);
17603 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
17605 if (!x86_64_immediate_operand (operands[3], DImode))
17607 emit_move_insn (operands[2], operands[3]);
17608 operands[3] = operands[2];
17614 (define_insn "*bt<mode>"
17615 [(set (reg:CCC FLAGS_REG)
17617 (zero_extract:SWI48
17618 (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
17620 (match_operand:QI 1 "nonmemory_operand" "q<S>,<S>"))
17624 switch (get_attr_mode (insn))
17627 return "bt{l}\t{%k1, %k0|%k0, %k1}";
17630 return "bt{q}\t{%q1, %0|%0, %q1}";
17633 gcc_unreachable ();
17636 [(set_attr "type" "alu1")
17637 (set_attr "prefix_0f" "1")
17640 (and (match_test "CONST_INT_P (operands[1])")
17641 (match_test "INTVAL (operands[1]) < 32"))
17642 (const_string "SI")
17643 (const_string "<MODE>")))])
17645 (define_insn_and_split "*bt<SWI48:mode>_mask"
17646 [(set (reg:CCC FLAGS_REG)
17648 (zero_extract:SWI48
17649 (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
17653 (match_operand:SWI248 1 "register_operand")
17654 (match_operand 2 "const_int_operand")) 0))
17657 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<SWI48:MODE>mode)-1))
17658 == GET_MODE_BITSIZE (<SWI48:MODE>mode)-1
17659 && ix86_pre_reload_split ()"
17662 [(set (reg:CCC FLAGS_REG)
17664 (zero_extract:SWI48 (match_dup 0) (const_int 1) (match_dup 1))
17666 "operands[1] = gen_lowpart (QImode, operands[1]);")
17668 (define_insn_and_split "*jcc_bt<mode>"
17670 (if_then_else (match_operator 0 "bt_comparison_operator"
17671 [(zero_extract:SWI48
17672 (match_operand:SWI48 1 "nonimmediate_operand")
17674 (match_operand:QI 2 "nonmemory_operand"))
17676 (label_ref (match_operand 3))
17678 (clobber (reg:CC FLAGS_REG))]
17679 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
17680 && (CONST_INT_P (operands[2])
17681 ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
17682 && INTVAL (operands[2])
17683 >= (optimize_function_for_size_p (cfun) ? 8 : 32))
17684 : !memory_operand (operands[1], <MODE>mode))
17685 && ix86_pre_reload_split ()"
17688 [(set (reg:CCC FLAGS_REG)
17690 (zero_extract:SWI48
17696 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
17697 (label_ref (match_dup 3))
17700 operands[0] = shallow_copy_rtx (operands[0]);
17701 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
17704 ;; Avoid useless masking of bit offset operand.
17705 (define_insn_and_split "*jcc_bt<mode>_mask"
17707 (if_then_else (match_operator 0 "bt_comparison_operator"
17708 [(zero_extract:SWI48
17709 (match_operand:SWI48 1 "register_operand")
17712 (match_operand:QI 2 "register_operand")
17713 (match_operand 3 "const_int_operand")))
17715 (label_ref (match_operand 4))
17717 (clobber (reg:CC FLAGS_REG))]
17718 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
17719 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
17720 == GET_MODE_BITSIZE (<MODE>mode)-1
17721 && ix86_pre_reload_split ()"
17724 [(set (reg:CCC FLAGS_REG)
17726 (zero_extract:SWI48
17732 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
17733 (label_ref (match_dup 4))
17736 operands[0] = shallow_copy_rtx (operands[0]);
17737 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
17740 ;; Avoid useless masking of bit offset operand.
17741 (define_insn_and_split "*jcc_bt<SWI48:mode>_mask_1"
17743 (if_then_else (match_operator 0 "bt_comparison_operator"
17744 [(zero_extract:SWI48
17745 (match_operand:SWI48 1 "register_operand")
17749 (match_operand:SWI248 2 "register_operand")
17750 (match_operand 3 "const_int_operand")) 0))
17752 (label_ref (match_operand 4))
17754 (clobber (reg:CC FLAGS_REG))]
17755 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
17756 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<SWI48:MODE>mode)-1))
17757 == GET_MODE_BITSIZE (<SWI48:MODE>mode)-1
17758 && ix86_pre_reload_split ()"
17761 [(set (reg:CCC FLAGS_REG)
17763 (zero_extract:SWI48
17769 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
17770 (label_ref (match_dup 4))
17773 operands[0] = shallow_copy_rtx (operands[0]);
17774 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
17775 operands[2] = gen_lowpart (QImode, operands[2]);
17778 ;; Help combine recognize bt followed by cmov
17780 [(set (match_operand:SWI248 0 "register_operand")
17781 (if_then_else:SWI248
17782 (match_operator 5 "bt_comparison_operator"
17783 [(zero_extract:SWI48
17784 (match_operand:SWI48 1 "register_operand")
17786 (match_operand:QI 2 "register_operand"))
17788 (match_operand:SWI248 3 "nonimmediate_operand")
17789 (match_operand:SWI248 4 "nonimmediate_operand")))]
17790 "TARGET_USE_BT && TARGET_CMOVE
17791 && !(MEM_P (operands[3]) && MEM_P (operands[4]))
17792 && ix86_pre_reload_split ()"
17793 [(set (reg:CCC FLAGS_REG)
17795 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
17798 (if_then_else:SWI248 (eq (reg:CCC FLAGS_REG) (const_int 0))
17802 if (GET_CODE (operands[5]) == EQ)
17803 std::swap (operands[3], operands[4]);
17806 ;; Help combine recognize bt followed by setc
17807 (define_insn_and_split "*bt<mode>_setcqi"
17808 [(set (subreg:SWI48 (match_operand:QI 0 "register_operand") 0)
17809 (zero_extract:SWI48
17810 (match_operand:SWI48 1 "register_operand")
17812 (match_operand:QI 2 "register_operand")))
17813 (clobber (reg:CC FLAGS_REG))]
17814 "TARGET_USE_BT && ix86_pre_reload_split ()"
17817 [(set (reg:CCC FLAGS_REG)
17819 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
17822 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))])
17824 ;; Help combine recognize bt followed by setnc
17825 (define_insn_and_split "*bt<mode>_setncqi"
17826 [(set (match_operand:QI 0 "register_operand")
17830 (lshiftrt:SWI48 (match_operand:SWI48 1 "register_operand")
17831 (match_operand:QI 2 "register_operand")) 0))
17833 (clobber (reg:CC FLAGS_REG))]
17834 "TARGET_USE_BT && ix86_pre_reload_split ()"
17837 [(set (reg:CCC FLAGS_REG)
17839 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
17842 (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))])
17844 (define_insn_and_split "*bt<mode>_setnc<mode>"
17845 [(set (match_operand:SWI48 0 "register_operand")
17848 (lshiftrt:SWI48 (match_operand:SWI48 1 "register_operand")
17849 (match_operand:QI 2 "register_operand")))
17851 (clobber (reg:CC FLAGS_REG))]
17852 "TARGET_USE_BT && ix86_pre_reload_split ()"
17855 [(set (reg:CCC FLAGS_REG)
17857 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
17860 (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))
17861 (set (match_dup 0) (zero_extend:SWI48 (match_dup 3)))]
17862 "operands[3] = gen_reg_rtx (QImode);")
17864 ;; Help combine recognize bt followed by setnc (PR target/110588)
17865 (define_insn_and_split "*bt<mode>_setncqi_2"
17866 [(set (match_operand:QI 0 "register_operand")
17868 (zero_extract:SWI48
17869 (match_operand:SWI48 1 "register_operand")
17871 (match_operand:QI 2 "register_operand"))
17873 (clobber (reg:CC FLAGS_REG))]
17874 "TARGET_USE_BT && ix86_pre_reload_split ()"
17877 [(set (reg:CCC FLAGS_REG)
17879 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
17882 (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))])
17884 ;; Help combine recognize bt followed by setc
17885 (define_insn_and_split "*bt<mode>_setc<mode>_mask"
17886 [(set (match_operand:SWI48 0 "register_operand")
17887 (zero_extract:SWI48
17888 (match_operand:SWI48 1 "register_operand")
17892 (match_operand:SWI48 2 "register_operand")
17893 (match_operand 3 "const_int_operand")) 0)))
17894 (clobber (reg:CC FLAGS_REG))]
17896 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
17897 == GET_MODE_BITSIZE (<MODE>mode)-1
17898 && ix86_pre_reload_split ()"
17901 [(set (reg:CCC FLAGS_REG)
17903 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
17906 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))
17907 (set (match_dup 0) (zero_extend:SWI48 (match_dup 3)))]
17909 operands[2] = gen_lowpart (QImode, operands[2]);
17910 operands[3] = gen_reg_rtx (QImode);
17913 ;; Store-flag instructions.
17916 [(set (match_operand:QI 0 "nonimmediate_operand")
17917 (match_operator:QI 1 "add_comparison_operator"
17918 [(not:SWI (match_operand:SWI 2 "register_operand"))
17919 (match_operand:SWI 3 "nonimmediate_operand")]))]
17921 [(set (reg:CCC FLAGS_REG)
17923 (plus:SWI (match_dup 2) (match_dup 3))
17926 (match_op_dup 1 [(reg:CCC FLAGS_REG) (const_int 0)]))])
17929 [(set (match_operand:QI 0 "nonimmediate_operand")
17930 (match_operator:QI 1 "shr_comparison_operator"
17931 [(match_operand:DI 2 "register_operand")
17932 (match_operand 3 "const_int_operand")]))]
17934 && IN_RANGE (exact_log2 (UINTVAL (operands[3]) + 1), 32, 63)"
17935 [(set (reg:CCZ FLAGS_REG)
17937 (lshiftrt:DI (match_dup 2) (match_dup 4))
17940 (match_op_dup 1 [(reg:CCZ FLAGS_REG) (const_int 0)]))]
17942 enum rtx_code new_code;
17944 operands[1] = shallow_copy_rtx (operands[1]);
17945 switch (GET_CODE (operands[1]))
17947 case GTU: new_code = NE; break;
17948 case LEU: new_code = EQ; break;
17949 default: gcc_unreachable ();
17951 PUT_CODE (operands[1], new_code);
17953 operands[4] = GEN_INT (exact_log2 (UINTVAL (operands[3]) + 1));
17956 ;; For all sCOND expanders, also expand the compare or test insn that
17957 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
17959 (define_insn_and_split "*setcc_di_1"
17960 [(set (match_operand:DI 0 "register_operand" "=q")
17961 (match_operator:DI 1 "ix86_comparison_operator"
17962 [(reg FLAGS_REG) (const_int 0)]))]
17963 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
17965 "&& reload_completed"
17966 [(set (match_dup 2) (match_dup 1))
17967 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
17969 operands[1] = shallow_copy_rtx (operands[1]);
17970 PUT_MODE (operands[1], QImode);
17971 operands[2] = gen_lowpart (QImode, operands[0]);
17974 (define_insn_and_split "*setcc_<mode>_1_and"
17975 [(set (match_operand:SWI24 0 "register_operand" "=q")
17976 (match_operator:SWI24 1 "ix86_comparison_operator"
17977 [(reg FLAGS_REG) (const_int 0)]))
17978 (clobber (reg:CC FLAGS_REG))]
17979 "!TARGET_PARTIAL_REG_STALL
17980 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
17982 "&& reload_completed"
17983 [(set (match_dup 2) (match_dup 1))
17984 (parallel [(set (match_dup 0) (zero_extend:SWI24 (match_dup 2)))
17985 (clobber (reg:CC FLAGS_REG))])]
17987 operands[1] = shallow_copy_rtx (operands[1]);
17988 PUT_MODE (operands[1], QImode);
17989 operands[2] = gen_lowpart (QImode, operands[0]);
17992 (define_insn_and_split "*setcc_<mode>_1_movzbl"
17993 [(set (match_operand:SWI24 0 "register_operand" "=q")
17994 (match_operator:SWI24 1 "ix86_comparison_operator"
17995 [(reg FLAGS_REG) (const_int 0)]))]
17996 "!TARGET_PARTIAL_REG_STALL
17997 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
17999 "&& reload_completed"
18000 [(set (match_dup 2) (match_dup 1))
18001 (set (match_dup 0) (zero_extend:SWI24 (match_dup 2)))]
18003 operands[1] = shallow_copy_rtx (operands[1]);
18004 PUT_MODE (operands[1], QImode);
18005 operands[2] = gen_lowpart (QImode, operands[0]);
18008 (define_insn "*setcc_qi"
18009 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18010 (match_operator:QI 1 "ix86_comparison_operator"
18011 [(reg FLAGS_REG) (const_int 0)]))]
18014 [(set_attr "type" "setcc")
18015 (set_attr "mode" "QI")])
18017 (define_insn "*setcc_qi_slp"
18018 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+q"))
18019 (match_operator:QI 1 "ix86_comparison_operator"
18020 [(reg FLAGS_REG) (const_int 0)]))]
18023 [(set_attr "type" "setcc")
18024 (set_attr "mode" "QI")])
18026 ;; In general it is not safe to assume too much about CCmode registers,
18027 ;; so simplify-rtx stops when it sees a second one. Under certain
18028 ;; conditions this is safe on x86, so help combine not create
18035 [(set (match_operand:QI 0 "nonimmediate_operand")
18036 (ne:QI (match_operator 1 "ix86_comparison_operator"
18037 [(reg FLAGS_REG) (const_int 0)])
18040 [(set (match_dup 0) (match_dup 1))]
18042 operands[1] = shallow_copy_rtx (operands[1]);
18043 PUT_MODE (operands[1], QImode);
18047 [(set (strict_low_part (match_operand:QI 0 "register_operand"))
18048 (ne:QI (match_operator 1 "ix86_comparison_operator"
18049 [(reg FLAGS_REG) (const_int 0)])
18052 [(set (match_dup 0) (match_dup 1))]
18054 operands[1] = shallow_copy_rtx (operands[1]);
18055 PUT_MODE (operands[1], QImode);
18059 [(set (match_operand:QI 0 "nonimmediate_operand")
18060 (eq:QI (match_operator 1 "ix86_comparison_operator"
18061 [(reg FLAGS_REG) (const_int 0)])
18064 [(set (match_dup 0) (match_dup 1))]
18066 operands[1] = shallow_copy_rtx (operands[1]);
18067 PUT_MODE (operands[1], QImode);
18068 PUT_CODE (operands[1],
18069 ix86_reverse_condition (GET_CODE (operands[1]),
18070 GET_MODE (XEXP (operands[1], 0))));
18072 /* Make sure that (a) the CCmode we have for the flags is strong
18073 enough for the reversed compare or (b) we have a valid FP compare. */
18074 if (! ix86_comparison_operator (operands[1], VOIDmode))
18079 [(set (strict_low_part (match_operand:QI 0 "register_operand"))
18080 (eq:QI (match_operator 1 "ix86_comparison_operator"
18081 [(reg FLAGS_REG) (const_int 0)])
18084 [(set (match_dup 0) (match_dup 1))]
18086 operands[1] = shallow_copy_rtx (operands[1]);
18087 PUT_MODE (operands[1], QImode);
18088 PUT_CODE (operands[1],
18089 ix86_reverse_condition (GET_CODE (operands[1]),
18090 GET_MODE (XEXP (operands[1], 0))));
18092 /* Make sure that (a) the CCmode we have for the flags is strong
18093 enough for the reversed compare or (b) we have a valid FP compare. */
18094 if (! ix86_comparison_operator (operands[1], VOIDmode))
18098 ;; Eliminate redundant compare between set{z,nz} and j{z,nz}:
18099 ;; setz %al; test %al,%al; jz <...> -> setz %al; jnz <...> and
18100 ;; setnz %al, test %al,%al; jz <...> -> setnz %al; jz <...>.
18102 [(set (match_operand:QI 0 "nonimmediate_operand")
18103 (match_operator:QI 1 "bt_comparison_operator"
18104 [(reg:CCZ FLAGS_REG) (const_int 0)]))
18105 (set (reg:CCZ FLAGS_REG)
18106 (compare:CCZ (match_dup 0) (const_int 0)))
18108 (if_then_else (match_operator 2 "bt_comparison_operator"
18109 [(reg:CCZ FLAGS_REG) (const_int 0)])
18112 "peep2_regno_dead_p (3, FLAGS_REG)"
18113 [(set (match_dup 0)
18114 (match_op_dup 1 [(reg:CCZ FLAGS_REG) (const_int 0)]))
18116 (if_then_else (match_dup 2)
18120 if (GET_CODE (operands[1]) == EQ)
18122 operands[2] = shallow_copy_rtx (operands[2]);
18123 PUT_CODE (operands[2], reverse_condition (GET_CODE (operands[2])));
18127 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
18128 ;; subsequent logical operations are used to imitate conditional moves.
18129 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
18132 (define_insn "setcc_<mode>_sse"
18133 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
18134 (match_operator:MODEF 3 "sse_comparison_operator"
18135 [(match_operand:MODEF 1 "register_operand" "0,x")
18136 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xjm")]))]
18137 "SSE_FLOAT_MODE_P (<MODE>mode)"
18139 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
18140 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
18141 [(set_attr "isa" "noavx,avx")
18142 (set_attr "addr" "*,gpr16")
18143 (set_attr "type" "ssecmp")
18144 (set_attr "length_immediate" "1")
18145 (set_attr "prefix" "orig,vex")
18146 (set_attr "mode" "<MODE>")])
18148 (define_insn "setcc_hf_mask"
18149 [(set (match_operand:QI 0 "register_operand" "=k")
18151 [(match_operand:HF 1 "register_operand" "v")
18152 (match_operand:HF 2 "nonimmediate_operand" "vm")
18153 (match_operand:SI 3 "const_0_to_31_operand")]
18155 "TARGET_AVX512FP16"
18156 "vcmpsh\t{%3, %2, %1, %0|%0, %1, %2, %3}"
18157 [(set_attr "type" "ssecmp")
18158 (set_attr "prefix" "evex")
18159 (set_attr "mode" "HF")])
18162 ;; Basic conditional jump instructions.
18167 (match_operator 1 "add_comparison_operator"
18168 [(not:SWI (match_operand:SWI 2 "register_operand"))
18169 (match_operand:SWI 3 "nonimmediate_operand")])
18170 (label_ref (match_operand 0))
18173 [(set (reg:CCC FLAGS_REG)
18175 (plus:SWI (match_dup 2) (match_dup 3))
18178 (if_then_else (match_op_dup 1 [(reg:CCC FLAGS_REG) (const_int 0)])
18179 (label_ref (match_operand 0))
18185 (match_operator 1 "shr_comparison_operator"
18186 [(match_operand:DI 2 "register_operand")
18187 (match_operand 3 "const_int_operand")])
18188 (label_ref (match_operand 0))
18191 && IN_RANGE (exact_log2 (UINTVAL (operands[3]) + 1), 32, 63)"
18192 [(set (reg:CCZ FLAGS_REG)
18194 (lshiftrt:DI (match_dup 2) (match_dup 4))
18197 (if_then_else (match_op_dup 1 [(reg:CCZ FLAGS_REG) (const_int 0)])
18198 (label_ref (match_operand 0))
18201 enum rtx_code new_code;
18203 operands[1] = shallow_copy_rtx (operands[1]);
18204 switch (GET_CODE (operands[1]))
18206 case GTU: new_code = NE; break;
18207 case LEU: new_code = EQ; break;
18208 default: gcc_unreachable ();
18210 PUT_CODE (operands[1], new_code);
18212 operands[4] = GEN_INT (exact_log2 (UINTVAL (operands[3]) + 1));
18215 ;; We ignore the overflow flag for signed branch instructions.
18217 (define_insn "*jcc"
18219 (if_then_else (match_operator 1 "ix86_comparison_operator"
18220 [(reg FLAGS_REG) (const_int 0)])
18221 (label_ref (match_operand 0))
18225 [(set_attr "type" "ibr")
18226 (set_attr "modrm" "0")
18227 (set (attr "length")
18229 (and (ge (minus (match_dup 0) (pc))
18231 (lt (minus (match_dup 0) (pc))
18236 ;; In general it is not safe to assume too much about CCmode registers,
18237 ;; so simplify-rtx stops when it sees a second one. Under certain
18238 ;; conditions this is safe on x86, so help combine not create
18246 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
18247 [(reg FLAGS_REG) (const_int 0)])
18249 (label_ref (match_operand 1))
18253 (if_then_else (match_dup 0)
18254 (label_ref (match_dup 1))
18257 operands[0] = shallow_copy_rtx (operands[0]);
18258 PUT_MODE (operands[0], VOIDmode);
18263 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
18264 [(reg FLAGS_REG) (const_int 0)])
18266 (label_ref (match_operand 1))
18270 (if_then_else (match_dup 0)
18271 (label_ref (match_dup 1))
18274 operands[0] = shallow_copy_rtx (operands[0]);
18275 PUT_MODE (operands[0], VOIDmode);
18276 PUT_CODE (operands[0],
18277 ix86_reverse_condition (GET_CODE (operands[0]),
18278 GET_MODE (XEXP (operands[0], 0))));
18280 /* Make sure that (a) the CCmode we have for the flags is strong
18281 enough for the reversed compare or (b) we have a valid FP compare. */
18282 if (! ix86_comparison_operator (operands[0], VOIDmode))
18286 ;; Unconditional and other jump instructions
18288 (define_insn "jump"
18290 (label_ref (match_operand 0)))]
18293 [(set_attr "type" "ibr")
18294 (set_attr "modrm" "0")
18295 (set (attr "length")
18297 (and (ge (minus (match_dup 0) (pc))
18299 (lt (minus (match_dup 0) (pc))
18304 (define_expand "indirect_jump"
18305 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
18308 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
18309 operands[0] = convert_memory_address (word_mode, operands[0]);
18310 cfun->machine->has_local_indirect_jump = true;
18313 (define_insn "*indirect_jump"
18314 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
18316 "* return ix86_output_indirect_jmp (operands[0]);"
18317 [(set (attr "type")
18318 (if_then_else (match_test "(cfun->machine->indirect_branch_type
18319 != indirect_branch_keep)")
18320 (const_string "multi")
18321 (const_string "ibr")))
18322 (set_attr "length_immediate" "0")])
18324 (define_expand "tablejump"
18325 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
18326 (use (label_ref (match_operand 1)))])]
18329 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
18330 relative. Convert the relative address to an absolute address. */
18334 enum rtx_code code;
18336 /* We can't use @GOTOFF for text labels on VxWorks;
18337 see gotoff_operand. */
18338 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
18342 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
18344 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
18348 op1 = pic_offset_table_rtx;
18353 op0 = pic_offset_table_rtx;
18357 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
18361 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
18362 operands[0] = convert_memory_address (word_mode, operands[0]);
18363 cfun->machine->has_local_indirect_jump = true;
18366 (define_insn "*tablejump_1"
18367 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
18368 (use (label_ref (match_operand 1)))]
18370 "* return ix86_output_indirect_jmp (operands[0]);"
18371 [(set (attr "type")
18372 (if_then_else (match_test "(cfun->machine->indirect_branch_type
18373 != indirect_branch_keep)")
18374 (const_string "multi")
18375 (const_string "ibr")))
18376 (set_attr "length_immediate" "0")])
18378 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
18381 [(set (match_operand 4 "flags_reg_operand") (match_operand 0))
18382 (set (match_operand:QI 1 "register_operand")
18383 (match_operator:QI 2 "ix86_comparison_operator"
18384 [(reg FLAGS_REG) (const_int 0)]))
18385 (set (match_operand 3 "any_QIreg_operand")
18386 (zero_extend (match_dup 1)))]
18387 "(peep2_reg_dead_p (3, operands[1])
18388 || operands_match_p (operands[1], operands[3]))
18389 && ! reg_overlap_mentioned_p (operands[3], operands[0])
18390 && peep2_regno_dead_p (0, FLAGS_REG)"
18391 [(set (match_dup 4) (match_dup 0))
18392 (set (strict_low_part (match_dup 5))
18395 operands[5] = gen_lowpart (QImode, operands[3]);
18396 ix86_expand_clear (operands[3]);
18400 [(parallel [(set (match_operand 5 "flags_reg_operand") (match_operand 0))
18401 (match_operand 4)])
18402 (set (match_operand:QI 1 "register_operand")
18403 (match_operator:QI 2 "ix86_comparison_operator"
18404 [(reg FLAGS_REG) (const_int 0)]))
18405 (set (match_operand 3 "any_QIreg_operand")
18406 (zero_extend (match_dup 1)))]
18407 "(peep2_reg_dead_p (3, operands[1])
18408 || operands_match_p (operands[1], operands[3]))
18409 && ! reg_overlap_mentioned_p (operands[3], operands[0])
18410 && ! reg_overlap_mentioned_p (operands[3], operands[4])
18411 && ! reg_set_p (operands[3], operands[4])
18412 && peep2_regno_dead_p (0, FLAGS_REG)"
18413 [(parallel [(set (match_dup 5) (match_dup 0))
18415 (set (strict_low_part (match_dup 6))
18418 operands[6] = gen_lowpart (QImode, operands[3]);
18419 ix86_expand_clear (operands[3]);
18423 [(set (match_operand 6 "flags_reg_operand") (match_operand 0))
18424 (parallel [(set (match_operand 7 "flags_reg_operand") (match_operand 1))
18425 (match_operand 5)])
18426 (set (match_operand:QI 2 "register_operand")
18427 (match_operator:QI 3 "ix86_comparison_operator"
18428 [(reg FLAGS_REG) (const_int 0)]))
18429 (set (match_operand 4 "any_QIreg_operand")
18430 (zero_extend (match_dup 2)))]
18431 "(peep2_reg_dead_p (4, operands[2])
18432 || operands_match_p (operands[2], operands[4]))
18433 && ! reg_overlap_mentioned_p (operands[4], operands[0])
18434 && ! reg_overlap_mentioned_p (operands[4], operands[1])
18435 && ! reg_overlap_mentioned_p (operands[4], operands[5])
18436 && ! reg_set_p (operands[4], operands[5])
18437 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
18438 && peep2_regno_dead_p (0, FLAGS_REG)"
18439 [(set (match_dup 6) (match_dup 0))
18440 (parallel [(set (match_dup 7) (match_dup 1))
18442 (set (strict_low_part (match_dup 8))
18445 operands[8] = gen_lowpart (QImode, operands[4]);
18446 ix86_expand_clear (operands[4]);
18449 ;; Similar, but match zero extend with andsi3.
18452 [(set (match_operand 4 "flags_reg_operand") (match_operand 0))
18453 (set (match_operand:QI 1 "register_operand")
18454 (match_operator:QI 2 "ix86_comparison_operator"
18455 [(reg FLAGS_REG) (const_int 0)]))
18456 (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
18457 (and:SI (match_dup 3) (const_int 255)))
18458 (clobber (reg:CC FLAGS_REG))])]
18459 "REGNO (operands[1]) == REGNO (operands[3])
18460 && ! reg_overlap_mentioned_p (operands[3], operands[0])
18461 && peep2_regno_dead_p (0, FLAGS_REG)"
18462 [(set (match_dup 4) (match_dup 0))
18463 (set (strict_low_part (match_dup 5))
18466 operands[5] = gen_lowpart (QImode, operands[3]);
18467 ix86_expand_clear (operands[3]);
18471 [(parallel [(set (match_operand 5 "flags_reg_operand") (match_operand 0))
18472 (match_operand 4)])
18473 (set (match_operand:QI 1 "register_operand")
18474 (match_operator:QI 2 "ix86_comparison_operator"
18475 [(reg FLAGS_REG) (const_int 0)]))
18476 (parallel [(set (match_operand 3 "any_QIreg_operand")
18477 (zero_extend (match_dup 1)))
18478 (clobber (reg:CC FLAGS_REG))])]
18479 "(peep2_reg_dead_p (3, operands[1])
18480 || operands_match_p (operands[1], operands[3]))
18481 && ! reg_overlap_mentioned_p (operands[3], operands[0])
18482 && ! reg_overlap_mentioned_p (operands[3], operands[4])
18483 && ! reg_set_p (operands[3], operands[4])
18484 && peep2_regno_dead_p (0, FLAGS_REG)"
18485 [(parallel [(set (match_dup 5) (match_dup 0))
18487 (set (strict_low_part (match_dup 6))
18490 operands[6] = gen_lowpart (QImode, operands[3]);
18491 ix86_expand_clear (operands[3]);
18495 [(set (match_operand 6 "flags_reg_operand") (match_operand 0))
18496 (parallel [(set (match_operand 7 "flags_reg_operand") (match_operand 1))
18497 (match_operand 5)])
18498 (set (match_operand:QI 2 "register_operand")
18499 (match_operator:QI 3 "ix86_comparison_operator"
18500 [(reg FLAGS_REG) (const_int 0)]))
18501 (parallel [(set (match_operand 4 "any_QIreg_operand")
18502 (zero_extend (match_dup 2)))
18503 (clobber (reg:CC FLAGS_REG))])]
18504 "(peep2_reg_dead_p (4, operands[2])
18505 || operands_match_p (operands[2], operands[4]))
18506 && ! reg_overlap_mentioned_p (operands[4], operands[0])
18507 && ! reg_overlap_mentioned_p (operands[4], operands[1])
18508 && ! reg_overlap_mentioned_p (operands[4], operands[5])
18509 && ! reg_set_p (operands[4], operands[5])
18510 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
18511 && peep2_regno_dead_p (0, FLAGS_REG)"
18512 [(set (match_dup 6) (match_dup 0))
18513 (parallel [(set (match_dup 7) (match_dup 1))
18515 (set (strict_low_part (match_dup 8))
18518 operands[8] = gen_lowpart (QImode, operands[4]);
18519 ix86_expand_clear (operands[4]);
18522 ;; Call instructions.
18524 ;; The predicates normally associated with named expanders are not properly
18525 ;; checked for calls. This is a bug in the generic code, but it isn't that
18526 ;; easy to fix. Ignore it for now and be prepared to fix things up.
18528 ;; P6 processors will jump to the address after the decrement when %esp
18529 ;; is used as a call operand, so they will execute return address as a code.
18530 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
18532 ;; Register constraint for call instruction.
18533 (define_mode_attr c [(SI "l") (DI "r")])
18535 ;; Call subroutine returning no value.
18537 (define_expand "call"
18538 [(call (match_operand:QI 0)
18540 (use (match_operand 2))]
18543 ix86_expand_call (NULL, operands[0], operands[1],
18544 operands[2], NULL, false);
18548 (define_expand "sibcall"
18549 [(call (match_operand:QI 0)
18551 (use (match_operand 2))]
18554 ix86_expand_call (NULL, operands[0], operands[1],
18555 operands[2], NULL, true);
18559 (define_insn "*call"
18560 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
18561 (match_operand 1))]
18562 "!SIBLING_CALL_P (insn)"
18563 "* return ix86_output_call_insn (insn, operands[0]);"
18564 [(set_attr "type" "call")])
18566 ;; This covers both call and sibcall since only GOT slot is allowed.
18567 (define_insn "*call_got_x32"
18568 [(call (mem:QI (zero_extend:DI
18569 (match_operand:SI 0 "GOT_memory_operand" "Bg")))
18570 (match_operand 1))]
18573 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
18574 return ix86_output_call_insn (insn, fnaddr);
18576 [(set_attr "type" "call")])
18578 ;; Since sibcall never returns, we can only use call-clobbered register
18580 (define_insn "*sibcall_GOT_32"
18583 (match_operand:SI 0 "register_no_elim_operand" "U")
18584 (match_operand:SI 1 "GOT32_symbol_operand"))))
18585 (match_operand 2))]
18588 && !TARGET_INDIRECT_BRANCH_REGISTER
18589 && SIBLING_CALL_P (insn)"
18591 rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
18592 fnaddr = gen_const_mem (SImode, fnaddr);
18593 return ix86_output_call_insn (insn, fnaddr);
18595 [(set_attr "type" "call")])
18597 (define_insn "*sibcall"
18598 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
18599 (match_operand 1))]
18600 "SIBLING_CALL_P (insn)"
18601 "* return ix86_output_call_insn (insn, operands[0]);"
18602 [(set_attr "type" "call")])
18604 (define_insn "*sibcall_memory"
18605 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
18607 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
18608 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
18609 "* return ix86_output_call_insn (insn, operands[0]);"
18610 [(set_attr "type" "call")])
18613 [(set (match_operand:W 0 "register_operand")
18614 (match_operand:W 1 "memory_operand"))
18615 (call (mem:QI (match_dup 0))
18616 (match_operand 3))]
18618 && !TARGET_INDIRECT_BRANCH_REGISTER
18619 && SIBLING_CALL_P (peep2_next_insn (1))
18620 && !reg_mentioned_p (operands[0],
18621 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
18622 [(parallel [(call (mem:QI (match_dup 1))
18624 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
18627 [(set (match_operand:W 0 "register_operand")
18628 (match_operand:W 1 "memory_operand"))
18629 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
18630 (call (mem:QI (match_dup 0))
18631 (match_operand 3))]
18633 && !TARGET_INDIRECT_BRANCH_REGISTER
18634 && SIBLING_CALL_P (peep2_next_insn (2))
18635 && !reg_mentioned_p (operands[0],
18636 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
18637 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
18638 (parallel [(call (mem:QI (match_dup 1))
18640 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
18642 (define_expand "call_pop"
18643 [(parallel [(call (match_operand:QI 0)
18644 (match_operand:SI 1))
18645 (set (reg:SI SP_REG)
18646 (plus:SI (reg:SI SP_REG)
18647 (match_operand:SI 3)))])]
18650 ix86_expand_call (NULL, operands[0], operands[1],
18651 operands[2], operands[3], false);
18655 (define_insn "*call_pop"
18656 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz"))
18658 (set (reg:SI SP_REG)
18659 (plus:SI (reg:SI SP_REG)
18660 (match_operand:SI 2 "immediate_operand" "i")))]
18661 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
18662 "* return ix86_output_call_insn (insn, operands[0]);"
18663 [(set_attr "type" "call")])
18665 (define_insn "*sibcall_pop"
18666 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
18668 (set (reg:SI SP_REG)
18669 (plus:SI (reg:SI SP_REG)
18670 (match_operand:SI 2 "immediate_operand" "i")))]
18671 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
18672 "* return ix86_output_call_insn (insn, operands[0]);"
18673 [(set_attr "type" "call")])
18675 (define_insn "*sibcall_pop_memory"
18676 [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs"))
18678 (set (reg:SI SP_REG)
18679 (plus:SI (reg:SI SP_REG)
18680 (match_operand:SI 2 "immediate_operand" "i")))
18681 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
18683 "* return ix86_output_call_insn (insn, operands[0]);"
18684 [(set_attr "type" "call")])
18687 [(set (match_operand:SI 0 "register_operand")
18688 (match_operand:SI 1 "memory_operand"))
18689 (parallel [(call (mem:QI (match_dup 0))
18691 (set (reg:SI SP_REG)
18692 (plus:SI (reg:SI SP_REG)
18693 (match_operand:SI 4 "immediate_operand")))])]
18694 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
18695 && !reg_mentioned_p (operands[0],
18696 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
18697 [(parallel [(call (mem:QI (match_dup 1))
18699 (set (reg:SI SP_REG)
18700 (plus:SI (reg:SI SP_REG)
18702 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
18705 [(set (match_operand:SI 0 "register_operand")
18706 (match_operand:SI 1 "memory_operand"))
18707 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
18708 (parallel [(call (mem:QI (match_dup 0))
18710 (set (reg:SI SP_REG)
18711 (plus:SI (reg:SI SP_REG)
18712 (match_operand:SI 4 "immediate_operand")))])]
18713 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
18714 && !reg_mentioned_p (operands[0],
18715 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
18716 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
18717 (parallel [(call (mem:QI (match_dup 1))
18719 (set (reg:SI SP_REG)
18720 (plus:SI (reg:SI SP_REG)
18722 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
18724 ;; Combining simple memory jump instruction
18727 [(set (match_operand:W 0 "register_operand")
18728 (match_operand:W 1 "memory_operand"))
18729 (set (pc) (match_dup 0))]
18731 && !TARGET_INDIRECT_BRANCH_REGISTER
18732 && peep2_reg_dead_p (2, operands[0])"
18733 [(set (pc) (match_dup 1))])
18735 ;; Call subroutine, returning value in operand 0
18737 (define_expand "call_value"
18738 [(set (match_operand 0)
18739 (call (match_operand:QI 1)
18740 (match_operand 2)))
18741 (use (match_operand 3))]
18744 ix86_expand_call (operands[0], operands[1], operands[2],
18745 operands[3], NULL, false);
18749 (define_expand "sibcall_value"
18750 [(set (match_operand 0)
18751 (call (match_operand:QI 1)
18752 (match_operand 2)))
18753 (use (match_operand 3))]
18756 ix86_expand_call (operands[0], operands[1], operands[2],
18757 operands[3], NULL, true);
18761 (define_insn "*call_value"
18762 [(set (match_operand 0)
18763 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
18764 (match_operand 2)))]
18765 "!SIBLING_CALL_P (insn)"
18766 "* return ix86_output_call_insn (insn, operands[1]);"
18767 [(set_attr "type" "callv")])
18769 ;; This covers both call and sibcall since only GOT slot is allowed.
18770 (define_insn "*call_value_got_x32"
18771 [(set (match_operand 0)
18774 (match_operand:SI 1 "GOT_memory_operand" "Bg")))
18775 (match_operand 2)))]
18778 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
18779 return ix86_output_call_insn (insn, fnaddr);
18781 [(set_attr "type" "callv")])
18783 ;; Since sibcall never returns, we can only use call-clobbered register
18785 (define_insn "*sibcall_value_GOT_32"
18786 [(set (match_operand 0)
18789 (match_operand:SI 1 "register_no_elim_operand" "U")
18790 (match_operand:SI 2 "GOT32_symbol_operand"))))
18791 (match_operand 3)))]
18794 && !TARGET_INDIRECT_BRANCH_REGISTER
18795 && SIBLING_CALL_P (insn)"
18797 rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
18798 fnaddr = gen_const_mem (SImode, fnaddr);
18799 return ix86_output_call_insn (insn, fnaddr);
18801 [(set_attr "type" "callv")])
18803 (define_insn "*sibcall_value"
18804 [(set (match_operand 0)
18805 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
18806 (match_operand 2)))]
18807 "SIBLING_CALL_P (insn)"
18808 "* return ix86_output_call_insn (insn, operands[1]);"
18809 [(set_attr "type" "callv")])
18811 (define_insn "*sibcall_value_memory"
18812 [(set (match_operand 0)
18813 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
18814 (match_operand 2)))
18815 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
18816 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
18817 "* return ix86_output_call_insn (insn, operands[1]);"
18818 [(set_attr "type" "callv")])
18821 [(set (match_operand:W 0 "register_operand")
18822 (match_operand:W 1 "memory_operand"))
18823 (set (match_operand 2)
18824 (call (mem:QI (match_dup 0))
18825 (match_operand 3)))]
18827 && !TARGET_INDIRECT_BRANCH_REGISTER
18828 && SIBLING_CALL_P (peep2_next_insn (1))
18829 && !reg_mentioned_p (operands[0],
18830 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
18831 [(parallel [(set (match_dup 2)
18832 (call (mem:QI (match_dup 1))
18834 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
18837 [(set (match_operand:W 0 "register_operand")
18838 (match_operand:W 1 "memory_operand"))
18839 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
18840 (set (match_operand 2)
18841 (call (mem:QI (match_dup 0))
18842 (match_operand 3)))]
18844 && !TARGET_INDIRECT_BRANCH_REGISTER
18845 && SIBLING_CALL_P (peep2_next_insn (2))
18846 && !reg_mentioned_p (operands[0],
18847 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
18848 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
18849 (parallel [(set (match_dup 2)
18850 (call (mem:QI (match_dup 1))
18852 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
18854 (define_expand "call_value_pop"
18855 [(parallel [(set (match_operand 0)
18856 (call (match_operand:QI 1)
18857 (match_operand:SI 2)))
18858 (set (reg:SI SP_REG)
18859 (plus:SI (reg:SI SP_REG)
18860 (match_operand:SI 4)))])]
18863 ix86_expand_call (operands[0], operands[1], operands[2],
18864 operands[3], operands[4], false);
18868 (define_insn "*call_value_pop"
18869 [(set (match_operand 0)
18870 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz"))
18871 (match_operand 2)))
18872 (set (reg:SI SP_REG)
18873 (plus:SI (reg:SI SP_REG)
18874 (match_operand:SI 3 "immediate_operand" "i")))]
18875 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
18876 "* return ix86_output_call_insn (insn, operands[1]);"
18877 [(set_attr "type" "callv")])
18879 (define_insn "*sibcall_value_pop"
18880 [(set (match_operand 0)
18881 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
18882 (match_operand 2)))
18883 (set (reg:SI SP_REG)
18884 (plus:SI (reg:SI SP_REG)
18885 (match_operand:SI 3 "immediate_operand" "i")))]
18886 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
18887 "* return ix86_output_call_insn (insn, operands[1]);"
18888 [(set_attr "type" "callv")])
18890 (define_insn "*sibcall_value_pop_memory"
18891 [(set (match_operand 0)
18892 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
18893 (match_operand 2)))
18894 (set (reg:SI SP_REG)
18895 (plus:SI (reg:SI SP_REG)
18896 (match_operand:SI 3 "immediate_operand" "i")))
18897 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
18899 "* return ix86_output_call_insn (insn, operands[1]);"
18900 [(set_attr "type" "callv")])
18903 [(set (match_operand:SI 0 "register_operand")
18904 (match_operand:SI 1 "memory_operand"))
18905 (parallel [(set (match_operand 2)
18906 (call (mem:QI (match_dup 0))
18907 (match_operand 3)))
18908 (set (reg:SI SP_REG)
18909 (plus:SI (reg:SI SP_REG)
18910 (match_operand:SI 4 "immediate_operand")))])]
18911 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
18912 && !reg_mentioned_p (operands[0],
18913 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
18914 [(parallel [(set (match_dup 2)
18915 (call (mem:QI (match_dup 1))
18917 (set (reg:SI SP_REG)
18918 (plus:SI (reg:SI SP_REG)
18920 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
18923 [(set (match_operand:SI 0 "register_operand")
18924 (match_operand:SI 1 "memory_operand"))
18925 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
18926 (parallel [(set (match_operand 2)
18927 (call (mem:QI (match_dup 0))
18928 (match_operand 3)))
18929 (set (reg:SI SP_REG)
18930 (plus:SI (reg:SI SP_REG)
18931 (match_operand:SI 4 "immediate_operand")))])]
18932 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
18933 && !reg_mentioned_p (operands[0],
18934 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
18935 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
18936 (parallel [(set (match_dup 2)
18937 (call (mem:QI (match_dup 1))
18939 (set (reg:SI SP_REG)
18940 (plus:SI (reg:SI SP_REG)
18942 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
18944 ;; Call subroutine returning any type.
18946 (define_expand "untyped_call"
18947 [(parallel [(call (match_operand 0)
18950 (match_operand 2)])]
18955 /* In order to give reg-stack an easier job in validating two
18956 coprocessor registers as containing a possible return value,
18957 simply pretend the untyped call returns a complex long double
18960 We can't use SSE_REGPARM_MAX here since callee is unprototyped
18961 and should have the default ABI. */
18963 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
18964 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
18965 operands[0], const0_rtx,
18966 GEN_INT ((TARGET_64BIT
18967 ? (ix86_abi == SYSV_ABI
18968 ? X86_64_SSE_REGPARM_MAX
18969 : X86_64_MS_SSE_REGPARM_MAX)
18970 : X86_32_SSE_REGPARM_MAX)
18974 for (i = 0; i < XVECLEN (operands[2], 0); i++)
18976 rtx set = XVECEXP (operands[2], 0, i);
18977 emit_move_insn (SET_DEST (set), SET_SRC (set));
18980 /* The optimizer does not know that the call sets the function value
18981 registers we stored in the result block. We avoid problems by
18982 claiming that all hard registers are used and clobbered at this
18984 emit_insn (gen_blockage ());
18989 ;; Prologue and epilogue instructions
18991 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
18992 ;; all of memory. This blocks insns from being moved across this point.
18994 (define_insn "blockage"
18995 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
18998 [(set_attr "length" "0")])
19000 ;; Do not schedule instructions accessing memory across this point.
19002 (define_expand "memory_blockage"
19003 [(set (match_dup 0)
19004 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
19007 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
19008 MEM_VOLATILE_P (operands[0]) = 1;
19011 (define_insn "*memory_blockage"
19012 [(set (match_operand:BLK 0)
19013 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
19016 [(set_attr "length" "0")])
19018 ;; As USE insns aren't meaningful after reload, this is used instead
19019 ;; to prevent deleting instructions setting registers for PIC code
19020 (define_insn "prologue_use"
19021 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
19024 [(set_attr "length" "0")])
19026 ;; Insn emitted into the body of a function to return from a function.
19027 ;; This is only done if the function's epilogue is known to be simple.
19028 ;; See comments for ix86_can_use_return_insn_p in i386.cc.
19030 (define_expand "return"
19032 "ix86_can_use_return_insn_p ()"
19034 if (crtl->args.pops_args)
19036 rtx popc = GEN_INT (crtl->args.pops_args);
19037 emit_jump_insn (gen_simple_return_pop_internal (popc));
19042 ;; We need to disable this for TARGET_SEH, as otherwise
19043 ;; shrink-wrapped prologue gets enabled too. This might exceed
19044 ;; the maximum size of prologue in unwind information.
19045 ;; Also disallow shrink-wrapping if using stack slot to pass the
19046 ;; static chain pointer - the first instruction has to be pushl %esi
19047 ;; and it can't be moved around, as we use alternate entry points
19049 ;; Also disallow for ms_hook_prologue functions which have frame
19050 ;; pointer set up in function label which is correctly handled in
19051 ;; ix86_expand_{prologue|epligoue}() only.
19053 (define_expand "simple_return"
19055 "!TARGET_SEH && !ix86_static_chain_on_stack && !ix86_function_ms_hook_prologue (cfun->decl)"
19057 if (crtl->args.pops_args)
19059 rtx popc = GEN_INT (crtl->args.pops_args);
19060 emit_jump_insn (gen_simple_return_pop_internal (popc));
19065 (define_insn "simple_return_internal"
19068 "* return ix86_output_function_return (false);"
19069 [(set_attr "length" "1")
19070 (set_attr "atom_unit" "jeu")
19071 (set_attr "length_immediate" "0")
19072 (set_attr "modrm" "0")])
19074 (define_insn "interrupt_return"
19076 (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
19079 return TARGET_64BIT ? (TARGET_UINTR ? "uiret" : "iretq") : "iret";
19082 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
19083 ;; instruction Athlon and K8 have.
19085 (define_insn "simple_return_internal_long"
19087 (unspec [(const_int 0)] UNSPEC_REP)]
19089 "* return ix86_output_function_return (true);"
19090 [(set_attr "length" "2")
19091 (set_attr "atom_unit" "jeu")
19092 (set_attr "length_immediate" "0")
19093 (set_attr "prefix_rep" "1")
19094 (set_attr "modrm" "0")])
19096 (define_insn_and_split "simple_return_pop_internal"
19098 (use (match_operand:SI 0 "const_int_operand"))]
19101 "&& cfun->machine->function_return_type != indirect_branch_keep"
19103 "ix86_split_simple_return_pop_internal (operands[0]); DONE;"
19104 [(set_attr "length" "3")
19105 (set_attr "atom_unit" "jeu")
19106 (set_attr "length_immediate" "2")
19107 (set_attr "modrm" "0")])
19109 (define_expand "simple_return_indirect_internal"
19112 (use (match_operand 0 "register_operand"))])])
19114 (define_insn "*simple_return_indirect_internal<mode>"
19116 (use (match_operand:W 0 "register_operand" "r"))]
19118 "* return ix86_output_indirect_function_return (operands[0]);"
19119 [(set (attr "type")
19120 (if_then_else (match_test "(cfun->machine->indirect_branch_type
19121 != indirect_branch_keep)")
19122 (const_string "multi")
19123 (const_string "ibr")))
19124 (set_attr "length_immediate" "0")])
19130 [(set_attr "length" "1")
19131 (set_attr "length_immediate" "0")
19132 (set_attr "modrm" "0")])
19134 ;; Generate nops. Operand 0 is the number of nops, up to 8.
19135 (define_insn "nops"
19136 [(unspec_volatile [(match_operand 0 "const_int_operand")]
19140 int num = INTVAL (operands[0]);
19142 gcc_assert (IN_RANGE (num, 1, 8));
19145 fputs ("\tnop\n", asm_out_file);
19149 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
19150 (set_attr "length_immediate" "0")
19151 (set_attr "modrm" "0")])
19153 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
19154 ;; branch prediction penalty for the third jump in a 16-byte
19158 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
19161 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
19162 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
19164 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
19165 The align insn is used to avoid 3 jump instructions in the row to improve
19166 branch prediction and the benefits hardly outweigh the cost of extra 8
19167 nops on the average inserted by full alignment pseudo operation. */
19171 [(set_attr "length" "16")])
19173 (define_expand "prologue"
19176 "ix86_expand_prologue (); DONE;")
19178 (define_expand "set_got"
19180 [(set (match_operand:SI 0 "register_operand")
19181 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
19182 (clobber (reg:CC FLAGS_REG))])]
19185 if (flag_pic && !TARGET_VXWORKS_RTP)
19186 ix86_pc_thunk_call_expanded = true;
19189 (define_insn "*set_got"
19190 [(set (match_operand:SI 0 "register_operand" "=r")
19191 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
19192 (clobber (reg:CC FLAGS_REG))]
19194 "* return output_set_got (operands[0], NULL_RTX);"
19195 [(set_attr "type" "multi")
19196 (set_attr "length" "12")])
19198 (define_expand "set_got_labelled"
19200 [(set (match_operand:SI 0 "register_operand")
19201 (unspec:SI [(label_ref (match_operand 1))]
19203 (clobber (reg:CC FLAGS_REG))])]
19206 if (flag_pic && !TARGET_VXWORKS_RTP)
19207 ix86_pc_thunk_call_expanded = true;
19210 (define_insn "*set_got_labelled"
19211 [(set (match_operand:SI 0 "register_operand" "=r")
19212 (unspec:SI [(label_ref (match_operand 1))]
19214 (clobber (reg:CC FLAGS_REG))]
19216 "* return output_set_got (operands[0], operands[1]);"
19217 [(set_attr "type" "multi")
19218 (set_attr "length" "12")])
19220 (define_insn "set_got_rex64"
19221 [(set (match_operand:DI 0 "register_operand" "=r")
19222 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
19224 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
19225 [(set_attr "type" "lea")
19226 (set_attr "length_address" "4")
19227 (set_attr "mode" "DI")])
19229 (define_insn "set_rip_rex64"
19230 [(set (match_operand:DI 0 "register_operand" "=r")
19231 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
19233 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
19234 [(set_attr "type" "lea")
19235 (set_attr "length_address" "4")
19236 (set_attr "mode" "DI")])
19238 (define_insn "set_got_offset_rex64"
19239 [(set (match_operand:DI 0 "register_operand" "=r")
19241 [(label_ref (match_operand 1))]
19242 UNSPEC_SET_GOT_OFFSET))]
19244 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
19245 [(set_attr "type" "imov")
19246 (set_attr "length_immediate" "0")
19247 (set_attr "length_address" "8")
19248 (set_attr "mode" "DI")])
19250 (define_expand "epilogue"
19253 "ix86_expand_epilogue (1); DONE;")
19255 (define_expand "sibcall_epilogue"
19258 "ix86_expand_epilogue (0); DONE;")
19260 (define_expand "eh_return"
19261 [(use (match_operand 0 "register_operand"))]
19264 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
19266 /* Tricky bit: we write the address of the handler to which we will
19267 be returning into someone else's stack frame, one word below the
19268 stack address we wish to restore. */
19269 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
19270 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
19271 /* Return address is always in word_mode. */
19272 tmp = gen_rtx_MEM (word_mode, tmp);
19273 if (GET_MODE (ra) != word_mode)
19274 ra = convert_to_mode (word_mode, ra, 1);
19275 emit_move_insn (tmp, ra);
19277 emit_jump_insn (gen_eh_return_internal ());
19282 (define_insn_and_split "eh_return_internal"
19286 "epilogue_completed"
19288 "ix86_expand_epilogue (2); DONE;")
19290 (define_expand "@leave_<mode>"
19292 [(set (reg:W SP_REG) (plus:W (reg:W BP_REG) (match_dup 0)))
19293 (set (reg:W BP_REG) (mem:W (reg:W BP_REG)))
19294 (clobber (mem:BLK (scratch)))])]
19296 "operands[0] = GEN_INT (<MODE_SIZE>);")
19298 (define_insn "*leave"
19299 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
19300 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
19301 (clobber (mem:BLK (scratch)))]
19304 [(set_attr "type" "leave")])
19306 (define_insn "*leave_rex64"
19307 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
19308 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
19309 (clobber (mem:BLK (scratch)))]
19312 [(set_attr "type" "leave")])
19314 ;; Handle -fsplit-stack.
19316 (define_expand "split_stack_prologue"
19320 ix86_expand_split_stack_prologue ();
19324 ;; In order to support the call/return predictor, we use a return
19325 ;; instruction which the middle-end doesn't see.
19326 (define_insn "split_stack_return"
19327 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
19328 UNSPECV_SPLIT_STACK_RETURN)]
19331 if (operands[0] == const0_rtx)
19336 [(set_attr "atom_unit" "jeu")
19337 (set_attr "modrm" "0")
19338 (set (attr "length")
19339 (if_then_else (match_operand:SI 0 "const0_operand")
19342 (set (attr "length_immediate")
19343 (if_then_else (match_operand:SI 0 "const0_operand")
19347 ;; If there are operand 0 bytes available on the stack, jump to
19350 (define_expand "split_stack_space_check"
19351 [(set (pc) (if_then_else
19352 (ltu (minus (reg SP_REG)
19353 (match_operand 0 "register_operand"))
19355 (label_ref (match_operand 1))
19359 rtx reg = gen_reg_rtx (Pmode);
19361 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, operands[0]));
19363 operands[2] = ix86_split_stack_guard ();
19364 ix86_expand_branch (GEU, reg, operands[2], operands[1]);
19369 ;; Bit manipulation instructions.
19371 (define_expand "ffs<mode>2"
19372 [(set (match_dup 2) (const_int -1))
19373 (parallel [(set (match_dup 3) (match_dup 4))
19374 (set (match_operand:SWI48 0 "register_operand")
19376 (match_operand:SWI48 1 "nonimmediate_operand")))])
19377 (set (match_dup 0) (if_then_else:SWI48
19378 (eq (match_dup 3) (const_int 0))
19381 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
19382 (clobber (reg:CC FLAGS_REG))])]
19385 machine_mode flags_mode;
19387 if (<MODE>mode == SImode && !TARGET_CMOVE)
19389 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
19393 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
19395 operands[2] = gen_reg_rtx (<MODE>mode);
19396 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
19397 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
19400 (define_insn_and_split "ffssi2_no_cmove"
19401 [(set (match_operand:SI 0 "register_operand" "=r")
19402 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
19403 (clobber (match_scratch:SI 2 "=&q"))
19404 (clobber (reg:CC FLAGS_REG))]
19407 "&& reload_completed"
19408 [(parallel [(set (match_dup 4) (match_dup 5))
19409 (set (match_dup 0) (ctz:SI (match_dup 1)))])
19410 (set (strict_low_part (match_dup 3))
19411 (eq:QI (match_dup 4) (const_int 0)))
19412 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
19413 (clobber (reg:CC FLAGS_REG))])
19414 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
19415 (clobber (reg:CC FLAGS_REG))])
19416 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
19417 (clobber (reg:CC FLAGS_REG))])]
19419 machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
19421 operands[3] = gen_lowpart (QImode, operands[2]);
19422 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
19423 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
19425 ix86_expand_clear (operands[2]);
19428 (define_insn_and_split "*tzcnt<mode>_1"
19429 [(set (reg:CCC FLAGS_REG)
19430 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19432 (set (match_operand:SWI48 0 "register_operand" "=r")
19433 (ctz:SWI48 (match_dup 1)))]
19435 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
19436 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
19437 && optimize_function_for_speed_p (cfun)
19438 && !reg_mentioned_p (operands[0], operands[1])"
19440 [(set (reg:CCC FLAGS_REG)
19441 (compare:CCC (match_dup 1) (const_int 0)))
19443 (ctz:SWI48 (match_dup 1)))
19444 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
19445 "ix86_expand_clear (operands[0]);"
19446 [(set_attr "type" "alu1")
19447 (set_attr "prefix_0f" "1")
19448 (set_attr "prefix_rep" "1")
19449 (set_attr "btver2_decode" "double")
19450 (set_attr "mode" "<MODE>")])
19452 ; False dependency happens when destination is only updated by tzcnt,
19453 ; lzcnt or popcnt. There is no false dependency when destination is
19454 ; also used in source.
19455 (define_insn "*tzcnt<mode>_1_falsedep"
19456 [(set (reg:CCC FLAGS_REG)
19457 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19459 (set (match_operand:SWI48 0 "register_operand" "=r")
19460 (ctz:SWI48 (match_dup 1)))
19461 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
19462 UNSPEC_INSN_FALSE_DEP)]
19464 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
19465 [(set_attr "type" "alu1")
19466 (set_attr "prefix_0f" "1")
19467 (set_attr "prefix_rep" "1")
19468 (set_attr "btver2_decode" "double")
19469 (set_attr "mode" "<MODE>")])
19471 (define_insn "*bsf<mode>_1"
19472 [(set (reg:CCZ FLAGS_REG)
19473 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19475 (set (match_operand:SWI48 0 "register_operand" "=r")
19476 (ctz:SWI48 (match_dup 1)))]
19478 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
19479 [(set_attr "type" "alu1")
19480 (set_attr "prefix_0f" "1")
19481 (set_attr "btver2_decode" "double")
19482 (set_attr "znver1_decode" "vector")
19483 (set_attr "mode" "<MODE>")])
19485 (define_insn_and_split "ctz<mode>2"
19486 [(set (match_operand:SWI48 0 "register_operand" "=r")
19488 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
19489 (clobber (reg:CC FLAGS_REG))]
19493 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
19494 else if (optimize_function_for_size_p (cfun))
19496 else if (TARGET_CPU_P (GENERIC))
19497 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
19498 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
19500 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
19502 "(TARGET_BMI || TARGET_CPU_P (GENERIC))
19503 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
19504 && optimize_function_for_speed_p (cfun)
19505 && !reg_mentioned_p (operands[0], operands[1])"
19507 [(set (match_dup 0)
19508 (ctz:SWI48 (match_dup 1)))
19509 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
19510 (clobber (reg:CC FLAGS_REG))])]
19511 "ix86_expand_clear (operands[0]);"
19512 [(set_attr "type" "alu1")
19513 (set_attr "prefix_0f" "1")
19514 (set (attr "prefix_rep")
19516 (ior (match_test "TARGET_BMI")
19517 (and (not (match_test "optimize_function_for_size_p (cfun)"))
19518 (match_test "TARGET_CPU_P (GENERIC)")))
19520 (const_string "0")))
19521 (set_attr "mode" "<MODE>")])
19523 ; False dependency happens when destination is only updated by tzcnt,
19524 ; lzcnt or popcnt. There is no false dependency when destination is
19525 ; also used in source.
19526 (define_insn "*ctz<mode>2_falsedep"
19527 [(set (match_operand:SWI48 0 "register_operand" "=r")
19529 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
19530 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
19531 UNSPEC_INSN_FALSE_DEP)
19532 (clobber (reg:CC FLAGS_REG))]
19536 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
19537 else if (TARGET_CPU_P (GENERIC))
19538 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
19539 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
19541 gcc_unreachable ();
19543 [(set_attr "type" "alu1")
19544 (set_attr "prefix_0f" "1")
19545 (set_attr "prefix_rep" "1")
19546 (set_attr "mode" "<MODE>")])
19548 (define_insn_and_split "*ctzsi2_zext"
19549 [(set (match_operand:DI 0 "register_operand" "=r")
19553 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
19555 (clobber (reg:CC FLAGS_REG))]
19556 "TARGET_BMI && TARGET_64BIT"
19557 "tzcnt{l}\t{%1, %k0|%k0, %1}"
19558 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
19559 && optimize_function_for_speed_p (cfun)
19560 && !reg_mentioned_p (operands[0], operands[1])"
19562 [(set (match_dup 0)
19563 (and:DI (subreg:DI (ctz:SI (match_dup 1)) 0) (const_int 63)))
19564 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
19565 (clobber (reg:CC FLAGS_REG))])]
19566 "ix86_expand_clear (operands[0]);"
19567 [(set_attr "type" "alu1")
19568 (set_attr "prefix_0f" "1")
19569 (set_attr "prefix_rep" "1")
19570 (set_attr "mode" "SI")])
19572 ; False dependency happens when destination is only updated by tzcnt,
19573 ; lzcnt or popcnt. There is no false dependency when destination is
19574 ; also used in source.
19575 (define_insn "*ctzsi2_zext_falsedep"
19576 [(set (match_operand:DI 0 "register_operand" "=r")
19580 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
19582 (unspec [(match_operand:DI 2 "register_operand" "0")]
19583 UNSPEC_INSN_FALSE_DEP)
19584 (clobber (reg:CC FLAGS_REG))]
19585 "TARGET_BMI && TARGET_64BIT"
19586 "tzcnt{l}\t{%1, %k0|%k0, %1}"
19587 [(set_attr "type" "alu1")
19588 (set_attr "prefix_0f" "1")
19589 (set_attr "prefix_rep" "1")
19590 (set_attr "mode" "SI")])
19592 (define_insn_and_split "*ctzsidi2_<s>ext"
19593 [(set (match_operand:DI 0 "register_operand" "=r")
19596 (match_operand:SI 1 "nonimmediate_operand" "rm"))))
19597 (clobber (reg:CC FLAGS_REG))]
19601 return "tzcnt{l}\t{%1, %k0|%k0, %1}";
19602 else if (TARGET_CPU_P (GENERIC)
19603 && !optimize_function_for_size_p (cfun))
19604 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
19605 return "rep%; bsf{l}\t{%1, %k0|%k0, %1}";
19606 return "bsf{l}\t{%1, %k0|%k0, %1}";
19608 "(TARGET_BMI || TARGET_CPU_P (GENERIC))
19609 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
19610 && optimize_function_for_speed_p (cfun)
19611 && !reg_mentioned_p (operands[0], operands[1])"
19613 [(set (match_dup 0)
19614 (any_extend:DI (ctz:SI (match_dup 1))))
19615 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
19616 (clobber (reg:CC FLAGS_REG))])]
19617 "ix86_expand_clear (operands[0]);"
19618 [(set_attr "type" "alu1")
19619 (set_attr "prefix_0f" "1")
19620 (set (attr "prefix_rep")
19622 (ior (match_test "TARGET_BMI")
19623 (and (not (match_test "optimize_function_for_size_p (cfun)"))
19624 (match_test "TARGET_CPU_P (GENERIC)")))
19626 (const_string "0")))
19627 (set_attr "mode" "SI")])
19629 (define_insn "*ctzsidi2_<s>ext_falsedep"
19630 [(set (match_operand:DI 0 "register_operand" "=r")
19633 (match_operand:SI 1 "nonimmediate_operand" "rm"))))
19634 (unspec [(match_operand:DI 2 "register_operand" "0")]
19635 UNSPEC_INSN_FALSE_DEP)
19636 (clobber (reg:CC FLAGS_REG))]
19640 return "tzcnt{l}\t{%1, %k0|%k0, %1}";
19641 else if (TARGET_CPU_P (GENERIC))
19642 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
19643 return "rep%; bsf{l}\t{%1, %k0|%k0, %1}";
19645 gcc_unreachable ();
19647 [(set_attr "type" "alu1")
19648 (set_attr "prefix_0f" "1")
19649 (set_attr "prefix_rep" "1")
19650 (set_attr "mode" "SI")])
19652 (define_insn "bsr_rex64"
19653 [(set (reg:CCZ FLAGS_REG)
19654 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
19656 (set (match_operand:DI 0 "register_operand" "=r")
19657 (minus:DI (const_int 63)
19658 (clz:DI (match_dup 1))))]
19660 "bsr{q}\t{%1, %0|%0, %1}"
19661 [(set_attr "type" "alu1")
19662 (set_attr "prefix_0f" "1")
19663 (set_attr "znver1_decode" "vector")
19664 (set_attr "mode" "DI")])
19666 (define_insn "bsr_rex64_1"
19667 [(set (match_operand:DI 0 "register_operand" "=r")
19668 (minus:DI (const_int 63)
19669 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
19670 (clobber (reg:CC FLAGS_REG))]
19671 "!TARGET_LZCNT && TARGET_64BIT"
19672 "bsr{q}\t{%1, %0|%0, %1}"
19673 [(set_attr "type" "alu1")
19674 (set_attr "prefix_0f" "1")
19675 (set_attr "znver1_decode" "vector")
19676 (set_attr "mode" "DI")])
19678 (define_insn "bsr_rex64_1_zext"
19679 [(set (match_operand:DI 0 "register_operand" "=r")
19681 (minus:SI (const_int 63)
19683 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
19685 (clobber (reg:CC FLAGS_REG))]
19686 "!TARGET_LZCNT && TARGET_64BIT"
19687 "bsr{q}\t{%1, %0|%0, %1}"
19688 [(set_attr "type" "alu1")
19689 (set_attr "prefix_0f" "1")
19690 (set_attr "znver1_decode" "vector")
19691 (set_attr "mode" "DI")])
19694 [(set (reg:CCZ FLAGS_REG)
19695 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
19697 (set (match_operand:SI 0 "register_operand" "=r")
19698 (minus:SI (const_int 31)
19699 (clz:SI (match_dup 1))))]
19701 "bsr{l}\t{%1, %0|%0, %1}"
19702 [(set_attr "type" "alu1")
19703 (set_attr "prefix_0f" "1")
19704 (set_attr "znver1_decode" "vector")
19705 (set_attr "mode" "SI")])
19707 (define_insn "bsr_1"
19708 [(set (match_operand:SI 0 "register_operand" "=r")
19709 (minus:SI (const_int 31)
19710 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
19711 (clobber (reg:CC FLAGS_REG))]
19713 "bsr{l}\t{%1, %0|%0, %1}"
19714 [(set_attr "type" "alu1")
19715 (set_attr "prefix_0f" "1")
19716 (set_attr "znver1_decode" "vector")
19717 (set_attr "mode" "SI")])
19719 (define_insn "bsr_zext_1"
19720 [(set (match_operand:DI 0 "register_operand" "=r")
19724 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))))
19725 (clobber (reg:CC FLAGS_REG))]
19726 "!TARGET_LZCNT && TARGET_64BIT"
19727 "bsr{l}\t{%1, %k0|%k0, %1}"
19728 [(set_attr "type" "alu1")
19729 (set_attr "prefix_0f" "1")
19730 (set_attr "znver1_decode" "vector")
19731 (set_attr "mode" "SI")])
19733 ; As bsr is undefined behavior on zero and for other input
19734 ; values it is in range 0 to 63, we can optimize away sign-extends.
19735 (define_insn_and_split "*bsr_rex64_2"
19736 [(set (match_operand:DI 0 "register_operand")
19741 (subreg:SI (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
19744 (clobber (reg:CC FLAGS_REG))]
19745 "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
19748 [(parallel [(set (reg:CCZ FLAGS_REG)
19749 (compare:CCZ (match_dup 1) (const_int 0)))
19751 (minus:DI (const_int 63) (clz:DI (match_dup 1))))])
19752 (parallel [(set (match_dup 0)
19753 (zero_extend:DI (xor:SI (match_dup 3) (const_int 63))))
19754 (clobber (reg:CC FLAGS_REG))])]
19756 operands[2] = gen_reg_rtx (DImode);
19757 operands[3] = lowpart_subreg (SImode, operands[2], DImode);
19760 (define_insn_and_split "*bsr_2"
19761 [(set (match_operand:DI 0 "register_operand")
19766 (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
19768 (clobber (reg:CC FLAGS_REG))]
19769 "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
19772 [(parallel [(set (reg:CCZ FLAGS_REG)
19773 (compare:CCZ (match_dup 1) (const_int 0)))
19775 (minus:SI (const_int 31) (clz:SI (match_dup 1))))])
19776 (parallel [(set (match_dup 0)
19777 (zero_extend:DI (xor:SI (match_dup 2) (const_int 31))))
19778 (clobber (reg:CC FLAGS_REG))])]
19779 "operands[2] = gen_reg_rtx (SImode);")
19781 ; Splitters to optimize 64 - __builtin_clzl (x) or 32 - __builtin_clz (x).
19782 ; Again, as for !TARGET_LZCNT CLZ is UB at zero, CLZ is guaranteed to be
19783 ; in [0, 63] or [0, 31] range.
19785 [(set (match_operand:SI 0 "register_operand")
19787 (match_operand:SI 2 "const_int_operand")
19789 (minus:SI (const_int 63)
19791 (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
19794 "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
19795 [(set (match_dup 3)
19796 (minus:DI (const_int 63) (clz:DI (match_dup 1))))
19798 (plus:SI (match_dup 5) (match_dup 4)))]
19800 operands[3] = gen_reg_rtx (DImode);
19801 operands[5] = lowpart_subreg (SImode, operands[3], DImode);
19802 if (INTVAL (operands[2]) == 63)
19804 emit_insn (gen_bsr_rex64_1_zext (operands[3], operands[1]));
19805 emit_move_insn (operands[0], operands[5]);
19808 operands[4] = gen_int_mode (UINTVAL (operands[2]) - 63, SImode);
19812 [(set (match_operand:SI 0 "register_operand")
19814 (match_operand:SI 2 "const_int_operand")
19816 (minus:SI (const_int 31)
19817 (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
19819 "!TARGET_LZCNT && ix86_pre_reload_split ()"
19820 [(set (match_dup 3)
19821 (minus:SI (const_int 31) (clz:SI (match_dup 1))))
19823 (plus:SI (match_dup 3) (match_dup 4)))]
19825 if (INTVAL (operands[2]) == 31)
19827 emit_insn (gen_bsr_1 (operands[0], operands[1]));
19830 operands[3] = gen_reg_rtx (SImode);
19831 operands[4] = gen_int_mode (UINTVAL (operands[2]) - 31, SImode);
19835 [(set (match_operand:DI 0 "register_operand")
19837 (match_operand:DI 2 "const_int_operand")
19840 (minus:SI (const_int 63)
19842 (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
19847 && ix86_pre_reload_split ()
19848 && ((unsigned HOST_WIDE_INT)
19849 trunc_int_for_mode (UINTVAL (operands[2]) - 63, SImode)
19850 == UINTVAL (operands[2]) - 63)"
19851 [(set (match_dup 3)
19852 (minus:DI (const_int 63) (clz:DI (match_dup 1))))
19854 (plus:DI (match_dup 3) (match_dup 4)))]
19856 if (INTVAL (operands[2]) == 63)
19858 emit_insn (gen_bsr_rex64_1 (operands[0], operands[1]));
19861 operands[3] = gen_reg_rtx (DImode);
19862 operands[4] = GEN_INT (UINTVAL (operands[2]) - 63);
19866 [(set (match_operand:DI 0 "register_operand")
19868 (match_operand:DI 2 "const_int_operand")
19871 (minus:SI (const_int 31)
19872 (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
19873 (const_int 31)))))]
19876 && ix86_pre_reload_split ()
19877 && ((unsigned HOST_WIDE_INT)
19878 trunc_int_for_mode (UINTVAL (operands[2]) - 31, SImode)
19879 == UINTVAL (operands[2]) - 31)"
19880 [(set (match_dup 3)
19881 (zero_extend:DI (minus:SI (const_int 31) (clz:SI (match_dup 1)))))
19883 (plus:DI (match_dup 3) (match_dup 4)))]
19885 if (INTVAL (operands[2]) == 31)
19887 emit_insn (gen_bsr_zext_1 (operands[0], operands[1]));
19890 operands[3] = gen_reg_rtx (DImode);
19891 operands[4] = GEN_INT (UINTVAL (operands[2]) - 31);
19894 (define_expand "clz<mode>2"
19896 [(set (reg:CCZ FLAGS_REG)
19897 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19899 (set (match_dup 3) (minus:SWI48
19901 (clz:SWI48 (match_dup 1))))])
19903 [(set (match_operand:SWI48 0 "register_operand")
19904 (xor:SWI48 (match_dup 3) (match_dup 2)))
19905 (clobber (reg:CC FLAGS_REG))])]
19910 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
19913 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
19914 operands[3] = gen_reg_rtx (<MODE>mode);
19917 (define_insn_and_split "clz<mode>2_lzcnt"
19918 [(set (match_operand:SWI48 0 "register_operand" "=r")
19920 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
19921 (clobber (reg:CC FLAGS_REG))]
19923 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
19924 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
19925 && optimize_function_for_speed_p (cfun)
19926 && !reg_mentioned_p (operands[0], operands[1])"
19928 [(set (match_dup 0)
19929 (clz:SWI48 (match_dup 1)))
19930 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
19931 (clobber (reg:CC FLAGS_REG))])]
19932 "ix86_expand_clear (operands[0]);"
19933 [(set_attr "prefix_rep" "1")
19934 (set_attr "type" "bitmanip")
19935 (set_attr "mode" "<MODE>")])
19937 ; False dependency happens when destination is only updated by tzcnt,
19938 ; lzcnt or popcnt. There is no false dependency when destination is
19939 ; also used in source.
19940 (define_insn "*clz<mode>2_lzcnt_falsedep"
19941 [(set (match_operand:SWI48 0 "register_operand" "=r")
19943 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
19944 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
19945 UNSPEC_INSN_FALSE_DEP)
19946 (clobber (reg:CC FLAGS_REG))]
19948 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
19949 [(set_attr "prefix_rep" "1")
19950 (set_attr "type" "bitmanip")
19951 (set_attr "mode" "<MODE>")])
19953 (define_insn_and_split "*clzsi2_lzcnt_zext"
19954 [(set (match_operand:DI 0 "register_operand" "=r")
19958 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
19960 (clobber (reg:CC FLAGS_REG))]
19961 "TARGET_LZCNT && TARGET_64BIT"
19962 "lzcnt{l}\t{%1, %k0|%k0, %1}"
19963 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
19964 && optimize_function_for_speed_p (cfun)
19965 && !reg_mentioned_p (operands[0], operands[1])"
19967 [(set (match_dup 0)
19968 (and:DI (subreg:DI (clz:SI (match_dup 1)) 0) (const_int 63)))
19969 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
19970 (clobber (reg:CC FLAGS_REG))])]
19971 "ix86_expand_clear (operands[0]);"
19972 [(set_attr "prefix_rep" "1")
19973 (set_attr "type" "bitmanip")
19974 (set_attr "mode" "SI")])
19976 ; False dependency happens when destination is only updated by tzcnt,
19977 ; lzcnt or popcnt. There is no false dependency when destination is
19978 ; also used in source.
19979 (define_insn "*clzsi2_lzcnt_zext_falsedep"
19980 [(set (match_operand:DI 0 "register_operand" "=r")
19984 (match_operand:SWI48 1 "nonimmediate_operand" "rm")) 0)
19986 (unspec [(match_operand:DI 2 "register_operand" "0")]
19987 UNSPEC_INSN_FALSE_DEP)
19988 (clobber (reg:CC FLAGS_REG))]
19990 "lzcnt{l}\t{%1, %k0|%k0, %1}"
19991 [(set_attr "prefix_rep" "1")
19992 (set_attr "type" "bitmanip")
19993 (set_attr "mode" "SI")])
19995 (define_insn_and_split "*clzsi2_lzcnt_zext_2"
19996 [(set (match_operand:DI 0 "register_operand" "=r")
19998 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
19999 (clobber (reg:CC FLAGS_REG))]
20000 "TARGET_LZCNT && TARGET_64BIT"
20001 "lzcnt{l}\t{%1, %k0|%k0, %1}"
20002 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
20003 && optimize_function_for_speed_p (cfun)
20004 && !reg_mentioned_p (operands[0], operands[1])"
20006 [(set (match_dup 0)
20007 (zero_extend:DI (clz:SI (match_dup 1))))
20008 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
20009 (clobber (reg:CC FLAGS_REG))])]
20010 "ix86_expand_clear (operands[0]);"
20011 [(set_attr "prefix_rep" "1")
20012 (set_attr "type" "bitmanip")
20013 (set_attr "mode" "SI")])
20015 ; False dependency happens when destination is only updated by tzcnt,
20016 ; lzcnt or popcnt. There is no false dependency when destination is
20017 ; also used in source.
20018 (define_insn "*clzsi2_lzcnt_zext_2_falsedep"
20019 [(set (match_operand:DI 0 "register_operand" "=r")
20021 (clz:SI (match_operand:SWI48 1 "nonimmediate_operand" "rm"))))
20022 (unspec [(match_operand:DI 2 "register_operand" "0")]
20023 UNSPEC_INSN_FALSE_DEP)
20024 (clobber (reg:CC FLAGS_REG))]
20026 "lzcnt{l}\t{%1, %k0|%k0, %1}"
20027 [(set_attr "prefix_rep" "1")
20028 (set_attr "type" "bitmanip")
20029 (set_attr "mode" "SI")])
20031 (define_int_iterator LT_ZCNT
20032 [(UNSPEC_TZCNT "TARGET_BMI")
20033 (UNSPEC_LZCNT "TARGET_LZCNT")])
20035 (define_int_attr lt_zcnt
20036 [(UNSPEC_TZCNT "tzcnt")
20037 (UNSPEC_LZCNT "lzcnt")])
20039 (define_int_attr lt_zcnt_type
20040 [(UNSPEC_TZCNT "alu1")
20041 (UNSPEC_LZCNT "bitmanip")])
20043 ;; Version of lzcnt/tzcnt that is expanded from intrinsics. This version
20044 ;; provides operand size as output when source operand is zero.
20046 (define_insn_and_split "<lt_zcnt>_<mode>"
20047 [(set (match_operand:SWI48 0 "register_operand" "=r")
20049 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
20050 (clobber (reg:CC FLAGS_REG))]
20052 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
20053 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
20054 && optimize_function_for_speed_p (cfun)
20055 && !reg_mentioned_p (operands[0], operands[1])"
20057 [(set (match_dup 0)
20058 (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
20059 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
20060 (clobber (reg:CC FLAGS_REG))])]
20061 "ix86_expand_clear (operands[0]);"
20062 [(set_attr "type" "<lt_zcnt_type>")
20063 (set_attr "prefix_0f" "1")
20064 (set_attr "prefix_rep" "1")
20065 (set_attr "mode" "<MODE>")])
20067 ; False dependency happens when destination is only updated by tzcnt,
20068 ; lzcnt or popcnt. There is no false dependency when destination is
20069 ; also used in source.
20070 (define_insn "*<lt_zcnt>_<mode>_falsedep"
20071 [(set (match_operand:SWI48 0 "register_operand" "=r")
20073 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
20074 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
20075 UNSPEC_INSN_FALSE_DEP)
20076 (clobber (reg:CC FLAGS_REG))]
20078 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
20079 [(set_attr "type" "<lt_zcnt_type>")
20080 (set_attr "prefix_0f" "1")
20081 (set_attr "prefix_rep" "1")
20082 (set_attr "mode" "<MODE>")])
20084 (define_insn "<lt_zcnt>_hi"
20085 [(set (match_operand:HI 0 "register_operand" "=r")
20087 [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT))
20088 (clobber (reg:CC FLAGS_REG))]
20090 "<lt_zcnt>{w}\t{%1, %0|%0, %1}"
20091 [(set_attr "type" "<lt_zcnt_type>")
20092 (set_attr "prefix_0f" "1")
20093 (set_attr "prefix_rep" "1")
20094 (set_attr "mode" "HI")])
20096 ;; BMI instructions.
20098 (define_insn "bmi_bextr_<mode>"
20099 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
20100 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
20101 (match_operand:SWI48 2 "register_operand" "r,r")]
20103 (clobber (reg:CC FLAGS_REG))]
20105 "bextr\t{%2, %1, %0|%0, %1, %2}"
20106 [(set_attr "type" "bitmanip")
20107 (set_attr "btver2_decode" "direct, double")
20108 (set_attr "mode" "<MODE>")])
20110 (define_insn "*bmi_bextr_<mode>_ccz"
20111 [(set (reg:CCZ FLAGS_REG)
20113 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
20114 (match_operand:SWI48 2 "register_operand" "r,r")]
20117 (clobber (match_scratch:SWI48 0 "=r,r"))]
20119 "bextr\t{%2, %1, %0|%0, %1, %2}"
20120 [(set_attr "type" "bitmanip")
20121 (set_attr "btver2_decode" "direct, double")
20122 (set_attr "mode" "<MODE>")])
20124 (define_insn "*bmi_blsi_<mode>"
20125 [(set (match_operand:SWI48 0 "register_operand" "=r")
20128 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
20130 (clobber (reg:CC FLAGS_REG))]
20132 "blsi\t{%1, %0|%0, %1}"
20133 [(set_attr "type" "bitmanip")
20134 (set_attr "btver2_decode" "double")
20135 (set_attr "mode" "<MODE>")])
20137 (define_insn "*bmi_blsi_<mode>_cmp"
20138 [(set (reg FLAGS_REG)
20141 (neg:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
20144 (set (match_operand:SWI48 0 "register_operand" "=r")
20145 (and:SWI48 (neg:SWI48 (match_dup 1)) (match_dup 1)))]
20146 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
20147 "blsi\t{%1, %0|%0, %1}"
20148 [(set_attr "type" "bitmanip")
20149 (set_attr "btver2_decode" "double")
20150 (set_attr "mode" "<MODE>")])
20152 (define_insn "*bmi_blsi_<mode>_ccno"
20153 [(set (reg FLAGS_REG)
20156 (neg:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
20159 (clobber (match_scratch:SWI48 0 "=r"))]
20160 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
20161 "blsi\t{%1, %0|%0, %1}"
20162 [(set_attr "type" "bitmanip")
20163 (set_attr "btver2_decode" "double")
20164 (set_attr "mode" "<MODE>")])
20166 (define_insn "*bmi_blsmsk_<mode>"
20167 [(set (match_operand:SWI48 0 "register_operand" "=r")
20170 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
20173 (clobber (reg:CC FLAGS_REG))]
20175 "blsmsk\t{%1, %0|%0, %1}"
20176 [(set_attr "type" "bitmanip")
20177 (set_attr "btver2_decode" "double")
20178 (set_attr "mode" "<MODE>")])
20180 (define_insn "*bmi_blsr_<mode>"
20181 [(set (match_operand:SWI48 0 "register_operand" "=r")
20184 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
20187 (clobber (reg:CC FLAGS_REG))]
20189 "blsr\t{%1, %0|%0, %1}"
20190 [(set_attr "type" "bitmanip")
20191 (set_attr "btver2_decode" "double")
20192 (set_attr "mode" "<MODE>")])
20194 (define_insn "*bmi_blsr_<mode>_cmp"
20195 [(set (reg:CCZ FLAGS_REG)
20199 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
20203 (set (match_operand:SWI48 0 "register_operand" "=r")
20210 "blsr\t{%1, %0|%0, %1}"
20211 [(set_attr "type" "bitmanip")
20212 (set_attr "btver2_decode" "double")
20213 (set_attr "mode" "<MODE>")])
20215 (define_insn "*bmi_blsr_<mode>_ccz"
20216 [(set (reg:CCZ FLAGS_REG)
20220 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
20224 (clobber (match_scratch:SWI48 0 "=r"))]
20226 "blsr\t{%1, %0|%0, %1}"
20227 [(set_attr "type" "bitmanip")
20228 (set_attr "btver2_decode" "double")
20229 (set_attr "mode" "<MODE>")])
20231 ;; BMI2 instructions.
20232 (define_expand "bmi2_bzhi_<mode>3"
20234 [(set (match_operand:SWI48 0 "register_operand")
20235 (if_then_else:SWI48
20236 (ne:QI (match_operand:QI 2 "register_operand")
20238 (zero_extract:SWI48
20239 (match_operand:SWI48 1 "nonimmediate_operand")
20240 (umin:QI (match_dup 2) (match_dup 3))
20243 (clobber (reg:CC FLAGS_REG))])]
20246 operands[2] = gen_lowpart (QImode, operands[2]);
20247 operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
20250 (define_insn "*bmi2_bzhi_<mode>3"
20251 [(set (match_operand:SWI48 0 "register_operand" "=r")
20252 (if_then_else:SWI48
20253 (ne:QI (match_operand:QI 2 "register_operand" "q")
20255 (zero_extract:SWI48
20256 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
20257 (umin:QI (match_dup 2)
20258 (match_operand:QI 3 "const_int_operand"))
20261 (clobber (reg:CC FLAGS_REG))]
20262 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
20263 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
20264 [(set_attr "type" "bitmanip")
20265 (set_attr "prefix" "vex")
20266 (set_attr "mode" "<MODE>")])
20268 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
20269 [(set (reg:CCZ FLAGS_REG)
20271 (if_then_else:SWI48
20272 (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0))
20273 (zero_extract:SWI48
20274 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
20275 (umin:QI (match_dup 2)
20276 (match_operand:QI 3 "const_int_operand"))
20280 (clobber (match_scratch:SWI48 0 "=r"))]
20281 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
20282 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
20283 [(set_attr "type" "bitmanip")
20284 (set_attr "prefix" "vex")
20285 (set_attr "mode" "<MODE>")])
20287 (define_insn "*bmi2_bzhi_<mode>3_2"
20288 [(set (match_operand:SWI48 0 "register_operand" "=r")
20291 (ashift:SWI48 (const_int 1)
20292 (match_operand:QI 2 "register_operand" "r"))
20294 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
20295 (clobber (reg:CC FLAGS_REG))]
20297 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
20298 [(set_attr "type" "bitmanip")
20299 (set_attr "prefix" "vex")
20300 (set_attr "mode" "<MODE>")])
20302 (define_insn "*bmi2_bzhi_<mode>3_3"
20303 [(set (match_operand:SWI48 0 "register_operand" "=r")
20306 (ashift:SWI48 (const_int -1)
20307 (match_operand:QI 2 "register_operand" "r")))
20308 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
20309 (clobber (reg:CC FLAGS_REG))]
20311 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
20312 [(set_attr "type" "bitmanip")
20313 (set_attr "prefix" "vex")
20314 (set_attr "mode" "<MODE>")])
20316 (define_insn "*bmi2_bzhi_zero_extendsidi_4"
20317 [(set (match_operand:DI 0 "register_operand" "=r")
20321 (ashift:SI (const_int 1)
20322 (match_operand:QI 2 "register_operand" "r"))
20324 (match_operand:SI 1 "nonimmediate_operand" "rm"))))
20325 (clobber (reg:CC FLAGS_REG))]
20326 "TARGET_64BIT && TARGET_BMI2"
20327 "bzhi\t{%q2, %q1, %q0|%q0, %q1, %q2}"
20328 [(set_attr "type" "bitmanip")
20329 (set_attr "prefix" "vex")
20330 (set_attr "mode" "DI")])
20332 (define_insn "*bmi2_bzhi_zero_extendsidi_5"
20333 [(set (match_operand:DI 0 "register_operand" "=r")
20337 (ashift:SI (const_int 1)
20338 (match_operand:QI 2 "register_operand" "r"))
20340 (match_operand:DI 1 "nonimmediate_operand" "rm")))
20341 (clobber (reg:CC FLAGS_REG))]
20342 "TARGET_64BIT && TARGET_BMI2"
20343 "bzhi\t{%q2, %q1, %q0|%q0, %q1, %q2}"
20344 [(set_attr "type" "bitmanip")
20345 (set_attr "prefix" "vex")
20346 (set_attr "mode" "DI")])
20348 (define_insn "bmi2_pdep_<mode>3"
20349 [(set (match_operand:SWI48 0 "register_operand" "=r")
20350 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
20351 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
20354 "pdep\t{%2, %1, %0|%0, %1, %2}"
20355 [(set_attr "type" "bitmanip")
20356 (set_attr "prefix" "vex")
20357 (set_attr "mode" "<MODE>")])
20359 (define_insn "bmi2_pext_<mode>3"
20360 [(set (match_operand:SWI48 0 "register_operand" "=r")
20361 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
20362 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
20365 "pext\t{%2, %1, %0|%0, %1, %2}"
20366 [(set_attr "type" "bitmanip")
20367 (set_attr "prefix" "vex")
20368 (set_attr "mode" "<MODE>")])
20370 ;; TBM instructions.
20371 (define_insn "@tbm_bextri_<mode>"
20372 [(set (match_operand:SWI48 0 "register_operand" "=r")
20373 (zero_extract:SWI48
20374 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
20375 (match_operand:QI 2 "const_0_to_255_operand")
20376 (match_operand:QI 3 "const_0_to_255_operand")))
20377 (clobber (reg:CC FLAGS_REG))]
20380 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
20381 return "bextr\t{%2, %1, %0|%0, %1, %2}";
20383 [(set_attr "type" "bitmanip")
20384 (set_attr "mode" "<MODE>")])
20386 (define_insn "*tbm_blcfill_<mode>"
20387 [(set (match_operand:SWI48 0 "register_operand" "=r")
20390 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
20393 (clobber (reg:CC FLAGS_REG))]
20395 "blcfill\t{%1, %0|%0, %1}"
20396 [(set_attr "type" "bitmanip")
20397 (set_attr "mode" "<MODE>")])
20399 (define_insn "*tbm_blci_<mode>"
20400 [(set (match_operand:SWI48 0 "register_operand" "=r")
20404 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
20407 (clobber (reg:CC FLAGS_REG))]
20409 "blci\t{%1, %0|%0, %1}"
20410 [(set_attr "type" "bitmanip")
20411 (set_attr "mode" "<MODE>")])
20413 (define_insn "*tbm_blcic_<mode>"
20414 [(set (match_operand:SWI48 0 "register_operand" "=r")
20417 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
20421 (clobber (reg:CC FLAGS_REG))]
20423 "blcic\t{%1, %0|%0, %1}"
20424 [(set_attr "type" "bitmanip")
20425 (set_attr "mode" "<MODE>")])
20427 (define_insn "*tbm_blcmsk_<mode>"
20428 [(set (match_operand:SWI48 0 "register_operand" "=r")
20431 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
20434 (clobber (reg:CC FLAGS_REG))]
20436 "blcmsk\t{%1, %0|%0, %1}"
20437 [(set_attr "type" "bitmanip")
20438 (set_attr "mode" "<MODE>")])
20440 (define_insn "*tbm_blcs_<mode>"
20441 [(set (match_operand:SWI48 0 "register_operand" "=r")
20444 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
20447 (clobber (reg:CC FLAGS_REG))]
20449 "blcs\t{%1, %0|%0, %1}"
20450 [(set_attr "type" "bitmanip")
20451 (set_attr "mode" "<MODE>")])
20453 (define_insn "*tbm_blsfill_<mode>"
20454 [(set (match_operand:SWI48 0 "register_operand" "=r")
20457 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
20460 (clobber (reg:CC FLAGS_REG))]
20462 "blsfill\t{%1, %0|%0, %1}"
20463 [(set_attr "type" "bitmanip")
20464 (set_attr "mode" "<MODE>")])
20466 (define_insn "*tbm_blsic_<mode>"
20467 [(set (match_operand:SWI48 0 "register_operand" "=r")
20470 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
20474 (clobber (reg:CC FLAGS_REG))]
20476 "blsic\t{%1, %0|%0, %1}"
20477 [(set_attr "type" "bitmanip")
20478 (set_attr "mode" "<MODE>")])
20480 (define_insn "*tbm_t1mskc_<mode>"
20481 [(set (match_operand:SWI48 0 "register_operand" "=r")
20484 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
20488 (clobber (reg:CC FLAGS_REG))]
20490 "t1mskc\t{%1, %0|%0, %1}"
20491 [(set_attr "type" "bitmanip")
20492 (set_attr "mode" "<MODE>")])
20494 (define_insn "*tbm_tzmsk_<mode>"
20495 [(set (match_operand:SWI48 0 "register_operand" "=r")
20498 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
20502 (clobber (reg:CC FLAGS_REG))]
20504 "tzmsk\t{%1, %0|%0, %1}"
20505 [(set_attr "type" "bitmanip")
20506 (set_attr "mode" "<MODE>")])
20508 (define_insn_and_split "popcount<mode>2"
20509 [(set (match_operand:SWI48 0 "register_operand" "=r")
20511 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
20512 (clobber (reg:CC FLAGS_REG))]
20516 return "popcnt\t{%1, %0|%0, %1}";
20518 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
20521 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
20522 && optimize_function_for_speed_p (cfun)
20523 && !reg_mentioned_p (operands[0], operands[1])"
20525 [(set (match_dup 0)
20526 (popcount:SWI48 (match_dup 1)))
20527 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
20528 (clobber (reg:CC FLAGS_REG))])]
20529 "ix86_expand_clear (operands[0]);"
20530 [(set_attr "prefix_rep" "1")
20531 (set_attr "type" "bitmanip")
20532 (set_attr "mode" "<MODE>")])
20534 ; False dependency happens when destination is only updated by tzcnt,
20535 ; lzcnt or popcnt. There is no false dependency when destination is
20536 ; also used in source.
20537 (define_insn "*popcount<mode>2_falsedep"
20538 [(set (match_operand:SWI48 0 "register_operand" "=r")
20540 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
20541 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
20542 UNSPEC_INSN_FALSE_DEP)
20543 (clobber (reg:CC FLAGS_REG))]
20547 return "popcnt\t{%1, %0|%0, %1}";
20549 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
20552 [(set_attr "prefix_rep" "1")
20553 (set_attr "type" "bitmanip")
20554 (set_attr "mode" "<MODE>")])
20556 (define_insn_and_split "*popcountsi2_zext"
20557 [(set (match_operand:DI 0 "register_operand" "=r")
20561 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
20563 (clobber (reg:CC FLAGS_REG))]
20564 "TARGET_POPCNT && TARGET_64BIT"
20567 return "popcnt\t{%1, %k0|%k0, %1}";
20569 return "popcnt{l}\t{%1, %k0|%k0, %1}";
20572 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
20573 && optimize_function_for_speed_p (cfun)
20574 && !reg_mentioned_p (operands[0], operands[1])"
20576 [(set (match_dup 0)
20577 (and:DI (subreg:DI (popcount:SI (match_dup 1)) 0) (const_int 63)))
20578 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
20579 (clobber (reg:CC FLAGS_REG))])]
20580 "ix86_expand_clear (operands[0]);"
20581 [(set_attr "prefix_rep" "1")
20582 (set_attr "type" "bitmanip")
20583 (set_attr "mode" "SI")])
20585 ; False dependency happens when destination is only updated by tzcnt,
20586 ; lzcnt or popcnt. There is no false dependency when destination is
20587 ; also used in source.
20588 (define_insn "*popcountsi2_zext_falsedep"
20589 [(set (match_operand:DI 0 "register_operand" "=r")
20593 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
20595 (unspec [(match_operand:DI 2 "register_operand" "0")]
20596 UNSPEC_INSN_FALSE_DEP)
20597 (clobber (reg:CC FLAGS_REG))]
20598 "TARGET_POPCNT && TARGET_64BIT"
20601 return "popcnt\t{%1, %k0|%k0, %1}";
20603 return "popcnt{l}\t{%1, %k0|%k0, %1}";
20606 [(set_attr "prefix_rep" "1")
20607 (set_attr "type" "bitmanip")
20608 (set_attr "mode" "SI")])
20610 (define_insn_and_split "*popcountsi2_zext_2"
20611 [(set (match_operand:DI 0 "register_operand" "=r")
20613 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
20614 (clobber (reg:CC FLAGS_REG))]
20615 "TARGET_POPCNT && TARGET_64BIT"
20618 return "popcnt\t{%1, %k0|%k0, %1}";
20620 return "popcnt{l}\t{%1, %k0|%k0, %1}";
20623 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
20624 && optimize_function_for_speed_p (cfun)
20625 && !reg_mentioned_p (operands[0], operands[1])"
20627 [(set (match_dup 0)
20628 (zero_extend:DI (popcount:SI (match_dup 1))))
20629 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
20630 (clobber (reg:CC FLAGS_REG))])]
20631 "ix86_expand_clear (operands[0]);"
20632 [(set_attr "prefix_rep" "1")
20633 (set_attr "type" "bitmanip")
20634 (set_attr "mode" "SI")])
20636 ; False dependency happens when destination is only updated by tzcnt,
20637 ; lzcnt or popcnt. There is no false dependency when destination is
20638 ; also used in source.
20639 (define_insn "*popcountsi2_zext_2_falsedep"
20640 [(set (match_operand:DI 0 "register_operand" "=r")
20642 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
20643 (unspec [(match_operand:DI 2 "register_operand" "0")]
20644 UNSPEC_INSN_FALSE_DEP)
20645 (clobber (reg:CC FLAGS_REG))]
20646 "TARGET_POPCNT && TARGET_64BIT"
20649 return "popcnt\t{%1, %k0|%k0, %1}";
20651 return "popcnt{l}\t{%1, %k0|%k0, %1}";
20654 [(set_attr "prefix_rep" "1")
20655 (set_attr "type" "bitmanip")
20656 (set_attr "mode" "SI")])
20658 (define_insn_and_split "*popcounthi2_1"
20659 [(set (match_operand:SI 0 "register_operand")
20661 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
20662 (clobber (reg:CC FLAGS_REG))]
20664 && ix86_pre_reload_split ()"
20669 rtx tmp = gen_reg_rtx (HImode);
20671 emit_insn (gen_popcounthi2 (tmp, operands[1]));
20672 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
20676 (define_insn_and_split "*popcounthi2_2"
20677 [(set (match_operand:SI 0 "register_operand")
20679 (popcount:HI (match_operand:HI 1 "nonimmediate_operand"))))
20680 (clobber (reg:CC FLAGS_REG))]
20682 && ix86_pre_reload_split ()"
20687 rtx tmp = gen_reg_rtx (HImode);
20689 emit_insn (gen_popcounthi2 (tmp, operands[1]));
20690 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
20694 (define_insn "popcounthi2"
20695 [(set (match_operand:HI 0 "register_operand" "=r")
20697 (match_operand:HI 1 "nonimmediate_operand" "rm")))
20698 (clobber (reg:CC FLAGS_REG))]
20702 return "popcnt\t{%1, %0|%0, %1}";
20704 return "popcnt{w}\t{%1, %0|%0, %1}";
20707 [(set_attr "prefix_rep" "1")
20708 (set_attr "type" "bitmanip")
20709 (set_attr "mode" "HI")])
20711 (define_expand "bswapdi2"
20712 [(set (match_operand:DI 0 "register_operand")
20713 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
20717 operands[1] = force_reg (DImode, operands[1]);
20720 (define_expand "bswapsi2"
20721 [(set (match_operand:SI 0 "register_operand")
20722 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
20727 else if (TARGET_BSWAP)
20728 operands[1] = force_reg (SImode, operands[1]);
20731 rtx x = operands[0];
20733 emit_move_insn (x, operands[1]);
20734 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
20735 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
20736 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
20741 (define_insn "*bswap<mode>2_movbe"
20742 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
20743 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
20745 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
20748 movbe{<imodesuffix>}\t{%1, %0|%0, %1}
20749 movbe{<imodesuffix>}\t{%1, %0|%0, %1}"
20750 [(set_attr "type" "bitmanip,imov,imov")
20751 (set_attr "modrm" "0,1,1")
20752 (set_attr "prefix_0f" "*,1,1")
20753 (set_attr "prefix_extra" "*,1,1")
20754 (set_attr "mode" "<MODE>")])
20756 (define_insn "*bswap<mode>2"
20757 [(set (match_operand:SWI48 0 "register_operand" "=r")
20758 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
20761 [(set_attr "type" "bitmanip")
20762 (set_attr "modrm" "0")
20763 (set_attr "mode" "<MODE>")])
20765 (define_expand "bswaphi2"
20766 [(set (match_operand:HI 0 "register_operand")
20767 (bswap:HI (match_operand:HI 1 "nonimmediate_operand")))]
20770 (define_insn "*bswaphi2_movbe"
20771 [(set (match_operand:HI 0 "nonimmediate_operand" "=Q,r,m")
20772 (bswap:HI (match_operand:HI 1 "nonimmediate_operand" "0,m,r")))]
20774 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
20776 xchg{b}\t{%h0, %b0|%b0, %h0}
20777 movbe{w}\t{%1, %0|%0, %1}
20778 movbe{w}\t{%1, %0|%0, %1}"
20779 [(set_attr "type" "imov")
20780 (set_attr "modrm" "*,1,1")
20781 (set_attr "prefix_0f" "*,1,1")
20782 (set_attr "prefix_extra" "*,1,1")
20783 (set_attr "pent_pair" "np,*,*")
20784 (set_attr "athlon_decode" "vector,*,*")
20785 (set_attr "amdfam10_decode" "double,*,*")
20786 (set_attr "bdver1_decode" "double,*,*")
20787 (set_attr "mode" "QI,HI,HI")])
20790 [(set (match_operand:HI 0 "general_reg_operand")
20791 (bswap:HI (match_dup 0)))]
20793 && !(TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))
20794 && peep2_regno_dead_p (0, FLAGS_REG)"
20795 [(parallel [(set (match_dup 0) (rotate:HI (match_dup 0) (const_int 8)))
20796 (clobber (reg:CC FLAGS_REG))])])
20798 (define_insn "bswaphi_lowpart"
20799 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
20800 (bswap:HI (match_dup 0)))
20801 (clobber (reg:CC FLAGS_REG))]
20804 xchg{b}\t{%h0, %b0|%b0, %h0}
20805 rol{w}\t{$8, %0|%0, 8}"
20806 [(set (attr "preferred_for_size")
20807 (cond [(eq_attr "alternative" "0")
20808 (symbol_ref "true")]
20809 (symbol_ref "false")))
20810 (set (attr "preferred_for_speed")
20811 (cond [(eq_attr "alternative" "0")
20812 (symbol_ref "TARGET_USE_XCHGB")]
20813 (symbol_ref "!TARGET_USE_XCHGB")))
20814 (set_attr "length" "2,4")
20815 (set_attr "mode" "QI,HI")])
20817 (define_expand "paritydi2"
20818 [(set (match_operand:DI 0 "register_operand")
20819 (parity:DI (match_operand:DI 1 "register_operand")))]
20822 rtx scratch = gen_reg_rtx (QImode);
20823 rtx hipart1 = gen_reg_rtx (SImode);
20824 rtx lopart1 = gen_reg_rtx (SImode);
20825 rtx xor1 = gen_reg_rtx (SImode);
20826 rtx shift2 = gen_reg_rtx (SImode);
20827 rtx hipart2 = gen_reg_rtx (HImode);
20828 rtx lopart2 = gen_reg_rtx (HImode);
20829 rtx xor2 = gen_reg_rtx (HImode);
20833 rtx shift1 = gen_reg_rtx (DImode);
20834 emit_insn (gen_lshrdi3 (shift1, operands[1], GEN_INT (32)));
20835 emit_move_insn (hipart1, gen_lowpart (SImode, shift1));
20838 emit_move_insn (hipart1, gen_highpart (SImode, operands[1]));
20840 emit_move_insn (lopart1, gen_lowpart (SImode, operands[1]));
20841 emit_insn (gen_xorsi3 (xor1, hipart1, lopart1));
20843 emit_insn (gen_lshrsi3 (shift2, xor1, GEN_INT (16)));
20844 emit_move_insn (hipart2, gen_lowpart (HImode, shift2));
20845 emit_move_insn (lopart2, gen_lowpart (HImode, xor1));
20846 emit_insn (gen_xorhi3 (xor2, hipart2, lopart2));
20848 emit_insn (gen_parityhi2_cmp (xor2));
20850 ix86_expand_setcc (scratch, ORDERED,
20851 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
20854 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
20857 rtx tmp = gen_reg_rtx (SImode);
20859 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
20860 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
20865 (define_expand "paritysi2"
20866 [(set (match_operand:SI 0 "register_operand")
20867 (parity:SI (match_operand:SI 1 "register_operand")))]
20870 rtx scratch = gen_reg_rtx (QImode);
20871 rtx shift = gen_reg_rtx (SImode);
20872 rtx hipart = gen_reg_rtx (HImode);
20873 rtx lopart = gen_reg_rtx (HImode);
20874 rtx tmp = gen_reg_rtx (HImode);
20876 emit_insn (gen_lshrsi3 (shift, operands[1], GEN_INT (16)));
20877 emit_move_insn (hipart, gen_lowpart (HImode, shift));
20878 emit_move_insn (lopart, gen_lowpart (HImode, operands[1]));
20879 emit_insn (gen_xorhi3 (tmp, hipart, lopart));
20881 emit_insn (gen_parityhi2_cmp (tmp));
20883 ix86_expand_setcc (scratch, ORDERED,
20884 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
20886 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
20890 (define_expand "parityhi2"
20891 [(set (match_operand:HI 0 "register_operand")
20892 (parity:HI (match_operand:HI 1 "register_operand")))]
20895 rtx scratch = gen_reg_rtx (QImode);
20896 rtx tmp = gen_reg_rtx (HImode);
20898 emit_move_insn (tmp, operands[1]);
20899 emit_insn (gen_parityhi2_cmp (tmp));
20901 ix86_expand_setcc (scratch, ORDERED,
20902 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
20904 emit_insn (gen_zero_extendqihi2 (operands[0], scratch));
20908 (define_expand "parityqi2"
20909 [(set (match_operand:QI 0 "register_operand")
20910 (parity:QI (match_operand:QI 1 "register_operand")))]
20913 emit_insn (gen_parityqi2_cmp (operands[1]));
20915 ix86_expand_setcc (operands[0], ORDERED,
20916 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
20920 (define_insn "parityhi2_cmp"
20921 [(set (reg:CC FLAGS_REG)
20922 (unspec:CC [(match_operand:HI 0 "register_operand" "+Q")]
20924 (clobber (match_dup 0))]
20926 "xor{b}\t{%h0, %b0|%b0, %h0}"
20927 [(set_attr "length" "2")
20928 (set_attr "mode" "QI")])
20930 (define_insn "parityqi2_cmp"
20931 [(set (reg:CC FLAGS_REG)
20932 (unspec:CC [(match_operand:QI 0 "register_operand" "q")]
20936 [(set_attr "mode" "QI")])
20938 ;; Replace zero_extend:HI followed by parityhi2_cmp with parityqi2_cmp
20940 [(set (match_operand:HI 0 "register_operand")
20941 (zero_extend:HI (match_operand:QI 1 "general_reg_operand")))
20942 (parallel [(set (reg:CC FLAGS_REG)
20943 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
20944 (clobber (match_dup 0))])]
20946 [(set (reg:CC FLAGS_REG)
20947 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))])
20949 ;; Eliminate QImode popcount&1 using parity flag
20951 [(set (match_operand:SI 0 "register_operand")
20952 (zero_extend:SI (match_operand:QI 1 "general_reg_operand")))
20953 (parallel [(set (match_operand:SI 2 "register_operand")
20954 (popcount:SI (match_dup 0)))
20955 (clobber (reg:CC FLAGS_REG))])
20956 (set (reg:CCZ FLAGS_REG)
20957 (compare:CCZ (and:QI (match_operand:QI 3 "register_operand")
20960 (set (pc) (if_then_else (match_operator 4 "bt_comparison_operator"
20961 [(reg:CCZ FLAGS_REG)
20963 (label_ref (match_operand 5))
20965 "REGNO (operands[2]) == REGNO (operands[3])
20966 && peep2_reg_dead_p (3, operands[0])
20967 && peep2_reg_dead_p (3, operands[2])
20968 && peep2_regno_dead_p (4, FLAGS_REG)"
20969 [(set (reg:CC FLAGS_REG)
20970 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
20971 (set (pc) (if_then_else (match_op_dup 4 [(reg:CC FLAGS_REG)
20973 (label_ref (match_dup 5))
20976 operands[4] = shallow_copy_rtx (operands[4]);
20977 PUT_CODE (operands[4], GET_CODE (operands[4]) == EQ ? UNORDERED : ORDERED);
20980 ;; Eliminate HImode popcount&1 using parity flag
20982 [(match_scratch:HI 0 "Q")
20983 (parallel [(set (match_operand:HI 1 "register_operand")
20985 (match_operand:HI 2 "nonimmediate_operand")))
20986 (clobber (reg:CC FLAGS_REG))])
20987 (set (match_operand 3 "register_operand")
20988 (zero_extend (match_dup 1)))
20989 (set (reg:CCZ FLAGS_REG)
20990 (compare:CCZ (and:QI (match_operand:QI 4 "register_operand")
20993 (set (pc) (if_then_else (match_operator 5 "bt_comparison_operator"
20994 [(reg:CCZ FLAGS_REG)
20996 (label_ref (match_operand 6))
20998 "REGNO (operands[3]) == REGNO (operands[4])
20999 && peep2_reg_dead_p (3, operands[1])
21000 && peep2_reg_dead_p (3, operands[3])
21001 && peep2_regno_dead_p (4, FLAGS_REG)"
21002 [(set (match_dup 0) (match_dup 2))
21003 (parallel [(set (reg:CC FLAGS_REG)
21004 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
21005 (clobber (match_dup 0))])
21006 (set (pc) (if_then_else (match_op_dup 5 [(reg:CC FLAGS_REG)
21008 (label_ref (match_dup 6))
21011 operands[5] = shallow_copy_rtx (operands[5]);
21012 PUT_CODE (operands[5], GET_CODE (operands[5]) == EQ ? UNORDERED : ORDERED);
21015 ;; Eliminate HImode popcount&1 using parity flag (variant 2)
21017 [(match_scratch:HI 0 "Q")
21018 (parallel [(set (match_operand:HI 1 "register_operand")
21020 (match_operand:HI 2 "nonimmediate_operand")))
21021 (clobber (reg:CC FLAGS_REG))])
21022 (set (reg:CCZ FLAGS_REG)
21023 (compare:CCZ (and:QI (match_operand:QI 3 "register_operand")
21026 (set (pc) (if_then_else (match_operator 4 "bt_comparison_operator"
21027 [(reg:CCZ FLAGS_REG)
21029 (label_ref (match_operand 5))
21031 "REGNO (operands[1]) == REGNO (operands[3])
21032 && peep2_reg_dead_p (2, operands[1])
21033 && peep2_reg_dead_p (2, operands[3])
21034 && peep2_regno_dead_p (3, FLAGS_REG)"
21035 [(set (match_dup 0) (match_dup 2))
21036 (parallel [(set (reg:CC FLAGS_REG)
21037 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
21038 (clobber (match_dup 0))])
21039 (set (pc) (if_then_else (match_op_dup 4 [(reg:CC FLAGS_REG)
21041 (label_ref (match_dup 5))
21044 operands[4] = shallow_copy_rtx (operands[4]);
21045 PUT_CODE (operands[4], GET_CODE (operands[4]) == EQ ? UNORDERED : ORDERED);
21049 ;; Thread-local storage patterns for ELF.
21051 ;; Note that these code sequences must appear exactly as shown
21052 ;; in order to allow linker relaxation.
21054 (define_insn "*tls_global_dynamic_32_gnu"
21055 [(set (match_operand:SI 0 "register_operand" "=a")
21057 [(match_operand:SI 1 "register_operand" "Yb")
21058 (match_operand 2 "tls_symbolic_operand")
21059 (match_operand 3 "constant_call_address_operand" "Bz")
21062 (clobber (match_scratch:SI 4 "=d"))
21063 (clobber (match_scratch:SI 5 "=c"))
21064 (clobber (reg:CC FLAGS_REG))]
21065 "!TARGET_64BIT && TARGET_GNU_TLS"
21067 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
21069 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
21072 ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
21073 if (TARGET_SUN_TLS)
21074 #ifdef HAVE_AS_IX86_TLSGDPLT
21075 return "call\t%a2@tlsgdplt";
21077 return "call\t%p3@plt";
21079 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
21080 return "call\t%P3";
21081 return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
21083 [(set_attr "type" "multi")
21084 (set_attr "length" "12")])
21086 (define_expand "tls_global_dynamic_32"
21088 [(set (match_operand:SI 0 "register_operand")
21089 (unspec:SI [(match_operand:SI 2 "register_operand")
21090 (match_operand 1 "tls_symbolic_operand")
21091 (match_operand 3 "constant_call_address_operand")
21094 (clobber (scratch:SI))
21095 (clobber (scratch:SI))
21096 (clobber (reg:CC FLAGS_REG))])]
21098 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
21100 (define_insn "*tls_global_dynamic_64_<mode>"
21101 [(set (match_operand:P 0 "register_operand" "=a")
21103 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
21104 (match_operand 3)))
21105 (unspec:P [(match_operand 1 "tls_symbolic_operand")
21111 /* The .loc directive has effect for 'the immediately following assembly
21112 instruction'. So for a sequence:
21116 the 'immediately following assembly instruction' is insn1.
21117 We want to emit an insn prefix here, but if we use .byte (as shown in
21118 'ELF Handling For Thread-Local Storage'), a preceding .loc will point
21119 inside the insn sequence, rather than to the start. After relaxation
21120 of the sequence by the linker, the .loc might point inside an insn.
21121 Use data16 prefix instead, which doesn't have this problem. */
21122 fputs ("\tdata16", asm_out_file);
21124 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
21125 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
21126 fputs (ASM_SHORT "0x6666\n", asm_out_file);
21128 fputs (ASM_BYTE "0x66\n", asm_out_file);
21129 fputs ("\trex64\n", asm_out_file);
21130 if (TARGET_SUN_TLS)
21131 return "call\t%p2@plt";
21132 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
21133 return "call\t%P2";
21134 return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
21136 [(set_attr "type" "multi")
21137 (set (attr "length")
21138 (symbol_ref "TARGET_X32 ? 15 : 16"))])
21140 (define_insn "*tls_global_dynamic_64_largepic"
21141 [(set (match_operand:DI 0 "register_operand" "=a")
21143 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
21144 (match_operand:DI 3 "immediate_operand" "i")))
21145 (match_operand 4)))
21146 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
21149 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
21150 && GET_CODE (operands[3]) == CONST
21151 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
21152 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
21155 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
21156 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
21157 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
21158 return "call\t{*%%rax|rax}";
21160 [(set_attr "type" "multi")
21161 (set_attr "length" "22")])
21163 (define_expand "@tls_global_dynamic_64_<mode>"
21165 [(set (match_operand:P 0 "register_operand")
21167 (mem:QI (match_operand 2))
21169 (unspec:P [(match_operand 1 "tls_symbolic_operand")
21173 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
21175 (define_insn "*tls_local_dynamic_base_32_gnu"
21176 [(set (match_operand:SI 0 "register_operand" "=a")
21178 [(match_operand:SI 1 "register_operand" "Yb")
21179 (match_operand 2 "constant_call_address_operand" "Bz")
21181 UNSPEC_TLS_LD_BASE))
21182 (clobber (match_scratch:SI 3 "=d"))
21183 (clobber (match_scratch:SI 4 "=c"))
21184 (clobber (reg:CC FLAGS_REG))]
21185 "!TARGET_64BIT && TARGET_GNU_TLS"
21188 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
21189 if (TARGET_SUN_TLS)
21191 if (HAVE_AS_IX86_TLSLDMPLT)
21192 return "call\t%&@tlsldmplt";
21194 return "call\t%p2@plt";
21196 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
21197 return "call\t%P2";
21198 return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
21200 [(set_attr "type" "multi")
21201 (set_attr "length" "11")])
21203 (define_expand "tls_local_dynamic_base_32"
21205 [(set (match_operand:SI 0 "register_operand")
21207 [(match_operand:SI 1 "register_operand")
21208 (match_operand 2 "constant_call_address_operand")
21210 UNSPEC_TLS_LD_BASE))
21211 (clobber (scratch:SI))
21212 (clobber (scratch:SI))
21213 (clobber (reg:CC FLAGS_REG))])]
21215 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
21217 (define_insn "*tls_local_dynamic_base_64_<mode>"
21218 [(set (match_operand:P 0 "register_operand" "=a")
21220 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
21221 (match_operand 2)))
21222 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
21226 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
21227 if (TARGET_SUN_TLS)
21228 return "call\t%p1@plt";
21229 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
21230 return "call\t%P1";
21231 return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
21233 [(set_attr "type" "multi")
21234 (set_attr "length" "12")])
21236 (define_insn "*tls_local_dynamic_base_64_largepic"
21237 [(set (match_operand:DI 0 "register_operand" "=a")
21239 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
21240 (match_operand:DI 2 "immediate_operand" "i")))
21241 (match_operand 3)))
21242 (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
21243 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
21244 && GET_CODE (operands[2]) == CONST
21245 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
21246 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
21249 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
21250 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
21251 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
21252 return "call\t{*%%rax|rax}";
21254 [(set_attr "type" "multi")
21255 (set_attr "length" "22")])
21257 (define_expand "@tls_local_dynamic_base_64_<mode>"
21259 [(set (match_operand:P 0 "register_operand")
21261 (mem:QI (match_operand 1))
21263 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
21265 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
21267 ;; Local dynamic of a single variable is a lose. Show combine how
21268 ;; to convert that back to global dynamic.
21270 (define_insn_and_split "*tls_local_dynamic_32_once"
21271 [(set (match_operand:SI 0 "register_operand" "=a")
21273 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
21274 (match_operand 2 "constant_call_address_operand" "Bz")
21276 UNSPEC_TLS_LD_BASE)
21277 (const:SI (unspec:SI
21278 [(match_operand 3 "tls_symbolic_operand")]
21280 (clobber (match_scratch:SI 4 "=d"))
21281 (clobber (match_scratch:SI 5 "=c"))
21282 (clobber (reg:CC FLAGS_REG))]
21287 [(set (match_dup 0)
21288 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
21291 (clobber (match_dup 4))
21292 (clobber (match_dup 5))
21293 (clobber (reg:CC FLAGS_REG))])])
21295 ;; Load and add the thread base pointer from %<tp_seg>:0.
21296 (define_expand "get_thread_pointer<mode>"
21297 [(set (match_operand:PTR 0 "register_operand")
21298 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
21301 /* targetm is not visible in the scope of the condition. */
21302 if (!targetm.have_tls)
21303 error ("%<__builtin_thread_pointer%> is not supported on this target");
21306 (define_insn_and_split "*load_tp_<mode>"
21307 [(set (match_operand:PTR 0 "register_operand" "=r")
21308 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
21312 [(set (match_dup 0)
21315 addr_space_t as = DEFAULT_TLS_SEG_REG;
21317 operands[1] = gen_const_mem (<MODE>mode, const0_rtx);
21318 set_mem_addr_space (operands[1], as);
21321 (define_insn_and_split "*load_tp_x32_zext"
21322 [(set (match_operand:DI 0 "register_operand" "=r")
21324 (unspec:SI [(const_int 0)] UNSPEC_TP)))]
21328 [(set (match_dup 0)
21329 (zero_extend:DI (match_dup 1)))]
21331 addr_space_t as = DEFAULT_TLS_SEG_REG;
21333 operands[1] = gen_const_mem (SImode, const0_rtx);
21334 set_mem_addr_space (operands[1], as);
21337 (define_insn_and_split "*add_tp_<mode>"
21338 [(set (match_operand:PTR 0 "register_operand" "=r")
21340 (unspec:PTR [(const_int 0)] UNSPEC_TP)
21341 (match_operand:PTR 1 "register_operand" "0")))
21342 (clobber (reg:CC FLAGS_REG))]
21347 [(set (match_dup 0)
21348 (plus:PTR (match_dup 1) (match_dup 2)))
21349 (clobber (reg:CC FLAGS_REG))])]
21351 addr_space_t as = DEFAULT_TLS_SEG_REG;
21353 operands[2] = gen_const_mem (<MODE>mode, const0_rtx);
21354 set_mem_addr_space (operands[2], as);
21357 (define_insn_and_split "*add_tp_x32_zext"
21358 [(set (match_operand:DI 0 "register_operand" "=r")
21360 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
21361 (match_operand:SI 1 "register_operand" "0"))))
21362 (clobber (reg:CC FLAGS_REG))]
21367 [(set (match_dup 0)
21369 (plus:SI (match_dup 1) (match_dup 2))))
21370 (clobber (reg:CC FLAGS_REG))])]
21372 addr_space_t as = DEFAULT_TLS_SEG_REG;
21374 operands[2] = gen_const_mem (SImode, const0_rtx);
21375 set_mem_addr_space (operands[2], as);
21378 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
21379 ;; %rax as destination of the initial executable code sequence.
21380 (define_insn "tls_initial_exec_64_sun"
21381 [(set (match_operand:DI 0 "register_operand" "=a")
21383 [(match_operand 1 "tls_symbolic_operand")]
21384 UNSPEC_TLS_IE_SUN))
21385 (clobber (reg:CC FLAGS_REG))]
21386 "TARGET_64BIT && TARGET_SUN_TLS"
21389 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
21390 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
21392 [(set_attr "type" "multi")])
21394 ;; GNU2 TLS patterns can be split.
21396 (define_expand "tls_dynamic_gnu2_32"
21397 [(set (match_dup 3)
21398 (plus:SI (match_operand:SI 2 "register_operand")
21400 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
21403 [(set (match_operand:SI 0 "register_operand")
21404 (unspec:SI [(match_dup 1) (match_dup 3)
21405 (match_dup 2) (reg:SI SP_REG)]
21407 (clobber (reg:CC FLAGS_REG))])]
21408 "!TARGET_64BIT && TARGET_GNU2_TLS"
21410 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
21411 ix86_tls_descriptor_calls_expanded_in_cfun = true;
21414 (define_insn "*tls_dynamic_gnu2_lea_32"
21415 [(set (match_operand:SI 0 "register_operand" "=r")
21416 (plus:SI (match_operand:SI 1 "register_operand" "b")
21418 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
21419 UNSPEC_TLSDESC))))]
21420 "!TARGET_64BIT && TARGET_GNU2_TLS"
21421 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
21422 [(set_attr "type" "lea")
21423 (set_attr "mode" "SI")
21424 (set_attr "length" "6")
21425 (set_attr "length_address" "4")])
21427 (define_insn "*tls_dynamic_gnu2_call_32"
21428 [(set (match_operand:SI 0 "register_operand" "=a")
21429 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
21430 (match_operand:SI 2 "register_operand" "0")
21431 ;; we have to make sure %ebx still points to the GOT
21432 (match_operand:SI 3 "register_operand" "b")
21435 (clobber (reg:CC FLAGS_REG))]
21436 "!TARGET_64BIT && TARGET_GNU2_TLS"
21437 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
21438 [(set_attr "type" "call")
21439 (set_attr "length" "2")
21440 (set_attr "length_address" "0")])
21442 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
21443 [(set (match_operand:SI 0 "register_operand" "=&a")
21445 (unspec:SI [(match_operand 3 "tls_modbase_operand")
21446 (match_operand:SI 4)
21447 (match_operand:SI 2 "register_operand" "b")
21450 (const:SI (unspec:SI
21451 [(match_operand 1 "tls_symbolic_operand")]
21453 (clobber (reg:CC FLAGS_REG))]
21454 "!TARGET_64BIT && TARGET_GNU2_TLS"
21457 [(set (match_dup 0) (match_dup 5))]
21459 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
21460 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
21463 (define_expand "@tls_dynamic_gnu2_64_<mode>"
21464 [(set (match_dup 2)
21465 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")]
21468 [(set (match_operand:PTR 0 "register_operand")
21469 (unspec:PTR [(match_dup 1) (match_dup 2) (reg:PTR SP_REG)]
21471 (clobber (reg:CC FLAGS_REG))])]
21472 "TARGET_64BIT && TARGET_GNU2_TLS"
21474 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (ptr_mode) : operands[0];
21475 ix86_tls_descriptor_calls_expanded_in_cfun = true;
21478 (define_insn "*tls_dynamic_gnu2_lea_64_<mode>"
21479 [(set (match_operand:PTR 0 "register_operand" "=r")
21480 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")]
21482 "TARGET_64BIT && TARGET_GNU2_TLS"
21483 "lea%z0\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
21484 [(set_attr "type" "lea")
21485 (set_attr "mode" "<MODE>")
21486 (set_attr "length" "7")
21487 (set_attr "length_address" "4")])
21489 (define_insn "*tls_dynamic_gnu2_call_64_<mode>"
21490 [(set (match_operand:PTR 0 "register_operand" "=a")
21491 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")
21492 (match_operand:PTR 2 "register_operand" "0")
21495 (clobber (reg:CC FLAGS_REG))]
21496 "TARGET_64BIT && TARGET_GNU2_TLS"
21497 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
21498 [(set_attr "type" "call")
21499 (set_attr "length" "2")
21500 (set_attr "length_address" "0")])
21502 (define_insn_and_split "*tls_dynamic_gnu2_combine_64_<mode>"
21503 [(set (match_operand:PTR 0 "register_operand" "=&a")
21505 (unspec:PTR [(match_operand 2 "tls_modbase_operand")
21506 (match_operand:PTR 3)
21509 (const:PTR (unspec:PTR
21510 [(match_operand 1 "tls_symbolic_operand")]
21512 (clobber (reg:CC FLAGS_REG))]
21513 "TARGET_64BIT && TARGET_GNU2_TLS"
21516 [(set (match_dup 0) (match_dup 4))]
21518 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (ptr_mode) : operands[0];
21519 emit_insn (gen_tls_dynamic_gnu2_64 (ptr_mode, operands[4], operands[1]));
21523 [(match_operand 0 "tls_address_pattern")]
21524 "TARGET_TLS_DIRECT_SEG_REFS"
21526 "operands[0] = ix86_rewrite_tls_address (operands[0]);")
21529 ;; These patterns match the binary 387 instructions for addM3, subM3,
21530 ;; mulM3 and divM3. There are three patterns for each of DFmode and
21531 ;; SFmode. The first is the normal insn, the second the same insn but
21532 ;; with one operand a conversion, and the third the same insn but with
21533 ;; the other operand a conversion. The conversion may be SFmode or
21534 ;; SImode if the target mode DFmode, but only SImode if the target mode
21537 ;; Gcc is slightly more smart about handling normal two address instructions
21538 ;; so use special patterns for add and mull.
21540 (define_insn "*fop_xf_comm_i387"
21541 [(set (match_operand:XF 0 "register_operand" "=f")
21542 (match_operator:XF 3 "binary_fp_operator"
21543 [(match_operand:XF 1 "register_operand" "%0")
21544 (match_operand:XF 2 "register_operand" "f")]))]
21546 && COMMUTATIVE_ARITH_P (operands[3])"
21547 "* return output_387_binary_op (insn, operands);"
21548 [(set (attr "type")
21549 (if_then_else (match_operand:XF 3 "mult_operator")
21550 (const_string "fmul")
21551 (const_string "fop")))
21552 (set_attr "mode" "XF")])
21554 (define_insn "*fop_<mode>_comm"
21555 [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
21556 (match_operator:MODEF 3 "binary_fp_operator"
21557 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
21558 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
21559 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21560 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
21561 && COMMUTATIVE_ARITH_P (operands[3])
21562 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
21563 "* return output_387_binary_op (insn, operands);"
21564 [(set (attr "type")
21565 (if_then_else (eq_attr "alternative" "1,2")
21566 (if_then_else (match_operand:MODEF 3 "mult_operator")
21567 (const_string "ssemul")
21568 (const_string "sseadd"))
21569 (if_then_else (match_operand:MODEF 3 "mult_operator")
21570 (const_string "fmul")
21571 (const_string "fop"))))
21572 (set_attr "isa" "*,noavx,avx")
21573 (set_attr "prefix" "orig,orig,vex")
21574 (set_attr "mode" "<MODE>")
21575 (set (attr "enabled")
21577 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
21579 (eq_attr "alternative" "0")
21580 (symbol_ref "TARGET_MIX_SSE_I387
21581 && X87_ENABLE_ARITH (<MODE>mode)")
21582 (const_string "*"))
21584 (eq_attr "alternative" "0")
21585 (symbol_ref "true")
21586 (symbol_ref "false"))))])
21588 (define_insn "*<insn>hf"
21589 [(set (match_operand:HF 0 "register_operand" "=v")
21590 (plusminusmultdiv:HF
21591 (match_operand:HF 1 "nonimmediate_operand" "<comm>v")
21592 (match_operand:HF 2 "nonimmediate_operand" "vm")))]
21594 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
21595 "v<insn>sh\t{%2, %1, %0|%0, %1, %2}"
21596 [(set_attr "prefix" "evex")
21597 (set_attr "mode" "HF")])
21599 (define_insn "*rcpsf2_sse"
21600 [(set (match_operand:SF 0 "register_operand" "=x,x,x,x")
21601 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m,ja")]
21603 "TARGET_SSE && TARGET_SSE_MATH"
21605 %vrcpss\t{%d1, %0|%0, %d1}
21606 %vrcpss\t{%d1, %0|%0, %d1}
21607 rcpss\t{%1, %d0|%d0, %1}
21608 vrcpss\t{%1, %d0|%d0, %1}"
21609 [(set_attr "isa" "*,*,noavx,avx")
21610 (set_attr "addr" "*,*,*,gpr16")
21611 (set_attr "type" "sse")
21612 (set_attr "atom_sse_attr" "rcp")
21613 (set_attr "btver2_sse_attr" "rcp")
21614 (set_attr "prefix" "maybe_vex")
21615 (set_attr "mode" "SF")
21616 (set_attr "avx_partial_xmm_update" "false,false,true,true")
21617 (set (attr "preferred_for_speed")
21618 (cond [(match_test "TARGET_AVX")
21619 (symbol_ref "true")
21620 (eq_attr "alternative" "1,2,3")
21621 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
21623 (symbol_ref "true")))])
21625 (define_insn "rcphf2"
21626 [(set (match_operand:HF 0 "register_operand" "=v,v")
21627 (unspec:HF [(match_operand:HF 1 "nonimmediate_operand" "v,m")]
21629 "TARGET_AVX512FP16"
21631 vrcpsh\t{%d1, %0|%0, %d1}
21632 vrcpsh\t{%1, %d0|%d0, %1}"
21633 [(set_attr "type" "sse")
21634 (set_attr "prefix" "evex")
21635 (set_attr "mode" "HF")
21636 (set_attr "avx_partial_xmm_update" "false,true")])
21638 (define_insn "*fop_xf_1_i387"
21639 [(set (match_operand:XF 0 "register_operand" "=f,f")
21640 (match_operator:XF 3 "binary_fp_operator"
21641 [(match_operand:XF 1 "register_operand" "0,f")
21642 (match_operand:XF 2 "register_operand" "f,0")]))]
21644 && !COMMUTATIVE_ARITH_P (operands[3])"
21645 "* return output_387_binary_op (insn, operands);"
21646 [(set (attr "type")
21647 (if_then_else (match_operand:XF 3 "div_operator")
21648 (const_string "fdiv")
21649 (const_string "fop")))
21650 (set_attr "mode" "XF")])
21652 (define_insn "*fop_<mode>_1"
21653 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
21654 (match_operator:MODEF 3 "binary_fp_operator"
21655 [(match_operand:MODEF 1
21656 "x87nonimm_ssenomem_operand" "0,fm,0,v")
21657 (match_operand:MODEF 2
21658 "nonimmediate_operand" "fm,0,xm,vm")]))]
21659 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21660 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
21661 && !COMMUTATIVE_ARITH_P (operands[3])
21662 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
21663 "* return output_387_binary_op (insn, operands);"
21664 [(set (attr "type")
21665 (if_then_else (eq_attr "alternative" "2,3")
21666 (if_then_else (match_operand:MODEF 3 "div_operator")
21667 (const_string "ssediv")
21668 (const_string "sseadd"))
21669 (if_then_else (match_operand:MODEF 3 "div_operator")
21670 (const_string "fdiv")
21671 (const_string "fop"))))
21672 (set_attr "isa" "*,*,noavx,avx")
21673 (set_attr "prefix" "orig,orig,orig,vex")
21674 (set_attr "mode" "<MODE>")
21675 (set (attr "enabled")
21677 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
21679 (eq_attr "alternative" "0,1")
21680 (symbol_ref "TARGET_MIX_SSE_I387
21681 && X87_ENABLE_ARITH (<MODE>mode)")
21682 (const_string "*"))
21684 (eq_attr "alternative" "0,1")
21685 (symbol_ref "true")
21686 (symbol_ref "false"))))])
21688 (define_insn "*fop_<X87MODEF:mode>_2_i387"
21689 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
21690 (match_operator:X87MODEF 3 "binary_fp_operator"
21692 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
21693 (match_operand:X87MODEF 2 "register_operand" "0")]))]
21694 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
21695 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
21696 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
21697 || optimize_function_for_size_p (cfun))"
21698 "* return output_387_binary_op (insn, operands);"
21699 [(set (attr "type")
21700 (cond [(match_operand:X87MODEF 3 "mult_operator")
21701 (const_string "fmul")
21702 (match_operand:X87MODEF 3 "div_operator")
21703 (const_string "fdiv")
21705 (const_string "fop")))
21706 (set_attr "fp_int_src" "true")
21707 (set_attr "mode" "<SWI24:MODE>")])
21709 (define_insn "*fop_<X87MODEF:mode>_3_i387"
21710 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
21711 (match_operator:X87MODEF 3 "binary_fp_operator"
21712 [(match_operand:X87MODEF 1 "register_operand" "0")
21714 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
21715 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
21716 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
21717 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
21718 || optimize_function_for_size_p (cfun))"
21719 "* return output_387_binary_op (insn, operands);"
21720 [(set (attr "type")
21721 (cond [(match_operand:X87MODEF 3 "mult_operator")
21722 (const_string "fmul")
21723 (match_operand:X87MODEF 3 "div_operator")
21724 (const_string "fdiv")
21726 (const_string "fop")))
21727 (set_attr "fp_int_src" "true")
21728 (set_attr "mode" "<SWI24:MODE>")])
21730 (define_insn "*fop_xf_4_i387"
21731 [(set (match_operand:XF 0 "register_operand" "=f,f")
21732 (match_operator:XF 3 "binary_fp_operator"
21734 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
21735 (match_operand:XF 2 "register_operand" "0,f")]))]
21737 "* return output_387_binary_op (insn, operands);"
21738 [(set (attr "type")
21739 (cond [(match_operand:XF 3 "mult_operator")
21740 (const_string "fmul")
21741 (match_operand:XF 3 "div_operator")
21742 (const_string "fdiv")
21744 (const_string "fop")))
21745 (set_attr "mode" "<MODE>")])
21747 (define_insn "*fop_df_4_i387"
21748 [(set (match_operand:DF 0 "register_operand" "=f,f")
21749 (match_operator:DF 3 "binary_fp_operator"
21751 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
21752 (match_operand:DF 2 "register_operand" "0,f")]))]
21753 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
21754 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
21755 "* return output_387_binary_op (insn, operands);"
21756 [(set (attr "type")
21757 (cond [(match_operand:DF 3 "mult_operator")
21758 (const_string "fmul")
21759 (match_operand:DF 3 "div_operator")
21760 (const_string "fdiv")
21762 (const_string "fop")))
21763 (set_attr "mode" "SF")])
21765 (define_insn "*fop_xf_5_i387"
21766 [(set (match_operand:XF 0 "register_operand" "=f,f")
21767 (match_operator:XF 3 "binary_fp_operator"
21768 [(match_operand:XF 1 "register_operand" "0,f")
21770 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
21772 "* return output_387_binary_op (insn, operands);"
21773 [(set (attr "type")
21774 (cond [(match_operand:XF 3 "mult_operator")
21775 (const_string "fmul")
21776 (match_operand:XF 3 "div_operator")
21777 (const_string "fdiv")
21779 (const_string "fop")))
21780 (set_attr "mode" "<MODE>")])
21782 (define_insn "*fop_df_5_i387"
21783 [(set (match_operand:DF 0 "register_operand" "=f,f")
21784 (match_operator:DF 3 "binary_fp_operator"
21785 [(match_operand:DF 1 "register_operand" "0,f")
21787 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
21788 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
21789 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
21790 "* return output_387_binary_op (insn, operands);"
21791 [(set (attr "type")
21792 (cond [(match_operand:DF 3 "mult_operator")
21793 (const_string "fmul")
21794 (match_operand:DF 3 "div_operator")
21795 (const_string "fdiv")
21797 (const_string "fop")))
21798 (set_attr "mode" "SF")])
21800 (define_insn "*fop_xf_6_i387"
21801 [(set (match_operand:XF 0 "register_operand" "=f,f")
21802 (match_operator:XF 3 "binary_fp_operator"
21804 (match_operand:MODEF 1 "register_operand" "0,f"))
21806 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
21808 "* return output_387_binary_op (insn, operands);"
21809 [(set (attr "type")
21810 (cond [(match_operand:XF 3 "mult_operator")
21811 (const_string "fmul")
21812 (match_operand:XF 3 "div_operator")
21813 (const_string "fdiv")
21815 (const_string "fop")))
21816 (set_attr "mode" "<MODE>")])
21818 (define_insn "*fop_df_6_i387"
21819 [(set (match_operand:DF 0 "register_operand" "=f,f")
21820 (match_operator:DF 3 "binary_fp_operator"
21822 (match_operand:SF 1 "register_operand" "0,f"))
21824 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
21825 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
21826 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
21827 "* return output_387_binary_op (insn, operands);"
21828 [(set (attr "type")
21829 (cond [(match_operand:DF 3 "mult_operator")
21830 (const_string "fmul")
21831 (match_operand:DF 3 "div_operator")
21832 (const_string "fdiv")
21834 (const_string "fop")))
21835 (set_attr "mode" "SF")])
21837 ;; FPU special functions.
21839 ;; This pattern implements a no-op XFmode truncation for
21840 ;; all fancy i386 XFmode math functions.
21842 (define_insn "truncxf<mode>2_i387_noop_unspec"
21843 [(set (match_operand:MODEF 0 "nonimmediate_operand" "=mf")
21844 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
21845 UNSPEC_TRUNC_NOOP))]
21846 "TARGET_USE_FANCY_MATH_387"
21847 "* return output_387_reg_move (insn, operands);"
21848 [(set_attr "type" "fmov")
21849 (set_attr "mode" "<MODE>")])
21851 (define_insn "sqrtxf2"
21852 [(set (match_operand:XF 0 "register_operand" "=f")
21853 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
21854 "TARGET_USE_FANCY_MATH_387"
21856 [(set_attr "type" "fpspc")
21857 (set_attr "mode" "XF")
21858 (set_attr "athlon_decode" "direct")
21859 (set_attr "amdfam10_decode" "direct")
21860 (set_attr "bdver1_decode" "direct")])
21862 (define_insn "*rsqrtsf2_sse"
21863 [(set (match_operand:SF 0 "register_operand" "=x,x,x,x")
21864 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m,ja")]
21866 "TARGET_SSE && TARGET_SSE_MATH"
21868 %vrsqrtss\t{%d1, %0|%0, %d1}
21869 %vrsqrtss\t{%d1, %0|%0, %d1}
21870 rsqrtss\t{%1, %d0|%d0, %1}
21871 vrsqrtss\t{%1, %d0|%d0, %1}"
21872 [(set_attr "isa" "*,*,noavx,avx")
21873 (set_attr "addr" "*,*,*,gpr16")
21874 (set_attr "type" "sse")
21875 (set_attr "atom_sse_attr" "rcp")
21876 (set_attr "btver2_sse_attr" "rcp")
21877 (set_attr "prefix" "maybe_vex")
21878 (set_attr "mode" "SF")
21879 (set_attr "avx_partial_xmm_update" "false,false,true,true")
21880 (set (attr "preferred_for_speed")
21881 (cond [(match_test "TARGET_AVX")
21882 (symbol_ref "true")
21883 (eq_attr "alternative" "1,2,3")
21884 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
21886 (symbol_ref "true")))])
21888 (define_expand "rsqrtsf2"
21889 [(set (match_operand:SF 0 "register_operand")
21890 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
21892 "TARGET_SSE && TARGET_SSE_MATH"
21894 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
21898 (define_insn "rsqrthf2"
21899 [(set (match_operand:HF 0 "register_operand" "=v,v")
21900 (unspec:HF [(match_operand:HF 1 "nonimmediate_operand" "v,m")]
21902 "TARGET_AVX512FP16"
21904 vrsqrtsh\t{%d1, %0|%0, %d1}
21905 vrsqrtsh\t{%1, %d0|%d0, %1}"
21906 [(set_attr "type" "sse")
21907 (set_attr "prefix" "evex")
21908 (set_attr "avx_partial_xmm_update" "false,true")
21909 (set_attr "mode" "HF")])
21911 (define_insn "sqrthf2"
21912 [(set (match_operand:HF 0 "register_operand" "=v,v")
21914 (match_operand:HF 1 "nonimmediate_operand" "v,m")))]
21915 "TARGET_AVX512FP16"
21917 vsqrtsh\t{%d1, %0|%0, %d1}
21918 vsqrtsh\t{%1, %d0|%d0, %1}"
21919 [(set_attr "type" "sse")
21920 (set_attr "prefix" "evex")
21921 (set_attr "avx_partial_xmm_update" "false,true")
21922 (set_attr "mode" "HF")])
21924 (define_insn "*sqrt<mode>2_sse"
21925 [(set (match_operand:MODEF 0 "register_operand" "=v,v,v")
21927 (match_operand:MODEF 1 "nonimmediate_operand" "0,v,m")))]
21928 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
21930 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
21931 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
21932 %vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
21933 [(set_attr "type" "sse")
21934 (set_attr "atom_sse_attr" "sqrt")
21935 (set_attr "btver2_sse_attr" "sqrt")
21936 (set_attr "prefix" "maybe_vex")
21937 (set_attr "avx_partial_xmm_update" "false,false,true")
21938 (set_attr "mode" "<MODE>")
21939 (set (attr "preferred_for_speed")
21940 (cond [(match_test "TARGET_AVX")
21941 (symbol_ref "true")
21942 (eq_attr "alternative" "1,2")
21943 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
21945 (symbol_ref "true")))])
21947 (define_expand "sqrt<mode>2"
21948 [(set (match_operand:MODEF 0 "register_operand")
21950 (match_operand:MODEF 1 "nonimmediate_operand")))]
21951 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
21952 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
21954 if (<MODE>mode == SFmode
21955 && TARGET_SSE && TARGET_SSE_MATH
21956 && TARGET_RECIP_SQRT
21957 && !optimize_function_for_size_p (cfun)
21958 && flag_finite_math_only && !flag_trapping_math
21959 && flag_unsafe_math_optimizations)
21961 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
21965 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
21967 rtx op0 = gen_reg_rtx (XFmode);
21968 rtx op1 = gen_reg_rtx (XFmode);
21970 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21971 emit_insn (gen_sqrtxf2 (op0, op1));
21972 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
21977 (define_expand "hypot<mode>3"
21978 [(use (match_operand:MODEF 0 "register_operand"))
21979 (use (match_operand:MODEF 1 "general_operand"))
21980 (use (match_operand:MODEF 2 "general_operand"))]
21981 "TARGET_USE_FANCY_MATH_387
21982 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21983 || TARGET_MIX_SSE_I387)
21984 && flag_finite_math_only
21985 && flag_unsafe_math_optimizations"
21987 rtx op0 = gen_reg_rtx (XFmode);
21988 rtx op1 = gen_reg_rtx (XFmode);
21989 rtx op2 = gen_reg_rtx (XFmode);
21991 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
21992 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21994 emit_insn (gen_mulxf3 (op1, op1, op1));
21995 emit_insn (gen_mulxf3 (op2, op2, op2));
21996 emit_insn (gen_addxf3 (op0, op2, op1));
21997 emit_insn (gen_sqrtxf2 (op0, op0));
21999 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
22003 (define_insn "x86_fnstsw_1"
22004 [(set (match_operand:HI 0 "register_operand" "=a")
22005 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
22008 [(set_attr "length" "2")
22009 (set_attr "mode" "SI")
22010 (set_attr "unit" "i387")])
22012 (define_insn "fpremxf4_i387"
22013 [(set (match_operand:XF 0 "register_operand" "=f")
22014 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
22015 (match_operand:XF 3 "register_operand" "1")]
22017 (set (match_operand:XF 1 "register_operand" "=f")
22018 (unspec:XF [(match_dup 2) (match_dup 3)]
22020 (set (reg:CCFP FPSR_REG)
22021 (unspec:CCFP [(match_dup 2) (match_dup 3)]
22023 "TARGET_USE_FANCY_MATH_387"
22025 [(set_attr "type" "fpspc")
22026 (set_attr "znver1_decode" "vector")
22027 (set_attr "mode" "XF")])
22029 (define_expand "fmodxf3"
22030 [(use (match_operand:XF 0 "register_operand"))
22031 (use (match_operand:XF 1 "general_operand"))
22032 (use (match_operand:XF 2 "general_operand"))]
22033 "TARGET_USE_FANCY_MATH_387"
22035 rtx_code_label *label = gen_label_rtx ();
22037 rtx op1 = gen_reg_rtx (XFmode);
22038 rtx op2 = gen_reg_rtx (XFmode);
22040 emit_move_insn (op2, operands[2]);
22041 emit_move_insn (op1, operands[1]);
22043 emit_label (label);
22044 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
22045 ix86_emit_fp_unordered_jump (label);
22046 LABEL_NUSES (label) = 1;
22048 emit_move_insn (operands[0], op1);
22052 (define_expand "fmod<mode>3"
22053 [(use (match_operand:MODEF 0 "register_operand"))
22054 (use (match_operand:MODEF 1 "general_operand"))
22055 (use (match_operand:MODEF 2 "general_operand"))]
22056 "TARGET_USE_FANCY_MATH_387"
22058 rtx (*gen_truncxf) (rtx, rtx);
22060 rtx_code_label *label = gen_label_rtx ();
22062 rtx op1 = gen_reg_rtx (XFmode);
22063 rtx op2 = gen_reg_rtx (XFmode);
22065 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
22066 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22068 emit_label (label);
22069 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
22070 ix86_emit_fp_unordered_jump (label);
22071 LABEL_NUSES (label) = 1;
22073 /* Truncate the result properly for strict SSE math. */
22074 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
22075 && !TARGET_MIX_SSE_I387)
22076 gen_truncxf = gen_truncxf<mode>2;
22078 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
22080 emit_insn (gen_truncxf (operands[0], op1));
22084 (define_insn "fprem1xf4_i387"
22085 [(set (match_operand:XF 0 "register_operand" "=f")
22086 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
22087 (match_operand:XF 3 "register_operand" "1")]
22089 (set (match_operand:XF 1 "register_operand" "=f")
22090 (unspec:XF [(match_dup 2) (match_dup 3)]
22092 (set (reg:CCFP FPSR_REG)
22093 (unspec:CCFP [(match_dup 2) (match_dup 3)]
22095 "TARGET_USE_FANCY_MATH_387"
22097 [(set_attr "type" "fpspc")
22098 (set_attr "znver1_decode" "vector")
22099 (set_attr "mode" "XF")])
22101 (define_expand "remainderxf3"
22102 [(use (match_operand:XF 0 "register_operand"))
22103 (use (match_operand:XF 1 "general_operand"))
22104 (use (match_operand:XF 2 "general_operand"))]
22105 "TARGET_USE_FANCY_MATH_387"
22107 rtx_code_label *label = gen_label_rtx ();
22109 rtx op1 = gen_reg_rtx (XFmode);
22110 rtx op2 = gen_reg_rtx (XFmode);
22112 emit_move_insn (op2, operands[2]);
22113 emit_move_insn (op1, operands[1]);
22115 emit_label (label);
22116 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
22117 ix86_emit_fp_unordered_jump (label);
22118 LABEL_NUSES (label) = 1;
22120 emit_move_insn (operands[0], op1);
22124 (define_expand "remainder<mode>3"
22125 [(use (match_operand:MODEF 0 "register_operand"))
22126 (use (match_operand:MODEF 1 "general_operand"))
22127 (use (match_operand:MODEF 2 "general_operand"))]
22128 "TARGET_USE_FANCY_MATH_387"
22130 rtx (*gen_truncxf) (rtx, rtx);
22132 rtx_code_label *label = gen_label_rtx ();
22134 rtx op1 = gen_reg_rtx (XFmode);
22135 rtx op2 = gen_reg_rtx (XFmode);
22137 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
22138 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22140 emit_label (label);
22142 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
22143 ix86_emit_fp_unordered_jump (label);
22144 LABEL_NUSES (label) = 1;
22146 /* Truncate the result properly for strict SSE math. */
22147 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
22148 && !TARGET_MIX_SSE_I387)
22149 gen_truncxf = gen_truncxf<mode>2;
22151 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
22153 emit_insn (gen_truncxf (operands[0], op1));
22157 (define_int_iterator SINCOS
22161 (define_int_attr sincos
22162 [(UNSPEC_SIN "sin")
22163 (UNSPEC_COS "cos")])
22165 (define_insn "<sincos>xf2"
22166 [(set (match_operand:XF 0 "register_operand" "=f")
22167 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
22169 "TARGET_USE_FANCY_MATH_387
22170 && flag_unsafe_math_optimizations"
22172 [(set_attr "type" "fpspc")
22173 (set_attr "znver1_decode" "vector")
22174 (set_attr "mode" "XF")])
22176 (define_expand "<sincos><mode>2"
22177 [(set (match_operand:MODEF 0 "register_operand")
22178 (unspec:MODEF [(match_operand:MODEF 1 "general_operand")]
22180 "TARGET_USE_FANCY_MATH_387
22181 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22182 || TARGET_MIX_SSE_I387)
22183 && flag_unsafe_math_optimizations"
22185 rtx op0 = gen_reg_rtx (XFmode);
22186 rtx op1 = gen_reg_rtx (XFmode);
22188 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22189 emit_insn (gen_<sincos>xf2 (op0, op1));
22190 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
22194 (define_insn "sincosxf3"
22195 [(set (match_operand:XF 0 "register_operand" "=f")
22196 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
22197 UNSPEC_SINCOS_COS))
22198 (set (match_operand:XF 1 "register_operand" "=f")
22199 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
22200 "TARGET_USE_FANCY_MATH_387
22201 && flag_unsafe_math_optimizations"
22203 [(set_attr "type" "fpspc")
22204 (set_attr "znver1_decode" "vector")
22205 (set_attr "mode" "XF")])
22207 (define_expand "sincos<mode>3"
22208 [(use (match_operand:MODEF 0 "register_operand"))
22209 (use (match_operand:MODEF 1 "register_operand"))
22210 (use (match_operand:MODEF 2 "general_operand"))]
22211 "TARGET_USE_FANCY_MATH_387
22212 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22213 || TARGET_MIX_SSE_I387)
22214 && flag_unsafe_math_optimizations"
22216 rtx op0 = gen_reg_rtx (XFmode);
22217 rtx op1 = gen_reg_rtx (XFmode);
22218 rtx op2 = gen_reg_rtx (XFmode);
22220 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
22221 emit_insn (gen_sincosxf3 (op0, op1, op2));
22222 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
22223 emit_insn (gen_truncxf<mode>2 (operands[1], op1));
22227 (define_insn "fptanxf4_i387"
22228 [(set (match_operand:SF 0 "register_operand" "=f")
22229 (match_operand:SF 3 "const1_operand"))
22230 (set (match_operand:XF 1 "register_operand" "=f")
22231 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
22233 "TARGET_USE_FANCY_MATH_387
22234 && flag_unsafe_math_optimizations"
22236 [(set_attr "type" "fpspc")
22237 (set_attr "znver1_decode" "vector")
22238 (set_attr "mode" "XF")])
22240 (define_expand "tanxf2"
22241 [(use (match_operand:XF 0 "register_operand"))
22242 (use (match_operand:XF 1 "register_operand"))]
22243 "TARGET_USE_FANCY_MATH_387
22244 && flag_unsafe_math_optimizations"
22246 rtx one = gen_reg_rtx (SFmode);
22247 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1],
22248 CONST1_RTX (SFmode)));
22252 (define_expand "tan<mode>2"
22253 [(use (match_operand:MODEF 0 "register_operand"))
22254 (use (match_operand:MODEF 1 "general_operand"))]
22255 "TARGET_USE_FANCY_MATH_387
22256 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22257 || TARGET_MIX_SSE_I387)
22258 && flag_unsafe_math_optimizations"
22260 rtx op0 = gen_reg_rtx (XFmode);
22261 rtx op1 = gen_reg_rtx (XFmode);
22263 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22264 emit_insn (gen_tanxf2 (op0, op1));
22265 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
22269 (define_insn "atan2xf3"
22270 [(set (match_operand:XF 0 "register_operand" "=f")
22271 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
22272 (match_operand:XF 1 "register_operand" "f")]
22274 (clobber (match_scratch:XF 3 "=1"))]
22275 "TARGET_USE_FANCY_MATH_387
22276 && flag_unsafe_math_optimizations"
22278 [(set_attr "type" "fpspc")
22279 (set_attr "znver1_decode" "vector")
22280 (set_attr "mode" "XF")])
22282 (define_expand "atan2<mode>3"
22283 [(use (match_operand:MODEF 0 "register_operand"))
22284 (use (match_operand:MODEF 1 "general_operand"))
22285 (use (match_operand:MODEF 2 "general_operand"))]
22286 "TARGET_USE_FANCY_MATH_387
22287 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22288 || TARGET_MIX_SSE_I387)
22289 && flag_unsafe_math_optimizations"
22291 rtx op0 = gen_reg_rtx (XFmode);
22292 rtx op1 = gen_reg_rtx (XFmode);
22293 rtx op2 = gen_reg_rtx (XFmode);
22295 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
22296 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22298 emit_insn (gen_atan2xf3 (op0, op1, op2));
22299 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
22303 (define_expand "atanxf2"
22304 [(parallel [(set (match_operand:XF 0 "register_operand")
22305 (unspec:XF [(match_dup 2)
22306 (match_operand:XF 1 "register_operand")]
22308 (clobber (scratch:XF))])]
22309 "TARGET_USE_FANCY_MATH_387
22310 && flag_unsafe_math_optimizations"
22311 "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
22313 (define_expand "atan<mode>2"
22314 [(use (match_operand:MODEF 0 "register_operand"))
22315 (use (match_operand:MODEF 1 "general_operand"))]
22316 "TARGET_USE_FANCY_MATH_387
22317 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22318 || TARGET_MIX_SSE_I387)
22319 && flag_unsafe_math_optimizations"
22321 rtx op0 = gen_reg_rtx (XFmode);
22322 rtx op1 = gen_reg_rtx (XFmode);
22324 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22325 emit_insn (gen_atanxf2 (op0, op1));
22326 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
22330 (define_expand "asinxf2"
22331 [(set (match_dup 2)
22332 (mult:XF (match_operand:XF 1 "register_operand")
22334 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
22335 (set (match_dup 5) (sqrt:XF (match_dup 4)))
22336 (parallel [(set (match_operand:XF 0 "register_operand")
22337 (unspec:XF [(match_dup 5) (match_dup 1)]
22339 (clobber (scratch:XF))])]
22340 "TARGET_USE_FANCY_MATH_387
22341 && flag_unsafe_math_optimizations"
22345 for (i = 2; i < 6; i++)
22346 operands[i] = gen_reg_rtx (XFmode);
22348 emit_move_insn (operands[3], CONST1_RTX (XFmode));
22351 (define_expand "asin<mode>2"
22352 [(use (match_operand:MODEF 0 "register_operand"))
22353 (use (match_operand:MODEF 1 "general_operand"))]
22354 "TARGET_USE_FANCY_MATH_387
22355 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22356 || TARGET_MIX_SSE_I387)
22357 && flag_unsafe_math_optimizations"
22359 rtx op0 = gen_reg_rtx (XFmode);
22360 rtx op1 = gen_reg_rtx (XFmode);
22362 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22363 emit_insn (gen_asinxf2 (op0, op1));
22364 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
22368 (define_expand "acosxf2"
22369 [(set (match_dup 2)
22370 (mult:XF (match_operand:XF 1 "register_operand")
22372 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
22373 (set (match_dup 5) (sqrt:XF (match_dup 4)))
22374 (parallel [(set (match_operand:XF 0 "register_operand")
22375 (unspec:XF [(match_dup 1) (match_dup 5)]
22377 (clobber (scratch:XF))])]
22378 "TARGET_USE_FANCY_MATH_387
22379 && flag_unsafe_math_optimizations"
22383 for (i = 2; i < 6; i++)
22384 operands[i] = gen_reg_rtx (XFmode);
22386 emit_move_insn (operands[3], CONST1_RTX (XFmode));
22389 (define_expand "acos<mode>2"
22390 [(use (match_operand:MODEF 0 "register_operand"))
22391 (use (match_operand:MODEF 1 "general_operand"))]
22392 "TARGET_USE_FANCY_MATH_387
22393 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22394 || TARGET_MIX_SSE_I387)
22395 && flag_unsafe_math_optimizations"
22397 rtx op0 = gen_reg_rtx (XFmode);
22398 rtx op1 = gen_reg_rtx (XFmode);
22400 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22401 emit_insn (gen_acosxf2 (op0, op1));
22402 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
22406 (define_expand "sinhxf2"
22407 [(use (match_operand:XF 0 "register_operand"))
22408 (use (match_operand:XF 1 "register_operand"))]
22409 "TARGET_USE_FANCY_MATH_387
22410 && flag_finite_math_only
22411 && flag_unsafe_math_optimizations"
22413 ix86_emit_i387_sinh (operands[0], operands[1]);
22417 (define_expand "sinh<mode>2"
22418 [(use (match_operand:MODEF 0 "register_operand"))
22419 (use (match_operand:MODEF 1 "general_operand"))]
22420 "TARGET_USE_FANCY_MATH_387
22421 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22422 || TARGET_MIX_SSE_I387)
22423 && flag_finite_math_only
22424 && flag_unsafe_math_optimizations"
22426 rtx op0 = gen_reg_rtx (XFmode);
22427 rtx op1 = gen_reg_rtx (XFmode);
22429 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22430 emit_insn (gen_sinhxf2 (op0, op1));
22431 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
22435 (define_expand "coshxf2"
22436 [(use (match_operand:XF 0 "register_operand"))
22437 (use (match_operand:XF 1 "register_operand"))]
22438 "TARGET_USE_FANCY_MATH_387
22439 && flag_unsafe_math_optimizations"
22441 ix86_emit_i387_cosh (operands[0], operands[1]);
22445 (define_expand "cosh<mode>2"
22446 [(use (match_operand:MODEF 0 "register_operand"))
22447 (use (match_operand:MODEF 1 "general_operand"))]
22448 "TARGET_USE_FANCY_MATH_387
22449 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22450 || TARGET_MIX_SSE_I387)
22451 && flag_unsafe_math_optimizations"
22453 rtx op0 = gen_reg_rtx (XFmode);
22454 rtx op1 = gen_reg_rtx (XFmode);
22456 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22457 emit_insn (gen_coshxf2 (op0, op1));
22458 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
22462 (define_expand "tanhxf2"
22463 [(use (match_operand:XF 0 "register_operand"))
22464 (use (match_operand:XF 1 "register_operand"))]
22465 "TARGET_USE_FANCY_MATH_387
22466 && flag_unsafe_math_optimizations"
22468 ix86_emit_i387_tanh (operands[0], operands[1]);
22472 (define_expand "tanh<mode>2"
22473 [(use (match_operand:MODEF 0 "register_operand"))
22474 (use (match_operand:MODEF 1 "general_operand"))]
22475 "TARGET_USE_FANCY_MATH_387
22476 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22477 || TARGET_MIX_SSE_I387)
22478 && flag_unsafe_math_optimizations"
22480 rtx op0 = gen_reg_rtx (XFmode);
22481 rtx op1 = gen_reg_rtx (XFmode);
22483 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22484 emit_insn (gen_tanhxf2 (op0, op1));
22485 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
22489 (define_expand "asinhxf2"
22490 [(use (match_operand:XF 0 "register_operand"))
22491 (use (match_operand:XF 1 "register_operand"))]
22492 "TARGET_USE_FANCY_MATH_387
22493 && flag_finite_math_only
22494 && flag_unsafe_math_optimizations"
22496 ix86_emit_i387_asinh (operands[0], operands[1]);
22500 (define_expand "asinh<mode>2"
22501 [(use (match_operand:MODEF 0 "register_operand"))
22502 (use (match_operand:MODEF 1 "general_operand"))]
22503 "TARGET_USE_FANCY_MATH_387
22504 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22505 || TARGET_MIX_SSE_I387)
22506 && flag_finite_math_only
22507 && flag_unsafe_math_optimizations"
22509 rtx op0 = gen_reg_rtx (XFmode);
22510 rtx op1 = gen_reg_rtx (XFmode);
22512 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22513 emit_insn (gen_asinhxf2 (op0, op1));
22514 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
22518 (define_expand "acoshxf2"
22519 [(use (match_operand:XF 0 "register_operand"))
22520 (use (match_operand:XF 1 "register_operand"))]
22521 "TARGET_USE_FANCY_MATH_387
22522 && flag_unsafe_math_optimizations"
22524 ix86_emit_i387_acosh (operands[0], operands[1]);
22528 (define_expand "acosh<mode>2"
22529 [(use (match_operand:MODEF 0 "register_operand"))
22530 (use (match_operand:MODEF 1 "general_operand"))]
22531 "TARGET_USE_FANCY_MATH_387
22532 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22533 || TARGET_MIX_SSE_I387)
22534 && flag_unsafe_math_optimizations"
22536 rtx op0 = gen_reg_rtx (XFmode);
22537 rtx op1 = gen_reg_rtx (XFmode);
22539 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22540 emit_insn (gen_acoshxf2 (op0, op1));
22541 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
22545 (define_expand "atanhxf2"
22546 [(use (match_operand:XF 0 "register_operand"))
22547 (use (match_operand:XF 1 "register_operand"))]
22548 "TARGET_USE_FANCY_MATH_387
22549 && flag_unsafe_math_optimizations"
22551 ix86_emit_i387_atanh (operands[0], operands[1]);
22555 (define_expand "atanh<mode>2"
22556 [(use (match_operand:MODEF 0 "register_operand"))
22557 (use (match_operand:MODEF 1 "general_operand"))]
22558 "TARGET_USE_FANCY_MATH_387
22559 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22560 || TARGET_MIX_SSE_I387)
22561 && flag_unsafe_math_optimizations"
22563 rtx op0 = gen_reg_rtx (XFmode);
22564 rtx op1 = gen_reg_rtx (XFmode);
22566 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22567 emit_insn (gen_atanhxf2 (op0, op1));
22568 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
22572 (define_insn "fyl2xxf3_i387"
22573 [(set (match_operand:XF 0 "register_operand" "=f")
22574 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
22575 (match_operand:XF 2 "register_operand" "f")]
22577 (clobber (match_scratch:XF 3 "=2"))]
22578 "TARGET_USE_FANCY_MATH_387
22579 && flag_unsafe_math_optimizations"
22581 [(set_attr "type" "fpspc")
22582 (set_attr "znver1_decode" "vector")
22583 (set_attr "mode" "XF")])
22585 (define_expand "logxf2"
22586 [(parallel [(set (match_operand:XF 0 "register_operand")
22587 (unspec:XF [(match_operand:XF 1 "register_operand")
22588 (match_dup 2)] UNSPEC_FYL2X))
22589 (clobber (scratch:XF))])]
22590 "TARGET_USE_FANCY_MATH_387
22591 && flag_unsafe_math_optimizations"
22594 = force_reg (XFmode, standard_80387_constant_rtx (4)); /* fldln2 */
22597 (define_expand "log<mode>2"
22598 [(use (match_operand:MODEF 0 "register_operand"))
22599 (use (match_operand:MODEF 1 "general_operand"))]
22600 "TARGET_USE_FANCY_MATH_387
22601 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22602 || TARGET_MIX_SSE_I387)
22603 && flag_unsafe_math_optimizations"
22605 rtx op0 = gen_reg_rtx (XFmode);
22606 rtx op1 = gen_reg_rtx (XFmode);
22608 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22609 emit_insn (gen_logxf2 (op0, op1));
22610 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
22614 (define_expand "log10xf2"
22615 [(parallel [(set (match_operand:XF 0 "register_operand")
22616 (unspec:XF [(match_operand:XF 1 "register_operand")
22617 (match_dup 2)] UNSPEC_FYL2X))
22618 (clobber (scratch:XF))])]
22619 "TARGET_USE_FANCY_MATH_387
22620 && flag_unsafe_math_optimizations"
22623 = force_reg (XFmode, standard_80387_constant_rtx (3)); /* fldlg2 */
22626 (define_expand "log10<mode>2"
22627 [(use (match_operand:MODEF 0 "register_operand"))
22628 (use (match_operand:MODEF 1 "general_operand"))]
22629 "TARGET_USE_FANCY_MATH_387
22630 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22631 || TARGET_MIX_SSE_I387)
22632 && flag_unsafe_math_optimizations"
22634 rtx op0 = gen_reg_rtx (XFmode);
22635 rtx op1 = gen_reg_rtx (XFmode);
22637 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22638 emit_insn (gen_log10xf2 (op0, op1));
22639 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
22643 (define_expand "log2xf2"
22644 [(parallel [(set (match_operand:XF 0 "register_operand")
22645 (unspec:XF [(match_operand:XF 1 "register_operand")
22646 (match_dup 2)] UNSPEC_FYL2X))
22647 (clobber (scratch:XF))])]
22648 "TARGET_USE_FANCY_MATH_387
22649 && flag_unsafe_math_optimizations"
22650 "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
22652 (define_expand "log2<mode>2"
22653 [(use (match_operand:MODEF 0 "register_operand"))
22654 (use (match_operand:MODEF 1 "general_operand"))]
22655 "TARGET_USE_FANCY_MATH_387
22656 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22657 || TARGET_MIX_SSE_I387)
22658 && flag_unsafe_math_optimizations"
22660 rtx op0 = gen_reg_rtx (XFmode);
22661 rtx op1 = gen_reg_rtx (XFmode);
22663 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22664 emit_insn (gen_log2xf2 (op0, op1));
22665 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
22669 (define_insn "fyl2xp1xf3_i387"
22670 [(set (match_operand:XF 0 "register_operand" "=f")
22671 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
22672 (match_operand:XF 2 "register_operand" "f")]
22674 (clobber (match_scratch:XF 3 "=2"))]
22675 "TARGET_USE_FANCY_MATH_387
22676 && flag_unsafe_math_optimizations"
22678 [(set_attr "type" "fpspc")
22679 (set_attr "znver1_decode" "vector")
22680 (set_attr "mode" "XF")])
22682 (define_expand "log1pxf2"
22683 [(use (match_operand:XF 0 "register_operand"))
22684 (use (match_operand:XF 1 "register_operand"))]
22685 "TARGET_USE_FANCY_MATH_387
22686 && flag_unsafe_math_optimizations"
22688 ix86_emit_i387_log1p (operands[0], operands[1]);
22692 (define_expand "log1p<mode>2"
22693 [(use (match_operand:MODEF 0 "register_operand"))
22694 (use (match_operand:MODEF 1 "general_operand"))]
22695 "TARGET_USE_FANCY_MATH_387
22696 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22697 || TARGET_MIX_SSE_I387)
22698 && flag_unsafe_math_optimizations"
22700 rtx op0 = gen_reg_rtx (XFmode);
22701 rtx op1 = gen_reg_rtx (XFmode);
22703 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22704 emit_insn (gen_log1pxf2 (op0, op1));
22705 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
22709 (define_insn "fxtractxf3_i387"
22710 [(set (match_operand:XF 0 "register_operand" "=f")
22711 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
22712 UNSPEC_XTRACT_FRACT))
22713 (set (match_operand:XF 1 "register_operand" "=f")
22714 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
22715 "TARGET_USE_FANCY_MATH_387
22716 && flag_unsafe_math_optimizations"
22718 [(set_attr "type" "fpspc")
22719 (set_attr "znver1_decode" "vector")
22720 (set_attr "mode" "XF")])
22722 (define_expand "logbxf2"
22723 [(parallel [(set (match_dup 2)
22724 (unspec:XF [(match_operand:XF 1 "register_operand")]
22725 UNSPEC_XTRACT_FRACT))
22726 (set (match_operand:XF 0 "register_operand")
22727 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
22728 "TARGET_USE_FANCY_MATH_387
22729 && flag_unsafe_math_optimizations"
22730 "operands[2] = gen_reg_rtx (XFmode);")
22732 (define_expand "logb<mode>2"
22733 [(use (match_operand:MODEF 0 "register_operand"))
22734 (use (match_operand:MODEF 1 "general_operand"))]
22735 "TARGET_USE_FANCY_MATH_387
22736 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22737 || TARGET_MIX_SSE_I387)
22738 && flag_unsafe_math_optimizations"
22740 rtx op0 = gen_reg_rtx (XFmode);
22741 rtx op1 = gen_reg_rtx (XFmode);
22743 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22744 emit_insn (gen_logbxf2 (op0, op1));
22745 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
22749 (define_expand "ilogbxf2"
22750 [(use (match_operand:SI 0 "register_operand"))
22751 (use (match_operand:XF 1 "register_operand"))]
22752 "TARGET_USE_FANCY_MATH_387
22753 && flag_unsafe_math_optimizations"
22757 if (optimize_insn_for_size_p ())
22760 op0 = gen_reg_rtx (XFmode);
22761 op1 = gen_reg_rtx (XFmode);
22763 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
22764 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
22768 (define_expand "ilogb<mode>2"
22769 [(use (match_operand:SI 0 "register_operand"))
22770 (use (match_operand:MODEF 1 "general_operand"))]
22771 "TARGET_USE_FANCY_MATH_387
22772 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22773 || TARGET_MIX_SSE_I387)
22774 && flag_unsafe_math_optimizations"
22778 if (optimize_insn_for_size_p ())
22781 op0 = gen_reg_rtx (XFmode);
22782 op1 = gen_reg_rtx (XFmode);
22783 op2 = gen_reg_rtx (XFmode);
22785 emit_insn (gen_extend<mode>xf2 (op2, operands[1]));
22786 emit_insn (gen_fxtractxf3_i387 (op0, op1, op2));
22787 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
22791 (define_insn "*f2xm1xf2_i387"
22792 [(set (match_operand:XF 0 "register_operand" "=f")
22793 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
22795 "TARGET_USE_FANCY_MATH_387
22796 && flag_unsafe_math_optimizations"
22798 [(set_attr "type" "fpspc")
22799 (set_attr "znver1_decode" "vector")
22800 (set_attr "mode" "XF")])
22802 (define_insn "fscalexf4_i387"
22803 [(set (match_operand:XF 0 "register_operand" "=f")
22804 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
22805 (match_operand:XF 3 "register_operand" "1")]
22806 UNSPEC_FSCALE_FRACT))
22807 (set (match_operand:XF 1 "register_operand" "=f")
22808 (unspec:XF [(match_dup 2) (match_dup 3)]
22809 UNSPEC_FSCALE_EXP))]
22810 "TARGET_USE_FANCY_MATH_387
22811 && flag_unsafe_math_optimizations"
22813 [(set_attr "type" "fpspc")
22814 (set_attr "znver1_decode" "vector")
22815 (set_attr "mode" "XF")])
22817 (define_expand "expNcorexf3"
22818 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
22819 (match_operand:XF 2 "register_operand")))
22820 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
22821 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
22822 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
22823 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
22824 (parallel [(set (match_operand:XF 0 "register_operand")
22825 (unspec:XF [(match_dup 8) (match_dup 4)]
22826 UNSPEC_FSCALE_FRACT))
22828 (unspec:XF [(match_dup 8) (match_dup 4)]
22829 UNSPEC_FSCALE_EXP))])]
22830 "TARGET_USE_FANCY_MATH_387
22831 && flag_unsafe_math_optimizations"
22835 for (i = 3; i < 10; i++)
22836 operands[i] = gen_reg_rtx (XFmode);
22838 emit_move_insn (operands[7], CONST1_RTX (XFmode));
22841 (define_expand "expxf2"
22842 [(use (match_operand:XF 0 "register_operand"))
22843 (use (match_operand:XF 1 "register_operand"))]
22844 "TARGET_USE_FANCY_MATH_387
22845 && flag_unsafe_math_optimizations"
22847 rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (5)); /* fldl2e */
22849 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
22853 (define_expand "exp<mode>2"
22854 [(use (match_operand:MODEF 0 "register_operand"))
22855 (use (match_operand:MODEF 1 "general_operand"))]
22856 "TARGET_USE_FANCY_MATH_387
22857 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22858 || TARGET_MIX_SSE_I387)
22859 && flag_unsafe_math_optimizations"
22861 rtx op0 = gen_reg_rtx (XFmode);
22862 rtx op1 = gen_reg_rtx (XFmode);
22864 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22865 emit_insn (gen_expxf2 (op0, op1));
22866 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
22870 (define_expand "exp10xf2"
22871 [(use (match_operand:XF 0 "register_operand"))
22872 (use (match_operand:XF 1 "register_operand"))]
22873 "TARGET_USE_FANCY_MATH_387
22874 && flag_unsafe_math_optimizations"
22876 rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (6)); /* fldl2t */
22878 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
22882 (define_expand "exp10<mode>2"
22883 [(use (match_operand:MODEF 0 "register_operand"))
22884 (use (match_operand:MODEF 1 "general_operand"))]
22885 "TARGET_USE_FANCY_MATH_387
22886 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22887 || TARGET_MIX_SSE_I387)
22888 && flag_unsafe_math_optimizations"
22890 rtx op0 = gen_reg_rtx (XFmode);
22891 rtx op1 = gen_reg_rtx (XFmode);
22893 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22894 emit_insn (gen_exp10xf2 (op0, op1));
22895 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
22899 (define_expand "exp2xf2"
22900 [(use (match_operand:XF 0 "register_operand"))
22901 (use (match_operand:XF 1 "register_operand"))]
22902 "TARGET_USE_FANCY_MATH_387
22903 && flag_unsafe_math_optimizations"
22905 rtx op2 = force_reg (XFmode, CONST1_RTX (XFmode));
22907 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
22911 (define_expand "exp2<mode>2"
22912 [(use (match_operand:MODEF 0 "register_operand"))
22913 (use (match_operand:MODEF 1 "general_operand"))]
22914 "TARGET_USE_FANCY_MATH_387
22915 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22916 || TARGET_MIX_SSE_I387)
22917 && flag_unsafe_math_optimizations"
22919 rtx op0 = gen_reg_rtx (XFmode);
22920 rtx op1 = gen_reg_rtx (XFmode);
22922 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22923 emit_insn (gen_exp2xf2 (op0, op1));
22924 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
22928 (define_expand "expm1xf2"
22929 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
22931 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
22932 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
22933 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
22934 (parallel [(set (match_dup 7)
22935 (unspec:XF [(match_dup 6) (match_dup 4)]
22936 UNSPEC_FSCALE_FRACT))
22938 (unspec:XF [(match_dup 6) (match_dup 4)]
22939 UNSPEC_FSCALE_EXP))])
22940 (parallel [(set (match_dup 10)
22941 (unspec:XF [(match_dup 9) (match_dup 8)]
22942 UNSPEC_FSCALE_FRACT))
22943 (set (match_dup 11)
22944 (unspec:XF [(match_dup 9) (match_dup 8)]
22945 UNSPEC_FSCALE_EXP))])
22946 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
22947 (set (match_operand:XF 0 "register_operand")
22948 (plus:XF (match_dup 12) (match_dup 7)))]
22949 "TARGET_USE_FANCY_MATH_387
22950 && flag_unsafe_math_optimizations"
22954 for (i = 2; i < 13; i++)
22955 operands[i] = gen_reg_rtx (XFmode);
22957 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
22958 emit_move_insn (operands[9], CONST1_RTX (XFmode));
22961 (define_expand "expm1<mode>2"
22962 [(use (match_operand:MODEF 0 "register_operand"))
22963 (use (match_operand:MODEF 1 "general_operand"))]
22964 "TARGET_USE_FANCY_MATH_387
22965 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22966 || TARGET_MIX_SSE_I387)
22967 && flag_unsafe_math_optimizations"
22969 rtx op0 = gen_reg_rtx (XFmode);
22970 rtx op1 = gen_reg_rtx (XFmode);
22972 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22973 emit_insn (gen_expm1xf2 (op0, op1));
22974 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
22978 (define_insn "avx512f_scalef<mode>2"
22979 [(set (match_operand:MODEF 0 "register_operand" "=v")
22981 [(match_operand:MODEF 1 "register_operand" "v")
22982 (match_operand:MODEF 2 "nonimmediate_operand" "vm")]
22985 "vscalef<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
22986 [(set_attr "prefix" "evex")
22987 (set_attr "mode" "<MODE>")])
22989 (define_expand "ldexpxf3"
22990 [(match_operand:XF 0 "register_operand")
22991 (match_operand:XF 1 "register_operand")
22992 (match_operand:SI 2 "register_operand")]
22993 "TARGET_USE_FANCY_MATH_387
22994 && flag_unsafe_math_optimizations"
22996 rtx tmp1 = gen_reg_rtx (XFmode);
22997 rtx tmp2 = gen_reg_rtx (XFmode);
22999 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
23000 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
23001 operands[1], tmp1));
23005 (define_expand "ldexp<mode>3"
23006 [(use (match_operand:MODEF 0 "register_operand"))
23007 (use (match_operand:MODEF 1 "general_operand"))
23008 (use (match_operand:SI 2 "register_operand"))]
23009 "((TARGET_USE_FANCY_MATH_387
23010 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
23011 || TARGET_MIX_SSE_I387))
23012 || (TARGET_AVX512F && TARGET_SSE_MATH))
23013 && flag_unsafe_math_optimizations"
23015 /* Prefer avx512f version. */
23016 if (TARGET_AVX512F && TARGET_SSE_MATH)
23018 rtx op2 = gen_reg_rtx (<MODE>mode);
23019 operands[1] = force_reg (<MODE>mode, operands[1]);
23021 emit_insn (gen_floatsi<mode>2 (op2, operands[2]));
23022 emit_insn (gen_avx512f_scalef<mode>2 (operands[0], operands[1], op2));
23026 rtx op0 = gen_reg_rtx (XFmode);
23027 rtx op1 = gen_reg_rtx (XFmode);
23029 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
23030 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
23031 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
23036 (define_expand "scalbxf3"
23037 [(parallel [(set (match_operand:XF 0 " register_operand")
23038 (unspec:XF [(match_operand:XF 1 "register_operand")
23039 (match_operand:XF 2 "register_operand")]
23040 UNSPEC_FSCALE_FRACT))
23042 (unspec:XF [(match_dup 1) (match_dup 2)]
23043 UNSPEC_FSCALE_EXP))])]
23044 "TARGET_USE_FANCY_MATH_387
23045 && flag_unsafe_math_optimizations"
23046 "operands[3] = gen_reg_rtx (XFmode);")
23048 (define_expand "scalb<mode>3"
23049 [(use (match_operand:MODEF 0 "register_operand"))
23050 (use (match_operand:MODEF 1 "general_operand"))
23051 (use (match_operand:MODEF 2 "general_operand"))]
23052 "TARGET_USE_FANCY_MATH_387
23053 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
23054 || TARGET_MIX_SSE_I387)
23055 && flag_unsafe_math_optimizations"
23057 rtx op0 = gen_reg_rtx (XFmode);
23058 rtx op1 = gen_reg_rtx (XFmode);
23059 rtx op2 = gen_reg_rtx (XFmode);
23061 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
23062 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
23063 emit_insn (gen_scalbxf3 (op0, op1, op2));
23064 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
23068 (define_expand "significandxf2"
23069 [(parallel [(set (match_operand:XF 0 "register_operand")
23070 (unspec:XF [(match_operand:XF 1 "register_operand")]
23071 UNSPEC_XTRACT_FRACT))
23073 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
23074 "TARGET_USE_FANCY_MATH_387
23075 && flag_unsafe_math_optimizations"
23076 "operands[2] = gen_reg_rtx (XFmode);")
23078 (define_expand "significand<mode>2"
23079 [(use (match_operand:MODEF 0 "register_operand"))
23080 (use (match_operand:MODEF 1 "general_operand"))]
23081 "TARGET_USE_FANCY_MATH_387
23082 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
23083 || TARGET_MIX_SSE_I387)
23084 && flag_unsafe_math_optimizations"
23086 rtx op0 = gen_reg_rtx (XFmode);
23087 rtx op1 = gen_reg_rtx (XFmode);
23089 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
23090 emit_insn (gen_significandxf2 (op0, op1));
23091 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
23096 (define_insn "sse4_1_round<mode>2"
23097 [(set (match_operand:MODEFH 0 "register_operand" "=x,x,x,v,v")
23099 [(match_operand:MODEFH 1 "nonimmediate_operand" "0,x,jm,v,m")
23100 (match_operand:SI 2 "const_0_to_15_operand")]
23104 %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
23105 %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
23106 %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
23107 vrndscale<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
23108 vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
23109 [(set_attr "type" "ssecvt")
23110 (set_attr "prefix_extra" "1,1,1,*,*")
23111 (set_attr "length_immediate" "1")
23112 (set_attr "addr" "*,*,gpr16,*,*")
23113 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,evex,evex")
23114 (set_attr "isa" "noavx512f,noavx512f,noavx512f,avx512f,avx512f")
23115 (set_attr "avx_partial_xmm_update" "false,false,true,false,true")
23116 (set_attr "mode" "<MODE>")
23117 (set (attr "preferred_for_speed")
23118 (cond [(match_test "TARGET_AVX")
23119 (symbol_ref "true")
23120 (eq_attr "alternative" "1,2")
23121 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
23123 (symbol_ref "true")))])
23125 (define_insn "rintxf2"
23126 [(set (match_operand:XF 0 "register_operand" "=f")
23127 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
23129 "TARGET_USE_FANCY_MATH_387"
23131 [(set_attr "type" "fpspc")
23132 (set_attr "znver1_decode" "vector")
23133 (set_attr "mode" "XF")])
23135 (define_expand "rinthf2"
23136 [(match_operand:HF 0 "register_operand")
23137 (match_operand:HF 1 "nonimmediate_operand")]
23138 "TARGET_AVX512FP16"
23140 emit_insn (gen_sse4_1_roundhf2 (operands[0],
23142 GEN_INT (ROUND_MXCSR)));
23146 (define_expand "rint<mode>2"
23147 [(use (match_operand:MODEF 0 "register_operand"))
23148 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
23149 "TARGET_USE_FANCY_MATH_387
23150 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
23152 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
23155 emit_insn (gen_sse4_1_round<mode>2
23156 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
23158 ix86_expand_rint (operands[0], operands[1]);
23162 rtx op0 = gen_reg_rtx (XFmode);
23163 rtx op1 = gen_reg_rtx (XFmode);
23165 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
23166 emit_insn (gen_rintxf2 (op0, op1));
23167 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
23172 (define_expand "nearbyintxf2"
23173 [(set (match_operand:XF 0 "register_operand")
23174 (unspec:XF [(match_operand:XF 1 "register_operand")]
23176 "TARGET_USE_FANCY_MATH_387
23177 && !flag_trapping_math")
23179 (define_expand "nearbyinthf2"
23180 [(match_operand:HF 0 "register_operand")
23181 (match_operand:HF 1 "nonimmediate_operand")]
23182 "TARGET_AVX512FP16"
23184 emit_insn (gen_sse4_1_roundhf2 (operands[0],
23186 GEN_INT (ROUND_MXCSR | ROUND_NO_EXC)));
23190 (define_expand "nearbyint<mode>2"
23191 [(use (match_operand:MODEF 0 "register_operand"))
23192 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
23193 "(TARGET_USE_FANCY_MATH_387
23194 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
23195 || TARGET_MIX_SSE_I387)
23196 && !flag_trapping_math)
23197 || (TARGET_SSE4_1 && TARGET_SSE_MATH)"
23199 if (TARGET_SSE4_1 && TARGET_SSE_MATH)
23200 emit_insn (gen_sse4_1_round<mode>2
23201 (operands[0], operands[1], GEN_INT (ROUND_MXCSR
23205 rtx op0 = gen_reg_rtx (XFmode);
23206 rtx op1 = gen_reg_rtx (XFmode);
23208 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
23209 emit_insn (gen_nearbyintxf2 (op0, op1));
23210 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
23215 (define_expand "roundhf2"
23216 [(match_operand:HF 0 "register_operand")
23217 (match_operand:HF 1 "register_operand")]
23218 "TARGET_AVX512FP16 && !flag_trapping_math && !flag_rounding_math"
23220 ix86_expand_round_sse4 (operands[0], operands[1]);
23224 (define_expand "round<mode>2"
23225 [(match_operand:X87MODEF 0 "register_operand")
23226 (match_operand:X87MODEF 1 "nonimmediate_operand")]
23227 "(TARGET_USE_FANCY_MATH_387
23228 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
23229 || TARGET_MIX_SSE_I387)
23230 && flag_unsafe_math_optimizations
23231 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
23232 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
23233 && !flag_trapping_math && !flag_rounding_math)"
23235 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
23236 && !flag_trapping_math && !flag_rounding_math)
23240 operands[1] = force_reg (<MODE>mode, operands[1]);
23241 ix86_expand_round_sse4 (operands[0], operands[1]);
23243 else if (TARGET_64BIT || (<MODE>mode != DFmode))
23244 ix86_expand_round (operands[0], operands[1]);
23246 ix86_expand_rounddf_32 (operands[0], operands[1]);
23250 operands[1] = force_reg (<MODE>mode, operands[1]);
23251 ix86_emit_i387_round (operands[0], operands[1]);
23256 (define_insn "lrintxfdi2"
23257 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
23258 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
23260 (clobber (match_scratch:XF 2 "=&f"))]
23261 "TARGET_USE_FANCY_MATH_387"
23262 "* return output_fix_trunc (insn, operands, false);"
23263 [(set_attr "type" "fpspc")
23264 (set_attr "mode" "DI")])
23266 (define_insn "lrintxf<mode>2"
23267 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
23268 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
23270 "TARGET_USE_FANCY_MATH_387"
23271 "* return output_fix_trunc (insn, operands, false);"
23272 [(set_attr "type" "fpspc")
23273 (set_attr "mode" "<MODE>")])
23275 (define_expand "lroundhf<mode>2"
23276 [(set (match_operand:SWI248 0 "register_operand")
23277 (unspec:SWI248 [(match_operand:HF 1 "nonimmediate_operand")]
23278 UNSPEC_FIX_NOTRUNC))]
23279 "TARGET_AVX512FP16 && !flag_trapping_math && !flag_rounding_math"
23281 ix86_expand_lround (operands[0], operands[1]);
23285 (define_expand "lrinthf<mode>2"
23286 [(set (match_operand:SWI48 0 "register_operand")
23287 (unspec:SWI48 [(match_operand:HF 1 "nonimmediate_operand")]
23288 UNSPEC_FIX_NOTRUNC))]
23289 "TARGET_AVX512FP16")
23291 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
23292 [(set (match_operand:SWI48 0 "register_operand")
23293 (unspec:SWI48 [(match_operand:MODEF 1 "nonimmediate_operand")]
23294 UNSPEC_FIX_NOTRUNC))]
23295 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
23297 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
23298 [(match_operand:SWI248x 0 "nonimmediate_operand")
23299 (match_operand:X87MODEF 1 "register_operand")]
23300 "(TARGET_USE_FANCY_MATH_387
23301 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
23302 || TARGET_MIX_SSE_I387)
23303 && flag_unsafe_math_optimizations)
23304 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
23305 && <SWI248x:MODE>mode != HImode
23306 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
23307 && !flag_trapping_math && !flag_rounding_math)"
23309 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
23310 && <SWI248x:MODE>mode != HImode
23311 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
23312 && !flag_trapping_math && !flag_rounding_math)
23313 ix86_expand_lround (operands[0], operands[1]);
23315 ix86_emit_i387_round (operands[0], operands[1]);
23319 (define_int_iterator FRNDINT_ROUNDING
23320 [UNSPEC_FRNDINT_ROUNDEVEN
23321 UNSPEC_FRNDINT_FLOOR
23322 UNSPEC_FRNDINT_CEIL
23323 UNSPEC_FRNDINT_TRUNC])
23325 (define_int_iterator FIST_ROUNDING
23329 ;; Base name for define_insn
23330 (define_int_attr rounding_insn
23331 [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven")
23332 (UNSPEC_FRNDINT_FLOOR "floor")
23333 (UNSPEC_FRNDINT_CEIL "ceil")
23334 (UNSPEC_FRNDINT_TRUNC "btrunc")
23335 (UNSPEC_FIST_FLOOR "floor")
23336 (UNSPEC_FIST_CEIL "ceil")])
23338 (define_int_attr rounding
23339 [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven")
23340 (UNSPEC_FRNDINT_FLOOR "floor")
23341 (UNSPEC_FRNDINT_CEIL "ceil")
23342 (UNSPEC_FRNDINT_TRUNC "trunc")
23343 (UNSPEC_FIST_FLOOR "floor")
23344 (UNSPEC_FIST_CEIL "ceil")])
23346 (define_int_attr ROUNDING
23347 [(UNSPEC_FRNDINT_ROUNDEVEN "ROUNDEVEN")
23348 (UNSPEC_FRNDINT_FLOOR "FLOOR")
23349 (UNSPEC_FRNDINT_CEIL "CEIL")
23350 (UNSPEC_FRNDINT_TRUNC "TRUNC")
23351 (UNSPEC_FIST_FLOOR "FLOOR")
23352 (UNSPEC_FIST_CEIL "CEIL")])
23354 ;; Rounding mode control word calculation could clobber FLAGS_REG.
23355 (define_insn_and_split "frndintxf2_<rounding>"
23356 [(set (match_operand:XF 0 "register_operand")
23357 (unspec:XF [(match_operand:XF 1 "register_operand")]
23359 (clobber (reg:CC FLAGS_REG))]
23360 "TARGET_USE_FANCY_MATH_387
23361 && (flag_fp_int_builtin_inexact || !flag_trapping_math)
23362 && ix86_pre_reload_split ()"
23367 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
23369 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
23370 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
23372 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
23373 operands[2], operands[3]));
23376 [(set_attr "type" "frndint")
23377 (set_attr "i387_cw" "<rounding>")
23378 (set_attr "mode" "XF")])
23380 (define_insn "frndintxf2_<rounding>_i387"
23381 [(set (match_operand:XF 0 "register_operand" "=f")
23382 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
23384 (use (match_operand:HI 2 "memory_operand" "m"))
23385 (use (match_operand:HI 3 "memory_operand" "m"))]
23386 "TARGET_USE_FANCY_MATH_387
23387 && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
23388 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
23389 [(set_attr "type" "frndint")
23390 (set_attr "i387_cw" "<rounding>")
23391 (set_attr "mode" "XF")])
23393 (define_expand "<rounding_insn>xf2"
23394 [(parallel [(set (match_operand:XF 0 "register_operand")
23395 (unspec:XF [(match_operand:XF 1 "register_operand")]
23397 (clobber (reg:CC FLAGS_REG))])]
23398 "TARGET_USE_FANCY_MATH_387
23399 && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
23401 (define_expand "<rounding_insn>hf2"
23402 [(parallel [(set (match_operand:HF 0 "register_operand")
23403 (unspec:HF [(match_operand:HF 1 "register_operand")]
23405 (clobber (reg:CC FLAGS_REG))])]
23406 "TARGET_AVX512FP16"
23408 emit_insn (gen_sse4_1_roundhf2 (operands[0], operands[1],
23409 GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
23413 (define_expand "<rounding_insn><mode>2"
23414 [(parallel [(set (match_operand:MODEF 0 "register_operand")
23415 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
23417 (clobber (reg:CC FLAGS_REG))])]
23418 "(TARGET_USE_FANCY_MATH_387
23419 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
23420 || TARGET_MIX_SSE_I387)
23421 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
23422 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
23424 || (ROUND_<ROUNDING> != ROUND_ROUNDEVEN
23425 && (flag_fp_int_builtin_inexact || !flag_trapping_math))))"
23427 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
23429 || (ROUND_<ROUNDING> != ROUND_ROUNDEVEN
23430 && (flag_fp_int_builtin_inexact || !flag_trapping_math))))
23433 emit_insn (gen_sse4_1_round<mode>2
23434 (operands[0], operands[1],
23435 GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
23436 else if (TARGET_64BIT || (<MODE>mode != DFmode))
23438 if (ROUND_<ROUNDING> == ROUND_FLOOR)
23439 ix86_expand_floorceil (operands[0], operands[1], true);
23440 else if (ROUND_<ROUNDING> == ROUND_CEIL)
23441 ix86_expand_floorceil (operands[0], operands[1], false);
23442 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
23443 ix86_expand_trunc (operands[0], operands[1]);
23445 gcc_unreachable ();
23449 if (ROUND_<ROUNDING> == ROUND_FLOOR)
23450 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
23451 else if (ROUND_<ROUNDING> == ROUND_CEIL)
23452 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
23453 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
23454 ix86_expand_truncdf_32 (operands[0], operands[1]);
23456 gcc_unreachable ();
23461 rtx op0 = gen_reg_rtx (XFmode);
23462 rtx op1 = gen_reg_rtx (XFmode);
23464 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
23465 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
23466 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
23471 ;; Rounding mode control word calculation could clobber FLAGS_REG.
23472 (define_insn_and_split "*fist<mode>2_<rounding>_1"
23473 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
23474 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
23476 (clobber (reg:CC FLAGS_REG))]
23477 "TARGET_USE_FANCY_MATH_387
23478 && flag_unsafe_math_optimizations
23479 && ix86_pre_reload_split ()"
23484 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
23486 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
23487 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
23489 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
23490 operands[2], operands[3]));
23493 [(set_attr "type" "fistp")
23494 (set_attr "i387_cw" "<rounding>")
23495 (set_attr "mode" "<MODE>")])
23497 (define_insn "fistdi2_<rounding>"
23498 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
23499 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
23501 (use (match_operand:HI 2 "memory_operand" "m"))
23502 (use (match_operand:HI 3 "memory_operand" "m"))
23503 (clobber (match_scratch:XF 4 "=&f"))]
23504 "TARGET_USE_FANCY_MATH_387
23505 && flag_unsafe_math_optimizations"
23506 "* return output_fix_trunc (insn, operands, false);"
23507 [(set_attr "type" "fistp")
23508 (set_attr "i387_cw" "<rounding>")
23509 (set_attr "mode" "DI")])
23511 (define_insn "fist<mode>2_<rounding>"
23512 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
23513 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
23515 (use (match_operand:HI 2 "memory_operand" "m"))
23516 (use (match_operand:HI 3 "memory_operand" "m"))]
23517 "TARGET_USE_FANCY_MATH_387
23518 && flag_unsafe_math_optimizations"
23519 "* return output_fix_trunc (insn, operands, false);"
23520 [(set_attr "type" "fistp")
23521 (set_attr "i387_cw" "<rounding>")
23522 (set_attr "mode" "<MODE>")])
23524 (define_expand "l<rounding_insn>xf<mode>2"
23525 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
23526 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
23528 (clobber (reg:CC FLAGS_REG))])]
23529 "TARGET_USE_FANCY_MATH_387
23530 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
23531 && flag_unsafe_math_optimizations")
23533 (define_expand "l<rounding_insn>hf<mode>2"
23534 [(set (match_operand:SWI48 0 "nonimmediate_operand")
23535 (unspec:SWI48 [(match_operand:HF 1 "register_operand")]
23537 "TARGET_AVX512FP16"
23539 rtx tmp = gen_reg_rtx (HFmode);
23540 emit_insn (gen_sse4_1_roundhf2 (tmp, operands[1],
23541 GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
23542 emit_insn (gen_fix_trunchf<mode>2 (operands[0], tmp));
23546 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
23547 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
23548 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
23550 (clobber (reg:CC FLAGS_REG))])]
23551 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
23552 && (TARGET_SSE4_1 || !flag_trapping_math)"
23556 rtx tmp = gen_reg_rtx (<MODEF:MODE>mode);
23558 emit_insn (gen_sse4_1_round<MODEF:mode>2
23559 (tmp, operands[1], GEN_INT (ROUND_<ROUNDING>
23561 emit_insn (gen_fix_trunc<MODEF:mode><SWI48:mode>2
23562 (operands[0], tmp));
23564 else if (ROUND_<ROUNDING> == ROUND_FLOOR)
23565 ix86_expand_lfloorceil (operands[0], operands[1], true);
23566 else if (ROUND_<ROUNDING> == ROUND_CEIL)
23567 ix86_expand_lfloorceil (operands[0], operands[1], false);
23569 gcc_unreachable ();
23574 (define_insn "fxam<mode>2_i387"
23575 [(set (match_operand:HI 0 "register_operand" "=a")
23577 [(match_operand:X87MODEF 1 "register_operand" "f")]
23579 "TARGET_USE_FANCY_MATH_387"
23580 "fxam\n\tfnstsw\t%0"
23581 [(set_attr "type" "multi")
23582 (set_attr "length" "4")
23583 (set_attr "unit" "i387")
23584 (set_attr "mode" "<MODE>")])
23586 (define_expand "signbittf2"
23587 [(use (match_operand:SI 0 "register_operand"))
23588 (use (match_operand:TF 1 "register_operand"))]
23593 rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
23594 rtx scratch = gen_reg_rtx (QImode);
23596 emit_insn (gen_ptesttf2 (operands[1], mask));
23597 ix86_expand_setcc (scratch, NE,
23598 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
23600 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
23604 emit_insn (gen_sse_movmskps (operands[0],
23605 gen_lowpart (V4SFmode, operands[1])));
23606 emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8)));
23611 (define_expand "signbitxf2"
23612 [(use (match_operand:SI 0 "register_operand"))
23613 (use (match_operand:XF 1 "register_operand"))]
23614 "TARGET_USE_FANCY_MATH_387"
23616 rtx scratch = gen_reg_rtx (HImode);
23618 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
23619 emit_insn (gen_andsi3 (operands[0],
23620 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
23624 (define_insn "movmsk_df"
23625 [(set (match_operand:SI 0 "register_operand" "=r,jr")
23627 [(match_operand:DF 1 "register_operand" "x,x")]
23629 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
23630 "%vmovmskpd\t{%1, %0|%0, %1}"
23631 [(set_attr "isa" "noavx,avx")
23632 (set_attr "type" "ssemov")
23633 (set_attr "prefix" "maybe_evex")
23634 (set_attr "mode" "DF")])
23636 ;; Use movmskpd in SSE mode to avoid store forwarding stall
23637 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
23638 (define_expand "signbitdf2"
23639 [(use (match_operand:SI 0 "register_operand"))
23640 (use (match_operand:DF 1 "register_operand"))]
23641 "TARGET_USE_FANCY_MATH_387
23642 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
23644 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
23646 emit_insn (gen_movmsk_df (operands[0], operands[1]));
23647 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
23651 rtx scratch = gen_reg_rtx (HImode);
23653 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
23654 emit_insn (gen_andsi3 (operands[0],
23655 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
23660 (define_expand "signbitsf2"
23661 [(use (match_operand:SI 0 "register_operand"))
23662 (use (match_operand:SF 1 "register_operand"))]
23663 "TARGET_USE_FANCY_MATH_387
23664 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
23666 rtx scratch = gen_reg_rtx (HImode);
23668 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
23669 emit_insn (gen_andsi3 (operands[0],
23670 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
23674 ;; Block operation instructions
23677 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
23680 [(set_attr "length" "1")
23681 (set_attr "length_immediate" "0")
23682 (set_attr "modrm" "0")])
23684 (define_expand "cpymem<mode>"
23685 [(use (match_operand:BLK 0 "memory_operand"))
23686 (use (match_operand:BLK 1 "memory_operand"))
23687 (use (match_operand:SWI48 2 "nonmemory_operand"))
23688 (use (match_operand:SWI48 3 "const_int_operand"))
23689 (use (match_operand:SI 4 "const_int_operand"))
23690 (use (match_operand:SI 5 "const_int_operand"))
23691 (use (match_operand:SI 6 ""))
23692 (use (match_operand:SI 7 ""))
23693 (use (match_operand:SI 8 ""))]
23696 if (ix86_expand_set_or_cpymem (operands[0], operands[1],
23697 operands[2], NULL, operands[3],
23698 operands[4], operands[5],
23699 operands[6], operands[7],
23700 operands[8], false))
23706 ;; Most CPUs don't like single string operations
23707 ;; Handle this case here to simplify previous expander.
23709 (define_expand "strmov"
23710 [(set (match_dup 4) (match_operand 3 "memory_operand"))
23711 (set (match_operand 1 "memory_operand") (match_dup 4))
23712 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
23713 (clobber (reg:CC FLAGS_REG))])
23714 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
23715 (clobber (reg:CC FLAGS_REG))])]
23718 /* Can't use this for non-default address spaces. */
23719 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
23722 int piece_size = GET_MODE_SIZE (GET_MODE (operands[1]));
23724 /* If .md ever supports :P for Pmode, these can be directly
23725 in the pattern above. */
23726 operands[5] = plus_constant (Pmode, operands[0], piece_size);
23727 operands[6] = plus_constant (Pmode, operands[2], piece_size);
23729 /* Can't use this if the user has appropriated esi or edi. */
23730 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
23731 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
23733 emit_insn (gen_strmov_singleop (operands[0], operands[1],
23734 operands[2], operands[3],
23735 operands[5], operands[6]));
23739 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
23742 (define_expand "strmov_singleop"
23743 [(parallel [(set (match_operand 1 "memory_operand")
23744 (match_operand 3 "memory_operand"))
23745 (set (match_operand 0 "register_operand")
23747 (set (match_operand 2 "register_operand")
23748 (match_operand 5))])]
23752 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
23755 (define_insn "*strmovdi_rex_1"
23756 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
23757 (mem:DI (match_operand:P 3 "register_operand" "1")))
23758 (set (match_operand:P 0 "register_operand" "=D")
23759 (plus:P (match_dup 2)
23761 (set (match_operand:P 1 "register_operand" "=S")
23762 (plus:P (match_dup 3)
23765 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
23766 && ix86_check_no_addr_space (insn)"
23768 [(set_attr "type" "str")
23769 (set_attr "memory" "both")
23770 (set_attr "mode" "DI")])
23772 (define_insn "*strmovsi_1"
23773 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
23774 (mem:SI (match_operand:P 3 "register_operand" "1")))
23775 (set (match_operand:P 0 "register_operand" "=D")
23776 (plus:P (match_dup 2)
23778 (set (match_operand:P 1 "register_operand" "=S")
23779 (plus:P (match_dup 3)
23781 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
23782 && ix86_check_no_addr_space (insn)"
23784 [(set_attr "type" "str")
23785 (set_attr "memory" "both")
23786 (set_attr "mode" "SI")])
23788 (define_insn "*strmovhi_1"
23789 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
23790 (mem:HI (match_operand:P 3 "register_operand" "1")))
23791 (set (match_operand:P 0 "register_operand" "=D")
23792 (plus:P (match_dup 2)
23794 (set (match_operand:P 1 "register_operand" "=S")
23795 (plus:P (match_dup 3)
23797 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
23798 && ix86_check_no_addr_space (insn)"
23800 [(set_attr "type" "str")
23801 (set_attr "memory" "both")
23802 (set_attr "mode" "HI")])
23804 (define_insn "*strmovqi_1"
23805 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
23806 (mem:QI (match_operand:P 3 "register_operand" "1")))
23807 (set (match_operand:P 0 "register_operand" "=D")
23808 (plus:P (match_dup 2)
23810 (set (match_operand:P 1 "register_operand" "=S")
23811 (plus:P (match_dup 3)
23813 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
23814 && ix86_check_no_addr_space (insn)"
23816 [(set_attr "type" "str")
23817 (set_attr "memory" "both")
23818 (set (attr "prefix_rex")
23820 (match_test "<P:MODE>mode == DImode")
23822 (const_string "*")))
23823 (set_attr "mode" "QI")])
23825 (define_expand "rep_mov"
23826 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
23827 (set (match_operand 0 "register_operand")
23829 (set (match_operand 2 "register_operand")
23831 (set (match_operand 1 "memory_operand")
23832 (match_operand 3 "memory_operand"))
23833 (use (match_dup 4))])]
23837 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
23840 (define_insn "*rep_movdi_rex64"
23841 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
23842 (set (match_operand:P 0 "register_operand" "=D")
23843 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
23845 (match_operand:P 3 "register_operand" "0")))
23846 (set (match_operand:P 1 "register_operand" "=S")
23847 (plus:P (ashift:P (match_dup 5) (const_int 3))
23848 (match_operand:P 4 "register_operand" "1")))
23849 (set (mem:BLK (match_dup 3))
23850 (mem:BLK (match_dup 4)))
23851 (use (match_dup 5))]
23853 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
23854 && ix86_check_no_addr_space (insn)"
23856 [(set_attr "type" "str")
23857 (set_attr "prefix_rep" "1")
23858 (set_attr "memory" "both")
23859 (set_attr "mode" "DI")])
23861 (define_insn "*rep_movsi"
23862 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
23863 (set (match_operand:P 0 "register_operand" "=D")
23864 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
23866 (match_operand:P 3 "register_operand" "0")))
23867 (set (match_operand:P 1 "register_operand" "=S")
23868 (plus:P (ashift:P (match_dup 5) (const_int 2))
23869 (match_operand:P 4 "register_operand" "1")))
23870 (set (mem:BLK (match_dup 3))
23871 (mem:BLK (match_dup 4)))
23872 (use (match_dup 5))]
23873 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
23874 && ix86_check_no_addr_space (insn)"
23875 "%^rep{%;} movs{l|d}"
23876 [(set_attr "type" "str")
23877 (set_attr "prefix_rep" "1")
23878 (set_attr "memory" "both")
23879 (set_attr "mode" "SI")])
23881 (define_insn "*rep_movqi"
23882 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
23883 (set (match_operand:P 0 "register_operand" "=D")
23884 (plus:P (match_operand:P 3 "register_operand" "0")
23885 (match_operand:P 5 "register_operand" "2")))
23886 (set (match_operand:P 1 "register_operand" "=S")
23887 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
23888 (set (mem:BLK (match_dup 3))
23889 (mem:BLK (match_dup 4)))
23890 (use (match_dup 5))]
23891 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
23892 && ix86_check_no_addr_space (insn)"
23894 [(set_attr "type" "str")
23895 (set_attr "prefix_rep" "1")
23896 (set_attr "memory" "both")
23897 (set_attr "mode" "QI")])
23899 (define_expand "setmem<mode>"
23900 [(use (match_operand:BLK 0 "memory_operand"))
23901 (use (match_operand:SWI48 1 "nonmemory_operand"))
23902 (use (match_operand:QI 2 "nonmemory_operand"))
23903 (use (match_operand 3 "const_int_operand"))
23904 (use (match_operand:SI 4 "const_int_operand"))
23905 (use (match_operand:SI 5 "const_int_operand"))
23906 (use (match_operand:SI 6 ""))
23907 (use (match_operand:SI 7 ""))
23908 (use (match_operand:SI 8 ""))]
23911 if (ix86_expand_set_or_cpymem (operands[0], NULL,
23912 operands[1], operands[2],
23913 operands[3], operands[4],
23914 operands[5], operands[6],
23915 operands[7], operands[8], true))
23921 ;; Most CPUs don't like single string operations
23922 ;; Handle this case here to simplify previous expander.
23924 (define_expand "strset"
23925 [(set (match_operand 1 "memory_operand")
23926 (match_operand 2 "register_operand"))
23927 (parallel [(set (match_operand 0 "register_operand")
23929 (clobber (reg:CC FLAGS_REG))])]
23932 /* Can't use this for non-default address spaces. */
23933 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
23936 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
23937 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
23939 /* If .md ever supports :P for Pmode, this can be directly
23940 in the pattern above. */
23941 operands[3] = plus_constant (Pmode, operands[0],
23942 GET_MODE_SIZE (GET_MODE (operands[2])));
23944 /* Can't use this if the user has appropriated eax or edi. */
23945 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
23946 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
23948 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
23954 (define_expand "strset_singleop"
23955 [(parallel [(set (match_operand 1 "memory_operand")
23956 (match_operand 2 "register_operand"))
23957 (set (match_operand 0 "register_operand")
23959 (unspec [(const_int 0)] UNSPEC_STOS)])]
23963 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
23966 (define_insn "*strsetdi_rex_1"
23967 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
23968 (match_operand:DI 2 "register_operand" "a"))
23969 (set (match_operand:P 0 "register_operand" "=D")
23970 (plus:P (match_dup 1)
23972 (unspec [(const_int 0)] UNSPEC_STOS)]
23974 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
23975 && ix86_check_no_addr_space (insn)"
23977 [(set_attr "type" "str")
23978 (set_attr "memory" "store")
23979 (set_attr "mode" "DI")])
23981 (define_insn "*strsetsi_1"
23982 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
23983 (match_operand:SI 2 "register_operand" "a"))
23984 (set (match_operand:P 0 "register_operand" "=D")
23985 (plus:P (match_dup 1)
23987 (unspec [(const_int 0)] UNSPEC_STOS)]
23988 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
23989 && ix86_check_no_addr_space (insn)"
23991 [(set_attr "type" "str")
23992 (set_attr "memory" "store")
23993 (set_attr "mode" "SI")])
23995 (define_insn "*strsethi_1"
23996 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
23997 (match_operand:HI 2 "register_operand" "a"))
23998 (set (match_operand:P 0 "register_operand" "=D")
23999 (plus:P (match_dup 1)
24001 (unspec [(const_int 0)] UNSPEC_STOS)]
24002 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
24003 && ix86_check_no_addr_space (insn)"
24005 [(set_attr "type" "str")
24006 (set_attr "memory" "store")
24007 (set_attr "mode" "HI")])
24009 (define_insn "*strsetqi_1"
24010 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
24011 (match_operand:QI 2 "register_operand" "a"))
24012 (set (match_operand:P 0 "register_operand" "=D")
24013 (plus:P (match_dup 1)
24015 (unspec [(const_int 0)] UNSPEC_STOS)]
24016 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
24017 && ix86_check_no_addr_space (insn)"
24019 [(set_attr "type" "str")
24020 (set_attr "memory" "store")
24021 (set (attr "prefix_rex")
24023 (match_test "<P:MODE>mode == DImode")
24025 (const_string "*")))
24026 (set_attr "mode" "QI")])
24028 (define_expand "rep_stos"
24029 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
24030 (set (match_operand 0 "register_operand")
24032 (set (match_operand 2 "memory_operand") (const_int 0))
24033 (use (match_operand 3 "register_operand"))
24034 (use (match_dup 1))])]
24038 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
24041 (define_insn "*rep_stosdi_rex64"
24042 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
24043 (set (match_operand:P 0 "register_operand" "=D")
24044 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
24046 (match_operand:P 3 "register_operand" "0")))
24047 (set (mem:BLK (match_dup 3))
24049 (use (match_operand:DI 2 "register_operand" "a"))
24050 (use (match_dup 4))]
24052 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
24053 && ix86_check_no_addr_space (insn)"
24055 [(set_attr "type" "str")
24056 (set_attr "prefix_rep" "1")
24057 (set_attr "memory" "store")
24058 (set_attr "mode" "DI")])
24060 (define_insn "*rep_stossi"
24061 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
24062 (set (match_operand:P 0 "register_operand" "=D")
24063 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
24065 (match_operand:P 3 "register_operand" "0")))
24066 (set (mem:BLK (match_dup 3))
24068 (use (match_operand:SI 2 "register_operand" "a"))
24069 (use (match_dup 4))]
24070 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
24071 && ix86_check_no_addr_space (insn)"
24072 "%^rep{%;} stos{l|d}"
24073 [(set_attr "type" "str")
24074 (set_attr "prefix_rep" "1")
24075 (set_attr "memory" "store")
24076 (set_attr "mode" "SI")])
24078 (define_insn "*rep_stosqi"
24079 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
24080 (set (match_operand:P 0 "register_operand" "=D")
24081 (plus:P (match_operand:P 3 "register_operand" "0")
24082 (match_operand:P 4 "register_operand" "1")))
24083 (set (mem:BLK (match_dup 3))
24085 (use (match_operand:QI 2 "register_operand" "a"))
24086 (use (match_dup 4))]
24087 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
24088 && ix86_check_no_addr_space (insn)"
24090 [(set_attr "type" "str")
24091 (set_attr "prefix_rep" "1")
24092 (set_attr "memory" "store")
24093 (set (attr "prefix_rex")
24095 (match_test "<P:MODE>mode == DImode")
24097 (const_string "*")))
24098 (set_attr "mode" "QI")])
24100 (define_expand "cmpmemsi"
24101 [(set (match_operand:SI 0 "register_operand" "")
24102 (compare:SI (match_operand:BLK 1 "memory_operand" "")
24103 (match_operand:BLK 2 "memory_operand" "") ) )
24104 (use (match_operand 3 "general_operand"))
24105 (use (match_operand 4 "immediate_operand"))]
24108 if (ix86_expand_cmpstrn_or_cmpmem (operands[0], operands[1],
24109 operands[2], operands[3],
24110 operands[4], false))
24116 (define_expand "cmpstrnsi"
24117 [(set (match_operand:SI 0 "register_operand")
24118 (compare:SI (match_operand:BLK 1 "general_operand")
24119 (match_operand:BLK 2 "general_operand")))
24120 (use (match_operand 3 "general_operand"))
24121 (use (match_operand 4 "immediate_operand"))]
24124 if (ix86_expand_cmpstrn_or_cmpmem (operands[0], operands[1],
24125 operands[2], operands[3],
24126 operands[4], true))
24132 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
24134 (define_expand "cmpintqi"
24135 [(set (match_dup 1)
24136 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
24138 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
24139 (parallel [(set (match_operand:QI 0 "register_operand")
24140 (minus:QI (match_dup 1)
24142 (clobber (reg:CC FLAGS_REG))])]
24145 operands[1] = gen_reg_rtx (QImode);
24146 operands[2] = gen_reg_rtx (QImode);
24149 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
24150 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
24152 (define_expand "cmpstrnqi_nz_1"
24153 [(parallel [(set (reg:CC FLAGS_REG)
24154 (compare:CC (match_operand 4 "memory_operand")
24155 (match_operand 5 "memory_operand")))
24156 (use (match_operand 2 "register_operand"))
24157 (use (match_operand:SI 3 "immediate_operand"))
24158 (clobber (match_operand 0 "register_operand"))
24159 (clobber (match_operand 1 "register_operand"))
24160 (clobber (match_dup 2))])]
24164 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
24167 (define_insn "*cmpstrnqi_nz_1"
24168 [(set (reg:CC FLAGS_REG)
24169 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
24170 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
24171 (use (match_operand:P 6 "register_operand" "2"))
24172 (use (match_operand:SI 3 "immediate_operand" "i"))
24173 (clobber (match_operand:P 0 "register_operand" "=S"))
24174 (clobber (match_operand:P 1 "register_operand" "=D"))
24175 (clobber (match_operand:P 2 "register_operand" "=c"))]
24176 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
24177 && ix86_check_no_addr_space (insn)"
24179 [(set_attr "type" "str")
24180 (set_attr "mode" "QI")
24181 (set (attr "prefix_rex")
24183 (match_test "<P:MODE>mode == DImode")
24185 (const_string "*")))
24186 (set_attr "prefix_rep" "1")])
24188 ;; The same, but the count is not known to not be zero.
24190 (define_expand "cmpstrnqi_1"
24191 [(parallel [(set (reg:CC FLAGS_REG)
24192 (if_then_else:CC (ne (match_operand 2 "register_operand")
24194 (compare:CC (match_operand 4 "memory_operand")
24195 (match_operand 5 "memory_operand"))
24196 (reg:CC FLAGS_REG)))
24197 (use (match_operand:SI 3 "immediate_operand"))
24198 (clobber (match_operand 0 "register_operand"))
24199 (clobber (match_operand 1 "register_operand"))
24200 (clobber (match_dup 2))])]
24204 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
24207 (define_insn "*cmpstrnqi_1"
24208 [(set (reg:CC FLAGS_REG)
24209 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
24211 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
24212 (mem:BLK (match_operand:P 5 "register_operand" "1")))
24213 (reg:CC FLAGS_REG)))
24214 (use (match_operand:SI 3 "immediate_operand" "i"))
24215 (clobber (match_operand:P 0 "register_operand" "=S"))
24216 (clobber (match_operand:P 1 "register_operand" "=D"))
24217 (clobber (match_operand:P 2 "register_operand" "=c"))]
24218 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
24219 && ix86_check_no_addr_space (insn)"
24221 [(set_attr "type" "str")
24222 (set_attr "mode" "QI")
24223 (set (attr "prefix_rex")
24225 (match_test "<P:MODE>mode == DImode")
24227 (const_string "*")))
24228 (set_attr "prefix_rep" "1")])
24230 (define_expand "strlen<mode>"
24231 [(set (match_operand:P 0 "register_operand")
24232 (unspec:P [(match_operand:BLK 1 "general_operand")
24233 (match_operand:QI 2 "immediate_operand")
24234 (match_operand 3 "immediate_operand")]
24238 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
24244 (define_expand "strlenqi_1"
24245 [(parallel [(set (match_operand 0 "register_operand")
24247 (clobber (match_operand 1 "register_operand"))
24248 (clobber (reg:CC FLAGS_REG))])]
24252 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
24255 (define_insn "*strlenqi_1"
24256 [(set (match_operand:P 0 "register_operand" "=&c")
24257 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
24258 (match_operand:QI 2 "register_operand" "a")
24259 (match_operand:P 3 "immediate_operand" "i")
24260 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
24261 (clobber (match_operand:P 1 "register_operand" "=D"))
24262 (clobber (reg:CC FLAGS_REG))]
24263 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
24264 && ix86_check_no_addr_space (insn)"
24265 "%^repnz{%;} scasb"
24266 [(set_attr "type" "str")
24267 (set_attr "mode" "QI")
24268 (set (attr "prefix_rex")
24270 (match_test "<P:MODE>mode == DImode")
24272 (const_string "*")))
24273 (set_attr "prefix_rep" "1")])
24275 ;; Peephole optimizations to clean up after cmpstrn*. This should be
24276 ;; handled in combine, but it is not currently up to the task.
24277 ;; When used for their truth value, the cmpstrn* expanders generate
24286 ;; The intermediate three instructions are unnecessary.
24288 ;; This one handles cmpstrn*_nz_1...
24291 (set (reg:CC FLAGS_REG)
24292 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
24293 (mem:BLK (match_operand 5 "register_operand"))))
24294 (use (match_operand 6 "register_operand"))
24295 (use (match_operand:SI 3 "immediate_operand"))
24296 (clobber (match_operand 0 "register_operand"))
24297 (clobber (match_operand 1 "register_operand"))
24298 (clobber (match_operand 2 "register_operand"))])
24299 (set (match_operand:QI 7 "register_operand")
24300 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
24301 (set (match_operand:QI 8 "register_operand")
24302 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
24303 (set (reg FLAGS_REG)
24304 (compare (match_dup 7) (match_dup 8)))
24306 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
24308 (set (reg:CC FLAGS_REG)
24309 (compare:CC (mem:BLK (match_dup 4))
24310 (mem:BLK (match_dup 5))))
24311 (use (match_dup 6))
24312 (use (match_dup 3))
24313 (clobber (match_dup 0))
24314 (clobber (match_dup 1))
24315 (clobber (match_dup 2))])])
24317 ;; ...and this one handles cmpstrn*_1.
24320 (set (reg:CC FLAGS_REG)
24321 (if_then_else:CC (ne (match_operand 6 "register_operand")
24323 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
24324 (mem:BLK (match_operand 5 "register_operand")))
24325 (reg:CC FLAGS_REG)))
24326 (use (match_operand:SI 3 "immediate_operand"))
24327 (clobber (match_operand 0 "register_operand"))
24328 (clobber (match_operand 1 "register_operand"))
24329 (clobber (match_operand 2 "register_operand"))])
24330 (set (match_operand:QI 7 "register_operand")
24331 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
24332 (set (match_operand:QI 8 "register_operand")
24333 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
24334 (set (reg FLAGS_REG)
24335 (compare (match_dup 7) (match_dup 8)))
24337 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
24339 (set (reg:CC FLAGS_REG)
24340 (if_then_else:CC (ne (match_dup 6)
24342 (compare:CC (mem:BLK (match_dup 4))
24343 (mem:BLK (match_dup 5)))
24344 (reg:CC FLAGS_REG)))
24345 (use (match_dup 3))
24346 (clobber (match_dup 0))
24347 (clobber (match_dup 1))
24348 (clobber (match_dup 2))])])
24350 ;; Conditional move instructions.
24352 (define_expand "mov<mode>cc"
24353 [(set (match_operand:SWIM 0 "register_operand")
24354 (if_then_else:SWIM (match_operand 1 "comparison_operator")
24355 (match_operand:SWIM 2 "<general_operand>")
24356 (match_operand:SWIM 3 "<general_operand>")))]
24358 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
24360 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
24361 ;; the register first winds up with `sbbl $0,reg', which is also weird.
24362 ;; So just document what we're doing explicitly.
24364 (define_expand "x86_mov<mode>cc_0_m1"
24366 [(set (match_operand:SWI48 0 "register_operand")
24367 (if_then_else:SWI48
24368 (match_operator:SWI48 2 "ix86_carry_flag_operator"
24369 [(match_operand 1 "flags_reg_operand")
24373 (clobber (reg:CC FLAGS_REG))])])
24375 (define_insn "*x86_mov<mode>cc_0_m1"
24376 [(set (match_operand:SWI48 0 "register_operand" "=r")
24377 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
24378 [(reg FLAGS_REG) (const_int 0)])
24381 (clobber (reg:CC FLAGS_REG))]
24383 "sbb{<imodesuffix>}\t%0, %0"
24384 [(set_attr "type" "alu1")
24385 (set_attr "use_carry" "1")
24386 (set_attr "pent_pair" "pu")
24387 (set_attr "mode" "<MODE>")
24388 (set_attr "length_immediate" "0")])
24390 (define_insn "*x86_mov<mode>cc_0_m1_se"
24391 [(set (match_operand:SWI48 0 "register_operand" "=r")
24392 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
24393 [(reg FLAGS_REG) (const_int 0)])
24396 (clobber (reg:CC FLAGS_REG))]
24398 "sbb{<imodesuffix>}\t%0, %0"
24399 [(set_attr "type" "alu1")
24400 (set_attr "use_carry" "1")
24401 (set_attr "pent_pair" "pu")
24402 (set_attr "mode" "<MODE>")
24403 (set_attr "length_immediate" "0")])
24405 (define_insn "*x86_mov<mode>cc_0_m1_neg"
24406 [(set (match_operand:SWI 0 "register_operand" "=<r>")
24407 (neg:SWI (match_operator 1 "ix86_carry_flag_operator"
24408 [(reg FLAGS_REG) (const_int 0)])))
24409 (clobber (reg:CC FLAGS_REG))]
24411 "sbb{<imodesuffix>}\t%0, %0"
24412 [(set_attr "type" "alu1")
24413 (set_attr "use_carry" "1")
24414 (set_attr "pent_pair" "pu")
24415 (set_attr "mode" "<MODE>")
24416 (set_attr "length_immediate" "0")])
24418 (define_expand "x86_mov<mode>cc_0_m1_neg"
24420 [(set (match_operand:SWI48 0 "register_operand")
24421 (neg:SWI48 (ltu:SWI48 (reg:CCC FLAGS_REG) (const_int 0))))
24422 (clobber (reg:CC FLAGS_REG))])])
24425 [(set (match_operand:SWI48 0 "register_operand")
24428 (match_operand 1 "int_nonimmediate_operand")
24429 (match_operand 2 "const_int_operand"))))]
24430 "x86_64_immediate_operand (operands[2], VOIDmode)
24431 && INTVAL (operands[2]) != -1
24432 && INTVAL (operands[2]) != 2147483647"
24433 [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
24435 (neg:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))))]
24436 "operands[2] = GEN_INT (INTVAL (operands[2]) + 1);")
24439 [(set (match_operand:SWI 0 "register_operand")
24442 (match_operand 1 "int_nonimmediate_operand")
24445 [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (const_int 1)))
24447 (neg:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))))])
24450 [(set (match_operand:SWI 0 "register_operand")
24453 (match_operand 1 "int_nonimmediate_operand")
24456 [(set (reg:CCC FLAGS_REG)
24457 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
24459 (neg:SWI (ltu:SWI (reg:CCC FLAGS_REG) (const_int 0))))])
24461 (define_insn "*mov<mode>cc_noc"
24462 [(set (match_operand:SWI248 0 "register_operand" "=r,r,r,r")
24463 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
24464 [(reg FLAGS_REG) (const_int 0)])
24465 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0,rm,r")
24466 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm,r,rm")))]
24467 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
24469 cmov%O2%C1\t{%2, %0|%0, %2}
24470 cmov%O2%c1\t{%3, %0|%0, %3}
24471 cmov%O2%C1\t{%2, %3, %0|%0, %3, %2}
24472 cmov%O2%c1\t{%3, %2, %0|%0, %2, %3}"
24473 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
24474 (set_attr "type" "icmov")
24475 (set_attr "mode" "<MODE>")])
24477 (define_insn "*movsicc_noc_zext"
24478 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
24479 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
24480 [(reg FLAGS_REG) (const_int 0)])
24482 (match_operand:SI 2 "nonimmediate_operand" "rm,0,rm,r"))
24484 (match_operand:SI 3 "nonimmediate_operand" "0,rm,r,rm"))))]
24486 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
24488 cmov%O2%C1\t{%2, %k0|%k0, %2}
24489 cmov%O2%c1\t{%3, %k0|%k0, %3}
24490 cmov%O2%C1\t{%2, %3, %k0|%k0, %3, %2}
24491 cmov%O2%c1\t{%3, %2, %k0|%k0, %2, %3}"
24492 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
24493 (set_attr "type" "icmov")
24494 (set_attr "mode" "SI")])
24496 (define_insn "*movsicc_noc_zext_1"
24497 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r")
24499 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
24500 [(reg FLAGS_REG) (const_int 0)])
24501 (match_operand:SI 2 "nonimmediate_operand" "rm,0,rm,r")
24502 (match_operand:SI 3 "nonimmediate_operand" "0,rm,r,rm"))))]
24504 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
24506 cmov%O2%C1\t{%2, %k0|%k0, %2}
24507 cmov%O2%c1\t{%3, %k0|%k0, %3}
24508 cmov%O2%C1\t{%2, %3, %k0|%k0, %3, %2}
24509 cmov%O2%c1\t{%3, %2, %k0|%k0, %2, %3}"
24510 [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
24511 (set_attr "type" "icmov")
24512 (set_attr "mode" "SI")])
24515 ;; Don't do conditional moves with memory inputs. This splitter helps
24516 ;; register starved x86_32 by forcing inputs into registers before reload.
24518 [(set (match_operand:SWI248 0 "register_operand")
24519 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
24520 [(reg FLAGS_REG) (const_int 0)])
24521 (match_operand:SWI248 2 "nonimmediate_operand")
24522 (match_operand:SWI248 3 "nonimmediate_operand")))]
24523 "!TARGET_64BIT && TARGET_CMOVE
24524 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
24525 && (MEM_P (operands[2]) || MEM_P (operands[3]))
24526 && can_create_pseudo_p ()
24527 && optimize_insn_for_speed_p ()"
24528 [(set (match_dup 0)
24529 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
24531 operands[2] = force_reg (<MODE>mode, operands[2]);
24532 operands[3] = force_reg (<MODE>mode, operands[3]);
24535 (define_insn "*movqicc_noc"
24536 [(set (match_operand:QI 0 "register_operand" "=r,r,r")
24537 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
24538 [(reg FLAGS_REG) (const_int 0)])
24539 (match_operand:QI 2 "register_operand" "r,0,r")
24540 (match_operand:QI 3 "register_operand" "0,r,r")))]
24541 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
24543 [(set_attr "isa" "*,*,apx_ndd")
24544 (set_attr "type" "icmov")
24545 (set_attr "mode" "QI")])
24548 [(set (match_operand:SWI12 0 "register_operand")
24549 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
24550 [(reg FLAGS_REG) (const_int 0)])
24551 (match_operand:SWI12 2 "register_operand")
24552 (match_operand:SWI12 3 "register_operand")))]
24553 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
24554 && reload_completed"
24555 [(set (match_dup 0)
24556 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
24558 operands[0] = gen_lowpart (SImode, operands[0]);
24559 operands[2] = gen_lowpart (SImode, operands[2]);
24560 operands[3] = gen_lowpart (SImode, operands[3]);
24563 ;; Don't do conditional moves with memory inputs
24565 [(match_scratch:SWI248 4 "r")
24566 (set (match_operand:SWI248 0 "register_operand")
24567 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
24568 [(reg FLAGS_REG) (const_int 0)])
24569 (match_operand:SWI248 2 "nonimmediate_operand")
24570 (match_operand:SWI248 3 "nonimmediate_operand")))]
24571 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
24572 && (MEM_P (operands[2]) || MEM_P (operands[3]))
24573 && optimize_insn_for_speed_p ()"
24574 [(set (match_dup 4) (match_dup 5))
24576 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
24578 if (MEM_P (operands[2]))
24580 operands[5] = operands[2];
24581 operands[2] = operands[4];
24583 else if (MEM_P (operands[3]))
24585 operands[5] = operands[3];
24586 operands[3] = operands[4];
24589 gcc_unreachable ();
24593 [(match_scratch:SI 4 "r")
24594 (set (match_operand:DI 0 "register_operand")
24595 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
24596 [(reg FLAGS_REG) (const_int 0)])
24598 (match_operand:SI 2 "nonimmediate_operand"))
24600 (match_operand:SI 3 "nonimmediate_operand"))))]
24602 && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
24603 && (MEM_P (operands[2]) || MEM_P (operands[3]))
24604 && optimize_insn_for_speed_p ()"
24605 [(set (match_dup 4) (match_dup 5))
24607 (if_then_else:DI (match_dup 1)
24608 (zero_extend:DI (match_dup 2))
24609 (zero_extend:DI (match_dup 3))))]
24611 if (MEM_P (operands[2]))
24613 operands[5] = operands[2];
24614 operands[2] = operands[4];
24616 else if (MEM_P (operands[3]))
24618 operands[5] = operands[3];
24619 operands[3] = operands[4];
24622 gcc_unreachable ();
24625 ;; Eliminate a reg-reg mov by inverting the condition of a cmov (#1).
24626 ;; mov r0,r1; dec r0; mov r2,r3; cmov r0,r2 -> dec r1; mov r0,r3; cmov r0, r1
24628 [(set (match_operand:SWI248 0 "general_reg_operand")
24629 (match_operand:SWI248 1 "general_reg_operand"))
24630 (parallel [(set (reg FLAGS_REG) (match_operand 5))
24631 (set (match_dup 0) (match_operand:SWI248 6))])
24632 (set (match_operand:SWI248 2 "general_reg_operand")
24633 (match_operand:SWI248 3 "general_gr_operand"))
24635 (if_then_else:SWI248 (match_operator 4 "ix86_comparison_operator"
24636 [(reg FLAGS_REG) (const_int 0)])
24640 && REGNO (operands[2]) != REGNO (operands[0])
24641 && REGNO (operands[2]) != REGNO (operands[1])
24642 && peep2_reg_dead_p (1, operands[1])
24643 && peep2_reg_dead_p (4, operands[2])
24644 && !reg_overlap_mentioned_p (operands[0], operands[3])"
24645 [(parallel [(set (match_dup 7) (match_dup 8))
24646 (set (match_dup 1) (match_dup 9))])
24647 (set (match_dup 0) (match_dup 3))
24648 (set (match_dup 0) (if_then_else:SWI248 (match_dup 4)
24652 operands[7] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
24654 = ix86_replace_reg_with_reg (operands[5], operands[0], operands[1]);
24656 = ix86_replace_reg_with_reg (operands[6], operands[0], operands[1]);
24659 ;; Eliminate a reg-reg mov by inverting the condition of a cmov (#2).
24660 ;; mov r2,r3; mov r0,r1; dec r0; cmov r0,r2 -> dec r1; mov r0,r3; cmov r0, r1
24662 [(set (match_operand:SWI248 2 "general_reg_operand")
24663 (match_operand:SWI248 3 "general_gr_operand"))
24664 (set (match_operand:SWI248 0 "general_reg_operand")
24665 (match_operand:SWI248 1 "general_reg_operand"))
24666 (parallel [(set (reg FLAGS_REG) (match_operand 5))
24667 (set (match_dup 0) (match_operand:SWI248 6))])
24669 (if_then_else:SWI248 (match_operator 4 "ix86_comparison_operator"
24670 [(reg FLAGS_REG) (const_int 0)])
24674 && REGNO (operands[2]) != REGNO (operands[0])
24675 && REGNO (operands[2]) != REGNO (operands[1])
24676 && peep2_reg_dead_p (2, operands[1])
24677 && peep2_reg_dead_p (4, operands[2])
24678 && !reg_overlap_mentioned_p (operands[0], operands[3])
24679 && !reg_mentioned_p (operands[2], operands[6])"
24680 [(parallel [(set (match_dup 7) (match_dup 8))
24681 (set (match_dup 1) (match_dup 9))])
24682 (set (match_dup 0) (match_dup 3))
24683 (set (match_dup 0) (if_then_else:SWI248 (match_dup 4)
24687 operands[7] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (2)), 0, 0));
24689 = ix86_replace_reg_with_reg (operands[5], operands[0], operands[1]);
24691 = ix86_replace_reg_with_reg (operands[6], operands[0], operands[1]);
24694 (define_insn "movhf_mask"
24695 [(set (match_operand:HF 0 "nonimmediate_operand" "=v,m,v")
24697 [(match_operand:HF 1 "nonimmediate_operand" "m,v,v")
24698 (match_operand:HF 2 "nonimm_or_0_operand" "0C,0C,0C")
24699 (match_operand:QI 3 "register_operand" "Yk,Yk,Yk")]
24700 UNSPEC_MOVCC_MASK))]
24701 "TARGET_AVX512FP16"
24703 vmovsh\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}
24704 vmovsh\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}
24705 vmovsh\t{%d1, %0%{%3%}%N2|%0%{%3%}%N2, %d1}"
24706 [(set_attr "type" "ssemov")
24707 (set_attr "prefix" "evex")
24708 (set_attr "mode" "HF")])
24710 (define_expand "movhfcc"
24711 [(set (match_operand:HF 0 "register_operand")
24713 (match_operand 1 "comparison_operator")
24714 (match_operand:HF 2 "register_operand")
24715 (match_operand:HF 3 "register_operand")))]
24716 "TARGET_AVX512FP16"
24717 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
24719 (define_expand "mov<mode>cc"
24720 [(set (match_operand:X87MODEF 0 "register_operand")
24721 (if_then_else:X87MODEF
24722 (match_operand 1 "comparison_operator")
24723 (match_operand:X87MODEF 2 "register_operand")
24724 (match_operand:X87MODEF 3 "register_operand")))]
24725 "(TARGET_80387 && TARGET_CMOVE)
24726 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
24727 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
24729 (define_insn "*movxfcc_1"
24730 [(set (match_operand:XF 0 "register_operand" "=f,f")
24731 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
24732 [(reg FLAGS_REG) (const_int 0)])
24733 (match_operand:XF 2 "register_operand" "f,0")
24734 (match_operand:XF 3 "register_operand" "0,f")))]
24735 "TARGET_80387 && TARGET_CMOVE"
24737 fcmov%F1\t{%2, %0|%0, %2}
24738 fcmov%f1\t{%3, %0|%0, %3}"
24739 [(set_attr "type" "fcmov")
24740 (set_attr "mode" "XF")])
24742 (define_insn "*movdfcc_1"
24743 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
24744 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
24745 [(reg FLAGS_REG) (const_int 0)])
24746 (match_operand:DF 2 "nonimmediate_operand"
24748 (match_operand:DF 3 "nonimmediate_operand"
24749 "0 ,f,0 ,rm,0, rm")))]
24750 "TARGET_80387 && TARGET_CMOVE
24751 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
24753 fcmov%F1\t{%2, %0|%0, %2}
24754 fcmov%f1\t{%3, %0|%0, %3}
24757 cmov%O2%C1\t{%2, %0|%0, %2}
24758 cmov%O2%c1\t{%3, %0|%0, %3}"
24759 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
24760 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
24761 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
24764 [(set (match_operand:DF 0 "general_reg_operand")
24765 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
24766 [(reg FLAGS_REG) (const_int 0)])
24767 (match_operand:DF 2 "nonimmediate_operand")
24768 (match_operand:DF 3 "nonimmediate_operand")))]
24769 "!TARGET_64BIT && reload_completed"
24770 [(set (match_dup 2)
24771 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
24773 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
24775 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
24776 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
24779 (define_insn "*movsfcc_1_387"
24780 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
24781 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
24782 [(reg FLAGS_REG) (const_int 0)])
24783 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
24784 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
24785 "TARGET_80387 && TARGET_CMOVE
24786 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
24788 fcmov%F1\t{%2, %0|%0, %2}
24789 fcmov%f1\t{%3, %0|%0, %3}
24790 cmov%O2%C1\t{%2, %0|%0, %2}
24791 cmov%O2%c1\t{%3, %0|%0, %3}"
24792 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
24793 (set_attr "mode" "SF,SF,SI,SI")])
24795 ;; Don't do conditional moves with memory inputs. This splitter helps
24796 ;; register starved x86_32 by forcing inputs into registers before reload.
24798 [(set (match_operand:MODEF 0 "register_operand")
24799 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
24800 [(reg FLAGS_REG) (const_int 0)])
24801 (match_operand:MODEF 2 "nonimmediate_operand")
24802 (match_operand:MODEF 3 "nonimmediate_operand")))]
24803 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
24804 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
24805 && (MEM_P (operands[2]) || MEM_P (operands[3]))
24806 && can_create_pseudo_p ()
24807 && optimize_insn_for_speed_p ()"
24808 [(set (match_dup 0)
24809 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
24811 operands[2] = force_reg (<MODE>mode, operands[2]);
24812 operands[3] = force_reg (<MODE>mode, operands[3]);
24815 ;; Don't do conditional moves with memory inputs
24817 [(match_scratch:MODEF 4 "r")
24818 (set (match_operand:MODEF 0 "general_reg_operand")
24819 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
24820 [(reg FLAGS_REG) (const_int 0)])
24821 (match_operand:MODEF 2 "nonimmediate_operand")
24822 (match_operand:MODEF 3 "nonimmediate_operand")))]
24823 "(<MODE>mode != DFmode || TARGET_64BIT)
24824 && TARGET_80387 && TARGET_CMOVE
24825 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
24826 && (MEM_P (operands[2]) || MEM_P (operands[3]))
24827 && optimize_insn_for_speed_p ()"
24828 [(set (match_dup 4) (match_dup 5))
24830 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
24832 if (MEM_P (operands[2]))
24834 operands[5] = operands[2];
24835 operands[2] = operands[4];
24837 else if (MEM_P (operands[3]))
24839 operands[5] = operands[3];
24840 operands[3] = operands[4];
24843 gcc_unreachable ();
24846 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
24847 ;; the scalar versions to have only XMM registers as operands.
24849 ;; XOP conditional move
24850 (define_insn "*xop_pcmov_<mode>"
24851 [(set (match_operand:MODEF 0 "register_operand" "=x")
24852 (if_then_else:MODEF
24853 (match_operand:MODEF 1 "register_operand" "x")
24854 (match_operand:MODEF 2 "register_operand" "x")
24855 (match_operand:MODEF 3 "register_operand" "x")))]
24857 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
24858 [(set_attr "type" "sse4arg")
24859 (set_attr "mode" "TI")])
24861 ;; These versions of the min/max patterns are intentionally ignorant of
24862 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
24863 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
24864 ;; are undefined in this condition, we're certain this is correct.
24866 (define_insn "<code><mode>3"
24867 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
24869 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
24870 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
24871 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
24873 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
24874 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
24875 [(set_attr "isa" "noavx,avx")
24876 (set_attr "prefix" "orig,vex")
24877 (set_attr "type" "sseadd")
24878 (set_attr "mode" "<MODE>")])
24880 (define_insn "<code>hf3"
24881 [(set (match_operand:HF 0 "register_operand" "=v")
24883 (match_operand:HF 1 "nonimmediate_operand" "%v")
24884 (match_operand:HF 2 "nonimmediate_operand" "vm")))]
24885 "TARGET_AVX512FP16"
24886 "v<maxmin_float>sh\t{%2, %1, %0|%0, %1, %2}"
24887 [(set_attr "prefix" "evex")
24888 (set_attr "type" "sseadd")
24889 (set_attr "mode" "HF")])
24891 ;; These versions of the min/max patterns implement exactly the operations
24892 ;; min = (op1 < op2 ? op1 : op2)
24893 ;; max = (!(op1 < op2) ? op1 : op2)
24894 ;; Their operands are not commutative, and thus they may be used in the
24895 ;; presence of -0.0 and NaN.
24897 (define_insn "*ieee_s<ieee_maxmin>hf3"
24898 [(set (match_operand:HF 0 "register_operand" "=v")
24900 [(match_operand:HF 1 "register_operand" "v")
24901 (match_operand:HF 2 "nonimmediate_operand" "vm")]
24903 "TARGET_AVX512FP16"
24904 "v<ieee_maxmin>sh\t{%2, %1, %0|%0, %1, %2}"
24905 [(set_attr "prefix" "evex")
24906 (set_attr "type" "sseadd")
24907 (set_attr "mode" "HF")])
24909 (define_insn "*ieee_s<ieee_maxmin><mode>3"
24910 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
24912 [(match_operand:MODEF 1 "register_operand" "0,v")
24913 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
24915 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
24917 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
24918 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
24919 [(set_attr "isa" "noavx,avx")
24920 (set_attr "prefix" "orig,maybe_evex")
24921 (set_attr "type" "sseadd")
24922 (set_attr "mode" "<MODE>")])
24924 ;; Operands order in min/max instruction matters for signed zero and NANs.
24925 (define_insn_and_split "*ieee_max<mode>3_1"
24926 [(set (match_operand:MODEF 0 "register_operand")
24928 [(match_operand:MODEF 1 "register_operand")
24929 (match_operand:MODEF 2 "register_operand")
24931 (match_operand:MODEF 3 "register_operand")
24932 (match_operand:MODEF 4 "register_operand"))]
24934 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
24935 && (rtx_equal_p (operands[1], operands[3])
24936 && rtx_equal_p (operands[2], operands[4]))
24937 && ix86_pre_reload_split ()"
24940 [(set (match_dup 0)
24944 UNSPEC_IEEE_MAX))])
24946 (define_insn_and_split "*ieee_min<mode>3_1"
24947 [(set (match_operand:MODEF 0 "register_operand")
24949 [(match_operand:MODEF 1 "register_operand")
24950 (match_operand:MODEF 2 "register_operand")
24952 (match_operand:MODEF 3 "register_operand")
24953 (match_operand:MODEF 4 "register_operand"))]
24955 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
24956 && (rtx_equal_p (operands[1], operands[4])
24957 && rtx_equal_p (operands[2], operands[3]))
24958 && ix86_pre_reload_split ()"
24961 [(set (match_dup 0)
24965 UNSPEC_IEEE_MIN))])
24967 ;; Make two stack loads independent:
24969 ;; fld %st(0) -> fld bb
24970 ;; fmul bb fmul %st(1), %st
24972 ;; Actually we only match the last two instructions for simplicity.
24975 [(set (match_operand 0 "fp_register_operand")
24976 (match_operand 1 "fp_register_operand"))
24978 (match_operator 2 "binary_fp_operator"
24980 (match_operand 3 "memory_operand")]))]
24981 "REGNO (operands[0]) != REGNO (operands[1])"
24982 [(set (match_dup 0) (match_dup 3))
24985 [(match_dup 5) (match_dup 4)]))]
24987 operands[4] = operands[0];
24988 operands[5] = operands[1];
24990 /* The % modifier is not operational anymore in peephole2's, so we have to
24991 swap the operands manually in the case of addition and multiplication. */
24992 if (COMMUTATIVE_ARITH_P (operands[2]))
24993 std::swap (operands[4], operands[5]);
24997 [(set (match_operand 0 "fp_register_operand")
24998 (match_operand 1 "fp_register_operand"))
25000 (match_operator 2 "binary_fp_operator"
25001 [(match_operand 3 "memory_operand")
25003 "REGNO (operands[0]) != REGNO (operands[1])"
25004 [(set (match_dup 0) (match_dup 3))
25007 [(match_dup 4) (match_dup 5)]))]
25009 operands[4] = operands[0];
25010 operands[5] = operands[1];
25012 /* The % modifier is not operational anymore in peephole2's, so we have to
25013 swap the operands manually in the case of addition and multiplication. */
25014 if (COMMUTATIVE_ARITH_P (operands[2]))
25015 std::swap (operands[4], operands[5]);
25018 ;; Conditional addition patterns
25019 (define_expand "add<mode>cc"
25020 [(match_operand:SWI 0 "register_operand")
25021 (match_operand 1 "ordered_comparison_operator")
25022 (match_operand:SWI 2 "register_operand")
25023 (match_operand:SWI 3 "const_int_operand")]
25025 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
25027 ;; min/max patterns
25029 (define_code_attr maxmin_rel
25030 [(smax "GE") (smin "LE") (umax "GEU") (umin "LEU")])
25032 (define_expand "<code><mode>3"
25034 [(set (match_operand:SDWIM 0 "register_operand")
25036 (match_operand:SDWIM 1 "register_operand")
25037 (match_operand:SDWIM 2 "general_operand")))
25038 (clobber (reg:CC FLAGS_REG))])]
25040 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)")
25042 (define_insn_and_split "*<code><dwi>3_doubleword"
25043 [(set (match_operand:<DWI> 0 "register_operand")
25045 (match_operand:<DWI> 1 "register_operand")
25046 (match_operand:<DWI> 2 "general_operand")))
25047 (clobber (reg:CC FLAGS_REG))]
25049 && ix86_pre_reload_split ()"
25052 [(set (match_dup 0)
25053 (if_then_else:DWIH (match_dup 6)
25057 (if_then_else:DWIH (match_dup 6)
25061 operands[2] = force_reg (<DWI>mode, operands[2]);
25063 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
25065 rtx cmplo[2] = { operands[1], operands[2] };
25066 rtx cmphi[2] = { operands[4], operands[5] };
25068 enum rtx_code code = <maxmin_rel>;
25073 std::swap (cmplo[0], cmplo[1]);
25074 std::swap (cmphi[0], cmphi[1]);
25075 code = swap_condition (code);
25080 bool uns = (code == GEU);
25081 rtx (*sbb_insn) (machine_mode, rtx, rtx, rtx)
25082 = uns ? gen_sub3_carry_ccc : gen_sub3_carry_ccgz;
25084 emit_insn (gen_cmp_1 (<MODE>mode, cmplo[0], cmplo[1]));
25086 rtx tmp = gen_rtx_SCRATCH (<MODE>mode);
25087 emit_insn (sbb_insn (<MODE>mode, tmp, cmphi[0], cmphi[1]));
25089 rtx flags = gen_rtx_REG (uns ? CCCmode : CCGZmode, FLAGS_REG);
25090 operands[6] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
25096 gcc_unreachable ();
25100 (define_insn_and_split "*<code><mode>3_1"
25101 [(set (match_operand:SWI 0 "register_operand")
25103 (match_operand:SWI 1 "register_operand")
25104 (match_operand:SWI 2 "general_operand")))
25105 (clobber (reg:CC FLAGS_REG))]
25107 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
25108 && ix86_pre_reload_split ()"
25111 [(set (match_dup 0)
25112 (if_then_else:SWI (match_dup 3)
25116 machine_mode mode = <MODE>mode;
25117 rtx cmp_op = operands[2];
25119 operands[2] = force_reg (mode, cmp_op);
25121 enum rtx_code code = <maxmin_rel>;
25123 if (cmp_op == const1_rtx)
25125 /* Convert smax (x, 1) into (x > 0 ? x : 1).
25126 Convert umax (x, 1) into (x != 0 ? x : 1).
25127 Convert ?min (x, 1) into (x <= 0 ? x : 1). */
25128 cmp_op = const0_rtx;
25131 else if (code == GEU)
25134 /* Convert smin (x, -1) into (x < 0 ? x : -1). */
25135 else if (cmp_op == constm1_rtx && code == LE)
25137 cmp_op = const0_rtx;
25140 /* Convert smax (x, -1) into (x >= 0 ? x : -1). */
25141 else if (cmp_op == constm1_rtx && code == GE)
25142 cmp_op = const0_rtx;
25143 else if (cmp_op != const0_rtx)
25144 cmp_op = operands[2];
25146 machine_mode cmpmode = SELECT_CC_MODE (code, operands[1], cmp_op);
25147 rtx flags = gen_rtx_REG (cmpmode, FLAGS_REG);
25149 rtx tmp = gen_rtx_COMPARE (cmpmode, operands[1], cmp_op);
25150 emit_insn (gen_rtx_SET (flags, tmp));
25152 operands[3] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
25155 ;; Avoid clearing a register between a flags setting comparison and its use,
25156 ;; i.e. prefer "xorl %eax,%eax; test/cmp" over "test/cmp; movl $0, %eax".
25158 [(set (reg FLAGS_REG) (match_operand 0))
25159 (set (match_operand:SWI 1 "general_reg_operand") (const_int 0))]
25160 "peep2_regno_dead_p (0, FLAGS_REG)
25161 && !reg_overlap_mentioned_p (operands[1], operands[0])"
25162 [(set (match_dup 2) (match_dup 0))]
25164 operands[2] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
25165 ix86_expand_clear (operands[1]);
25168 ;; When optimizing for size, zeroing memory should use a register.
25170 [(match_scratch:SWI48 0 "r")
25171 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
25172 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))
25173 (set (match_operand:SWI48 3 "memory_operand") (const_int 0))
25174 (set (match_operand:SWI48 4 "memory_operand") (const_int 0))]
25175 "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
25178 ix86_expand_clear (operands[0]);
25179 emit_move_insn (operands[1], operands[0]);
25180 emit_move_insn (operands[2], operands[0]);
25181 emit_move_insn (operands[3], operands[0]);
25182 ix86_last_zero_store_uid
25183 = INSN_UID (emit_move_insn (operands[4], operands[0]));
25188 [(match_scratch:SWI48 0 "r")
25189 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
25190 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))]
25191 "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
25194 ix86_expand_clear (operands[0]);
25195 emit_move_insn (operands[1], operands[0]);
25196 ix86_last_zero_store_uid
25197 = INSN_UID (emit_move_insn (operands[2], operands[0]));
25202 [(match_scratch:SWI48 0 "r")
25203 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))]
25204 "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
25207 ix86_expand_clear (operands[0]);
25208 ix86_last_zero_store_uid
25209 = INSN_UID (emit_move_insn (operands[1], operands[0]));
25214 [(set (match_operand:SWI48 5 "memory_operand")
25215 (match_operand:SWI48 0 "general_reg_operand"))
25216 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
25217 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))
25218 (set (match_operand:SWI48 3 "memory_operand") (const_int 0))
25219 (set (match_operand:SWI48 4 "memory_operand") (const_int 0))]
25220 "optimize_insn_for_size_p ()
25221 && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
25224 emit_move_insn (operands[5], operands[0]);
25225 emit_move_insn (operands[1], operands[0]);
25226 emit_move_insn (operands[2], operands[0]);
25227 emit_move_insn (operands[3], operands[0]);
25228 ix86_last_zero_store_uid
25229 = INSN_UID (emit_move_insn (operands[4], operands[0]));
25234 [(set (match_operand:SWI48 3 "memory_operand")
25235 (match_operand:SWI48 0 "general_reg_operand"))
25236 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
25237 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))]
25238 "optimize_insn_for_size_p ()
25239 && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
25242 emit_move_insn (operands[3], operands[0]);
25243 emit_move_insn (operands[1], operands[0]);
25244 ix86_last_zero_store_uid
25245 = INSN_UID (emit_move_insn (operands[2], operands[0]));
25250 [(set (match_operand:SWI48 2 "memory_operand")
25251 (match_operand:SWI48 0 "general_reg_operand"))
25252 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))]
25253 "optimize_insn_for_size_p ()
25254 && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
25257 emit_move_insn (operands[2], operands[0]);
25258 ix86_last_zero_store_uid
25259 = INSN_UID (emit_move_insn (operands[1], operands[0]));
25263 ;; Reload dislikes loading constants directly into class_likely_spilled
25264 ;; hard registers. Try to tidy things up here.
25266 [(set (match_operand:SWI 0 "general_reg_operand")
25267 (match_operand:SWI 1 "x86_64_general_operand"))
25268 (set (match_operand:SWI 2 "general_reg_operand")
25270 "peep2_reg_dead_p (2, operands[0])"
25271 [(set (match_dup 2) (match_dup 1))])
25273 ;; Misc patterns (?)
25275 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
25276 ;; Otherwise there will be nothing to keep
25278 ;; [(set (reg ebp) (reg esp))]
25279 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
25280 ;; (clobber (eflags)]
25281 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
25283 ;; in proper program order.
25285 (define_insn "@pro_epilogue_adjust_stack_add_<mode>"
25286 [(set (match_operand:P 0 "register_operand" "=r,r")
25287 (plus:P (match_operand:P 1 "register_operand" "0,r")
25288 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
25289 (clobber (reg:CC FLAGS_REG))
25290 (clobber (mem:BLK (scratch)))]
25293 switch (get_attr_type (insn))
25296 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
25299 gcc_assert (rtx_equal_p (operands[0], operands[1]));
25300 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
25301 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
25303 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
25306 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
25307 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
25310 [(set (attr "type")
25311 (cond [(and (eq_attr "alternative" "0")
25312 (not (match_test "TARGET_OPT_AGU")))
25313 (const_string "alu")
25314 (match_operand:<MODE> 2 "const0_operand")
25315 (const_string "imov")
25317 (const_string "lea")))
25318 (set (attr "length_immediate")
25319 (cond [(eq_attr "type" "imov")
25321 (and (eq_attr "type" "alu")
25322 (match_operand 2 "const128_operand"))
25325 (const_string "*")))
25326 (set_attr "mode" "<MODE>")])
25328 (define_insn "@pro_epilogue_adjust_stack_sub_<mode>"
25329 [(set (match_operand:P 0 "register_operand" "=r")
25330 (minus:P (match_operand:P 1 "register_operand" "0")
25331 (match_operand:P 2 "register_operand" "r")))
25332 (clobber (reg:CC FLAGS_REG))
25333 (clobber (mem:BLK (scratch)))]
25335 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
25336 [(set_attr "type" "alu")
25337 (set_attr "mode" "<MODE>")])
25339 (define_insn "@allocate_stack_worker_probe_<mode>"
25340 [(set (match_operand:P 0 "register_operand" "=a")
25341 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
25342 UNSPECV_STACK_PROBE))
25343 (clobber (reg:CC FLAGS_REG))]
25344 "ix86_target_stack_probe ()"
25345 "call\t___chkstk_ms"
25346 [(set_attr "type" "multi")
25347 (set_attr "length" "5")])
25349 (define_expand "allocate_stack"
25350 [(match_operand 0 "register_operand")
25351 (match_operand 1 "general_operand")]
25352 "ix86_target_stack_probe ()"
25356 #ifndef CHECK_STACK_LIMIT
25357 #define CHECK_STACK_LIMIT 0
25360 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
25361 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
25365 x = copy_to_mode_reg (Pmode, operands[1]);
25367 emit_insn (gen_allocate_stack_worker_probe (Pmode, x, x));
25370 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
25371 stack_pointer_rtx, 0, OPTAB_DIRECT);
25373 if (x != stack_pointer_rtx)
25374 emit_move_insn (stack_pointer_rtx, x);
25376 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
25380 (define_expand "probe_stack"
25381 [(match_operand 0 "memory_operand")]
25384 emit_insn (gen_probe_stack_1
25385 (word_mode, operands[0], const0_rtx));
25389 ;; Use OR for stack probes, this is shorter.
25390 (define_insn "@probe_stack_1_<mode>"
25391 [(set (match_operand:W 0 "memory_operand" "=m")
25392 (unspec:W [(match_operand:W 1 "const0_operand")]
25393 UNSPEC_PROBE_STACK))
25394 (clobber (reg:CC FLAGS_REG))]
25396 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
25397 [(set_attr "type" "alu1")
25398 (set_attr "mode" "<MODE>")
25399 (set_attr "length_immediate" "1")])
25401 (define_insn "@adjust_stack_and_probe_<mode>"
25402 [(set (match_operand:P 0 "register_operand" "=r")
25403 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
25404 UNSPECV_PROBE_STACK_RANGE))
25405 (set (reg:P SP_REG)
25406 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand")))
25407 (clobber (reg:CC FLAGS_REG))
25408 (clobber (mem:BLK (scratch)))]
25410 "* return output_adjust_stack_and_probe (operands[0]);"
25411 [(set_attr "type" "multi")])
25413 (define_insn "@probe_stack_range_<mode>"
25414 [(set (match_operand:P 0 "register_operand" "=r")
25415 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
25416 (match_operand:P 2 "const_int_operand")]
25417 UNSPECV_PROBE_STACK_RANGE))
25418 (clobber (reg:CC FLAGS_REG))]
25420 "* return output_probe_stack_range (operands[0], operands[2]);"
25421 [(set_attr "type" "multi")])
25423 (define_expand "builtin_setjmp_receiver"
25424 [(label_ref (match_operand 0))]
25425 "!TARGET_64BIT && flag_pic"
25431 rtx_code_label *label_rtx = gen_label_rtx ();
25432 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
25433 xops[0] = xops[1] = pic_offset_table_rtx;
25434 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
25435 ix86_expand_binary_operator (MINUS, SImode, xops);
25439 emit_insn (gen_set_got (pic_offset_table_rtx));
25443 (define_expand "save_stack_nonlocal"
25444 [(set (match_operand 0 "memory_operand")
25445 (match_operand 1 "register_operand"))]
25450 if (flag_cf_protection & CF_RETURN)
25452 /* Copy shadow stack pointer to the first slot
25453 and stack pointer to the second slot. */
25454 rtx ssp_slot = adjust_address (operands[0], word_mode, 0);
25455 stack_slot = adjust_address (operands[0], Pmode, UNITS_PER_WORD);
25457 rtx reg_ssp = force_reg (word_mode, const0_rtx);
25458 emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
25459 emit_move_insn (ssp_slot, reg_ssp);
25462 stack_slot = adjust_address (operands[0], Pmode, 0);
25463 emit_move_insn (stack_slot, operands[1]);
25467 (define_expand "restore_stack_nonlocal"
25468 [(set (match_operand 0 "register_operand" "")
25469 (match_operand 1 "memory_operand" ""))]
25474 if (flag_cf_protection & CF_RETURN)
25476 /* Restore shadow stack pointer from the first slot
25477 and stack pointer from the second slot. */
25478 rtx ssp_slot = adjust_address (operands[1], word_mode, 0);
25479 stack_slot = adjust_address (operands[1], Pmode, UNITS_PER_WORD);
25481 /* Get the current shadow stack pointer. The code below will check if
25482 SHSTK feature is enabled. If it is not enabled the RDSSP instruction
25484 rtx reg_ssp = force_reg (word_mode, const0_rtx);
25485 emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
25487 /* Compare through subtraction the saved and the current ssp
25488 to decide if ssp has to be adjusted. */
25489 reg_ssp = expand_simple_binop (word_mode, MINUS,
25491 reg_ssp, 1, OPTAB_DIRECT);
25493 /* Compare and jump over adjustment code. */
25494 rtx noadj_label = gen_label_rtx ();
25495 emit_cmp_and_jump_insns (reg_ssp, const0_rtx, EQ, NULL_RTX,
25496 word_mode, 1, noadj_label);
25498 /* Compute the number of frames to adjust. */
25499 rtx reg_adj = gen_lowpart (ptr_mode, reg_ssp);
25500 rtx reg_adj_neg = expand_simple_unop (ptr_mode, NEG, reg_adj,
25503 reg_adj = expand_simple_binop (ptr_mode, LSHIFTRT, reg_adj_neg,
25504 GEN_INT (exact_log2 (UNITS_PER_WORD)),
25505 reg_adj, 1, OPTAB_DIRECT);
25507 /* Check if number of frames <= 255 so no loop is needed. */
25508 rtx inc_label = gen_label_rtx ();
25509 emit_cmp_and_jump_insns (reg_adj, GEN_INT (255), LEU, NULL_RTX,
25510 ptr_mode, 1, inc_label);
25512 /* Adjust the ssp in a loop. */
25513 rtx loop_label = gen_label_rtx ();
25514 emit_label (loop_label);
25515 LABEL_NUSES (loop_label) = 1;
25517 rtx reg_255 = force_reg (word_mode, GEN_INT (255));
25518 emit_insn (gen_incssp (word_mode, reg_255));
25520 reg_adj = expand_simple_binop (ptr_mode, MINUS,
25521 reg_adj, GEN_INT (255),
25522 reg_adj, 1, OPTAB_DIRECT);
25524 /* Compare and jump to the loop label. */
25525 emit_cmp_and_jump_insns (reg_adj, GEN_INT (255), GTU, NULL_RTX,
25526 ptr_mode, 1, loop_label);
25528 emit_label (inc_label);
25529 LABEL_NUSES (inc_label) = 1;
25531 emit_insn (gen_incssp (word_mode, reg_ssp));
25533 emit_label (noadj_label);
25534 LABEL_NUSES (noadj_label) = 1;
25537 stack_slot = adjust_address (operands[1], Pmode, 0);
25538 emit_move_insn (operands[0], stack_slot);
25542 (define_expand "stack_protect_set"
25543 [(match_operand 0 "memory_operand")
25544 (match_operand 1 "memory_operand")]
25547 rtx scratch = gen_reg_rtx (word_mode);
25549 emit_insn (gen_stack_protect_set_1
25550 (ptr_mode, word_mode, operands[0], operands[1], scratch));
25554 (define_insn "@stack_protect_set_1_<PTR:mode>_<W:mode>"
25555 [(set (match_operand:PTR 0 "memory_operand" "=m")
25556 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
25558 (set (match_operand:W 2 "register_operand" "=&r") (const_int 0))
25559 (clobber (reg:CC FLAGS_REG))]
25562 output_asm_insn ("mov{<PTR:imodesuffix>}\t{%1, %<PTR:k>2|%<PTR:k>2, %1}",
25564 output_asm_insn ("mov{<PTR:imodesuffix>}\t{%<PTR:k>2, %0|%0, %<PTR:k>2}",
25566 if (!TARGET_USE_MOV0 || optimize_insn_for_size_p ())
25567 return "xor{l}\t%k2, %k2";
25569 return "mov{l}\t{$0, %k2|%k2, 0}";
25571 [(set_attr "type" "multi")])
25573 ;; Patterns and peephole2s to optimize stack_protect_set_1_<mode>
25574 ;; immediately followed by *mov{s,d}i_internal, where we can avoid
25575 ;; the xor{l} above. We don't split this, so that scheduling or
25576 ;; anything else doesn't separate the *stack_protect_set* pattern from
25577 ;; the set of the register that overwrites the register with a new value.
25580 [(parallel [(set (match_operand:PTR 0 "memory_operand")
25581 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
25583 (set (match_operand 2 "general_reg_operand") (const_int 0))
25584 (clobber (reg:CC FLAGS_REG))])
25585 (set (match_operand 3 "general_reg_operand")
25586 (match_operand 4 "const0_operand"))]
25587 "GET_MODE (operands[2]) == word_mode
25588 && GET_MODE_SIZE (GET_MODE (operands[3])) <= UNITS_PER_WORD
25589 && peep2_reg_dead_p (0, operands[3])
25590 && peep2_reg_dead_p (1, operands[2])"
25591 [(parallel [(set (match_dup 0)
25592 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
25593 (set (match_dup 3) (const_int 0))
25594 (clobber (reg:CC FLAGS_REG))])]
25595 "operands[3] = gen_lowpart (word_mode, operands[3]);")
25597 (define_insn "*stack_protect_set_2_<mode>_si"
25598 [(set (match_operand:PTR 0 "memory_operand" "=m")
25599 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
25601 (set (match_operand:SI 1 "register_operand" "=&r")
25602 (match_operand:SI 2 "general_operand" "g"))]
25605 output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
25606 output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
25607 if (pic_32bit_operand (operands[2], SImode)
25608 || ix86_use_lea_for_mov (insn, operands + 1))
25609 return "lea{l}\t{%E2, %1|%1, %E2}";
25611 return "mov{l}\t{%2, %1|%1, %2}";
25613 [(set_attr "type" "multi")
25614 (set_attr "length" "24")])
25616 (define_insn "*stack_protect_set_2_<mode>_di"
25617 [(set (match_operand:PTR 0 "memory_operand" "=m,m,m")
25618 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m,m,m")]
25620 (set (match_operand:DI 1 "register_operand" "=&r,&r,&r")
25621 (match_operand:DI 2 "general_operand" "Z,rem,i"))]
25622 "TARGET_64BIT && reload_completed"
25624 output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
25625 output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
25626 if (pic_32bit_operand (operands[2], DImode))
25627 return "lea{q}\t{%E2, %1|%1, %E2}";
25628 else if (which_alternative == 0)
25629 return "mov{l}\t{%k2, %k1|%k1, %k2}";
25630 else if (which_alternative == 2)
25631 return "movabs{q}\t{%2, %1|%1, %2}";
25632 else if (ix86_use_lea_for_mov (insn, operands + 1))
25633 return "lea{q}\t{%E2, %1|%1, %E2}";
25635 return "mov{q}\t{%2, %1|%1, %2}";
25637 [(set_attr "type" "multi")
25638 (set_attr "length" "24")])
25641 [(parallel [(set (match_operand:PTR 0 "memory_operand")
25642 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
25644 (set (match_operand 2 "general_reg_operand") (const_int 0))
25645 (clobber (reg:CC FLAGS_REG))])
25646 (set (match_operand:SWI48 3 "general_reg_operand")
25647 (match_operand:SWI48 4 "general_gr_operand"))]
25648 "GET_MODE (operands[2]) == word_mode
25649 && peep2_reg_dead_p (0, operands[3])
25650 && peep2_reg_dead_p (1, operands[2])"
25651 [(parallel [(set (match_dup 0)
25652 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
25653 (set (match_dup 3) (match_dup 4))])])
25656 [(set (match_operand:SWI48 3 "general_reg_operand")
25657 (match_operand:SWI48 4 "general_gr_operand"))
25658 (parallel [(set (match_operand:PTR 0 "memory_operand")
25659 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
25661 (set (match_operand 2 "general_reg_operand") (const_int 0))
25662 (clobber (reg:CC FLAGS_REG))])]
25663 "GET_MODE (operands[2]) == word_mode
25664 && peep2_reg_dead_p (0, operands[3])
25665 && peep2_reg_dead_p (2, operands[2])
25666 && !reg_mentioned_p (operands[3], operands[0])
25667 && !reg_mentioned_p (operands[3], operands[1])"
25668 [(parallel [(set (match_dup 0)
25669 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
25670 (set (match_dup 3) (match_dup 4))])])
25672 (define_insn "*stack_protect_set_3_<PTR:mode>_<SWI48:mode>"
25673 [(set (match_operand:PTR 0 "memory_operand" "=m")
25674 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
25676 (set (match_operand:SWI48 1 "register_operand" "=&r")
25677 (match_operand:SWI48 2 "address_no_seg_operand" "Ts"))]
25680 output_asm_insn ("mov{<PTR:imodesuffix>}\t{%3, %<PTR:k>1|%<PTR:k>1, %3}",
25682 output_asm_insn ("mov{<PTR:imodesuffix>}\t{%<PTR:k>1, %0|%0, %<PTR:k>1}",
25684 if (SImode_address_operand (operands[2], VOIDmode))
25686 gcc_assert (TARGET_64BIT);
25687 return "lea{l}\t{%E2, %k1|%k1, %E2}";
25690 return "lea{<SWI48:imodesuffix>}\t{%E2, %1|%1, %E2}";
25692 [(set_attr "type" "multi")
25693 (set_attr "length" "24")])
25696 [(parallel [(set (match_operand:PTR 0 "memory_operand")
25697 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
25699 (set (match_operand 2 "general_reg_operand") (const_int 0))
25700 (clobber (reg:CC FLAGS_REG))])
25701 (set (match_operand:SWI48 3 "general_reg_operand")
25702 (match_operand:SWI48 4 "address_no_seg_operand"))]
25703 "GET_MODE (operands[2]) == word_mode
25704 && peep2_reg_dead_p (0, operands[3])
25705 && peep2_reg_dead_p (1, operands[2])"
25706 [(parallel [(set (match_dup 0)
25707 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
25708 (set (match_dup 3) (match_dup 4))])])
25710 (define_insn "*stack_protect_set_4z_<mode>_di"
25711 [(set (match_operand:PTR 0 "memory_operand" "=m")
25712 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
25714 (set (match_operand:DI 1 "register_operand" "=&r")
25715 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))]
25716 "TARGET_64BIT && reload_completed"
25718 output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
25719 output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
25720 if (ix86_use_lea_for_mov (insn, operands + 1))
25721 return "lea{l}\t{%E2, %k1|%k1, %E2}";
25723 return "mov{l}\t{%2, %k1|%k1, %2}";
25725 [(set_attr "type" "multi")
25726 (set_attr "length" "24")])
25728 (define_insn "*stack_protect_set_4s_<mode>_di"
25729 [(set (match_operand:PTR 0 "memory_operand" "=m")
25730 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
25732 (set (match_operand:DI 1 "register_operand" "=&r")
25733 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))]
25734 "TARGET_64BIT && reload_completed"
25736 output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
25737 output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
25738 return "movs{lq|x}\t{%2, %1|%1, %2}";
25740 [(set_attr "type" "multi")
25741 (set_attr "length" "24")])
25744 [(parallel [(set (match_operand:PTR 0 "memory_operand")
25745 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
25747 (set (match_operand 2 "general_reg_operand") (const_int 0))
25748 (clobber (reg:CC FLAGS_REG))])
25749 (set (match_operand:DI 3 "general_reg_operand")
25751 (match_operand:SI 4 "nonimmediate_gr_operand")))]
25753 && GET_MODE (operands[2]) == word_mode
25754 && peep2_reg_dead_p (0, operands[3])
25755 && peep2_reg_dead_p (1, operands[2])"
25756 [(parallel [(set (match_dup 0)
25757 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
25759 (any_extend:DI (match_dup 4)))])])
25761 (define_expand "stack_protect_test"
25762 [(match_operand 0 "memory_operand")
25763 (match_operand 1 "memory_operand")
25767 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
25769 emit_insn (gen_stack_protect_test_1
25770 (ptr_mode, flags, operands[0], operands[1]));
25772 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
25773 flags, const0_rtx, operands[2]));
25777 (define_insn "@stack_protect_test_1_<mode>"
25778 [(set (match_operand:CCZ 0 "flags_reg_operand")
25779 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
25780 (match_operand:PTR 2 "memory_operand" "m")]
25782 (clobber (match_scratch:PTR 3 "=&r"))]
25785 output_asm_insn ("mov{<imodesuffix>}\t{%1, %3|%3, %1}", operands);
25786 return "sub{<imodesuffix>}\t{%2, %3|%3, %2}";
25788 [(set_attr "type" "multi")])
25790 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
25791 ;; Do not split instructions with mask registers.
25793 [(set (match_operand 0 "general_reg_operand")
25794 (match_operator 3 "promotable_binary_operator"
25795 [(match_operand 1 "general_reg_operand")
25796 (match_operand 2 "aligned_operand")]))
25797 (clobber (reg:CC FLAGS_REG))]
25798 "! TARGET_PARTIAL_REG_STALL && reload_completed
25799 && ((GET_MODE (operands[0]) == HImode
25800 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
25801 /* ??? next two lines just !satisfies_constraint_K (...) */
25802 || !CONST_INT_P (operands[2])
25803 || satisfies_constraint_K (operands[2])))
25804 || (GET_MODE (operands[0]) == QImode
25805 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
25806 [(parallel [(set (match_dup 0)
25807 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
25808 (clobber (reg:CC FLAGS_REG))])]
25810 operands[0] = gen_lowpart (SImode, operands[0]);
25811 operands[1] = gen_lowpart (SImode, operands[1]);
25812 if (GET_CODE (operands[3]) != ASHIFT)
25813 operands[2] = gen_lowpart (SImode, operands[2]);
25814 operands[3] = shallow_copy_rtx (operands[3]);
25815 PUT_MODE (operands[3], SImode);
25818 ; Promote the QImode tests, as i386 has encoding of the AND
25819 ; instruction with 32-bit sign-extended immediate and thus the
25820 ; instruction size is unchanged, except in the %eax case for
25821 ; which it is increased by one byte, hence the ! optimize_size.
25823 [(set (match_operand 0 "flags_reg_operand")
25824 (match_operator 2 "compare_operator"
25825 [(and (match_operand 3 "aligned_operand")
25826 (match_operand 4 "const_int_operand"))
25828 (set (match_operand 1 "register_operand")
25829 (and (match_dup 3) (match_dup 4)))]
25830 "! TARGET_PARTIAL_REG_STALL && reload_completed
25831 && optimize_insn_for_speed_p ()
25832 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
25833 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
25834 /* Ensure that the operand will remain sign-extended immediate. */
25835 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
25836 [(parallel [(set (match_dup 0)
25837 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
25840 (and:SI (match_dup 3) (match_dup 4)))])]
25843 = gen_int_mode (INTVAL (operands[4])
25844 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
25845 operands[1] = gen_lowpart (SImode, operands[1]);
25846 operands[3] = gen_lowpart (SImode, operands[3]);
25849 ; Don't promote the QImode tests, as i386 doesn't have encoding of
25850 ; the TEST instruction with 32-bit sign-extended immediate and thus
25851 ; the instruction size would at least double, which is not what we
25852 ; want even with ! optimize_size.
25854 [(set (match_operand 0 "flags_reg_operand")
25855 (match_operator 1 "compare_operator"
25856 [(and (match_operand:HI 2 "aligned_operand")
25857 (match_operand:HI 3 "const_int_operand"))
25859 "! TARGET_PARTIAL_REG_STALL && reload_completed
25860 && ! TARGET_FAST_PREFIX
25861 && optimize_insn_for_speed_p ()
25862 /* Ensure that the operand will remain sign-extended immediate. */
25863 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
25864 [(set (match_dup 0)
25865 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
25869 = gen_int_mode (INTVAL (operands[3])
25870 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
25871 operands[2] = gen_lowpart (SImode, operands[2]);
25875 [(set (match_operand 0 "register_operand")
25876 (neg (match_operand 1 "register_operand")))
25877 (clobber (reg:CC FLAGS_REG))]
25878 "! TARGET_PARTIAL_REG_STALL && reload_completed
25879 && (GET_MODE (operands[0]) == HImode
25880 || (GET_MODE (operands[0]) == QImode
25881 && (TARGET_PROMOTE_QImode
25882 || optimize_insn_for_size_p ())))"
25883 [(parallel [(set (match_dup 0)
25884 (neg:SI (match_dup 1)))
25885 (clobber (reg:CC FLAGS_REG))])]
25887 operands[0] = gen_lowpart (SImode, operands[0]);
25888 operands[1] = gen_lowpart (SImode, operands[1]);
25891 ;; Do not split instructions with mask regs.
25893 [(set (match_operand 0 "general_reg_operand")
25894 (not (match_operand 1 "general_reg_operand")))]
25895 "! TARGET_PARTIAL_REG_STALL && reload_completed
25896 && (GET_MODE (operands[0]) == HImode
25897 || (GET_MODE (operands[0]) == QImode
25898 && (TARGET_PROMOTE_QImode
25899 || optimize_insn_for_size_p ())))"
25900 [(set (match_dup 0)
25901 (not:SI (match_dup 1)))]
25903 operands[0] = gen_lowpart (SImode, operands[0]);
25904 operands[1] = gen_lowpart (SImode, operands[1]);
25907 ;; RTL Peephole optimizations, run before sched2. These primarily look to
25908 ;; transform a complex memory operation into two memory to register operations.
25910 ;; Don't push memory operands
25912 [(set (match_operand:SWI 0 "push_operand")
25913 (match_operand:SWI 1 "memory_operand"))
25914 (match_scratch:SWI 2 "<r>")]
25915 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
25916 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
25917 [(set (match_dup 2) (match_dup 1))
25918 (set (match_dup 0) (match_dup 2))])
25920 ;; We need to handle SFmode only, because DFmode and XFmode are split to
25923 [(set (match_operand:SF 0 "push_operand")
25924 (match_operand:SF 1 "memory_operand"))
25925 (match_scratch:SF 2 "r")]
25926 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
25927 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
25928 [(set (match_dup 2) (match_dup 1))
25929 (set (match_dup 0) (match_dup 2))])
25931 ;; Don't move an immediate directly to memory when the instruction
25932 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
25934 [(match_scratch:SWI124 1 "<r>")
25935 (set (match_operand:SWI124 0 "memory_operand")
25937 "optimize_insn_for_speed_p ()
25938 && ((<MODE>mode == HImode
25939 && TARGET_LCP_STALL)
25940 || (!TARGET_USE_MOV0
25941 && TARGET_SPLIT_LONG_MOVES
25942 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
25943 && peep2_regno_dead_p (0, FLAGS_REG)"
25944 [(parallel [(set (match_dup 2) (const_int 0))
25945 (clobber (reg:CC FLAGS_REG))])
25946 (set (match_dup 0) (match_dup 1))]
25947 "operands[2] = gen_lowpart (SImode, operands[1]);")
25950 [(match_scratch:SWI124 2 "<r>")
25951 (set (match_operand:SWI124 0 "memory_operand")
25952 (match_operand:SWI124 1 "immediate_operand"))]
25953 "optimize_insn_for_speed_p ()
25954 && ((<MODE>mode == HImode
25955 && TARGET_LCP_STALL)
25956 || (TARGET_SPLIT_LONG_MOVES
25957 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
25958 [(set (match_dup 2) (match_dup 1))
25959 (set (match_dup 0) (match_dup 2))])
25961 ;; Don't compare memory with zero, load and use a test instead.
25963 [(set (match_operand 0 "flags_reg_operand")
25964 (match_operator 1 "compare_operator"
25965 [(match_operand:SI 2 "memory_operand")
25967 (match_scratch:SI 3 "r")]
25968 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
25969 [(set (match_dup 3) (match_dup 2))
25970 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
25972 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
25973 ;; Don't split NOTs with a displacement operand, because resulting XOR
25974 ;; will not be pairable anyway.
25976 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
25977 ;; represented using a modRM byte. The XOR replacement is long decoded,
25978 ;; so this split helps here as well.
25980 ;; Note: Can't do this as a regular split because we can't get proper
25981 ;; lifetime information then.
25984 [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
25985 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
25986 "optimize_insn_for_speed_p ()
25987 && ((TARGET_NOT_UNPAIRABLE
25988 && (!MEM_P (operands[0])
25989 || !memory_displacement_operand (operands[0], <MODE>mode)))
25990 || (TARGET_NOT_VECTORMODE
25991 && long_memory_operand (operands[0], <MODE>mode)))
25992 && peep2_regno_dead_p (0, FLAGS_REG)"
25993 [(parallel [(set (match_dup 0)
25994 (xor:SWI124 (match_dup 1) (const_int -1)))
25995 (clobber (reg:CC FLAGS_REG))])])
25997 ;; Non pairable "test imm, reg" instructions can be translated to
25998 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
25999 ;; byte opcode instead of two, have a short form for byte operands),
26000 ;; so do it for other CPUs as well. Given that the value was dead,
26001 ;; this should not create any new dependencies. Pass on the sub-word
26002 ;; versions if we're concerned about partial register stalls.
26005 [(set (match_operand 0 "flags_reg_operand")
26006 (match_operator 1 "compare_operator"
26007 [(and:SI (match_operand:SI 2 "register_operand")
26008 (match_operand:SI 3 "immediate_operand"))
26010 "ix86_match_ccmode (insn, CCNOmode)
26011 && (REGNO (operands[2]) != AX_REG
26012 || satisfies_constraint_K (operands[3]))
26013 && peep2_reg_dead_p (1, operands[2])"
26015 [(set (match_dup 0)
26016 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
26019 (and:SI (match_dup 2) (match_dup 3)))])])
26021 ;; We don't need to handle HImode case, because it will be promoted to SImode
26022 ;; on ! TARGET_PARTIAL_REG_STALL
26025 [(set (match_operand 0 "flags_reg_operand")
26026 (match_operator 1 "compare_operator"
26027 [(and:QI (match_operand:QI 2 "register_operand")
26028 (match_operand:QI 3 "immediate_operand"))
26030 "! TARGET_PARTIAL_REG_STALL
26031 && ix86_match_ccmode (insn, CCNOmode)
26032 && REGNO (operands[2]) != AX_REG
26033 && peep2_reg_dead_p (1, operands[2])"
26035 [(set (match_dup 0)
26036 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
26039 (and:QI (match_dup 2) (match_dup 3)))])])
26042 [(set (match_operand 0 "flags_reg_operand")
26043 (match_operator 1 "compare_operator"
26046 (match_operator:SWI248 4 "extract_operator"
26047 [(match_operand 2 "int248_register_operand")
26050 (match_operand 3 "const_int_operand"))
26052 "! TARGET_PARTIAL_REG_STALL
26053 && ix86_match_ccmode (insn, CCNOmode)
26054 && REGNO (operands[2]) != AX_REG
26055 && peep2_reg_dead_p (1, operands[2])"
26057 [(set (match_dup 0)
26061 (match_op_dup 4 [(match_dup 2)
26066 (set (zero_extract:SWI248 (match_dup 2)
26072 (match_op_dup 4 [(match_dup 2)
26075 (match_dup 3)) 0))])])
26077 ;; Don't do logical operations with memory inputs.
26079 [(match_scratch:SWI 2 "<r>")
26080 (parallel [(set (match_operand:SWI 0 "register_operand")
26081 (match_operator:SWI 3 "arith_or_logical_operator"
26083 (match_operand:SWI 1 "memory_operand")]))
26084 (clobber (reg:CC FLAGS_REG))])]
26085 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
26086 [(set (match_dup 2) (match_dup 1))
26087 (parallel [(set (match_dup 0)
26088 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
26089 (clobber (reg:CC FLAGS_REG))])])
26092 [(match_scratch:SWI 2 "<r>")
26093 (parallel [(set (match_operand:SWI 0 "register_operand")
26094 (match_operator:SWI 3 "arith_or_logical_operator"
26095 [(match_operand:SWI 1 "memory_operand")
26097 (clobber (reg:CC FLAGS_REG))])]
26098 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
26099 [(set (match_dup 2) (match_dup 1))
26100 (parallel [(set (match_dup 0)
26101 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
26102 (clobber (reg:CC FLAGS_REG))])])
26104 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when
26105 ;; the memory address refers to the destination of the load!
26108 [(set (match_operand:SWI 0 "general_reg_operand")
26109 (match_operand:SWI 1 "general_reg_operand"))
26110 (parallel [(set (match_dup 0)
26111 (match_operator:SWI 3 "commutative_operator"
26113 (match_operand:SWI 2 "memory_operand")]))
26114 (clobber (reg:CC FLAGS_REG))])]
26115 "REGNO (operands[0]) != REGNO (operands[1])
26116 && (<MODE>mode != QImode
26117 || any_QIreg_operand (operands[1], QImode))"
26118 [(set (match_dup 0) (match_dup 4))
26119 (parallel [(set (match_dup 0)
26120 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
26121 (clobber (reg:CC FLAGS_REG))])]
26124 = ix86_replace_reg_with_reg (operands[2], operands[0], operands[1]);
26128 [(set (match_operand 0 "mmx_reg_operand")
26129 (match_operand 1 "mmx_reg_operand"))
26131 (match_operator 3 "commutative_operator"
26133 (match_operand 2 "memory_operand")]))]
26134 "REGNO (operands[0]) != REGNO (operands[1])"
26135 [(set (match_dup 0) (match_dup 2))
26137 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
26140 [(set (match_operand 0 "sse_reg_operand")
26141 (match_operand 1 "sse_reg_operand"))
26143 (match_operator 3 "commutative_operator"
26145 (match_operand 2 "memory_operand")]))]
26146 "REGNO (operands[0]) != REGNO (operands[1])
26147 /* Punt if operands[1] is %[xy]mm16+ and AVX512BW is not enabled,
26148 as EVEX encoded vpadd[bw], vpmullw, vpmin[su][bw] and vpmax[su][bw]
26149 instructions require AVX512BW and AVX512VL, but with the original
26150 instructions it might require just AVX512VL.
26151 AVX512VL is implied from TARGET_HARD_REGNO_MODE_OK. */
26152 && (!EXT_REX_SSE_REGNO_P (REGNO (operands[1]))
26154 || GET_MODE_SIZE (GET_MODE_INNER (GET_MODE (operands[0]))) > 2
26155 || logic_operator (operands[3], VOIDmode))"
26156 [(set (match_dup 0) (match_dup 2))
26158 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
26160 ; Don't do logical operations with memory outputs
26162 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
26163 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
26164 ; the same decoder scheduling characteristics as the original.
26167 [(match_scratch:SWI 2 "<r>")
26168 (parallel [(set (match_operand:SWI 0 "memory_operand")
26169 (match_operator:SWI 3 "arith_or_logical_operator"
26171 (match_operand:SWI 1 "<nonmemory_operand>")]))
26172 (clobber (reg:CC FLAGS_REG))])]
26173 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
26174 [(set (match_dup 2) (match_dup 0))
26175 (parallel [(set (match_dup 2)
26176 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
26177 (clobber (reg:CC FLAGS_REG))])
26178 (set (match_dup 0) (match_dup 2))])
26181 [(match_scratch:SWI 2 "<r>")
26182 (parallel [(set (match_operand:SWI 0 "memory_operand")
26183 (match_operator:SWI 3 "arith_or_logical_operator"
26184 [(match_operand:SWI 1 "<nonmemory_operand>")
26186 (clobber (reg:CC FLAGS_REG))])]
26187 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
26188 [(set (match_dup 2) (match_dup 0))
26189 (parallel [(set (match_dup 2)
26190 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
26191 (clobber (reg:CC FLAGS_REG))])
26192 (set (match_dup 0) (match_dup 2))])
26194 ;; Attempt to use arith or logical operations with memory outputs with
26195 ;; setting of flags.
26197 [(set (match_operand:SWI 0 "register_operand")
26198 (match_operand:SWI 1 "memory_operand"))
26199 (parallel [(set (match_dup 0)
26200 (match_operator:SWI 3 "plusminuslogic_operator"
26202 (match_operand:SWI 2 "<nonmemory_operand>")]))
26203 (clobber (reg:CC FLAGS_REG))])
26204 (set (match_dup 1) (match_dup 0))
26205 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
26206 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
26207 && peep2_reg_dead_p (4, operands[0])
26208 && !reg_overlap_mentioned_p (operands[0], operands[1])
26209 && !reg_overlap_mentioned_p (operands[0], operands[2])
26210 && (<MODE>mode != QImode
26211 || immediate_operand (operands[2], QImode)
26212 || any_QIreg_operand (operands[2], QImode))
26213 && ix86_match_ccmode (peep2_next_insn (3),
26214 (GET_CODE (operands[3]) == PLUS
26215 || GET_CODE (operands[3]) == MINUS)
26216 ? CCGOCmode : CCNOmode)"
26217 [(parallel [(set (match_dup 4) (match_dup 6))
26218 (set (match_dup 1) (match_dup 5))])]
26220 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
26222 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
26223 copy_rtx (operands[1]),
26226 = gen_rtx_COMPARE (GET_MODE (operands[4]),
26227 copy_rtx (operands[5]),
26231 ;; Likewise for cmpelim optimized pattern.
26233 [(set (match_operand:SWI 0 "register_operand")
26234 (match_operand:SWI 1 "memory_operand"))
26235 (parallel [(set (reg FLAGS_REG)
26236 (compare (match_operator:SWI 3 "plusminuslogic_operator"
26238 (match_operand:SWI 2 "<nonmemory_operand>")])
26240 (set (match_dup 0) (match_dup 3))])
26241 (set (match_dup 1) (match_dup 0))]
26242 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
26243 && peep2_reg_dead_p (3, operands[0])
26244 && !reg_overlap_mentioned_p (operands[0], operands[1])
26245 && !reg_overlap_mentioned_p (operands[0], operands[2])
26246 && ix86_match_ccmode (peep2_next_insn (1),
26247 (GET_CODE (operands[3]) == PLUS
26248 || GET_CODE (operands[3]) == MINUS)
26249 ? CCGOCmode : CCNOmode)"
26250 [(parallel [(set (match_dup 4) (match_dup 6))
26251 (set (match_dup 1) (match_dup 5))])]
26253 operands[4] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
26255 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
26256 copy_rtx (operands[1]), operands[2]);
26258 = gen_rtx_COMPARE (GET_MODE (operands[4]), copy_rtx (operands[5]),
26262 ;; Likewise for instances where we have a lea pattern.
26264 [(set (match_operand:SWI 0 "register_operand")
26265 (match_operand:SWI 1 "memory_operand"))
26266 (set (match_operand:<LEAMODE> 3 "register_operand")
26267 (plus:<LEAMODE> (match_operand:<LEAMODE> 4 "register_operand")
26268 (match_operand:<LEAMODE> 2 "<nonmemory_operand>")))
26269 (set (match_dup 1) (match_operand:SWI 5 "register_operand"))
26270 (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
26271 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
26272 && REGNO (operands[4]) == REGNO (operands[0])
26273 && REGNO (operands[5]) == REGNO (operands[3])
26274 && peep2_reg_dead_p (4, operands[3])
26275 && ((REGNO (operands[0]) == REGNO (operands[3]))
26276 || peep2_reg_dead_p (2, operands[0]))
26277 && !reg_overlap_mentioned_p (operands[0], operands[1])
26278 && !reg_overlap_mentioned_p (operands[3], operands[1])
26279 && !reg_overlap_mentioned_p (operands[0], operands[2])
26280 && (<MODE>mode != QImode
26281 || immediate_operand (operands[2], QImode)
26282 || any_QIreg_operand (operands[2], QImode))
26283 && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
26284 [(parallel [(set (match_dup 6) (match_dup 8))
26285 (set (match_dup 1) (match_dup 7))])]
26287 operands[6] = SET_DEST (PATTERN (peep2_next_insn (3)));
26289 = gen_rtx_PLUS (<MODE>mode,
26290 copy_rtx (operands[1]),
26291 gen_lowpart (<MODE>mode, operands[2]));
26293 = gen_rtx_COMPARE (GET_MODE (operands[6]),
26294 copy_rtx (operands[7]),
26299 [(parallel [(set (match_operand:SWI 0 "register_operand")
26300 (match_operator:SWI 2 "plusminuslogic_operator"
26302 (match_operand:SWI 1 "memory_operand")]))
26303 (clobber (reg:CC FLAGS_REG))])
26304 (set (match_dup 1) (match_dup 0))
26305 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
26306 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
26307 && COMMUTATIVE_ARITH_P (operands[2])
26308 && peep2_reg_dead_p (3, operands[0])
26309 && !reg_overlap_mentioned_p (operands[0], operands[1])
26310 && ix86_match_ccmode (peep2_next_insn (2),
26311 GET_CODE (operands[2]) == PLUS
26312 ? CCGOCmode : CCNOmode)"
26313 [(parallel [(set (match_dup 3) (match_dup 5))
26314 (set (match_dup 1) (match_dup 4))])]
26316 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
26318 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
26319 copy_rtx (operands[1]),
26322 = gen_rtx_COMPARE (GET_MODE (operands[3]),
26323 copy_rtx (operands[4]),
26327 ;; Likewise for cmpelim optimized pattern.
26329 [(parallel [(set (reg FLAGS_REG)
26330 (compare (match_operator:SWI 2 "plusminuslogic_operator"
26331 [(match_operand:SWI 0 "register_operand")
26332 (match_operand:SWI 1 "memory_operand")])
26334 (set (match_dup 0) (match_dup 2))])
26335 (set (match_dup 1) (match_dup 0))]
26336 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
26337 && COMMUTATIVE_ARITH_P (operands[2])
26338 && peep2_reg_dead_p (2, operands[0])
26339 && !reg_overlap_mentioned_p (operands[0], operands[1])
26340 && ix86_match_ccmode (peep2_next_insn (0),
26341 GET_CODE (operands[2]) == PLUS
26342 ? CCGOCmode : CCNOmode)"
26343 [(parallel [(set (match_dup 3) (match_dup 5))
26344 (set (match_dup 1) (match_dup 4))])]
26346 operands[3] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (0)), 0, 0));
26348 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
26349 copy_rtx (operands[1]), operands[0]);
26351 = gen_rtx_COMPARE (GET_MODE (operands[3]), copy_rtx (operands[4]),
26356 [(set (match_operand:SWI12 0 "register_operand")
26357 (match_operand:SWI12 1 "memory_operand"))
26358 (parallel [(set (match_operand:SI 4 "register_operand")
26359 (match_operator:SI 3 "plusminuslogic_operator"
26361 (match_operand:SI 2 "nonmemory_operand")]))
26362 (clobber (reg:CC FLAGS_REG))])
26363 (set (match_dup 1) (match_dup 0))
26364 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
26365 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
26366 && REGNO (operands[0]) == REGNO (operands[4])
26367 && peep2_reg_dead_p (4, operands[0])
26368 && (<MODE>mode != QImode
26369 || immediate_operand (operands[2], SImode)
26370 || any_QIreg_operand (operands[2], SImode))
26371 && !reg_overlap_mentioned_p (operands[0], operands[1])
26372 && !reg_overlap_mentioned_p (operands[0], operands[2])
26373 && ix86_match_ccmode (peep2_next_insn (3),
26374 (GET_CODE (operands[3]) == PLUS
26375 || GET_CODE (operands[3]) == MINUS)
26376 ? CCGOCmode : CCNOmode)"
26377 [(parallel [(set (match_dup 5) (match_dup 7))
26378 (set (match_dup 1) (match_dup 6))])]
26380 operands[5] = SET_DEST (PATTERN (peep2_next_insn (3)));
26382 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
26383 copy_rtx (operands[1]),
26384 gen_lowpart (<MODE>mode, operands[2]));
26386 = gen_rtx_COMPARE (GET_MODE (operands[5]),
26387 copy_rtx (operands[6]),
26391 ;; peephole2 comes before regcprop, so deal also with a case that
26392 ;; would be cleaned up by regcprop.
26394 [(set (match_operand:SWI 0 "register_operand")
26395 (match_operand:SWI 1 "memory_operand"))
26396 (parallel [(set (match_dup 0)
26397 (match_operator:SWI 3 "plusminuslogic_operator"
26399 (match_operand:SWI 2 "<nonmemory_operand>")]))
26400 (clobber (reg:CC FLAGS_REG))])
26401 (set (match_operand:SWI 4 "register_operand") (match_dup 0))
26402 (set (match_dup 1) (match_dup 4))
26403 (set (reg FLAGS_REG) (compare (match_dup 4) (const_int 0)))]
26404 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
26405 && peep2_reg_dead_p (3, operands[0])
26406 && peep2_reg_dead_p (5, operands[4])
26407 && !reg_overlap_mentioned_p (operands[0], operands[1])
26408 && !reg_overlap_mentioned_p (operands[0], operands[2])
26409 && !reg_overlap_mentioned_p (operands[4], operands[1])
26410 && (<MODE>mode != QImode
26411 || immediate_operand (operands[2], QImode)
26412 || any_QIreg_operand (operands[2], QImode))
26413 && ix86_match_ccmode (peep2_next_insn (4),
26414 (GET_CODE (operands[3]) == PLUS
26415 || GET_CODE (operands[3]) == MINUS)
26416 ? CCGOCmode : CCNOmode)"
26417 [(parallel [(set (match_dup 5) (match_dup 7))
26418 (set (match_dup 1) (match_dup 6))])]
26420 operands[5] = SET_DEST (PATTERN (peep2_next_insn (4)));
26422 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
26423 copy_rtx (operands[1]),
26426 = gen_rtx_COMPARE (GET_MODE (operands[5]),
26427 copy_rtx (operands[6]),
26432 [(set (match_operand:SWI12 0 "register_operand")
26433 (match_operand:SWI12 1 "memory_operand"))
26434 (parallel [(set (match_operand:SI 4 "register_operand")
26435 (match_operator:SI 3 "plusminuslogic_operator"
26437 (match_operand:SI 2 "nonmemory_operand")]))
26438 (clobber (reg:CC FLAGS_REG))])
26439 (set (match_operand:SWI12 5 "register_operand") (match_dup 0))
26440 (set (match_dup 1) (match_dup 5))
26441 (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
26442 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
26443 && REGNO (operands[0]) == REGNO (operands[4])
26444 && peep2_reg_dead_p (3, operands[0])
26445 && peep2_reg_dead_p (5, operands[5])
26446 && (<MODE>mode != QImode
26447 || immediate_operand (operands[2], SImode)
26448 || any_QIreg_operand (operands[2], SImode))
26449 && !reg_overlap_mentioned_p (operands[0], operands[1])
26450 && !reg_overlap_mentioned_p (operands[0], operands[2])
26451 && !reg_overlap_mentioned_p (operands[5], operands[1])
26452 && ix86_match_ccmode (peep2_next_insn (4),
26453 (GET_CODE (operands[3]) == PLUS
26454 || GET_CODE (operands[3]) == MINUS)
26455 ? CCGOCmode : CCNOmode)"
26456 [(parallel [(set (match_dup 6) (match_dup 8))
26457 (set (match_dup 1) (match_dup 7))])]
26459 operands[6] = SET_DEST (PATTERN (peep2_next_insn (4)));
26461 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
26462 copy_rtx (operands[1]),
26463 gen_lowpart (<MODE>mode, operands[2]));
26465 = gen_rtx_COMPARE (GET_MODE (operands[6]),
26466 copy_rtx (operands[7]),
26470 ;; Likewise for cmpelim optimized pattern.
26472 [(set (match_operand:SWI 0 "register_operand")
26473 (match_operand:SWI 1 "memory_operand"))
26474 (parallel [(set (reg FLAGS_REG)
26475 (compare (match_operator:SWI 3 "plusminuslogic_operator"
26477 (match_operand:SWI 2 "<nonmemory_operand>")])
26479 (set (match_dup 0) (match_dup 3))])
26480 (set (match_operand:SWI 4 "register_operand") (match_dup 0))
26481 (set (match_dup 1) (match_dup 4))]
26482 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
26483 && peep2_reg_dead_p (3, operands[0])
26484 && peep2_reg_dead_p (4, operands[4])
26485 && !reg_overlap_mentioned_p (operands[0], operands[1])
26486 && !reg_overlap_mentioned_p (operands[0], operands[2])
26487 && !reg_overlap_mentioned_p (operands[4], operands[1])
26488 && ix86_match_ccmode (peep2_next_insn (1),
26489 (GET_CODE (operands[3]) == PLUS
26490 || GET_CODE (operands[3]) == MINUS)
26491 ? CCGOCmode : CCNOmode)"
26492 [(parallel [(set (match_dup 5) (match_dup 7))
26493 (set (match_dup 1) (match_dup 6))])]
26495 operands[5] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
26497 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
26498 copy_rtx (operands[1]), operands[2]);
26500 = gen_rtx_COMPARE (GET_MODE (operands[5]), copy_rtx (operands[6]),
26504 ;; Special cases for xor, where (x ^= y) != 0 is (misoptimized)
26505 ;; into x = z; x ^= y; x != z
26507 [(set (match_operand:SWI 0 "register_operand")
26508 (match_operand:SWI 1 "memory_operand"))
26509 (set (match_operand:SWI 3 "register_operand") (match_dup 0))
26510 (parallel [(set (match_operand:SWI 4 "register_operand")
26511 (xor:SWI (match_dup 4)
26512 (match_operand:SWI 2 "<nonmemory_operand>")))
26513 (clobber (reg:CC FLAGS_REG))])
26514 (set (match_dup 1) (match_dup 4))
26515 (set (reg:CCZ FLAGS_REG)
26516 (compare:CCZ (match_operand:SWI 5 "register_operand")
26517 (match_operand:SWI 6 "<nonmemory_operand>")))]
26518 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
26519 && (REGNO (operands[4]) == REGNO (operands[0])
26520 || REGNO (operands[4]) == REGNO (operands[3]))
26521 && (rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
26522 ? 3 : 0], operands[5])
26523 ? rtx_equal_p (operands[2], operands[6])
26524 : rtx_equal_p (operands[2], operands[5])
26525 && rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
26526 ? 3 : 0], operands[6]))
26527 && peep2_reg_dead_p (4, operands[4])
26528 && peep2_reg_dead_p (5, operands[REGNO (operands[4]) == REGNO (operands[0])
26530 && !reg_overlap_mentioned_p (operands[0], operands[1])
26531 && !reg_overlap_mentioned_p (operands[0], operands[2])
26532 && !reg_overlap_mentioned_p (operands[3], operands[0])
26533 && !reg_overlap_mentioned_p (operands[3], operands[1])
26534 && !reg_overlap_mentioned_p (operands[3], operands[2])
26535 && (<MODE>mode != QImode
26536 || immediate_operand (operands[2], QImode)
26537 || any_QIreg_operand (operands[2], QImode))"
26538 [(parallel [(set (match_dup 7) (match_dup 9))
26539 (set (match_dup 1) (match_dup 8))])]
26541 operands[7] = SET_DEST (PATTERN (peep2_next_insn (4)));
26542 operands[8] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
26545 = gen_rtx_COMPARE (GET_MODE (operands[7]),
26546 copy_rtx (operands[8]),
26551 [(set (match_operand:SWI12 0 "register_operand")
26552 (match_operand:SWI12 1 "memory_operand"))
26553 (set (match_operand:SWI12 3 "register_operand") (match_dup 0))
26554 (parallel [(set (match_operand:SI 4 "register_operand")
26555 (xor:SI (match_dup 4)
26556 (match_operand:SI 2 "<nonmemory_operand>")))
26557 (clobber (reg:CC FLAGS_REG))])
26558 (set (match_dup 1) (match_operand:SWI12 5 "register_operand"))
26559 (set (reg:CCZ FLAGS_REG)
26560 (compare:CCZ (match_operand:SWI12 6 "register_operand")
26561 (match_operand:SWI12 7 "<nonmemory_operand>")))]
26562 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
26563 && (REGNO (operands[5]) == REGNO (operands[0])
26564 || REGNO (operands[5]) == REGNO (operands[3]))
26565 && REGNO (operands[5]) == REGNO (operands[4])
26566 && (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
26567 ? 3 : 0], operands[6])
26568 ? (REG_P (operands[2])
26569 ? REG_P (operands[7]) && REGNO (operands[2]) == REGNO (operands[7])
26570 : rtx_equal_p (operands[2], operands[7]))
26571 : (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
26572 ? 3 : 0], operands[7])
26573 && REG_P (operands[2])
26574 && REGNO (operands[2]) == REGNO (operands[6])))
26575 && peep2_reg_dead_p (4, operands[5])
26576 && peep2_reg_dead_p (5, operands[REGNO (operands[5]) == REGNO (operands[0])
26578 && !reg_overlap_mentioned_p (operands[0], operands[1])
26579 && !reg_overlap_mentioned_p (operands[0], operands[2])
26580 && !reg_overlap_mentioned_p (operands[3], operands[0])
26581 && !reg_overlap_mentioned_p (operands[3], operands[1])
26582 && !reg_overlap_mentioned_p (operands[3], operands[2])
26583 && (<MODE>mode != QImode
26584 || immediate_operand (operands[2], SImode)
26585 || any_QIreg_operand (operands[2], SImode))"
26586 [(parallel [(set (match_dup 8) (match_dup 10))
26587 (set (match_dup 1) (match_dup 9))])]
26589 operands[8] = SET_DEST (PATTERN (peep2_next_insn (4)));
26590 operands[9] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
26591 gen_lowpart (<MODE>mode, operands[2]));
26593 = gen_rtx_COMPARE (GET_MODE (operands[8]),
26594 copy_rtx (operands[9]),
26598 ;; Attempt to optimize away memory stores of values the memory already
26599 ;; has. See PR79593.
26601 [(set (match_operand 0 "register_operand")
26602 (match_operand 1 "memory_operand"))
26603 (set (match_operand 2 "memory_operand") (match_dup 0))]
26604 "!MEM_VOLATILE_P (operands[1])
26605 && !MEM_VOLATILE_P (operands[2])
26606 && rtx_equal_p (operands[1], operands[2])
26607 && !reg_overlap_mentioned_p (operands[0], operands[2])"
26608 [(set (match_dup 0) (match_dup 1))])
26610 ;; Attempt to always use XOR for zeroing registers (including FP modes).
26612 [(set (match_operand 0 "general_reg_operand")
26613 (match_operand 1 "const0_operand"))]
26614 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
26615 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
26616 && peep2_regno_dead_p (0, FLAGS_REG)"
26617 [(parallel [(set (match_dup 0) (const_int 0))
26618 (clobber (reg:CC FLAGS_REG))])]
26619 "operands[0] = gen_lowpart (word_mode, operands[0]);")
26622 [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
26624 "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
26625 && peep2_regno_dead_p (0, FLAGS_REG)"
26626 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
26627 (clobber (reg:CC FLAGS_REG))])])
26629 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
26631 [(set (match_operand:SWI248 0 "general_reg_operand")
26633 "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
26634 && peep2_regno_dead_p (0, FLAGS_REG)"
26635 [(parallel [(set (match_dup 0) (const_int -1))
26636 (clobber (reg:CC FLAGS_REG))])]
26638 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
26639 operands[0] = gen_lowpart (SImode, operands[0]);
26642 ;; Attempt to convert simple lea to add/shift.
26643 ;; These can be created by move expanders.
26644 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
26645 ;; relevant lea instructions were already split.
26648 [(set (match_operand:SWI48 0 "register_operand")
26649 (plus:SWI48 (match_dup 0)
26650 (match_operand:SWI48 1 "<nonmemory_operand>")))]
26652 && peep2_regno_dead_p (0, FLAGS_REG)"
26653 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
26654 (clobber (reg:CC FLAGS_REG))])])
26657 [(set (match_operand:SWI48 0 "register_operand")
26658 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
26661 && peep2_regno_dead_p (0, FLAGS_REG)"
26662 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
26663 (clobber (reg:CC FLAGS_REG))])])
26666 [(set (match_operand:DI 0 "register_operand")
26668 (plus:SI (match_operand:SI 1 "register_operand")
26669 (match_operand:SI 2 "nonmemory_operand"))))]
26670 "TARGET_64BIT && !TARGET_OPT_AGU
26671 && REGNO (operands[0]) == REGNO (operands[1])
26672 && peep2_regno_dead_p (0, FLAGS_REG)"
26673 [(parallel [(set (match_dup 0)
26674 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
26675 (clobber (reg:CC FLAGS_REG))])])
26678 [(set (match_operand:DI 0 "register_operand")
26680 (plus:SI (match_operand:SI 1 "nonmemory_operand")
26681 (match_operand:SI 2 "register_operand"))))]
26682 "TARGET_64BIT && !TARGET_OPT_AGU
26683 && REGNO (operands[0]) == REGNO (operands[2])
26684 && peep2_regno_dead_p (0, FLAGS_REG)"
26685 [(parallel [(set (match_dup 0)
26686 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
26687 (clobber (reg:CC FLAGS_REG))])])
26690 [(set (match_operand:SWI48 0 "register_operand")
26691 (mult:SWI48 (match_dup 0)
26692 (match_operand:SWI48 1 "const_int_operand")))]
26693 "pow2p_hwi (INTVAL (operands[1]))
26694 && peep2_regno_dead_p (0, FLAGS_REG)"
26695 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
26696 (clobber (reg:CC FLAGS_REG))])]
26697 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
26700 [(set (match_operand:DI 0 "register_operand")
26702 (mult:SI (match_operand:SI 1 "register_operand")
26703 (match_operand:SI 2 "const_int_operand"))))]
26705 && pow2p_hwi (INTVAL (operands[2]))
26706 && REGNO (operands[0]) == REGNO (operands[1])
26707 && peep2_regno_dead_p (0, FLAGS_REG)"
26708 [(parallel [(set (match_dup 0)
26709 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
26710 (clobber (reg:CC FLAGS_REG))])]
26711 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
26713 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
26714 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
26715 ;; On many CPUs it is also faster, since special hardware to avoid esp
26716 ;; dependencies is present.
26718 ;; While some of these conversions may be done using splitters, we use
26719 ;; peepholes in order to allow combine_stack_adjustments pass to see
26720 ;; nonobfuscated RTL.
26722 ;; Convert prologue esp subtractions to push.
26723 ;; We need register to push. In order to keep verify_flow_info happy we have
26725 ;; - use scratch and clobber it in order to avoid dependencies
26726 ;; - use already live register
26727 ;; We can't use the second way right now, since there is no reliable way how to
26728 ;; verify that given register is live. First choice will also most likely in
26729 ;; fewer dependencies. On the place of esp adjustments it is very likely that
26730 ;; call clobbered registers are dead. We may want to use base pointer as an
26731 ;; alternative when no register is available later.
26734 [(match_scratch:W 1 "r")
26735 (parallel [(set (reg:P SP_REG)
26736 (plus:P (reg:P SP_REG)
26737 (match_operand:P 0 "const_int_operand")))
26738 (clobber (reg:CC FLAGS_REG))
26739 (clobber (mem:BLK (scratch)))])]
26740 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
26741 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
26742 && !ix86_red_zone_used"
26743 [(clobber (match_dup 1))
26744 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
26745 (clobber (mem:BLK (scratch)))])])
26748 [(match_scratch:W 1 "r")
26749 (parallel [(set (reg:P SP_REG)
26750 (plus:P (reg:P SP_REG)
26751 (match_operand:P 0 "const_int_operand")))
26752 (clobber (reg:CC FLAGS_REG))
26753 (clobber (mem:BLK (scratch)))])]
26754 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
26755 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
26756 && !ix86_red_zone_used"
26757 [(clobber (match_dup 1))
26758 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
26759 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
26760 (clobber (mem:BLK (scratch)))])])
26762 ;; Convert esp subtractions to push.
26764 [(match_scratch:W 1 "r")
26765 (parallel [(set (reg:P SP_REG)
26766 (plus:P (reg:P SP_REG)
26767 (match_operand:P 0 "const_int_operand")))
26768 (clobber (reg:CC FLAGS_REG))])]
26769 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
26770 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
26771 && !ix86_red_zone_used"
26772 [(clobber (match_dup 1))
26773 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
26776 [(match_scratch:W 1 "r")
26777 (parallel [(set (reg:P SP_REG)
26778 (plus:P (reg:P SP_REG)
26779 (match_operand:P 0 "const_int_operand")))
26780 (clobber (reg:CC FLAGS_REG))])]
26781 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
26782 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
26783 && !ix86_red_zone_used"
26784 [(clobber (match_dup 1))
26785 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
26786 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
26788 ;; Convert epilogue deallocator to pop.
26790 [(match_scratch:W 1 "r")
26791 (parallel [(set (reg:P SP_REG)
26792 (plus:P (reg:P SP_REG)
26793 (match_operand:P 0 "const_int_operand")))
26794 (clobber (reg:CC FLAGS_REG))
26795 (clobber (mem:BLK (scratch)))])]
26796 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
26797 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
26798 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
26799 (clobber (mem:BLK (scratch)))])])
26801 ;; Two pops case is tricky, since pop causes dependency
26802 ;; on destination register. We use two registers if available.
26804 [(match_scratch:W 1 "r")
26805 (match_scratch:W 2 "r")
26806 (parallel [(set (reg:P SP_REG)
26807 (plus:P (reg:P SP_REG)
26808 (match_operand:P 0 "const_int_operand")))
26809 (clobber (reg:CC FLAGS_REG))
26810 (clobber (mem:BLK (scratch)))])]
26811 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
26812 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
26813 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
26814 (clobber (mem:BLK (scratch)))])
26815 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
26818 [(match_scratch:W 1 "r")
26819 (parallel [(set (reg:P SP_REG)
26820 (plus:P (reg:P SP_REG)
26821 (match_operand:P 0 "const_int_operand")))
26822 (clobber (reg:CC FLAGS_REG))
26823 (clobber (mem:BLK (scratch)))])]
26824 "optimize_insn_for_size_p ()
26825 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
26826 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
26827 (clobber (mem:BLK (scratch)))])
26828 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
26830 ;; Convert esp additions to pop.
26832 [(match_scratch:W 1 "r")
26833 (parallel [(set (reg:P SP_REG)
26834 (plus:P (reg:P SP_REG)
26835 (match_operand:P 0 "const_int_operand")))
26836 (clobber (reg:CC FLAGS_REG))])]
26837 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
26838 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
26840 ;; Two pops case is tricky, since pop causes dependency
26841 ;; on destination register. We use two registers if available.
26843 [(match_scratch:W 1 "r")
26844 (match_scratch:W 2 "r")
26845 (parallel [(set (reg:P SP_REG)
26846 (plus:P (reg:P SP_REG)
26847 (match_operand:P 0 "const_int_operand")))
26848 (clobber (reg:CC FLAGS_REG))])]
26849 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
26850 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
26851 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
26854 [(match_scratch:W 1 "r")
26855 (parallel [(set (reg:P SP_REG)
26856 (plus:P (reg:P SP_REG)
26857 (match_operand:P 0 "const_int_operand")))
26858 (clobber (reg:CC FLAGS_REG))])]
26859 "optimize_insn_for_size_p ()
26860 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
26861 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
26862 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
26864 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
26865 ;; required and register dies. Similarly for 128 to -128.
26867 [(set (match_operand 0 "flags_reg_operand")
26868 (match_operator 1 "compare_operator"
26869 [(match_operand 2 "register_operand")
26870 (match_operand 3 "const_int_operand")]))]
26871 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
26872 && incdec_operand (operands[3], GET_MODE (operands[3])))
26873 || (!TARGET_FUSE_CMP_AND_BRANCH
26874 && INTVAL (operands[3]) == 128))
26875 && ix86_match_ccmode (insn, CCGCmode)
26876 && peep2_reg_dead_p (1, operands[2])"
26877 [(parallel [(set (match_dup 0)
26878 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
26879 (clobber (match_dup 2))])])
26881 ;; Convert imul by three, five and nine into lea
26884 [(set (match_operand:SWI48 0 "register_operand")
26885 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
26886 (match_operand:SWI48 2 "const359_operand")))
26887 (clobber (reg:CC FLAGS_REG))])]
26888 "!TARGET_PARTIAL_REG_STALL
26889 || <MODE>mode == SImode
26890 || optimize_function_for_size_p (cfun)"
26891 [(set (match_dup 0)
26892 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
26894 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
26898 [(set (match_operand:SWI48 0 "register_operand")
26899 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
26900 (match_operand:SWI48 2 "const359_operand")))
26901 (clobber (reg:CC FLAGS_REG))])]
26902 "optimize_insn_for_speed_p ()
26903 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
26904 [(set (match_dup 0) (match_dup 1))
26906 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
26908 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
26910 ;; imul $32bit_imm, mem, reg is vector decoded, while
26911 ;; imul $32bit_imm, reg, reg is direct decoded.
26913 [(match_scratch:SWI48 3 "r")
26914 (parallel [(set (match_operand:SWI48 0 "register_operand")
26915 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
26916 (match_operand:SWI48 2 "immediate_operand")))
26917 (clobber (reg:CC FLAGS_REG))])]
26918 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
26919 && !satisfies_constraint_K (operands[2])"
26920 [(set (match_dup 3) (match_dup 1))
26921 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
26922 (clobber (reg:CC FLAGS_REG))])])
26925 [(match_scratch:SI 3 "r")
26926 (parallel [(set (match_operand:DI 0 "register_operand")
26928 (mult:SI (match_operand:SI 1 "memory_operand")
26929 (match_operand:SI 2 "immediate_operand"))))
26930 (clobber (reg:CC FLAGS_REG))])]
26932 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
26933 && !satisfies_constraint_K (operands[2])"
26934 [(set (match_dup 3) (match_dup 1))
26935 (parallel [(set (match_dup 0)
26936 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
26937 (clobber (reg:CC FLAGS_REG))])])
26939 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
26940 ;; Convert it into imul reg, reg
26941 ;; It would be better to force assembler to encode instruction using long
26942 ;; immediate, but there is apparently no way to do so.
26944 [(parallel [(set (match_operand:SWI248 0 "register_operand")
26946 (match_operand:SWI248 1 "nonimmediate_operand")
26947 (match_operand:SWI248 2 "const_int_operand")))
26948 (clobber (reg:CC FLAGS_REG))])
26949 (match_scratch:SWI248 3 "r")]
26950 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
26951 && satisfies_constraint_K (operands[2])"
26952 [(set (match_dup 3) (match_dup 2))
26953 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
26954 (clobber (reg:CC FLAGS_REG))])]
26956 if (!rtx_equal_p (operands[0], operands[1]))
26957 emit_move_insn (operands[0], operands[1]);
26960 ;; After splitting up read-modify operations, array accesses with memory
26961 ;; operands might end up in form:
26963 ;; movl 4(%esp), %edx
26965 ;; instead of pre-splitting:
26967 ;; addl 4(%esp), %eax
26969 ;; movl 4(%esp), %edx
26970 ;; leal (%edx,%eax,4), %eax
26973 [(match_scratch:W 5 "r")
26974 (parallel [(set (match_operand 0 "register_operand")
26975 (ashift (match_operand 1 "register_operand")
26976 (match_operand 2 "const_int_operand")))
26977 (clobber (reg:CC FLAGS_REG))])
26978 (parallel [(set (match_operand 3 "register_operand")
26979 (plus (match_dup 0)
26980 (match_operand 4 "x86_64_general_operand")))
26981 (clobber (reg:CC FLAGS_REG))])]
26982 "IN_RANGE (INTVAL (operands[2]), 1, 3)
26983 /* Validate MODE for lea. */
26984 && ((!TARGET_PARTIAL_REG_STALL
26985 && (GET_MODE (operands[0]) == QImode
26986 || GET_MODE (operands[0]) == HImode))
26987 || GET_MODE (operands[0]) == SImode
26988 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
26989 && (rtx_equal_p (operands[0], operands[3])
26990 || peep2_reg_dead_p (2, operands[0]))
26991 /* We reorder load and the shift. */
26992 && !reg_overlap_mentioned_p (operands[0], operands[4])"
26993 [(set (match_dup 5) (match_dup 4))
26994 (set (match_dup 0) (match_dup 1))]
26996 machine_mode op1mode = GET_MODE (operands[1]);
26997 machine_mode mode = op1mode == DImode ? DImode : SImode;
26998 int scale = 1 << INTVAL (operands[2]);
26999 rtx index = gen_lowpart (word_mode, operands[1]);
27000 rtx base = gen_lowpart (word_mode, operands[5]);
27001 rtx dest = gen_lowpart (mode, operands[3]);
27003 operands[1] = gen_rtx_PLUS (word_mode, base,
27004 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
27005 if (mode != word_mode)
27006 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
27008 operands[5] = base;
27009 if (op1mode != word_mode)
27010 operands[5] = gen_lowpart (op1mode, operands[5]);
27012 operands[0] = dest;
27015 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
27016 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
27017 ;; caught for use by garbage collectors and the like. Using an insn that
27018 ;; maps to SIGILL makes it more likely the program will rightfully die.
27019 ;; Keeping with tradition, "6" is in honor of #UD.
27020 (define_insn "trap"
27021 [(trap_if (const_int 1) (const_int 6))]
27024 #ifdef HAVE_AS_IX86_UD2
27027 return ASM_SHORT "0x0b0f";
27030 [(set_attr "length" "2")])
27033 [(unspec_volatile [(const_int 0)] UNSPECV_UD2)]
27036 #ifdef HAVE_AS_IX86_UD2
27039 return ASM_SHORT "0x0b0f";
27042 [(set_attr "length" "2")])
27044 (define_expand "prefetch"
27045 [(prefetch (match_operand 0 "address_operand")
27046 (match_operand:SI 1 "const_int_operand")
27047 (match_operand:SI 2 "const_int_operand"))]
27048 "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
27050 bool write = operands[1] != const0_rtx;
27051 int locality = INTVAL (operands[2]);
27053 gcc_assert (IN_RANGE (locality, 0, 3));
27055 /* Use 3dNOW prefetch in case we are asking for write prefetch not
27056 supported by SSE counterpart (non-SSE2 athlon machines) or the
27057 SSE prefetch is not available (K6 machines). Otherwise use SSE
27058 prefetch as it allows specifying of locality. */
27062 if (TARGET_PREFETCHWT1)
27063 operands[2] = GEN_INT (MAX (locality, 2));
27064 else if (TARGET_PRFCHW)
27065 operands[2] = GEN_INT (3);
27066 else if (TARGET_3DNOW && !TARGET_SSE2)
27067 operands[2] = GEN_INT (3);
27068 else if (TARGET_PREFETCH_SSE)
27069 operands[1] = const0_rtx;
27072 gcc_assert (TARGET_3DNOW);
27073 operands[2] = GEN_INT (3);
27078 if (TARGET_PREFETCH_SSE)
27082 gcc_assert (TARGET_3DNOW);
27083 operands[2] = GEN_INT (3);
27088 (define_insn "*prefetch_sse"
27089 [(prefetch (match_operand 0 "address_operand" "p")
27091 (match_operand:SI 1 "const_int_operand"))]
27092 "TARGET_PREFETCH_SSE"
27094 static const char * const patterns[4] = {
27095 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
27098 int locality = INTVAL (operands[1]);
27099 gcc_assert (IN_RANGE (locality, 0, 3));
27101 return patterns[locality];
27103 [(set_attr "type" "sse")
27104 (set_attr "atom_sse_attr" "prefetch")
27105 (set (attr "length_address")
27106 (symbol_ref "memory_address_length (operands[0], false)"))
27107 (set_attr "memory" "none")])
27109 (define_insn "*prefetch_3dnow"
27110 [(prefetch (match_operand 0 "address_operand" "p")
27111 (match_operand:SI 1 "const_int_operand")
27113 "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1"
27115 if (operands[1] == const0_rtx)
27116 return "prefetch\t%a0";
27118 return "prefetchw\t%a0";
27120 [(set_attr "type" "mmx")
27121 (set (attr "length_address")
27122 (symbol_ref "memory_address_length (operands[0], false)"))
27123 (set_attr "memory" "none")])
27125 (define_insn "*prefetch_prefetchwt1"
27126 [(prefetch (match_operand 0 "address_operand" "p")
27129 "TARGET_PREFETCHWT1"
27130 "prefetchwt1\t%a0";
27131 [(set_attr "type" "sse")
27132 (set (attr "length_address")
27133 (symbol_ref "memory_address_length (operands[0], false)"))
27134 (set_attr "memory" "none")])
27136 (define_insn "prefetchi"
27137 [(unspec_volatile [(match_operand 0 "local_func_symbolic_operand" "p")
27138 (match_operand:SI 1 "const_int_operand")]
27139 UNSPECV_PREFETCHI)]
27140 "TARGET_PREFETCHI && TARGET_64BIT"
27142 static const char * const patterns[2] = {
27143 "prefetchit1\t%0", "prefetchit0\t%0"
27146 int locality = INTVAL (operands[1]);
27147 gcc_assert (IN_RANGE (locality, 2, 3));
27149 return patterns[locality - 2];
27151 [(set_attr "type" "sse")
27152 (set (attr "length_address")
27153 (symbol_ref "memory_address_length (operands[0], false)"))
27154 (set_attr "memory" "none")])
27156 (define_insn "sse4_2_crc32<mode>"
27157 [(set (match_operand:SI 0 "register_operand" "=r")
27159 [(match_operand:SI 1 "register_operand" "0")
27160 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
27163 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
27164 [(set_attr "type" "sselog1")
27165 (set_attr "prefix_rep" "1")
27166 (set_attr "prefix_extra" "1")
27167 (set (attr "prefix_data16")
27168 (if_then_else (match_operand:HI 2)
27170 (const_string "*")))
27171 (set (attr "prefix_rex")
27172 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
27174 (const_string "*")))
27175 (set_attr "mode" "SI")])
27177 (define_insn "sse4_2_crc32di"
27178 [(set (match_operand:DI 0 "register_operand" "=r")
27181 [(match_operand:SI 1 "register_operand" "0")
27182 (match_operand:DI 2 "nonimmediate_operand" "rm")]
27184 "TARGET_64BIT && TARGET_CRC32"
27185 "crc32{q}\t{%2, %0|%0, %2}"
27186 [(set_attr "type" "sselog1")
27187 (set_attr "prefix_rep" "1")
27188 (set_attr "prefix_extra" "1")
27189 (set_attr "mode" "DI")])
27191 (define_insn "rdpmc"
27192 [(set (match_operand:DI 0 "register_operand" "=A")
27193 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
27197 [(set_attr "type" "other")
27198 (set_attr "length" "2")])
27200 (define_insn "rdpmc_rex64"
27201 [(set (match_operand:DI 0 "register_operand" "=a")
27202 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
27204 (set (match_operand:DI 1 "register_operand" "=d")
27205 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
27208 [(set_attr "type" "other")
27209 (set_attr "length" "2")])
27211 (define_insn "rdtsc"
27212 [(set (match_operand:DI 0 "register_operand" "=A")
27213 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
27216 [(set_attr "type" "other")
27217 (set_attr "length" "2")])
27219 (define_insn "rdtsc_rex64"
27220 [(set (match_operand:DI 0 "register_operand" "=a")
27221 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
27222 (set (match_operand:DI 1 "register_operand" "=d")
27223 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
27226 [(set_attr "type" "other")
27227 (set_attr "length" "2")])
27229 (define_insn "rdtscp"
27230 [(set (match_operand:DI 0 "register_operand" "=A")
27231 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
27232 (set (match_operand:SI 1 "register_operand" "=c")
27233 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
27236 [(set_attr "type" "other")
27237 (set_attr "length" "3")])
27239 (define_insn "rdtscp_rex64"
27240 [(set (match_operand:DI 0 "register_operand" "=a")
27241 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
27242 (set (match_operand:DI 1 "register_operand" "=d")
27243 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
27244 (set (match_operand:SI 2 "register_operand" "=c")
27245 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
27248 [(set_attr "type" "other")
27249 (set_attr "length" "3")])
27251 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
27253 ;; FXSR, XSAVE and XSAVEOPT instructions
27255 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
27257 (define_insn "fxsave"
27258 [(set (match_operand:BLK 0 "memory_operand" "=m")
27259 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
27262 [(set_attr "type" "other")
27263 (set_attr "memory" "store")
27264 (set (attr "length")
27265 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
27267 (define_insn "fxsave64"
27268 [(set (match_operand:BLK 0 "memory_operand" "=jm")
27269 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
27270 "TARGET_64BIT && TARGET_FXSR"
27272 [(set_attr "type" "other")
27273 (set_attr "addr" "gpr16")
27274 (set_attr "memory" "store")
27275 (set (attr "length")
27276 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
27278 (define_insn "fxrstor"
27279 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
27283 [(set_attr "type" "other")
27284 (set_attr "memory" "load")
27285 (set (attr "length")
27286 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
27288 (define_insn "fxrstor64"
27289 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "jm")]
27290 UNSPECV_FXRSTOR64)]
27291 "TARGET_64BIT && TARGET_FXSR"
27293 [(set_attr "type" "other")
27294 (set_attr "addr" "gpr16")
27295 (set_attr "memory" "load")
27296 (set (attr "length")
27297 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
27299 (define_int_iterator ANY_XSAVE
27301 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
27302 (UNSPECV_XSAVEC "TARGET_XSAVEC")
27303 (UNSPECV_XSAVES "TARGET_XSAVES")])
27305 (define_int_iterator ANY_XSAVE64
27307 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
27308 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
27309 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
27311 (define_int_attr xsave
27312 [(UNSPECV_XSAVE "xsave")
27313 (UNSPECV_XSAVE64 "xsave64")
27314 (UNSPECV_XSAVEOPT "xsaveopt")
27315 (UNSPECV_XSAVEOPT64 "xsaveopt64")
27316 (UNSPECV_XSAVEC "xsavec")
27317 (UNSPECV_XSAVEC64 "xsavec64")
27318 (UNSPECV_XSAVES "xsaves")
27319 (UNSPECV_XSAVES64 "xsaves64")])
27321 (define_int_iterator ANY_XRSTOR
27323 (UNSPECV_XRSTORS "TARGET_XSAVES")])
27325 (define_int_iterator ANY_XRSTOR64
27327 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
27329 (define_int_attr xrstor
27330 [(UNSPECV_XRSTOR "xrstor")
27331 (UNSPECV_XRSTOR64 "xrstor")
27332 (UNSPECV_XRSTORS "xrstors")
27333 (UNSPECV_XRSTORS64 "xrstors")])
27335 (define_insn "<xsave>"
27336 [(set (match_operand:BLK 0 "memory_operand" "=m")
27337 (unspec_volatile:BLK
27338 [(match_operand:DI 1 "register_operand" "A")]
27340 "!TARGET_64BIT && TARGET_XSAVE"
27342 [(set_attr "type" "other")
27343 (set_attr "memory" "store")
27344 (set (attr "length")
27345 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
27347 (define_insn "<xsave>_rex64"
27348 [(set (match_operand:BLK 0 "memory_operand" "=jm")
27349 (unspec_volatile:BLK
27350 [(match_operand:SI 1 "register_operand" "a")
27351 (match_operand:SI 2 "register_operand" "d")]
27353 "TARGET_64BIT && TARGET_XSAVE"
27355 [(set_attr "type" "other")
27356 (set_attr "memory" "store")
27357 (set_attr "addr" "gpr16")
27358 (set (attr "length")
27359 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
27361 (define_insn "<xsave>"
27362 [(set (match_operand:BLK 0 "memory_operand" "=jm")
27363 (unspec_volatile:BLK
27364 [(match_operand:SI 1 "register_operand" "a")
27365 (match_operand:SI 2 "register_operand" "d")]
27367 "TARGET_64BIT && TARGET_XSAVE"
27369 [(set_attr "type" "other")
27370 (set_attr "memory" "store")
27371 (set_attr "addr" "gpr16")
27372 (set (attr "length")
27373 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
27375 (define_insn "<xrstor>"
27376 [(unspec_volatile:BLK
27377 [(match_operand:BLK 0 "memory_operand" "m")
27378 (match_operand:DI 1 "register_operand" "A")]
27380 "!TARGET_64BIT && TARGET_XSAVE"
27382 [(set_attr "type" "other")
27383 (set_attr "memory" "load")
27384 (set (attr "length")
27385 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
27387 (define_insn "<xrstor>_rex64"
27388 [(unspec_volatile:BLK
27389 [(match_operand:BLK 0 "memory_operand" "jm")
27390 (match_operand:SI 1 "register_operand" "a")
27391 (match_operand:SI 2 "register_operand" "d")]
27393 "TARGET_64BIT && TARGET_XSAVE"
27395 [(set_attr "type" "other")
27396 (set_attr "memory" "load")
27397 (set_attr "addr" "gpr16")
27398 (set (attr "length")
27399 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
27401 (define_insn "<xrstor>64"
27402 [(unspec_volatile:BLK
27403 [(match_operand:BLK 0 "memory_operand" "jm")
27404 (match_operand:SI 1 "register_operand" "a")
27405 (match_operand:SI 2 "register_operand" "d")]
27407 "TARGET_64BIT && TARGET_XSAVE"
27409 [(set_attr "type" "other")
27410 (set_attr "memory" "load")
27411 (set_attr "addr" "gpr16")
27412 (set (attr "length")
27413 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
27415 (define_insn "xsetbv"
27416 [(unspec_volatile:SI
27417 [(match_operand:SI 0 "register_operand" "c")
27418 (match_operand:DI 1 "register_operand" "A")]
27420 "!TARGET_64BIT && TARGET_XSAVE"
27422 [(set_attr "type" "other")])
27424 (define_insn "xsetbv_rex64"
27425 [(unspec_volatile:SI
27426 [(match_operand:SI 0 "register_operand" "c")
27427 (match_operand:SI 1 "register_operand" "a")
27428 (match_operand:SI 2 "register_operand" "d")]
27430 "TARGET_64BIT && TARGET_XSAVE"
27432 [(set_attr "type" "other")])
27434 (define_insn "xgetbv"
27435 [(set (match_operand:DI 0 "register_operand" "=A")
27436 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
27438 "!TARGET_64BIT && TARGET_XSAVE"
27440 [(set_attr "type" "other")])
27442 (define_insn "xgetbv_rex64"
27443 [(set (match_operand:DI 0 "register_operand" "=a")
27444 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
27446 (set (match_operand:DI 1 "register_operand" "=d")
27447 (unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))]
27448 "TARGET_64BIT && TARGET_XSAVE"
27450 [(set_attr "type" "other")])
27452 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
27454 ;; Floating-point instructions for atomic compound assignments
27456 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
27458 ; Clobber all floating-point registers on environment save and restore
27459 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
27460 (define_insn "fnstenv"
27461 [(set (match_operand:BLK 0 "memory_operand" "=m")
27462 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
27463 (clobber (reg:XF ST0_REG))
27464 (clobber (reg:XF ST1_REG))
27465 (clobber (reg:XF ST2_REG))
27466 (clobber (reg:XF ST3_REG))
27467 (clobber (reg:XF ST4_REG))
27468 (clobber (reg:XF ST5_REG))
27469 (clobber (reg:XF ST6_REG))
27470 (clobber (reg:XF ST7_REG))]
27473 [(set_attr "type" "other")
27474 (set_attr "memory" "store")
27475 (set (attr "length")
27476 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
27478 (define_insn "fldenv"
27479 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
27481 (clobber (reg:XF ST0_REG))
27482 (clobber (reg:XF ST1_REG))
27483 (clobber (reg:XF ST2_REG))
27484 (clobber (reg:XF ST3_REG))
27485 (clobber (reg:XF ST4_REG))
27486 (clobber (reg:XF ST5_REG))
27487 (clobber (reg:XF ST6_REG))
27488 (clobber (reg:XF ST7_REG))]
27491 [(set_attr "type" "other")
27492 (set_attr "memory" "load")
27493 (set (attr "length")
27494 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
27496 (define_insn "fnstsw"
27497 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
27498 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
27501 [(set_attr "type" "other,other")
27502 (set_attr "memory" "none,store")
27503 (set (attr "length")
27504 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
27506 (define_insn "fnclex"
27507 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
27510 [(set_attr "type" "other")
27511 (set_attr "memory" "none")
27512 (set_attr "length" "2")])
27514 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
27516 ;; LWP instructions
27518 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
27520 (define_insn "@lwp_llwpcb<mode>"
27521 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
27522 UNSPECV_LLWP_INTRINSIC)]
27525 [(set_attr "type" "lwp")
27526 (set_attr "mode" "<MODE>")
27527 (set_attr "length" "5")])
27529 (define_insn "@lwp_slwpcb<mode>"
27530 [(set (match_operand:P 0 "register_operand" "=r")
27531 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
27534 [(set_attr "type" "lwp")
27535 (set_attr "mode" "<MODE>")
27536 (set_attr "length" "5")])
27538 (define_insn "@lwp_lwpval<mode>"
27539 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
27540 (match_operand:SI 1 "nonimmediate_operand" "rm")
27541 (match_operand:SI 2 "const_int_operand")]
27542 UNSPECV_LWPVAL_INTRINSIC)]
27544 "lwpval\t{%2, %1, %0|%0, %1, %2}"
27545 [(set_attr "type" "lwp")
27546 (set_attr "mode" "<MODE>")
27547 (set (attr "length")
27548 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
27550 (define_insn "@lwp_lwpins<mode>"
27551 [(set (reg:CCC FLAGS_REG)
27552 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
27553 (match_operand:SI 1 "nonimmediate_operand" "rm")
27554 (match_operand:SI 2 "const_int_operand")]
27555 UNSPECV_LWPINS_INTRINSIC))]
27557 "lwpins\t{%2, %1, %0|%0, %1, %2}"
27558 [(set_attr "type" "lwp")
27559 (set_attr "mode" "<MODE>")
27560 (set (attr "length")
27561 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
27563 (define_int_iterator RDFSGSBASE
27567 (define_int_iterator WRFSGSBASE
27571 (define_int_attr fsgs
27572 [(UNSPECV_RDFSBASE "fs")
27573 (UNSPECV_RDGSBASE "gs")
27574 (UNSPECV_WRFSBASE "fs")
27575 (UNSPECV_WRGSBASE "gs")])
27577 (define_insn "rd<fsgs>base<mode>"
27578 [(set (match_operand:SWI48 0 "register_operand" "=r")
27579 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
27580 "TARGET_64BIT && TARGET_FSGSBASE"
27582 [(set_attr "type" "other")
27583 (set_attr "prefix_0f" "1")
27584 (set_attr "prefix_rep" "1")])
27586 (define_insn "wr<fsgs>base<mode>"
27587 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
27589 "TARGET_64BIT && TARGET_FSGSBASE"
27591 [(set_attr "type" "other")
27592 (set_attr "prefix_0f" "1")
27593 (set_attr "prefix_rep" "1")])
27595 (define_insn "ptwrite<mode>"
27596 [(unspec_volatile [(match_operand:SWI48 0 "nonimmediate_operand" "rm")]
27600 [(set_attr "type" "other")
27601 (set_attr "prefix_0f" "1")
27602 (set_attr "prefix_rep" "1")])
27604 (define_insn "@rdrand<mode>"
27605 [(set (match_operand:SWI248 0 "register_operand" "=r")
27606 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
27607 (set (reg:CCC FLAGS_REG)
27608 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
27611 [(set_attr "type" "other")
27612 (set_attr "prefix_0f" "1")])
27614 (define_insn "@rdseed<mode>"
27615 [(set (match_operand:SWI248 0 "register_operand" "=r")
27616 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
27617 (set (reg:CCC FLAGS_REG)
27618 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
27621 [(set_attr "type" "other")
27622 (set_attr "prefix_0f" "1")])
27624 (define_expand "pause"
27625 [(set (match_dup 0)
27626 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
27629 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
27630 MEM_VOLATILE_P (operands[0]) = 1;
27633 ;; Use "rep; nop", instead of "pause", to support older assemblers.
27634 ;; They have the same encoding.
27635 (define_insn "*pause"
27636 [(set (match_operand:BLK 0)
27637 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
27640 [(set_attr "length" "2")
27641 (set_attr "memory" "unknown")])
27643 ;; CET instructions
27644 (define_insn "@rdssp<mode>"
27645 [(set (match_operand:SWI48 0 "register_operand" "=r")
27646 (unspec_volatile:SWI48 [(match_operand:SWI48 1 "register_operand" "0")]
27647 UNSPECV_NOP_RDSSP))]
27648 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
27649 "rdssp<mskmodesuffix>\t%0"
27650 [(set_attr "length" "6")
27651 (set_attr "type" "other")])
27653 (define_insn "@incssp<mode>"
27654 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
27656 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
27657 "incssp<mskmodesuffix>\t%0"
27658 [(set_attr "length" "4")
27659 (set_attr "type" "other")])
27661 (define_insn "saveprevssp"
27662 [(unspec_volatile [(const_int 0)] UNSPECV_SAVEPREVSSP)]
27665 [(set_attr "length" "5")
27666 (set_attr "type" "other")])
27668 (define_insn "rstorssp"
27669 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")]
27673 [(set_attr "length" "5")
27674 (set_attr "type" "other")])
27676 (define_insn "@wrss<mode>"
27677 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
27678 (match_operand:SWI48 1 "memory_operand" "m")]
27681 "wrss<mskmodesuffix>\t%0, %1"
27682 [(set_attr "length" "3")
27683 (set_attr "type" "other")])
27685 (define_insn "@wruss<mode>"
27686 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
27687 (match_operand:SWI48 1 "memory_operand" "m")]
27690 "wruss<mskmodesuffix>\t%0, %1"
27691 [(set_attr "length" "4")
27692 (set_attr "type" "other")])
27694 (define_insn "setssbsy"
27695 [(unspec_volatile [(const_int 0)] UNSPECV_SETSSBSY)]
27698 [(set_attr "length" "4")
27699 (set_attr "type" "other")])
27701 (define_insn "clrssbsy"
27702 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")]
27706 [(set_attr "length" "4")
27707 (set_attr "type" "other")])
27709 (define_insn "nop_endbr"
27710 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]
27711 "(flag_cf_protection & CF_BRANCH)"
27713 return TARGET_64BIT ? "endbr64" : "endbr32";
27715 [(set_attr "length" "4")
27716 (set_attr "length_immediate" "0")
27717 (set_attr "modrm" "0")])
27720 (define_expand "xbegin"
27721 [(set (match_operand:SI 0 "register_operand")
27722 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
27725 rtx_code_label *label = gen_label_rtx ();
27727 /* xbegin is emitted as jump_insn, so reload won't be able
27728 to reload its operand. Force the value into AX hard register. */
27729 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
27730 emit_move_insn (ax_reg, constm1_rtx);
27732 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
27734 emit_label (label);
27735 LABEL_NUSES (label) = 1;
27737 emit_move_insn (operands[0], ax_reg);
27742 (define_insn "xbegin_1"
27744 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
27746 (label_ref (match_operand 1))
27748 (set (match_operand:SI 0 "register_operand" "+a")
27749 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
27752 [(set_attr "type" "other")
27753 (set_attr "length" "6")])
27755 (define_insn "xend"
27756 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
27759 [(set_attr "type" "other")
27760 (set_attr "length" "3")])
27762 (define_insn "xabort"
27763 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand")]
27767 [(set_attr "type" "other")
27768 (set_attr "length" "3")])
27770 (define_expand "xtest"
27771 [(set (match_operand:QI 0 "register_operand")
27772 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
27775 emit_insn (gen_xtest_1 ());
27777 ix86_expand_setcc (operands[0], NE,
27778 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
27782 (define_insn "xtest_1"
27783 [(set (reg:CCZ FLAGS_REG)
27784 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
27787 [(set_attr "type" "other")
27788 (set_attr "length" "3")])
27790 (define_insn "clwb"
27791 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
27795 [(set_attr "type" "sse")
27796 (set_attr "atom_sse_attr" "fence")
27797 (set_attr "memory" "unknown")])
27799 (define_insn "clflushopt"
27800 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
27801 UNSPECV_CLFLUSHOPT)]
27802 "TARGET_CLFLUSHOPT"
27804 [(set_attr "type" "sse")
27805 (set_attr "atom_sse_attr" "fence")
27806 (set_attr "memory" "unknown")])
27808 ;; MONITORX and MWAITX
27809 (define_insn "mwaitx"
27810 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
27811 (match_operand:SI 1 "register_operand" "a")
27812 (match_operand:SI 2 "register_operand" "b")]
27815 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
27816 ;; Since 32bit register operands are implicitly zero extended to 64bit,
27817 ;; we only need to set up 32bit registers.
27819 [(set_attr "length" "3")])
27821 (define_insn "@monitorx_<mode>"
27822 [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
27823 (match_operand:SI 1 "register_operand" "c")
27824 (match_operand:SI 2 "register_operand" "d")]
27827 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
27828 ;; RCX and RDX are used. Since 32bit register operands are implicitly
27829 ;; zero extended to 64bit, we only need to set up 32bit registers.
27831 [(set (attr "length")
27832 (symbol_ref ("(Pmode != word_mode) + 3")))])
27835 (define_insn "@clzero_<mode>"
27836 [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
27840 [(set_attr "length" "3")
27841 (set_attr "memory" "unknown")])
27843 ;; RDPKRU and WRPKRU
27845 (define_expand "rdpkru"
27847 [(set (match_operand:SI 0 "register_operand")
27848 (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
27849 (set (match_dup 2) (const_int 0))])]
27852 operands[1] = force_reg (SImode, const0_rtx);
27853 operands[2] = gen_reg_rtx (SImode);
27856 (define_insn "*rdpkru"
27857 [(set (match_operand:SI 0 "register_operand" "=a")
27858 (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
27860 (set (match_operand:SI 1 "register_operand" "=d")
27864 [(set_attr "type" "other")])
27866 (define_expand "wrpkru"
27867 [(unspec_volatile:SI
27868 [(match_operand:SI 0 "register_operand")
27869 (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
27872 operands[1] = force_reg (SImode, const0_rtx);
27873 operands[2] = force_reg (SImode, const0_rtx);
27876 (define_insn "*wrpkru"
27877 [(unspec_volatile:SI
27878 [(match_operand:SI 0 "register_operand" "a")
27879 (match_operand:SI 1 "register_operand" "d")
27880 (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
27883 [(set_attr "type" "other")])
27885 (define_insn "rdpid"
27886 [(set (match_operand:SI 0 "register_operand" "=r")
27887 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDPID))]
27888 "!TARGET_64BIT && TARGET_RDPID"
27890 [(set_attr "type" "other")])
27892 (define_insn "rdpid_rex64"
27893 [(set (match_operand:DI 0 "register_operand" "=r")
27894 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPID))]
27895 "TARGET_64BIT && TARGET_RDPID"
27897 [(set_attr "type" "other")])
27899 ;; Intirinsics for > i486
27901 (define_insn "wbinvd"
27902 [(unspec_volatile [(const_int 0)] UNSPECV_WBINVD)]
27905 [(set_attr "type" "other")])
27907 (define_insn "wbnoinvd"
27908 [(unspec_volatile [(const_int 0)] UNSPECV_WBNOINVD)]
27911 [(set_attr "type" "other")])
27913 ;; MOVDIRI and MOVDIR64B
27915 (define_insn "movdiri<mode>"
27916 [(set (match_operand:SWI48 0 "memory_operand" "=m")
27917 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")]
27920 "movdiri\t{%1, %0|%0, %1}"
27921 [(set_attr "type" "other")])
27923 (define_insn "@movdir64b_<mode>"
27924 [(set (mem:XI (match_operand:P 0 "register_operand" "r"))
27925 (unspec:XI [(match_operand:XI 1 "memory_operand" "m")]
27926 UNSPEC_MOVDIR64B))]
27928 "movdir64b\t{%1, %0|%0, %1}"
27929 [(set_attr "type" "other")])
27932 (define_int_iterator TSXLDTRK [UNSPECV_XSUSLDTRK UNSPECV_XRESLDTRK])
27933 (define_int_attr tsxldtrk [(UNSPECV_XSUSLDTRK "xsusldtrk")
27934 (UNSPECV_XRESLDTRK "xresldtrk")])
27935 (define_insn "<tsxldtrk>"
27936 [(unspec_volatile [(const_int 0)] TSXLDTRK)]
27939 [(set_attr "type" "other")
27940 (set_attr "length" "4")])
27942 ;; ENQCMD and ENQCMDS
27944 (define_int_iterator ENQCMD [UNSPECV_ENQCMD UNSPECV_ENQCMDS])
27945 (define_int_attr enqcmd_sfx [(UNSPECV_ENQCMD "") (UNSPECV_ENQCMDS "s")])
27947 (define_insn "@enqcmd<enqcmd_sfx>_<mode>"
27948 [(set (reg:CCZ FLAGS_REG)
27949 (unspec_volatile:CCZ [(match_operand:P 0 "register_operand" "r")
27950 (match_operand:XI 1 "memory_operand" "m")]
27953 "enqcmd<enqcmd_sfx>\t{%1, %0|%0, %1}"
27954 [(set_attr "type" "other")])
27957 (define_int_iterator UINTR [UNSPECV_CLUI UNSPECV_STUI])
27958 (define_int_attr uintr [(UNSPECV_CLUI "clui") (UNSPECV_STUI "stui")])
27960 (define_insn "<uintr>"
27961 [(unspec_volatile [(const_int 0)] UINTR)]
27962 "TARGET_UINTR && TARGET_64BIT"
27964 [(set_attr "type" "other")
27965 (set_attr "length" "4")])
27967 (define_insn "testui"
27968 [(set (reg:CCC FLAGS_REG)
27969 (unspec_volatile:CCC [(const_int 0)] UNSPECV_TESTUI))]
27970 "TARGET_UINTR && TARGET_64BIT"
27972 [(set_attr "type" "other")
27973 (set_attr "length" "4")])
27975 (define_insn "senduipi"
27977 [(match_operand:DI 0 "register_operand" "r")]
27979 "TARGET_UINTR && TARGET_64BIT"
27981 [(set_attr "type" "other")
27982 (set_attr "length" "4")])
27986 (define_insn "umwait"
27987 [(set (reg:CCC FLAGS_REG)
27988 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
27989 (match_operand:DI 1 "register_operand" "A")]
27991 "!TARGET_64BIT && TARGET_WAITPKG"
27993 [(set_attr "length" "3")])
27995 (define_insn "umwait_rex64"
27996 [(set (reg:CCC FLAGS_REG)
27997 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
27998 (match_operand:SI 1 "register_operand" "a")
27999 (match_operand:SI 2 "register_operand" "d")]
28001 "TARGET_64BIT && TARGET_WAITPKG"
28003 [(set_attr "length" "3")])
28005 (define_insn "@umonitor_<mode>"
28006 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
28010 [(set (attr "length")
28011 (symbol_ref ("(Pmode != word_mode) + 3")))])
28013 (define_insn "tpause"
28014 [(set (reg:CCC FLAGS_REG)
28015 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
28016 (match_operand:DI 1 "register_operand" "A")]
28018 "!TARGET_64BIT && TARGET_WAITPKG"
28020 [(set_attr "length" "3")])
28022 (define_insn "tpause_rex64"
28023 [(set (reg:CCC FLAGS_REG)
28024 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
28025 (match_operand:SI 1 "register_operand" "a")
28026 (match_operand:SI 2 "register_operand" "d")]
28028 "TARGET_64BIT && TARGET_WAITPKG"
28030 [(set_attr "length" "3")])
28032 (define_insn "cldemote"
28033 [(unspec_volatile[(match_operand 0 "address_operand" "p")]
28037 [(set_attr "type" "other")
28038 (set_attr "memory" "unknown")])
28040 (define_insn "speculation_barrier"
28041 [(unspec_volatile [(const_int 0)] UNSPECV_SPECULATION_BARRIER)]
28044 [(set_attr "type" "other")
28045 (set_attr "length" "3")])
28047 (define_insn "serialize"
28048 [(unspec_volatile [(const_int 0)] UNSPECV_SERIALIZE)]
28051 [(set_attr "type" "other")
28052 (set_attr "length" "3")])
28054 (define_insn "patchable_area"
28055 [(unspec_volatile [(match_operand 0 "const_int_operand")
28056 (match_operand 1 "const_int_operand")]
28057 UNSPECV_PATCHABLE_AREA)]
28060 ix86_output_patchable_area (INTVAL (operands[0]),
28061 INTVAL (operands[1]) != 0);
28064 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
28065 (set_attr "length_immediate" "0")
28066 (set_attr "modrm" "0")])
28068 (define_insn "hreset"
28069 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")]
28073 [(set_attr "type" "other")
28074 (set_attr "length" "4")])
28076 ;; Spaceship optimization
28077 (define_expand "spaceship<mode>3"
28078 [(match_operand:SI 0 "register_operand")
28079 (match_operand:MODEF 1 "cmp_fp_expander_operand")
28080 (match_operand:MODEF 2 "cmp_fp_expander_operand")]
28081 "(TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
28082 && (TARGET_CMOVE || (TARGET_SAHF && TARGET_USE_SAHF))"
28084 ix86_expand_fp_spaceship (operands[0], operands[1], operands[2]);
28088 (define_expand "spaceshipxf3"
28089 [(match_operand:SI 0 "register_operand")
28090 (match_operand:XF 1 "nonmemory_operand")
28091 (match_operand:XF 2 "nonmemory_operand")]
28092 "TARGET_80387 && (TARGET_CMOVE || (TARGET_SAHF && TARGET_USE_SAHF))"
28094 ix86_expand_fp_spaceship (operands[0], operands[1], operands[2]);
28098 ;; Defined because the generic expand_builtin_issignaling for XFmode
28099 ;; only tests for sNaNs, but i387 treats also pseudo numbers as always
28101 (define_expand "issignalingxf2"
28102 [(match_operand:SI 0 "register_operand")
28103 (match_operand:XF 1 "general_operand")]
28106 rtx temp = operands[1];
28109 rtx mem = assign_stack_temp (XFmode, GET_MODE_SIZE (XFmode));
28110 emit_move_insn (mem, temp);
28113 rtx ex = adjust_address (temp, HImode, 8);
28114 rtx hi = adjust_address (temp, SImode, 4);
28115 rtx lo = adjust_address (temp, SImode, 0);
28116 rtx val = GEN_INT (HOST_WIDE_INT_M1U << 30);
28117 rtx mask = GEN_INT (0x7fff);
28118 rtx bit = GEN_INT (HOST_WIDE_INT_1U << 30);
28120 ((ex & mask) && (int) hi >= 0)
28121 || ((ex & mask) == mask && ((hi ^ bit) | ((lo | -lo) >> 31)) > val). */
28122 rtx nlo = expand_unop (SImode, neg_optab, lo, NULL_RTX, 0);
28123 lo = expand_binop (SImode, ior_optab, lo, nlo,
28124 NULL_RTX, 1, OPTAB_LIB_WIDEN);
28125 lo = expand_shift (RSHIFT_EXPR, SImode, lo, 31, NULL_RTX, 1);
28126 temp = expand_binop (SImode, xor_optab, hi, bit,
28127 NULL_RTX, 1, OPTAB_LIB_WIDEN);
28128 temp = expand_binop (SImode, ior_optab, temp, lo,
28129 NULL_RTX, 1, OPTAB_LIB_WIDEN);
28130 temp = emit_store_flag_force (gen_reg_rtx (SImode), GTU, temp, val,
28132 ex = expand_binop (HImode, and_optab, ex, mask,
28133 NULL_RTX, 1, OPTAB_LIB_WIDEN);
28134 rtx temp2 = emit_store_flag_force (gen_reg_rtx (SImode), NE,
28135 ex, const0_rtx, SImode, 1, 1);
28136 ex = emit_store_flag_force (gen_reg_rtx (SImode), EQ,
28137 ex, mask, HImode, 1, 1);
28138 temp = expand_binop (SImode, and_optab, temp, ex,
28139 NULL_RTX, 1, OPTAB_LIB_WIDEN);
28140 rtx temp3 = emit_store_flag_force (gen_reg_rtx (SImode), GE,
28141 hi, const0_rtx, SImode, 0, 1);
28142 temp2 = expand_binop (SImode, and_optab, temp2, temp3,
28143 NULL_RTX, 1, OPTAB_LIB_WIDEN);
28144 temp = expand_binop (SImode, ior_optab, temp, temp2,
28145 NULL_RTX, 1, OPTAB_LIB_WIDEN);
28146 emit_move_insn (operands[0], temp);
28150 (define_insn "urdmsr"
28151 [(set (match_operand:DI 0 "register_operand" "=r")
28152 (unspec_volatile:DI
28153 [(match_operand:DI 1 "x86_64_szext_nonmemory_operand" "reZ")]
28155 "TARGET_USER_MSR && TARGET_64BIT"
28156 "urdmsr\t{%1, %0|%0, %1}"
28157 [(set_attr "prefix" "vex")
28158 (set_attr "type" "other")])
28160 (define_insn "uwrmsr"
28162 [(match_operand:DI 0 "x86_64_szext_nonmemory_operand" "reZ")
28163 (match_operand:DI 1 "register_operand" "r")]
28165 "TARGET_USER_MSR && TARGET_64BIT"
28166 "uwrmsr\t{%1, %0|%0, %1}"
28167 [(set_attr "prefix" "vex")
28168 (set_attr "type" "other")])
28170 (define_insn "ldtilecfg"
28171 [(unspec_volatile [(match_operand:XI 0 "memory_operand" "m")]
28172 UNSPECV_LDTILECFG)]
28175 [(set_attr "type" "other")
28176 (set_attr "prefix" "maybe_evex")
28177 (set_attr "memory" "load")
28178 (set_attr "mode" "XI")])
28180 (define_insn "sttilecfg"
28181 [(set (match_operand:XI 0 "memory_operand" "=m")
28182 (unspec_volatile:XI [(const_int 0)] UNSPECV_STTILECFG))]
28185 [(set_attr "type" "other")
28186 (set_attr "prefix" "maybe_evex")
28187 (set_attr "memory" "store")
28188 (set_attr "mode" "XI")])
28192 (include "sync.md")