1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2023 Free Software Foundation, Inc.
3 ;; Mostly by William Schelter.
4 ;; x86_64 support added by Jan Hubicka
6 ;; This file is part of GCC.
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3. If not see
20 ;; <http://www.gnu.org/licenses/>. */
22 ;; The original PO technology requires these to be ordered by speed,
23 ;; so that assigner will pick the fastest.
25 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
27 ;; The special asm out single letter directives following a '%' are:
28 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
29 ;; C -- print opcode suffix for set/cmov insn.
30 ;; c -- like C, but print reversed condition
31 ;; F,f -- likewise, but for floating-point.
32 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
34 ;; R -- print the prefix for register names.
35 ;; z -- print the opcode suffix for the size of the current operand.
36 ;; Z -- likewise, with special suffixes for x87 instructions.
37 ;; * -- print a star (in certain assembler syntax)
38 ;; A -- print an absolute memory reference.
39 ;; E -- print address with DImode register names if TARGET_64BIT.
40 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
41 ;; s -- print a shift double count, followed by the assemblers argument
43 ;; b -- print the QImode name of the register for the indicated operand.
44 ;; %b0 would print %al if operands[0] is reg 0.
45 ;; w -- likewise, print the HImode name of the register.
46 ;; k -- likewise, print the SImode name of the register.
47 ;; q -- likewise, print the DImode name of the register.
48 ;; x -- likewise, print the V4SFmode name of the register.
49 ;; t -- likewise, print the V8SFmode name of the register.
50 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
51 ;; y -- print "st(0)" instead of "st" as a register.
52 ;; d -- print duplicated register operand for AVX instruction.
53 ;; D -- print condition for SSE cmp instruction.
54 ;; P -- if PIC, print an @PLT suffix.
55 ;; p -- print raw symbol name.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; K -- print HLE lock prefix
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
63 ;; ~ -- print "i" if TARGET_AVX2, "f" otherwise.
64 ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
65 ;; ! -- print NOTRACK prefix for jxx/call/ret instructions if required.
67 (define_c_enum "unspec" [
68 ;; Relocation specifiers
79 UNSPEC_MACHOPIC_OFFSET
88 UNSPEC_MEMORY_BLOCKAGE
98 ;; Other random patterns
106 UNSPEC_LD_MPIC ; load_macho_picbase
108 UNSPEC_DIV_ALREADY_SPLIT
114 UNSPEC_INSN_FALSE_DEP
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 PUSH2/POP2 support
219 (define_c_enum "unspecv" [
223 UNSPECV_PROBE_STACK_RANGE
226 UNSPECV_SPLIT_STACK_RETURN
232 UNSPECV_LLWP_INTRINSIC
233 UNSPECV_SLWP_INTRINSIC
234 UNSPECV_LWPVAL_INTRINSIC
235 UNSPECV_LWPINS_INTRINSIC
261 ;; For atomic compound assignments.
267 ;; For RDRAND support
270 ;; For RDSEED support
284 ;; For CLFLUSHOPT support
287 ;; For MONITORX and MWAITX support
291 ;; For CLZERO support
294 ;; For RDPKRU and WRPKRU support
311 ;; For TSXLDTRK support
315 ;; For WAITPKG support
326 ;; For CLDEMOTE support
329 ;; For Speculation Barrier support
330 UNSPECV_SPECULATION_BARRIER
334 ;; For ENQCMD and ENQCMDS support
338 ;; For SERIALIZE support
341 ;; For patchable area support
342 UNSPECV_PATCHABLE_AREA
344 ;; For HRESET support
347 ;; For PREFETCHI support
350 ;; For USER_MSR support
355 ;; Constants to represent rounding modes in the ROUND instruction
357 [(ROUND_ROUNDEVEN 0x0)
365 ;; Constants to represent AVX512F embeded rounding
367 [(ROUND_NEAREST_INT 0)
375 ;; Constants to represent pcomtrue/pcomfalse variants
385 ;; Constants used in the XOP pperm instruction
387 [(PPERM_SRC 0x00) /* copy source */
388 (PPERM_INVERT 0x20) /* invert source */
389 (PPERM_REVERSE 0x40) /* bit reverse source */
390 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
391 (PPERM_ZERO 0x80) /* all 0's */
392 (PPERM_ONES 0xa0) /* all 1's */
393 (PPERM_SIGN 0xc0) /* propagate sign bit */
394 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
395 (PPERM_SRC1 0x00) /* use first source byte */
396 (PPERM_SRC2 0x10) /* use second source byte */
399 ;; Registers by name.
493 (FIRST_PSEUDO_REG 92)
496 ;; Insn callee abi index.
502 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
505 ;; In C guard expressions, put expressions which may be compile-time
506 ;; constants first. This allows for better optimization. For
507 ;; example, write "TARGET_64BIT && reload_completed", not
508 ;; "reload_completed && TARGET_64BIT".
512 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
513 atom,slm,glm,haswell,generic,lujiazui,yongfeng,amdfam10,bdver1,
514 bdver2,bdver3,bdver4,btver2,znver1,znver2,znver3,znver4"
515 (const (symbol_ref "ix86_schedule")))
517 ;; A basic instruction type. Refinements due to arguments to be
518 ;; provided in other attributes.
521 alu,alu1,negnot,imov,imovx,lea,
522 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
523 imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
524 push,pop,call,callv,leave,
526 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
527 fxch,fistp,fisttp,frndint,
528 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
529 ssemul,sseimul,ssediv,sselog,sselog1,
530 sseishft,sseishft1,ssecmp,ssecomi,
531 ssecvt,ssecvt1,sseicvt,sseins,
532 sseshuf,sseshuf1,ssemuladd,sse4arg,
534 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
535 (const_string "other"))
537 ;; Main data type used by the insn
539 "unknown,none,QI,HI,SI,DI,TI,OI,XI,HF,BF,SF,DF,XF,TF,V32HF,V16HF,V8HF,
540 V16SF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF,V8DF,V4HF,V4BF,V2HF,V2BF"
541 (const_string "unknown"))
543 ;; The CPU unit operations uses.
544 (define_attr "unit" "integer,i387,sse,mmx,unknown"
545 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
546 fxch,fistp,fisttp,frndint")
547 (const_string "i387")
548 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
549 ssemul,sseimul,ssediv,sselog,sselog1,
550 sseishft,sseishft1,ssecmp,ssecomi,
551 ssecvt,ssecvt1,sseicvt,sseins,
552 sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
554 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
556 (eq_attr "type" "other")
557 (const_string "unknown")]
558 (const_string "integer")))
560 ;; Used to control the "enabled" attribute on a per-instruction basis.
561 (define_attr "isa" "base,x64,nox64,x64_sse2,x64_sse4,x64_sse4_noavx,
562 x64_avx,x64_avx512bw,x64_avx512dq,aes,
563 sse_noavx,sse2,sse2_noavx,sse3,sse3_noavx,sse4,sse4_noavx,
564 avx,noavx,avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,avx512f_512,
565 noavx512f,avx512bw,avx512bw_512,noavx512bw,avx512dq,
566 noavx512dq,fma_or_avx512vl,avx512vl,noavx512vl,avxvnni,
567 avx512vnnivl,avx512fp16,avxifma,avx512ifmavl,avxneconvert,
568 avx512bf16vl,vpclmulqdqvl,avx_noavx512f,avx_noavx512vl"
569 (const_string "base"))
571 ;; The (bounding maximum) length of an instruction immediate.
572 (define_attr "length_immediate" ""
573 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
574 bitmanip,imulx,msklog,mskmov")
576 (ior (eq_attr "type" "sse4arg")
577 (eq_attr "isa" "fma4"))
579 (eq_attr "unit" "i387,sse,mmx")
581 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
582 rotate,rotatex,rotate1,imul,icmp,push,pop")
583 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
584 (eq_attr "type" "imov,test")
585 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
586 (eq_attr "type" "call")
587 (if_then_else (match_operand 0 "constant_call_address_operand")
590 (eq_attr "type" "callv")
591 (if_then_else (match_operand 1 "constant_call_address_operand")
594 ;; We don't know the size before shorten_branches. Expect
595 ;; the instruction to fit for better scheduling.
596 (eq_attr "type" "ibr")
599 (symbol_ref "/* Update immediate_length and other attributes! */
600 gcc_unreachable (),1")))
602 ;; The (bounding maximum) length of an instruction address.
603 (define_attr "length_address" ""
604 (cond [(eq_attr "type" "str,other,multi,fxch")
606 (and (eq_attr "type" "call")
607 (match_operand 0 "constant_call_address_operand"))
609 (and (eq_attr "type" "callv")
610 (match_operand 1 "constant_call_address_operand"))
613 (symbol_ref "ix86_attr_length_address_default (insn)")))
615 ;; Set when length prefix is used.
616 (define_attr "prefix_data16" ""
617 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
619 (eq_attr "mode" "HI")
621 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
626 ;; Set when string REP prefix is used.
627 (define_attr "prefix_rep" ""
628 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
630 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
635 ;; Set when 0f opcode prefix is used.
636 (define_attr "prefix_0f" ""
638 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov")
639 (eq_attr "unit" "sse,mmx"))
643 ;; Set when REX opcode prefix is used.
644 (define_attr "prefix_rex" ""
645 (cond [(not (match_test "TARGET_64BIT"))
647 (and (eq_attr "mode" "DI")
648 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
649 (eq_attr "unit" "!mmx")))
651 (and (eq_attr "mode" "QI")
652 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
654 (match_test "x86_extended_reg_mentioned_p (insn)")
656 (and (eq_attr "type" "imovx")
657 (match_operand:QI 1 "ext_QIreg_operand"))
662 ;; There are also additional prefixes in 3DNOW, SSSE3.
663 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
664 ;; While generally inapplicable to VEX/XOP/EVEX encodings, "length_vex" uses
665 ;; the attribute evaluating to zero to know that VEX2 encoding may be usable.
666 (define_attr "prefix_extra" ""
667 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
672 ;; Prefix used: original, VEX or maybe VEX.
673 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
674 (cond [(eq_attr "mode" "OI,V8SF,V4DF")
676 (eq_attr "mode" "XI,V16SF,V8DF")
677 (const_string "evex")
678 (eq_attr "type" "ssemuladd")
679 (if_then_else (eq_attr "isa" "fma4")
681 (const_string "maybe_evex"))
682 (eq_attr "type" "sse4arg")
685 (const_string "orig")))
687 ;; VEX W bit is used.
688 (define_attr "prefix_vex_w" "" (const_int 0))
690 ;; The length of VEX prefix
691 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
692 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
693 ;; still prefix_0f 1, with prefix_extra 1.
694 (define_attr "length_vex" ""
695 (if_then_else (and (eq_attr "prefix_0f" "1")
696 (eq_attr "prefix_extra" "0"))
697 (if_then_else (eq_attr "prefix_vex_w" "1")
698 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
699 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
700 (if_then_else (eq_attr "prefix_vex_w" "1")
701 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
702 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
704 ;; 4-bytes evex prefix and 1 byte opcode.
705 (define_attr "length_evex" "" (const_int 5))
707 ;; Set when modrm byte is used.
708 (define_attr "modrm" ""
709 (cond [(eq_attr "type" "str,leave")
711 (eq_attr "unit" "i387")
713 (and (eq_attr "type" "incdec")
714 (and (not (match_test "TARGET_64BIT"))
715 (ior (match_operand:SI 1 "register_operand")
716 (match_operand:HI 1 "register_operand"))))
718 (and (eq_attr "type" "push")
719 (not (match_operand 1 "memory_operand")))
721 (and (eq_attr "type" "pop")
722 (not (match_operand 0 "memory_operand")))
724 (and (eq_attr "type" "imov")
725 (and (not (eq_attr "mode" "DI"))
726 (ior (and (match_operand 0 "register_operand")
727 (match_operand 1 "immediate_operand"))
728 (ior (and (match_operand 0 "ax_reg_operand")
729 (match_operand 1 "memory_displacement_only_operand"))
730 (and (match_operand 0 "memory_displacement_only_operand")
731 (match_operand 1 "ax_reg_operand"))))))
733 (and (eq_attr "type" "call")
734 (match_operand 0 "constant_call_address_operand"))
736 (and (eq_attr "type" "callv")
737 (match_operand 1 "constant_call_address_operand"))
739 (and (eq_attr "type" "alu,alu1,icmp,test")
740 (match_operand 0 "ax_reg_operand"))
741 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
745 ;; The (bounding maximum) length of an instruction in bytes.
746 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
747 ;; Later we may want to split them and compute proper length as for
749 (define_attr "length" ""
750 (cond [(eq_attr "type" "other,multi,fistp,frndint")
752 (eq_attr "type" "fcmp")
754 (eq_attr "unit" "i387")
756 (plus (attr "prefix_data16")
757 (attr "length_address")))
758 (ior (eq_attr "prefix" "evex")
759 (and (ior (eq_attr "prefix" "maybe_evex")
760 (eq_attr "prefix" "maybe_vex"))
761 (match_test "TARGET_AVX512F")))
762 (plus (attr "length_evex")
763 (plus (attr "length_immediate")
765 (attr "length_address"))))
766 (ior (eq_attr "prefix" "vex")
767 (and (ior (eq_attr "prefix" "maybe_vex")
768 (eq_attr "prefix" "maybe_evex"))
769 (match_test "TARGET_AVX")))
770 (plus (attr "length_vex")
771 (plus (attr "length_immediate")
773 (attr "length_address"))))]
774 (plus (plus (attr "modrm")
775 (plus (attr "prefix_0f")
776 (plus (attr "prefix_rex")
777 (plus (attr "prefix_extra")
779 (plus (attr "prefix_rep")
780 (plus (attr "prefix_data16")
781 (plus (attr "length_immediate")
782 (attr "length_address")))))))
784 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
785 ;; `store' if there is a simple memory reference therein, or `unknown'
786 ;; if the instruction is complex.
788 (define_attr "memory" "none,load,store,both,unknown"
789 (cond [(eq_attr "type" "other,multi,str,lwp")
790 (const_string "unknown")
791 (eq_attr "type" "lea,fcmov,fpspc")
792 (const_string "none")
793 (eq_attr "type" "fistp,leave")
794 (const_string "both")
795 (eq_attr "type" "frndint")
796 (const_string "load")
797 (eq_attr "type" "push")
798 (if_then_else (match_operand 1 "memory_operand")
799 (const_string "both")
800 (const_string "store"))
801 (eq_attr "type" "pop")
802 (if_then_else (match_operand 0 "memory_operand")
803 (const_string "both")
804 (const_string "load"))
805 (eq_attr "type" "setcc")
806 (if_then_else (match_operand 0 "memory_operand")
807 (const_string "store")
808 (const_string "none"))
809 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
810 (if_then_else (ior (match_operand 0 "memory_operand")
811 (match_operand 1 "memory_operand"))
812 (const_string "load")
813 (const_string "none"))
814 (eq_attr "type" "ibr")
815 (if_then_else (match_operand 0 "memory_operand")
816 (const_string "load")
817 (const_string "none"))
818 (eq_attr "type" "call")
819 (if_then_else (match_operand 0 "constant_call_address_operand")
820 (const_string "none")
821 (const_string "load"))
822 (eq_attr "type" "callv")
823 (if_then_else (match_operand 1 "constant_call_address_operand")
824 (const_string "none")
825 (const_string "load"))
826 (and (eq_attr "type" "alu1,negnot,ishift1,rotate1,sselog1,sseshuf1")
827 (match_operand 1 "memory_operand"))
828 (const_string "both")
829 (and (match_operand 0 "memory_operand")
830 (match_operand 1 "memory_operand"))
831 (const_string "both")
832 (match_operand 0 "memory_operand")
833 (const_string "store")
834 (match_operand 1 "memory_operand")
835 (const_string "load")
837 "!alu1,negnot,ishift1,rotate1,
838 imov,imovx,icmp,test,bitmanip,
840 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
841 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
842 mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog")
843 (match_operand 2 "memory_operand"))
844 (const_string "load")
845 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
846 (match_operand 3 "memory_operand"))
847 (const_string "load")
849 (const_string "none")))
851 ;; Indicates if an instruction has both an immediate and a displacement.
853 (define_attr "imm_disp" "false,true,unknown"
854 (cond [(eq_attr "type" "other,multi")
855 (const_string "unknown")
856 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
857 (and (match_operand 0 "memory_displacement_operand")
858 (match_operand 1 "immediate_operand")))
859 (const_string "true")
860 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
861 (and (match_operand 0 "memory_displacement_operand")
862 (match_operand 2 "immediate_operand")))
863 (const_string "true")
865 (const_string "false")))
867 ;; Indicates if an FP operation has an integer source.
869 (define_attr "fp_int_src" "false,true"
870 (const_string "false"))
872 ;; Defines rounding mode of an FP operation.
874 (define_attr "i387_cw" "roundeven,floor,ceil,trunc,uninitialized,any"
875 (const_string "any"))
877 ;; Define attribute to indicate AVX insns with partial XMM register update.
878 (define_attr "avx_partial_xmm_update" "false,true"
879 (const_string "false"))
881 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
882 (define_attr "use_carry" "0,1" (const_string "0"))
884 ;; Define attribute to indicate unaligned ssemov insns
885 (define_attr "movu" "0,1" (const_string "0"))
887 ;; Define attribute to limit memory address register set.
888 (define_attr "addr" "gpr8,gpr16,gpr32" (const_string "gpr32"))
890 ;; Define instruction set of MMX instructions
891 (define_attr "mmx_isa" "base,native,sse,sse_noavx,avx"
892 (const_string "base"))
894 (define_attr "enabled" ""
895 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
896 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
897 (eq_attr "isa" "x64_sse2")
898 (symbol_ref "TARGET_64BIT && TARGET_SSE2")
899 (eq_attr "isa" "x64_sse4")
900 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
901 (eq_attr "isa" "x64_sse4_noavx")
902 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
903 (eq_attr "isa" "x64_avx")
904 (symbol_ref "TARGET_64BIT && TARGET_AVX")
905 (eq_attr "isa" "x64_avx512bw")
906 (symbol_ref "TARGET_64BIT && TARGET_AVX512BW")
907 (eq_attr "isa" "x64_avx512dq")
908 (symbol_ref "TARGET_64BIT && TARGET_AVX512DQ")
909 (eq_attr "isa" "aes") (symbol_ref "TARGET_AES")
910 (eq_attr "isa" "sse_noavx")
911 (symbol_ref "TARGET_SSE && !TARGET_AVX")
912 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
913 (eq_attr "isa" "sse2_noavx")
914 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
915 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
916 (eq_attr "isa" "sse3_noavx")
917 (symbol_ref "TARGET_SSE3 && !TARGET_AVX")
918 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
919 (eq_attr "isa" "sse4_noavx")
920 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
921 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
922 (eq_attr "isa" "avx_noavx512f")
923 (symbol_ref "TARGET_AVX && !TARGET_AVX512F")
924 (eq_attr "isa" "avx_noavx512vl")
925 (symbol_ref "TARGET_AVX && !TARGET_AVX512VL")
926 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
927 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
928 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
929 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
930 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
931 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
932 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
933 (eq_attr "isa" "fma_or_avx512vl")
934 (symbol_ref "TARGET_FMA || TARGET_AVX512VL")
935 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
936 (eq_attr "isa" "avx512f_512")
937 (symbol_ref "TARGET_AVX512F && TARGET_EVEX512")
938 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
939 (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
940 (eq_attr "isa" "avx512bw_512")
941 (symbol_ref "TARGET_AVX512BW && TARGET_EVEX512")
942 (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
943 (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
944 (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
945 (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
946 (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
947 (eq_attr "isa" "avxvnni") (symbol_ref "TARGET_AVXVNNI")
948 (eq_attr "isa" "avx512vnnivl")
949 (symbol_ref "TARGET_AVX512VNNI && TARGET_AVX512VL")
950 (eq_attr "isa" "avx512fp16")
951 (symbol_ref "TARGET_AVX512FP16")
952 (eq_attr "isa" "avxifma") (symbol_ref "TARGET_AVXIFMA")
953 (eq_attr "isa" "avx512ifmavl")
954 (symbol_ref "TARGET_AVX512IFMA && TARGET_AVX512VL")
955 (eq_attr "isa" "avxneconvert") (symbol_ref "TARGET_AVXNECONVERT")
956 (eq_attr "isa" "avx512bf16vl")
957 (symbol_ref "TARGET_AVX512BF16 && TARGET_AVX512VL")
958 (eq_attr "isa" "vpclmulqdqvl")
959 (symbol_ref "TARGET_VPCLMULQDQ && TARGET_AVX512VL")
961 (eq_attr "mmx_isa" "native")
962 (symbol_ref "!TARGET_MMX_WITH_SSE")
963 (eq_attr "mmx_isa" "sse")
964 (symbol_ref "TARGET_MMX_WITH_SSE")
965 (eq_attr "mmx_isa" "sse_noavx")
966 (symbol_ref "TARGET_MMX_WITH_SSE && !TARGET_AVX")
967 (eq_attr "mmx_isa" "avx")
968 (symbol_ref "TARGET_MMX_WITH_SSE && TARGET_AVX")
972 (define_attr "preferred_for_size" "" (const_int 1))
973 (define_attr "preferred_for_speed" "" (const_int 1))
975 ;; Describe a user's asm statement.
976 (define_asm_attributes
977 [(set_attr "length" "128")
978 (set_attr "type" "multi")])
980 (define_code_iterator plusminus [plus minus])
981 (define_code_iterator plusminusmult [plus minus mult])
982 (define_code_iterator plusminusmultdiv [plus minus mult div])
984 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
986 ;; Base name for insn mnemonic.
987 (define_code_attr plusminus_mnemonic
988 [(plus "add") (ss_plus "adds") (us_plus "addus")
989 (minus "sub") (ss_minus "subs") (us_minus "subus")])
991 (define_code_iterator multdiv [mult div])
993 (define_code_attr multdiv_mnemonic
994 [(mult "mul") (div "div")])
996 ;; Mark commutative operators as such in constraints.
997 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
998 (minus "") (ss_minus "") (us_minus "")
999 (mult "%") (div "")])
1001 ;; Mapping of max and min
1002 (define_code_iterator maxmin [smax smin umax umin])
1004 ;; Mapping of signed max and min
1005 (define_code_iterator smaxmin [smax smin])
1007 ;; Mapping of unsigned max and min
1008 (define_code_iterator umaxmin [umax umin])
1010 ;; Base name for integer and FP insn mnemonic
1011 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
1012 (umax "maxu") (umin "minu")])
1013 (define_code_attr maxmin_float [(smax "max") (smin "min")])
1015 (define_int_iterator IEEE_MAXMIN
1019 (define_int_attr ieee_maxmin
1020 [(UNSPEC_IEEE_MAX "max")
1021 (UNSPEC_IEEE_MIN "min")])
1023 ;; Mapping of logic operators
1024 (define_code_iterator any_logic [and ior xor])
1025 (define_code_iterator any_or [ior xor])
1026 (define_code_iterator fpint_logic [and xor])
1028 ;; Base name for insn mnemonic.
1029 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
1031 ;; Mapping of logic-shift operators
1032 (define_code_iterator any_lshift [ashift lshiftrt])
1034 ;; Mapping of shift-right operators
1035 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
1037 ;; Mapping of all shift operators
1038 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
1040 ;; Base name for insn mnemonic.
1041 (define_code_attr shift [(ashift "sal") (lshiftrt "shr") (ashiftrt "sar")])
1042 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
1044 ;; Mapping of rotate operators
1045 (define_code_iterator any_rotate [rotate rotatert])
1047 ;; Base name for insn mnemonic.
1048 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
1050 ;; Mapping of abs neg operators
1051 (define_code_iterator absneg [abs neg])
1053 ;; Mapping of abs neg operators to logic operation
1054 (define_code_attr absneg_op [(abs "and") (neg "xor")])
1056 ;; Base name for x87 insn mnemonic.
1057 (define_code_attr absneg_mnemonic [(abs "fabs") (neg "fchs")])
1059 ;; Mapping of extend operators
1060 (define_code_iterator any_extend [sign_extend zero_extend])
1062 ;; Mapping of highpart multiply operators
1063 (define_code_iterator any_mul_highpart [smul_highpart umul_highpart])
1065 ;; Prefix for insn menmonic.
1066 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
1067 (smul_highpart "i") (umul_highpart "")
1068 (div "i") (udiv "")])
1069 ;; Prefix for define_insn
1070 (define_code_attr s [(sign_extend "s") (zero_extend "u")
1071 (smul_highpart "s") (umul_highpart "u")])
1072 (define_code_attr u [(sign_extend "") (zero_extend "u")
1073 (div "") (udiv "u")])
1074 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")
1075 (div "false") (udiv "true")])
1077 ;; Used in signed and unsigned truncations.
1078 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
1079 ;; Instruction suffix for truncations.
1080 (define_code_attr trunsuffix
1081 [(ss_truncate "s") (truncate "") (us_truncate "us")])
1083 ;; Instruction suffix for SSE sign and zero extensions.
1084 (define_code_attr extsuffix [(sign_extend "sx") (zero_extend "zx")])
1086 ;; Used in signed and unsigned fix.
1087 (define_code_iterator any_fix [fix unsigned_fix])
1088 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
1089 (define_code_attr fixunssuffix [(fix "") (unsigned_fix "uns")])
1090 (define_code_attr fixprefix [(fix "s") (unsigned_fix "u")])
1092 ;; Used in signed and unsigned float.
1093 (define_code_iterator any_float [float unsigned_float])
1094 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
1095 (define_code_attr floatunssuffix [(float "") (unsigned_float "uns")])
1096 (define_code_attr floatprefix [(float "s") (unsigned_float "u")])
1098 ;; Base name for expression
1099 (define_code_attr insn
1100 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
1101 (minus "sub") (ss_minus "sssub") (us_minus "ussub")
1102 (sign_extend "extend") (zero_extend "zero_extend")
1103 (ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")
1104 (rotate "rotl") (rotatert "rotr")
1105 (mult "mul") (div "div")])
1107 ;; All integer modes.
1108 (define_mode_iterator SWI1248x [QI HI SI DI])
1110 ;; All integer modes without QImode.
1111 (define_mode_iterator SWI248x [HI SI DI])
1113 ;; All integer modes without QImode and HImode.
1114 (define_mode_iterator SWI48x [SI DI])
1116 ;; All integer modes without SImode and DImode.
1117 (define_mode_iterator SWI12 [QI HI])
1119 ;; All integer modes without DImode.
1120 (define_mode_iterator SWI124 [QI HI SI])
1122 ;; All integer modes without QImode and DImode.
1123 (define_mode_iterator SWI24 [HI SI])
1125 ;; Single word integer modes.
1126 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
1128 ;; Single word integer modes without QImode.
1129 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
1131 ;; Single word integer modes without QImode and HImode.
1132 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
1134 ;; All math-dependant single and double word integer modes.
1135 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
1136 (HI "TARGET_HIMODE_MATH")
1137 SI DI (TI "TARGET_64BIT")])
1139 ;; Math-dependant single word integer modes.
1140 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
1141 (HI "TARGET_HIMODE_MATH")
1142 SI (DI "TARGET_64BIT")])
1144 ;; Math-dependant integer modes without DImode.
1145 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
1146 (HI "TARGET_HIMODE_MATH")
1149 ;; Math-dependant integer modes with DImode.
1150 (define_mode_iterator SWIM1248x
1151 [(QI "TARGET_QIMODE_MATH")
1152 (HI "TARGET_HIMODE_MATH")
1155 ;; Math-dependant single word integer modes without QImode.
1156 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
1157 SI (DI "TARGET_64BIT")])
1159 ;; Double word integer modes.
1160 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
1161 (TI "TARGET_64BIT")])
1163 ;; SWI and DWI together.
1164 (define_mode_iterator SWIDWI [QI HI SI DI (TI "TARGET_64BIT")])
1166 ;; SWI48 and DWI together.
1167 (define_mode_iterator SWI48DWI [SI DI (TI "TARGET_64BIT")])
1169 ;; GET_MODE_SIZE for selected modes. As GET_MODE_SIZE is not
1170 ;; compile time constant, it is faster to use <MODE_SIZE> than
1171 ;; GET_MODE_SIZE (<MODE>mode). For XFmode which depends on
1172 ;; command line options just use GET_MODE_SIZE macro.
1173 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8")
1174 (TI "16") (HF "2") (BF "2") (SF "4") (DF "8")
1175 (XF "GET_MODE_SIZE (XFmode)")
1176 (V16QI "16") (V32QI "32") (V64QI "64")
1177 (V8HI "16") (V16HI "32") (V32HI "64")
1178 (V4SI "16") (V8SI "32") (V16SI "64")
1179 (V2DI "16") (V4DI "32") (V8DI "64")
1180 (V1TI "16") (V2TI "32") (V4TI "64")
1181 (V2DF "16") (V4DF "32") (V8DF "64")
1182 (V4SF "16") (V8SF "32") (V16SF "64")
1183 (V8HF "16") (V16HF "32") (V32HF "64")
1184 (V4HF "8") (V2HF "4")
1185 (V8BF "16") (V16BF "32") (V32BF "64")
1186 (V4BF "8") (V2BF "4")])
1188 ;; Double word integer modes as mode attribute.
1189 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI") (TI "OI")])
1190 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti") (TI "oi")])
1192 ;; Half sized integer modes.
1193 (define_mode_attr HALF [(TI "DI") (DI "SI")])
1194 (define_mode_attr half [(TI "di") (DI "si")])
1196 ;; LEA mode corresponding to an integer mode
1197 (define_mode_attr LEAMODE [(QI "SI") (HI "SI") (SI "SI") (DI "DI")])
1199 ;; Half mode for double word integer modes.
1200 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1201 (DI "TARGET_64BIT")])
1203 ;; Instruction suffix for integer modes.
1204 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1206 ;; Instruction suffix for masks.
1207 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1209 ;; Pointer size prefix for integer modes (Intel asm dialect)
1210 (define_mode_attr iptrsize [(QI "BYTE")
1215 ;; Register class for integer modes.
1216 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1218 ;; Immediate operand constraint for integer modes.
1219 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1221 ;; General operand constraint for word modes.
1222 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1224 ;; Memory operand constraint for word modes.
1225 (define_mode_attr m [(QI "m") (HI "m") (SI "BM") (DI "BM")])
1227 ;; Immediate operand constraint for double integer modes.
1228 (define_mode_attr di [(SI "nF") (DI "Wd")])
1230 ;; Immediate operand constraint for shifts.
1231 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1232 (define_mode_attr KS [(QI "Wb") (HI "Ww") (SI "I") (DI "J")])
1234 ;; Print register name in the specified mode.
1235 (define_mode_attr k [(QI "b") (HI "w") (SI "k") (DI "q")])
1237 ;; General operand predicate for integer modes.
1238 (define_mode_attr general_operand
1239 [(QI "general_operand")
1240 (HI "general_operand")
1241 (SI "x86_64_general_operand")
1242 (DI "x86_64_general_operand")
1243 (TI "x86_64_general_operand")])
1245 ;; General operand predicate for integer modes, where for TImode
1246 ;; we need both words of the operand to be general operands.
1247 (define_mode_attr general_hilo_operand
1248 [(QI "general_operand")
1249 (HI "general_operand")
1250 (SI "x86_64_general_operand")
1251 (DI "x86_64_general_operand")
1252 (TI "x86_64_hilo_general_operand")])
1254 ;; General sign extend operand predicate for integer modes,
1255 ;; which disallows VOIDmode operands and thus it is suitable
1256 ;; for use inside sign_extend.
1257 (define_mode_attr general_sext_operand
1258 [(QI "sext_operand")
1260 (SI "x86_64_sext_operand")
1261 (DI "x86_64_sext_operand")])
1263 ;; General sign/zero extend operand predicate for integer modes.
1264 (define_mode_attr general_szext_operand
1265 [(QI "general_operand")
1266 (HI "general_operand")
1267 (SI "x86_64_szext_general_operand")
1268 (DI "x86_64_szext_general_operand")
1269 (TI "x86_64_hilo_general_operand")])
1271 (define_mode_attr nonmemory_szext_operand
1272 [(QI "nonmemory_operand")
1273 (HI "nonmemory_operand")
1274 (SI "x86_64_szext_nonmemory_operand")
1275 (DI "x86_64_szext_nonmemory_operand")])
1277 ;; Immediate operand predicate for integer modes.
1278 (define_mode_attr immediate_operand
1279 [(QI "immediate_operand")
1280 (HI "immediate_operand")
1281 (SI "x86_64_immediate_operand")
1282 (DI "x86_64_immediate_operand")])
1284 ;; Nonmemory operand predicate for integer modes.
1285 (define_mode_attr nonmemory_operand
1286 [(QI "nonmemory_operand")
1287 (HI "nonmemory_operand")
1288 (SI "x86_64_nonmemory_operand")
1289 (DI "x86_64_nonmemory_operand")])
1291 ;; Operand predicate for shifts.
1292 (define_mode_attr shift_operand
1293 [(QI "nonimmediate_operand")
1294 (HI "nonimmediate_operand")
1295 (SI "nonimmediate_operand")
1296 (DI "shiftdi_operand")
1297 (TI "register_operand")])
1299 ;; Operand predicate for shift argument.
1300 (define_mode_attr shift_immediate_operand
1301 [(QI "const_1_to_31_operand")
1302 (HI "const_1_to_31_operand")
1303 (SI "const_1_to_31_operand")
1304 (DI "const_1_to_63_operand")])
1306 ;; Input operand predicate for arithmetic left shifts.
1307 (define_mode_attr ashl_input_operand
1308 [(QI "nonimmediate_operand")
1309 (HI "nonimmediate_operand")
1310 (SI "nonimmediate_operand")
1311 (DI "ashldi_input_operand")
1312 (TI "reg_or_pm1_operand")])
1314 ;; SSE and x87 SFmode and DFmode floating point modes
1315 (define_mode_iterator MODEF [SF DF])
1317 ;; SSE floating point modes
1318 (define_mode_iterator MODEFH [(HF "TARGET_AVX512FP16") SF DF])
1320 ;; All x87 floating point modes
1321 (define_mode_iterator X87MODEF [SF DF XF])
1323 ;; All x87 floating point modes plus HFmode
1324 (define_mode_iterator X87MODEFH [HF SF DF XF BF])
1326 ;; All SSE floating point modes
1327 (define_mode_iterator SSEMODEF [HF SF DF TF])
1328 (define_mode_attr ssevecmodef [(HF "V8HF") (SF "V4SF") (DF "V2DF") (TF "TF")])
1330 ;; SSE instruction suffix for various modes
1331 (define_mode_attr ssemodesuffix
1332 [(HF "sh") (SF "ss") (DF "sd")
1333 (V32HF "ph") (V16SF "ps") (V8DF "pd")
1334 (V16HF "ph") (V16BF "bf") (V8SF "ps") (V4DF "pd")
1335 (V8HF "ph") (V8BF "bf") (V4SF "ps") (V2DF "pd")
1336 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1337 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1338 (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1340 ;; SSE vector suffix for floating point modes
1341 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1343 ;; SSE vector mode corresponding to a scalar mode
1344 (define_mode_attr ssevecmode
1345 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (HF "V8HF") (BF "V8BF") (SF "V4SF") (DF "V2DF")])
1346 (define_mode_attr ssevecmodelower
1347 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1349 ;; AVX512F vector mode corresponding to a scalar mode
1350 (define_mode_attr avx512fvecmode
1351 [(QI "V64QI") (HI "V32HI") (SI "V16SI") (DI "V8DI") (SF "V16SF") (DF "V8DF")])
1353 ;; Instruction suffix for REX 64bit operators.
1354 (define_mode_attr rex64suffix [(SI "{l}") (DI "{q}")])
1355 (define_mode_attr rex64namesuffix [(SI "") (DI "q")])
1357 ;; This mode iterator allows :P to be used for patterns that operate on
1358 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1359 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1361 ;; This mode iterator allows :W to be used for patterns that operate on
1362 ;; word_mode sized quantities.
1363 (define_mode_iterator W
1364 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1366 ;; This mode iterator allows :PTR to be used for patterns that operate on
1367 ;; ptr_mode sized quantities.
1368 (define_mode_iterator PTR
1369 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1371 ;; Scheduling descriptions
1373 (include "pentium.md")
1376 (include "athlon.md")
1377 (include "bdver1.md")
1378 (include "bdver3.md")
1379 (include "btver2.md")
1380 (include "znver.md")
1381 (include "znver4.md")
1382 (include "geode.md")
1386 (include "core2.md")
1387 (include "haswell.md")
1388 (include "lujiazui.md")
1389 (include "yongfeng.md")
1392 ;; Operand and operator predicates and constraints
1394 (include "predicates.md")
1395 (include "constraints.md")
1398 ;; Compare and branch/compare and store instructions.
1400 (define_expand "cbranch<mode>4"
1401 [(set (reg:CC FLAGS_REG)
1402 (compare:CC (match_operand:SWIM1248x 1 "nonimmediate_operand")
1403 (match_operand:SWIM1248x 2 "<general_operand>")))
1404 (set (pc) (if_then_else
1405 (match_operator 0 "ordered_comparison_operator"
1406 [(reg:CC FLAGS_REG) (const_int 0)])
1407 (label_ref (match_operand 3))
1411 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1412 operands[1] = force_reg (<MODE>mode, operands[1]);
1413 ix86_expand_branch (GET_CODE (operands[0]),
1414 operands[1], operands[2], operands[3]);
1418 (define_expand "cbranchti4"
1419 [(set (reg:CC FLAGS_REG)
1420 (compare:CC (match_operand:TI 1 "nonimmediate_operand")
1421 (match_operand:TI 2 "ix86_timode_comparison_operand")))
1422 (set (pc) (if_then_else
1423 (match_operator 0 "ix86_timode_comparison_operator"
1424 [(reg:CC FLAGS_REG) (const_int 0)])
1425 (label_ref (match_operand 3))
1427 "TARGET_64BIT || TARGET_SSE4_1"
1429 ix86_expand_branch (GET_CODE (operands[0]),
1430 operands[1], operands[2], operands[3]);
1434 (define_expand "cbranchoi4"
1435 [(set (reg:CC FLAGS_REG)
1436 (compare:CC (match_operand:OI 1 "nonimmediate_operand")
1437 (match_operand:OI 2 "nonimmediate_operand")))
1438 (set (pc) (if_then_else
1439 (match_operator 0 "bt_comparison_operator"
1440 [(reg:CC FLAGS_REG) (const_int 0)])
1441 (label_ref (match_operand 3))
1445 ix86_expand_branch (GET_CODE (operands[0]),
1446 operands[1], operands[2], operands[3]);
1450 (define_expand "cbranchxi4"
1451 [(set (reg:CC FLAGS_REG)
1452 (compare:CC (match_operand:XI 1 "nonimmediate_operand")
1453 (match_operand:XI 2 "nonimmediate_operand")))
1454 (set (pc) (if_then_else
1455 (match_operator 0 "bt_comparison_operator"
1456 [(reg:CC FLAGS_REG) (const_int 0)])
1457 (label_ref (match_operand 3))
1459 "TARGET_AVX512F && TARGET_EVEX512 && !TARGET_PREFER_AVX256"
1461 ix86_expand_branch (GET_CODE (operands[0]),
1462 operands[1], operands[2], operands[3]);
1466 (define_expand "cstore<mode>4"
1467 [(set (reg:CC FLAGS_REG)
1468 (compare:CC (match_operand:SDWIM 2 "nonimmediate_operand")
1469 (match_operand:SDWIM 3 "<general_operand>")))
1470 (set (match_operand:QI 0 "register_operand")
1471 (match_operator 1 "ordered_comparison_operator"
1472 [(reg:CC FLAGS_REG) (const_int 0)]))]
1475 if (<MODE>mode == (TARGET_64BIT ? TImode : DImode))
1477 if (GET_CODE (operands[1]) != EQ
1478 && GET_CODE (operands[1]) != NE)
1481 else if (MEM_P (operands[2]) && MEM_P (operands[3]))
1482 operands[2] = force_reg (<MODE>mode, operands[2]);
1483 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1484 operands[2], operands[3]);
1488 (define_expand "@cmp<mode>_1"
1489 [(set (reg:CC FLAGS_REG)
1490 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1491 (match_operand:SWI48 1 "<general_operand>")))])
1493 (define_mode_iterator SWI1248_AVX512BWDQ_64
1494 [(QI "TARGET_AVX512DQ") HI
1495 (SI "TARGET_AVX512BW")
1496 (DI "TARGET_AVX512BW && TARGET_EVEX512 && TARGET_64BIT")])
1498 (define_insn "*cmp<mode>_ccz_1"
1499 [(set (reg FLAGS_REG)
1500 (compare (match_operand:SWI1248_AVX512BWDQ_64 0
1501 "nonimmediate_operand" "<r>,?m<r>,$k")
1502 (match_operand:SWI1248_AVX512BWDQ_64 1 "const0_operand")))]
1503 "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
1505 test{<imodesuffix>}\t%0, %0
1506 cmp{<imodesuffix>}\t{%1, %0|%0, %1}
1507 kortest<mskmodesuffix>\t%0, %0"
1508 [(set_attr "type" "test,icmp,msklog")
1509 (set_attr "length_immediate" "0,1,*")
1510 (set_attr "prefix" "*,*,vex")
1511 (set_attr "mode" "<MODE>")])
1513 (define_insn "*cmp<mode>_ccno_1"
1514 [(set (reg FLAGS_REG)
1515 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1516 (match_operand:SWI 1 "const0_operand")))]
1517 "ix86_match_ccmode (insn, CCNOmode)"
1519 test{<imodesuffix>}\t%0, %0
1520 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1521 [(set_attr "type" "test,icmp")
1522 (set_attr "length_immediate" "0,1")
1523 (set_attr "mode" "<MODE>")])
1525 (define_insn "*cmp<mode>_1"
1526 [(set (reg FLAGS_REG)
1527 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1528 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r><m>")))]
1529 "ix86_match_ccmode (insn, CCmode)"
1530 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1531 [(set_attr "type" "icmp")
1532 (set_attr "mode" "<MODE>")])
1534 (define_insn "*cmp<mode>_minus_1"
1535 [(set (reg FLAGS_REG)
1537 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1538 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r><m>"))
1540 "ix86_match_ccmode (insn, CCGOCmode)"
1541 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1542 [(set_attr "type" "icmp")
1543 (set_attr "mode" "<MODE>")])
1545 (define_insn "*cmpqi_ext<mode>_1"
1546 [(set (reg FLAGS_REG)
1548 (match_operand:QI 0 "nonimmediate_operand" "QBn")
1550 (match_operator:SWI248 2 "extract_operator"
1551 [(match_operand 1 "int248_register_operand" "Q")
1553 (const_int 8)]) 0)))]
1554 "ix86_match_ccmode (insn, CCmode)"
1555 "cmp{b}\t{%h1, %0|%0, %h1}"
1556 [(set_attr "addr" "gpr8")
1557 (set_attr "type" "icmp")
1558 (set_attr "mode" "QI")])
1560 (define_insn "*cmpqi_ext<mode>_2"
1561 [(set (reg FLAGS_REG)
1564 (match_operator:SWI248 2 "extract_operator"
1565 [(match_operand 0 "int248_register_operand" "Q")
1568 (match_operand:QI 1 "const0_operand")))]
1569 "ix86_match_ccmode (insn, CCNOmode)"
1571 [(set_attr "type" "test")
1572 (set_attr "length_immediate" "0")
1573 (set_attr "mode" "QI")])
1575 (define_expand "cmpqi_ext_3"
1576 [(set (reg:CC FLAGS_REG)
1580 (match_operand:HI 0 "register_operand")
1583 (match_operand:QI 1 "const_int_operand")))])
1585 (define_insn "*cmpqi_ext<mode>_3"
1586 [(set (reg FLAGS_REG)
1589 (match_operator:SWI248 2 "extract_operator"
1590 [(match_operand 0 "int248_register_operand" "Q")
1593 (match_operand:QI 1 "general_operand" "QnBn")))]
1594 "ix86_match_ccmode (insn, CCmode)"
1595 "cmp{b}\t{%1, %h0|%h0, %1}"
1596 [(set_attr "addr" "gpr8")
1597 (set_attr "type" "icmp")
1598 (set_attr "mode" "QI")])
1600 (define_insn "*cmpqi_ext<mode>_4"
1601 [(set (reg FLAGS_REG)
1604 (match_operator:SWI248 2 "extract_operator"
1605 [(match_operand 0 "int248_register_operand" "Q")
1609 (match_operator:SWI248 3 "extract_operator"
1610 [(match_operand 1 "int248_register_operand" "Q")
1612 (const_int 8)]) 0)))]
1613 "ix86_match_ccmode (insn, CCmode)"
1614 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1615 [(set_attr "type" "icmp")
1616 (set_attr "mode" "QI")])
1618 (define_insn_and_split "*cmp<dwi>_doubleword"
1619 [(set (reg:CCZ FLAGS_REG)
1620 (compare:CCZ (match_operand:<DWI> 0 "nonimmediate_operand")
1621 (match_operand:<DWI> 1 "general_operand")))]
1622 "ix86_pre_reload_split ()"
1625 [(parallel [(set (reg:CCZ FLAGS_REG)
1626 (compare:CCZ (ior:DWIH (match_dup 4) (match_dup 5))
1628 (set (match_dup 4) (ior:DWIH (match_dup 4) (match_dup 5)))])]
1630 split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);
1631 /* Placing the SUBREG pieces in pseudos helps reload. */
1632 for (int i = 0; i < 4; i++)
1633 if (SUBREG_P (operands[i]))
1634 operands[i] = force_reg (<MODE>mode, operands[i]);
1636 operands[4] = gen_reg_rtx (<MODE>mode);
1638 /* Special case comparisons against -1. */
1639 if (operands[1] == constm1_rtx && operands[3] == constm1_rtx)
1641 emit_insn (gen_and<mode>3 (operands[4], operands[0], operands[2]));
1642 emit_insn (gen_cmp_1 (<MODE>mode, operands[4], constm1_rtx));
1646 if (operands[1] == const0_rtx)
1647 emit_move_insn (operands[4], operands[0]);
1648 else if (operands[0] == const0_rtx)
1649 emit_move_insn (operands[4], operands[1]);
1650 else if (operands[1] == constm1_rtx)
1651 emit_insn (gen_one_cmpl<mode>2 (operands[4], operands[0]));
1652 else if (operands[0] == constm1_rtx)
1653 emit_insn (gen_one_cmpl<mode>2 (operands[4], operands[1]));
1656 if (CONST_SCALAR_INT_P (operands[1])
1657 && !x86_64_immediate_operand (operands[1], <MODE>mode))
1658 operands[1] = force_reg (<MODE>mode, operands[1]);
1659 emit_insn (gen_xor<mode>3 (operands[4], operands[0], operands[1]));
1662 if (operands[3] == const0_rtx)
1663 operands[5] = operands[2];
1664 else if (operands[2] == const0_rtx)
1665 operands[5] = operands[3];
1668 operands[5] = gen_reg_rtx (<MODE>mode);
1669 if (operands[3] == constm1_rtx)
1670 emit_insn (gen_one_cmpl<mode>2 (operands[5], operands[2]));
1671 else if (operands[2] == constm1_rtx)
1672 emit_insn (gen_one_cmpl<mode>2 (operands[5], operands[3]));
1675 if (CONST_SCALAR_INT_P (operands[3])
1676 && !x86_64_immediate_operand (operands[3], <MODE>mode))
1677 operands[3] = force_reg (<MODE>mode, operands[3]);
1678 emit_insn (gen_xor<mode>3 (operands[5], operands[2], operands[3]));
1683 ;; These implement float point compares.
1684 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1685 ;; which would allow mix and match FP modes on the compares. Which is what
1686 ;; the old patterns did, but with many more of them.
1688 (define_expand "cbranchxf4"
1689 [(set (reg:CC FLAGS_REG)
1690 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1691 (match_operand:XF 2 "nonmemory_operand")))
1692 (set (pc) (if_then_else
1693 (match_operator 0 "ix86_fp_comparison_operator"
1696 (label_ref (match_operand 3))
1700 ix86_expand_branch (GET_CODE (operands[0]),
1701 operands[1], operands[2], operands[3]);
1705 (define_expand "cstorexf4"
1706 [(set (reg:CC FLAGS_REG)
1707 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1708 (match_operand:XF 3 "nonmemory_operand")))
1709 (set (match_operand:QI 0 "register_operand")
1710 (match_operator 1 "ix86_fp_comparison_operator"
1715 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1716 operands[2], operands[3]);
1720 (define_expand "cbranchhf4"
1721 [(set (reg:CC FLAGS_REG)
1722 (compare:CC (match_operand:HF 1 "cmp_fp_expander_operand")
1723 (match_operand:HF 2 "cmp_fp_expander_operand")))
1724 (set (pc) (if_then_else
1725 (match_operator 0 "ix86_fp_comparison_operator"
1728 (label_ref (match_operand 3))
1732 ix86_expand_branch (GET_CODE (operands[0]),
1733 operands[1], operands[2], operands[3]);
1737 (define_expand "cbranch<mode>4"
1738 [(set (reg:CC FLAGS_REG)
1739 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1740 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1741 (set (pc) (if_then_else
1742 (match_operator 0 "ix86_fp_comparison_operator"
1745 (label_ref (match_operand 3))
1747 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1749 ix86_expand_branch (GET_CODE (operands[0]),
1750 operands[1], operands[2], operands[3]);
1754 (define_expand "cbranchbf4"
1755 [(set (reg:CC FLAGS_REG)
1756 (compare:CC (match_operand:BF 1 "cmp_fp_expander_operand")
1757 (match_operand:BF 2 "cmp_fp_expander_operand")))
1758 (set (pc) (if_then_else
1759 (match_operator 0 "comparison_operator"
1762 (label_ref (match_operand 3))
1764 "TARGET_80387 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
1766 rtx op1 = ix86_expand_fast_convert_bf_to_sf (operands[1]);
1767 rtx op2 = ix86_expand_fast_convert_bf_to_sf (operands[2]);
1768 do_compare_rtx_and_jump (op1, op2, GET_CODE (operands[0]), 0,
1769 SFmode, NULL_RTX, NULL,
1770 as_a <rtx_code_label *> (operands[3]),
1771 /* Unfortunately this isn't propagated. */
1772 profile_probability::even ());
1776 (define_expand "cstorehf4"
1777 [(set (reg:CC FLAGS_REG)
1778 (compare:CC (match_operand:HF 2 "cmp_fp_expander_operand")
1779 (match_operand:HF 3 "cmp_fp_expander_operand")))
1780 (set (match_operand:QI 0 "register_operand")
1781 (match_operator 1 "ix86_fp_comparison_operator"
1786 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1787 operands[2], operands[3]);
1791 (define_expand "cstorebf4"
1792 [(set (reg:CC FLAGS_REG)
1793 (compare:CC (match_operand:BF 2 "cmp_fp_expander_operand")
1794 (match_operand:BF 3 "cmp_fp_expander_operand")))
1795 (set (match_operand:QI 0 "register_operand")
1796 (match_operator 1 "comparison_operator"
1799 "TARGET_80387 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
1801 rtx op1 = ix86_expand_fast_convert_bf_to_sf (operands[2]);
1802 rtx op2 = ix86_expand_fast_convert_bf_to_sf (operands[3]);
1803 rtx res = emit_store_flag_force (operands[0], GET_CODE (operands[1]),
1804 op1, op2, SFmode, 0, 1);
1805 if (!rtx_equal_p (res, operands[0]))
1806 emit_move_insn (operands[0], res);
1810 (define_expand "cstore<mode>4"
1811 [(set (reg:CC FLAGS_REG)
1812 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1813 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1814 (set (match_operand:QI 0 "register_operand")
1815 (match_operator 1 "ix86_fp_comparison_operator"
1818 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1820 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1821 operands[2], operands[3]);
1825 (define_expand "cbranchcc4"
1826 [(set (pc) (if_then_else
1827 (match_operator 0 "comparison_operator"
1828 [(match_operand 1 "flags_reg_operand")
1829 (match_operand 2 "const0_operand")])
1830 (label_ref (match_operand 3))
1834 ix86_expand_branch (GET_CODE (operands[0]),
1835 operands[1], operands[2], operands[3]);
1839 (define_expand "cstorecc4"
1840 [(set (match_operand:QI 0 "register_operand")
1841 (match_operator 1 "comparison_operator"
1842 [(match_operand 2 "flags_reg_operand")
1843 (match_operand 3 "const0_operand")]))]
1846 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1847 operands[2], operands[3]);
1851 ;; FP compares, step 1:
1852 ;; Set the FP condition codes and move fpsr to ax.
1854 ;; We may not use "#" to split and emit these
1855 ;; due to reg-stack pops killing fpsr.
1857 (define_insn "*cmpxf_i387"
1858 [(set (match_operand:HI 0 "register_operand" "=a")
1861 (match_operand:XF 1 "register_operand" "f")
1862 (match_operand:XF 2 "reg_or_0_operand" "fC"))]
1865 "* return output_fp_compare (insn, operands, false, false);"
1866 [(set_attr "type" "multi")
1867 (set_attr "unit" "i387")
1868 (set_attr "mode" "XF")])
1870 (define_insn "*cmp<mode>_i387"
1871 [(set (match_operand:HI 0 "register_operand" "=a")
1874 (match_operand:MODEF 1 "register_operand" "f")
1875 (match_operand:MODEF 2 "nonimm_or_0_operand" "fmC"))]
1878 "* return output_fp_compare (insn, operands, false, false);"
1879 [(set_attr "type" "multi")
1880 (set_attr "unit" "i387")
1881 (set_attr "mode" "<MODE>")])
1883 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1884 [(set (match_operand:HI 0 "register_operand" "=a")
1887 (match_operand:X87MODEF 1 "register_operand" "f")
1889 (match_operand:SWI24 2 "nonimmediate_operand" "m")))]
1892 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1893 || optimize_function_for_size_p (cfun))"
1894 "* return output_fp_compare (insn, operands, false, false);"
1895 [(set_attr "type" "multi")
1896 (set_attr "unit" "i387")
1897 (set_attr "fp_int_src" "true")
1898 (set_attr "mode" "<SWI24:MODE>")])
1900 (define_insn "*cmpu<mode>_i387"
1901 [(set (match_operand:HI 0 "register_operand" "=a")
1905 (match_operand:X87MODEF 1 "register_operand" "f")
1906 (match_operand:X87MODEF 2 "register_operand" "f"))]
1910 "* return output_fp_compare (insn, operands, false, true);"
1911 [(set_attr "type" "multi")
1912 (set_attr "unit" "i387")
1913 (set_attr "mode" "<MODE>")])
1915 ;; FP compares, step 2:
1916 ;; Get ax into flags, general case.
1918 (define_insn "x86_sahf_1"
1919 [(set (reg:CC FLAGS_REG)
1920 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1924 #ifndef HAVE_AS_IX86_SAHF
1926 return ASM_BYTE "0x9e";
1931 [(set_attr "length" "1")
1932 (set_attr "athlon_decode" "vector")
1933 (set_attr "amdfam10_decode" "direct")
1934 (set_attr "bdver1_decode" "direct")
1935 (set_attr "mode" "SI")])
1937 ;; Pentium Pro can do both steps in one go.
1938 ;; (these instructions set flags directly)
1940 (define_subst_attr "unord" "unord_subst" "" "u")
1941 (define_subst_attr "unordered" "unord_subst" "false" "true")
1943 (define_subst "unord_subst"
1944 [(set (match_operand:CCFP 0)
1945 (match_operand:CCFP 1))]
1952 (define_insn "*cmpi<unord>xf_i387"
1953 [(set (reg:CCFP FLAGS_REG)
1955 (match_operand:XF 0 "register_operand" "f")
1956 (match_operand:XF 1 "register_operand" "f")))]
1957 "TARGET_80387 && TARGET_CMOVE"
1958 "* return output_fp_compare (insn, operands, true, <unordered>);"
1959 [(set_attr "type" "fcmp")
1960 (set_attr "mode" "XF")
1961 (set_attr "athlon_decode" "vector")
1962 (set_attr "amdfam10_decode" "direct")
1963 (set_attr "bdver1_decode" "double")
1964 (set_attr "znver1_decode" "double")])
1966 (define_insn "*cmpi<unord><MODEF:mode>"
1967 [(set (reg:CCFP FLAGS_REG)
1969 (match_operand:MODEF 0 "register_operand" "f,v")
1970 (match_operand:MODEF 1 "register_ssemem_operand" "f,vm")))]
1971 "(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
1972 || (TARGET_80387 && TARGET_CMOVE)"
1974 * return output_fp_compare (insn, operands, true, <unordered>);
1975 %v<unord>comi<MODEF:ssemodesuffix>\t{%1, %0|%0, %1}"
1976 [(set_attr "type" "fcmp,ssecomi")
1977 (set_attr "prefix" "orig,maybe_vex")
1978 (set_attr "mode" "<MODEF:MODE>")
1979 (set_attr "prefix_rep" "*,0")
1980 (set (attr "prefix_data16")
1981 (cond [(eq_attr "alternative" "0")
1983 (eq_attr "mode" "DF")
1986 (const_string "0")))
1987 (set_attr "athlon_decode" "vector")
1988 (set_attr "amdfam10_decode" "direct")
1989 (set_attr "bdver1_decode" "double")
1990 (set_attr "znver1_decode" "double")
1991 (set (attr "enabled")
1993 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
1995 (eq_attr "alternative" "0")
1996 (symbol_ref "TARGET_MIX_SSE_I387")
1997 (symbol_ref "true"))
1999 (eq_attr "alternative" "0")
2001 (symbol_ref "false"))))])
2003 (define_insn "*cmpi<unord>hf"
2004 [(set (reg:CCFP FLAGS_REG)
2006 (match_operand:HF 0 "register_operand" "v")
2007 (match_operand:HF 1 "nonimmediate_operand" "vm")))]
2009 "v<unord>comish\t{%1, %0|%0, %1}"
2010 [(set_attr "type" "ssecomi")
2011 (set_attr "prefix" "evex")
2012 (set_attr "mode" "HF")])
2015 (define_insn "x86_stc"
2016 [(set (reg:CCC FLAGS_REG) (unspec:CCC [(const_int 0)] UNSPEC_STC))]
2019 [(set_attr "length" "1")
2020 (set_attr "length_immediate" "0")
2021 (set_attr "modrm" "0")])
2023 ;; On Pentium 4, set the carry flag using mov $1,%al;addb $-1,%al.
2025 [(match_scratch:QI 0 "r")
2026 (set (reg:CCC FLAGS_REG) (unspec:CCC [(const_int 0)] UNSPEC_STC))]
2027 "TARGET_SLOW_STC && !optimize_insn_for_size_p ()"
2028 [(set (match_dup 0) (const_int 1))
2030 [(set (reg:CCC FLAGS_REG)
2031 (compare:CCC (plus:QI (match_dup 0) (const_int -1))
2033 (set (match_dup 0) (plus:QI (match_dup 0) (const_int -1)))])])
2035 ;; Complement carry flag.
2036 (define_insn "*x86_cmc"
2037 [(set (reg:CCC FLAGS_REG)
2038 (compare:CCC (neg:QI (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
2039 (geu:QI (reg:CCC FLAGS_REG) (const_int 0))))]
2042 [(set_attr "length" "1")
2043 (set_attr "length_immediate" "0")
2044 (set_attr "use_carry" "1")
2045 (set_attr "modrm" "0")])
2047 ;; On Pentium 4, cmc is replaced with setnc %al;addb $-1,%al.
2049 [(match_scratch:QI 0 "r")
2050 (set (reg:CCC FLAGS_REG)
2051 (compare:CCC (neg:QI (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
2052 (geu:QI (reg:CCC FLAGS_REG) (const_int 0))))]
2053 "TARGET_SLOW_STC && !optimize_insn_for_size_p ()"
2054 [(set (match_dup 0) (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))
2056 [(set (reg:CCC FLAGS_REG)
2057 (compare:CCC (plus:QI (match_dup 0) (const_int -1))
2059 (set (match_dup 0) (plus:QI (match_dup 0) (const_int -1)))])])
2061 ;; Push/pop instructions.
2063 (define_insn_and_split "*pushv1ti2"
2064 [(set (match_operand:V1TI 0 "push_operand" "=<")
2065 (match_operand:V1TI 1 "register_operand" "v"))]
2066 "TARGET_64BIT && TARGET_STV"
2068 "&& reload_completed"
2069 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2070 (set (match_dup 0) (match_dup 1))]
2072 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (V1TImode)));
2073 /* Preserve memory attributes. */
2074 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2076 [(set_attr "type" "multi")
2077 (set_attr "mode" "TI")])
2079 (define_insn "*push<mode>2"
2080 [(set (match_operand:DWI 0 "push_operand" "=<,<")
2081 (match_operand:DWI 1 "general_no_elim_operand" "riF*o,*v"))]
2084 [(set_attr "type" "multi")
2085 (set_attr "mode" "<MODE>")])
2088 [(set (match_operand:DWI 0 "push_operand")
2089 (match_operand:DWI 1 "general_gr_operand"))]
2092 "ix86_split_long_move (operands); DONE;")
2094 (define_insn "*pushdi2_rex64"
2095 [(set (match_operand:DI 0 "push_operand" "=<,<,!<")
2096 (match_operand:DI 1 "general_no_elim_operand" "re*m,*v,n"))]
2102 [(set_attr "type" "push,multi,multi")
2103 (set_attr "mode" "DI")])
2105 ;; Convert impossible pushes of immediate to existing instructions.
2106 ;; First try to get scratch register and go through it. In case this
2107 ;; fails, push sign extended lower part first and then overwrite
2108 ;; upper part by 32bit move.
2111 [(match_scratch:DI 2 "r")
2112 (set (match_operand:DI 0 "push_operand")
2113 (match_operand:DI 1 "immediate_operand"))]
2115 && !symbolic_operand (operands[1], DImode)
2116 && !x86_64_immediate_operand (operands[1], DImode)"
2117 [(set (match_dup 2) (match_dup 1))
2118 (set (match_dup 0) (match_dup 2))])
2121 [(set (match_operand:DI 0 "push_operand")
2122 (match_operand:DI 1 "immediate_operand"))]
2123 "TARGET_64BIT && epilogue_completed
2124 && !symbolic_operand (operands[1], DImode)
2125 && !x86_64_immediate_operand (operands[1], DImode)"
2126 [(set (match_dup 0) (match_dup 1))
2127 (set (match_dup 2) (match_dup 3))]
2129 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
2131 operands[1] = gen_lowpart (DImode, operands[2]);
2132 operands[2] = gen_rtx_MEM (SImode,
2133 plus_constant (Pmode, stack_pointer_rtx, 4));
2136 ;; For TARGET_64BIT we always round up to 8 bytes.
2137 (define_insn "*pushsi2_rex64"
2138 [(set (match_operand:SI 0 "push_operand" "=X,X")
2139 (match_operand:SI 1 "nonmemory_no_elim_operand" "re,*v"))]
2144 [(set_attr "type" "push,multi")
2145 (set_attr "mode" "DI")])
2147 (define_insn "*pushsi2"
2148 [(set (match_operand:SI 0 "push_operand" "=<,<")
2149 (match_operand:SI 1 "general_no_elim_operand" "ri*m,*v"))]
2154 [(set_attr "type" "push,multi")
2155 (set_attr "mode" "SI")])
2158 [(set (match_operand:SWI48DWI 0 "push_operand")
2159 (match_operand:SWI48DWI 1 "sse_reg_operand"))]
2160 "TARGET_SSE && reload_completed"
2161 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2162 (set (match_dup 0) (match_dup 1))]
2164 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (<SWI48DWI:MODE>mode)));
2165 /* Preserve memory attributes. */
2166 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2169 ;; emit_push_insn when it calls move_by_pieces requires an insn to
2170 ;; "push a byte/word". But actually we use push{l,q}, which has
2171 ;; the effect of rounding the amount pushed up to a word.
2173 (define_insn "*push<mode>2"
2174 [(set (match_operand:SWI12 0 "push_operand" "=X")
2175 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
2177 "* return TARGET_64BIT ? \"push{q}\t%q1\" : \"push{l}\t%k1\";"
2178 [(set_attr "type" "push")
2180 (if_then_else (match_test "TARGET_64BIT")
2182 (const_string "SI")))])
2184 (define_insn "*push<mode>2_prologue"
2185 [(set (match_operand:W 0 "push_operand" "=<")
2186 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
2187 (clobber (mem:BLK (scratch)))]
2189 "push{<imodesuffix>}\t%1"
2190 [(set_attr "type" "push")
2191 (set_attr "mode" "<MODE>")])
2193 (define_insn "*pop<mode>1"
2194 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
2195 (match_operand:W 1 "pop_operand" ">"))]
2197 "pop{<imodesuffix>}\t%0"
2198 [(set_attr "type" "pop")
2199 (set_attr "mode" "<MODE>")])
2201 (define_insn "*pop<mode>1_epilogue"
2202 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
2203 (match_operand:W 1 "pop_operand" ">"))
2204 (clobber (mem:BLK (scratch)))]
2206 "pop{<imodesuffix>}\t%0"
2207 [(set_attr "type" "pop")
2208 (set_attr "mode" "<MODE>")])
2210 (define_insn "@pushfl<mode>2"
2211 [(set (match_operand:W 0 "push_operand" "=<")
2212 (unspec:W [(match_operand:CC 1 "flags_reg_operand")]
2215 "pushf{<imodesuffix>}"
2216 [(set_attr "type" "push")
2217 (set_attr "mode" "<MODE>")])
2219 (define_insn "@popfl<mode>1"
2220 [(set (match_operand:CC 0 "flags_reg_operand")
2221 (unspec:CC [(match_operand:W 1 "pop_operand" ">")]
2224 "popf{<imodesuffix>}"
2225 [(set_attr "type" "pop")
2226 (set_attr "mode" "<MODE>")])
2229 ;; Reload patterns to support multi-word load/store
2230 ;; with non-offsetable address.
2231 (define_expand "reload_noff_store"
2232 [(parallel [(match_operand 0 "memory_operand" "=m")
2233 (match_operand 1 "register_operand" "r")
2234 (match_operand:DI 2 "register_operand" "=&r")])]
2237 rtx mem = operands[0];
2238 rtx addr = XEXP (mem, 0);
2240 emit_move_insn (operands[2], addr);
2241 mem = replace_equiv_address_nv (mem, operands[2]);
2243 emit_insn (gen_rtx_SET (mem, operands[1]));
2247 (define_expand "reload_noff_load"
2248 [(parallel [(match_operand 0 "register_operand" "=r")
2249 (match_operand 1 "memory_operand" "m")
2250 (match_operand:DI 2 "register_operand" "=r")])]
2253 rtx mem = operands[1];
2254 rtx addr = XEXP (mem, 0);
2256 emit_move_insn (operands[2], addr);
2257 mem = replace_equiv_address_nv (mem, operands[2]);
2259 emit_insn (gen_rtx_SET (operands[0], mem));
2263 ;; Move instructions.
2265 (define_expand "movxi"
2266 [(set (match_operand:XI 0 "nonimmediate_operand")
2267 (match_operand:XI 1 "general_operand"))]
2268 "TARGET_AVX512F && TARGET_EVEX512"
2269 "ix86_expand_vector_move (XImode, operands); DONE;")
2271 (define_expand "movoi"
2272 [(set (match_operand:OI 0 "nonimmediate_operand")
2273 (match_operand:OI 1 "general_operand"))]
2275 "ix86_expand_vector_move (OImode, operands); DONE;")
2277 (define_expand "movti"
2278 [(set (match_operand:TI 0 "nonimmediate_operand")
2279 (match_operand:TI 1 "general_operand"))]
2280 "TARGET_64BIT || TARGET_SSE"
2283 ix86_expand_move (TImode, operands);
2285 ix86_expand_vector_move (TImode, operands);
2289 ;; This expands to what emit_move_complex would generate if we didn't
2290 ;; have a movti pattern. Having this avoids problems with reload on
2291 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2292 ;; to have around all the time.
2293 (define_expand "movcdi"
2294 [(set (match_operand:CDI 0 "nonimmediate_operand")
2295 (match_operand:CDI 1 "general_operand"))]
2298 if (push_operand (operands[0], CDImode))
2299 emit_move_complex_push (CDImode, operands[0], operands[1]);
2301 emit_move_complex_parts (operands[0], operands[1]);
2305 (define_expand "mov<mode>"
2306 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
2307 (match_operand:SWI1248x 1 "general_operand"))]
2309 "ix86_expand_move (<MODE>mode, operands); DONE;")
2311 (define_insn "*mov<mode>_xor"
2312 [(set (match_operand:SWI48 0 "register_operand" "=r")
2313 (match_operand:SWI48 1 "const0_operand"))
2314 (clobber (reg:CC FLAGS_REG))]
2317 [(set_attr "type" "alu1")
2318 (set_attr "mode" "SI")
2319 (set_attr "length_immediate" "0")])
2321 (define_insn "*mov<mode>_and"
2322 [(set (match_operand:SWI248 0 "memory_operand" "=m")
2323 (match_operand:SWI248 1 "const0_operand"))
2324 (clobber (reg:CC FLAGS_REG))]
2326 "and{<imodesuffix>}\t{%1, %0|%0, %1}"
2327 [(set_attr "type" "alu1")
2328 (set_attr "mode" "<MODE>")
2329 (set_attr "length_immediate" "1")])
2331 (define_insn "*mov<mode>_or"
2332 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
2333 (match_operand:SWI248 1 "constm1_operand"))
2334 (clobber (reg:CC FLAGS_REG))]
2336 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
2337 [(set_attr "type" "alu1")
2338 (set_attr "mode" "<MODE>")
2339 (set_attr "length_immediate" "1")])
2341 (define_insn "*movxi_internal_avx512f"
2342 [(set (match_operand:XI 0 "nonimmediate_operand" "=v,v ,v ,m")
2343 (match_operand:XI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2344 "TARGET_AVX512F && TARGET_EVEX512
2345 && (register_operand (operands[0], XImode)
2346 || register_operand (operands[1], XImode))"
2348 switch (get_attr_type (insn))
2351 return standard_sse_constant_opcode (insn, operands);
2354 return ix86_output_ssemov (insn, operands);
2360 [(set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2361 (set_attr "prefix" "evex")
2362 (set_attr "mode" "XI")])
2364 (define_insn "*movoi_internal_avx"
2365 [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,v ,m")
2366 (match_operand:OI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2368 && (register_operand (operands[0], OImode)
2369 || register_operand (operands[1], OImode))"
2371 switch (get_attr_type (insn))
2374 return standard_sse_constant_opcode (insn, operands);
2377 return ix86_output_ssemov (insn, operands);
2383 [(set_attr "isa" "*,avx2,*,*")
2384 (set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2385 (set_attr "prefix" "vex")
2386 (set_attr "mode" "OI")])
2388 (define_insn "*movti_internal"
2389 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,v ,m,?jc,?Yd")
2390 (match_operand:TI 1 "general_operand" "riFo,re,C,BC,vm,v,Yd,jc"))]
2392 && !(MEM_P (operands[0]) && MEM_P (operands[1])))
2394 && nonimmediate_or_sse_const_operand (operands[1], TImode)
2395 && (register_operand (operands[0], TImode)
2396 || register_operand (operands[1], TImode)))"
2398 switch (get_attr_type (insn))
2404 return standard_sse_constant_opcode (insn, operands);
2407 return ix86_output_ssemov (insn, operands);
2414 (cond [(eq_attr "alternative" "0,1,6,7")
2415 (const_string "x64")
2416 (eq_attr "alternative" "3")
2417 (const_string "sse2")
2419 (const_string "*")))
2421 (cond [(eq_attr "alternative" "0,1,6,7")
2422 (const_string "multi")
2423 (eq_attr "alternative" "2,3")
2424 (const_string "sselog1")
2426 (const_string "ssemov")))
2427 (set (attr "prefix")
2428 (if_then_else (eq_attr "type" "sselog1,ssemov")
2429 (const_string "maybe_vex")
2430 (const_string "orig")))
2432 (cond [(eq_attr "alternative" "0,1")
2434 (match_test "TARGET_AVX")
2436 (ior (not (match_test "TARGET_SSE2"))
2437 (match_test "optimize_function_for_size_p (cfun)"))
2438 (const_string "V4SF")
2439 (and (eq_attr "alternative" "5")
2440 (match_test "TARGET_SSE_TYPELESS_STORES"))
2441 (const_string "V4SF")
2443 (const_string "TI")))
2444 (set (attr "preferred_for_speed")
2445 (cond [(eq_attr "alternative" "6")
2446 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2447 (eq_attr "alternative" "7")
2448 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2450 (symbol_ref "true")))])
2453 [(set (match_operand:TI 0 "sse_reg_operand")
2454 (match_operand:TI 1 "general_reg_operand"))]
2455 "TARGET_64BIT && TARGET_SSE4_1
2456 && reload_completed"
2459 (vec_duplicate:V2DI (match_dup 3))
2463 operands[2] = lowpart_subreg (V2DImode, operands[0], TImode);
2464 operands[3] = gen_highpart (DImode, operands[1]);
2466 emit_move_insn (gen_lowpart (DImode, operands[0]),
2467 gen_lowpart (DImode, operands[1]));
2470 (define_insn "*movdi_internal"
2471 [(set (match_operand:DI 0 "nonimmediate_operand"
2472 "=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")
2473 (match_operand:DI 1 "general_operand"
2474 "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"))]
2475 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2476 && ix86_hardreg_mov_ok (operands[0], operands[1])"
2478 switch (get_attr_type (insn))
2481 return "kmovq\t{%1, %0|%0, %1}";
2484 if (operands[1] == const0_rtx)
2485 return "kxorq\t%0, %0, %0";
2486 else if (operands[1] == constm1_rtx)
2487 return "kxnorq\t%0, %0, %0";
2494 return "pxor\t%0, %0";
2497 /* Handle broken assemblers that require movd instead of movq. */
2498 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2499 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2500 return "movd\t{%1, %0|%0, %1}";
2501 return "movq\t{%1, %0|%0, %1}";
2504 return standard_sse_constant_opcode (insn, operands);
2507 return ix86_output_ssemov (insn, operands);
2510 if (SSE_REG_P (operands[0]))
2511 return "movq2dq\t{%1, %0|%0, %1}";
2513 return "movdq2q\t{%1, %0|%0, %1}";
2516 return "lea{q}\t{%E1, %0|%0, %E1}";
2519 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2520 if (get_attr_mode (insn) == MODE_SI)
2521 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2522 else if (which_alternative == 4)
2523 return "movabs{q}\t{%1, %0|%0, %1}";
2524 else if (ix86_use_lea_for_mov (insn, operands))
2525 return "lea{q}\t{%E1, %0|%0, %E1}";
2527 return "mov{q}\t{%1, %0|%0, %1}";
2534 (cond [(eq_attr "alternative" "0,1,17,18")
2535 (const_string "nox64")
2536 (eq_attr "alternative" "2,3,4,5,10,11,23,25")
2537 (const_string "x64")
2538 (eq_attr "alternative" "19,20")
2539 (const_string "x64_sse2")
2540 (eq_attr "alternative" "21,22")
2541 (const_string "sse2")
2543 (const_string "*")))
2545 (cond [(eq_attr "alternative" "0,1,17,18")
2546 (const_string "multi")
2547 (eq_attr "alternative" "6")
2548 (const_string "mmx")
2549 (eq_attr "alternative" "7,8,9,10,11")
2550 (const_string "mmxmov")
2551 (eq_attr "alternative" "12")
2552 (const_string "sselog1")
2553 (eq_attr "alternative" "13,14,15,16,19,20")
2554 (const_string "ssemov")
2555 (eq_attr "alternative" "21,22")
2556 (const_string "ssecvt")
2557 (eq_attr "alternative" "23,24,25,26")
2558 (const_string "mskmov")
2559 (eq_attr "alternative" "27")
2560 (const_string "msklog")
2561 (and (match_operand 0 "register_operand")
2562 (match_operand 1 "pic_32bit_operand"))
2563 (const_string "lea")
2565 (const_string "imov")))
2568 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2570 (const_string "*")))
2571 (set (attr "length_immediate")
2573 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2575 (const_string "*")))
2576 (set (attr "prefix_rex")
2578 (eq_attr "alternative" "10,11,19,20")
2580 (const_string "*")))
2581 (set (attr "prefix")
2582 (if_then_else (eq_attr "type" "sselog1,ssemov")
2583 (const_string "maybe_vex")
2584 (const_string "orig")))
2585 (set (attr "prefix_data16")
2586 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2588 (const_string "*")))
2590 (cond [(eq_attr "alternative" "2")
2592 (eq_attr "alternative" "12")
2593 (cond [(match_test "TARGET_AVX")
2595 (ior (not (match_test "TARGET_SSE2"))
2596 (match_test "optimize_function_for_size_p (cfun)"))
2597 (const_string "V4SF")
2599 (const_string "TI"))
2600 (eq_attr "alternative" "13")
2601 (cond [(match_test "TARGET_AVX512VL")
2603 (match_test "TARGET_AVX512F")
2605 (match_test "TARGET_AVX")
2607 (ior (not (match_test "TARGET_SSE2"))
2608 (match_test "optimize_function_for_size_p (cfun)"))
2609 (const_string "V4SF")
2611 (const_string "TI"))
2613 (and (eq_attr "alternative" "14,15,16")
2614 (not (match_test "TARGET_SSE2")))
2615 (const_string "V2SF")
2617 (const_string "DI")))
2618 (set (attr "preferred_for_speed")
2619 (cond [(eq_attr "alternative" "10,17,19")
2620 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2621 (eq_attr "alternative" "11,18,20")
2622 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2624 (symbol_ref "true")))
2625 (set (attr "enabled")
2626 (cond [(eq_attr "alternative" "15")
2628 (match_test "TARGET_STV && TARGET_SSE2")
2629 (symbol_ref "false")
2631 (eq_attr "alternative" "16")
2633 (match_test "TARGET_STV && TARGET_SSE2")
2635 (symbol_ref "false"))
2637 (const_string "*")))])
2640 [(set (match_operand:<DWI> 0 "general_reg_operand")
2641 (match_operand:<DWI> 1 "sse_reg_operand"))]
2643 && reload_completed"
2647 (parallel [(const_int 1)])))]
2649 operands[2] = gen_highpart (<MODE>mode, operands[0]);
2650 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[1], <DWI>mode);
2652 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]),
2653 gen_lowpart (<MODE>mode, operands[1]));
2657 [(set (match_operand:DWI 0 "nonimmediate_gr_operand")
2658 (match_operand:DWI 1 "general_gr_operand"))]
2661 "ix86_split_long_move (operands); DONE;")
2664 [(set (match_operand:DI 0 "sse_reg_operand")
2665 (match_operand:DI 1 "general_reg_operand"))]
2666 "!TARGET_64BIT && TARGET_SSE4_1
2667 && reload_completed"
2670 (vec_duplicate:V4SI (match_dup 3))
2674 operands[2] = lowpart_subreg (V4SImode, operands[0], DImode);
2675 operands[3] = gen_highpart (SImode, operands[1]);
2677 emit_move_insn (gen_lowpart (SImode, operands[0]),
2678 gen_lowpart (SImode, operands[1]));
2681 ;; movabsq $0x0012345678000000, %rax is longer
2682 ;; than movl $0x12345678, %eax; shlq $24, %rax.
2684 [(set (match_operand:DI 0 "register_operand")
2685 (match_operand:DI 1 "const_int_operand"))]
2687 && optimize_insn_for_size_p ()
2688 && LEGACY_INT_REG_P (operands[0])
2689 && !x86_64_immediate_operand (operands[1], DImode)
2690 && !x86_64_zext_immediate_operand (operands[1], DImode)
2691 && !((UINTVAL (operands[1]) >> ctz_hwi (UINTVAL (operands[1])))
2692 & ~(HOST_WIDE_INT) 0xffffffff)
2693 && peep2_regno_dead_p (0, FLAGS_REG)"
2694 [(set (match_dup 0) (match_dup 1))
2695 (parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
2696 (clobber (reg:CC FLAGS_REG))])]
2698 int shift = ctz_hwi (UINTVAL (operands[1]));
2699 operands[1] = gen_int_mode (UINTVAL (operands[1]) >> shift, DImode);
2700 operands[2] = gen_int_mode (shift, QImode);
2703 (define_insn "*movsi_internal"
2704 [(set (match_operand:SI 0 "nonimmediate_operand"
2705 "=r,m ,*y,*y,?*y,?m,?r,?*y,?Yv,?v,?v,m ,?r,?v,*k,*k ,*rm,*k")
2706 (match_operand:SI 1 "general_operand"
2707 "g ,re,C ,*y,Bk ,*y,*y,r ,C ,?v,Bk,?v,?v,r ,*r,*kBk,*k ,CBC"))]
2708 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2709 && ix86_hardreg_mov_ok (operands[0], operands[1])"
2711 switch (get_attr_type (insn))
2714 return standard_sse_constant_opcode (insn, operands);
2717 return "kmovd\t{%1, %0|%0, %1}";
2720 if (operands[1] == const0_rtx)
2721 return "kxord\t%0, %0, %0";
2722 else if (operands[1] == constm1_rtx)
2723 return "kxnord\t%0, %0, %0";
2727 return ix86_output_ssemov (insn, operands);
2730 return "pxor\t%0, %0";
2733 switch (get_attr_mode (insn))
2736 return "movq\t{%1, %0|%0, %1}";
2738 return "movd\t{%1, %0|%0, %1}";
2745 return "lea{l}\t{%E1, %0|%0, %E1}";
2748 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2749 if (ix86_use_lea_for_mov (insn, operands))
2750 return "lea{l}\t{%E1, %0|%0, %E1}";
2752 return "mov{l}\t{%1, %0|%0, %1}";
2759 (cond [(eq_attr "alternative" "12,13")
2760 (const_string "sse2")
2762 (const_string "*")))
2764 (cond [(eq_attr "alternative" "2")
2765 (const_string "mmx")
2766 (eq_attr "alternative" "3,4,5,6,7")
2767 (const_string "mmxmov")
2768 (eq_attr "alternative" "8")
2769 (const_string "sselog1")
2770 (eq_attr "alternative" "9,10,11,12,13")
2771 (const_string "ssemov")
2772 (eq_attr "alternative" "14,15,16")
2773 (const_string "mskmov")
2774 (eq_attr "alternative" "17")
2775 (const_string "msklog")
2776 (and (match_operand 0 "register_operand")
2777 (match_operand 1 "pic_32bit_operand"))
2778 (const_string "lea")
2780 (const_string "imov")))
2781 (set (attr "prefix")
2782 (if_then_else (eq_attr "type" "sselog1,ssemov")
2783 (const_string "maybe_vex")
2784 (const_string "orig")))
2785 (set (attr "prefix_data16")
2786 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2788 (const_string "*")))
2790 (cond [(eq_attr "alternative" "2,3")
2792 (eq_attr "alternative" "8")
2793 (cond [(match_test "TARGET_AVX")
2795 (ior (not (match_test "TARGET_SSE2"))
2796 (match_test "optimize_function_for_size_p (cfun)"))
2797 (const_string "V4SF")
2799 (const_string "TI"))
2800 (eq_attr "alternative" "9")
2801 (cond [(match_test "TARGET_AVX512VL")
2803 (match_test "TARGET_AVX512F")
2805 (match_test "TARGET_AVX")
2807 (ior (not (match_test "TARGET_SSE2"))
2808 (match_test "optimize_function_for_size_p (cfun)"))
2809 (const_string "V4SF")
2811 (const_string "TI"))
2813 (and (eq_attr "alternative" "10,11")
2814 (not (match_test "TARGET_SSE2")))
2817 (const_string "SI")))
2818 (set (attr "preferred_for_speed")
2819 (cond [(eq_attr "alternative" "6,12")
2820 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2821 (eq_attr "alternative" "7,13")
2822 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2824 (symbol_ref "true")))])
2826 ;; With -Oz, transform mov $imm,reg to the shorter push $imm; pop reg.
2828 [(set (match_operand:SWI248 0 "general_reg_operand")
2829 (match_operand:SWI248 1 "const_int_operand"))]
2830 "optimize_insn_for_size_p () && optimize_size > 1
2831 && operands[1] != const0_rtx
2832 && IN_RANGE (INTVAL (operands[1]), -128, 127)
2833 && !ix86_red_zone_used
2834 && REGNO (operands[0]) != SP_REG"
2835 [(set (match_dup 2) (match_dup 1))
2836 (set (match_dup 0) (match_dup 3))]
2838 if (GET_MODE (operands[0]) != word_mode)
2839 operands[0] = gen_rtx_REG (word_mode, REGNO (operands[0]));
2841 operands[2] = gen_rtx_MEM (word_mode,
2842 gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
2843 operands[3] = gen_rtx_MEM (word_mode,
2844 gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
2847 ;; With -Oz, transform mov $0,mem to the shorter and $0,mem.
2848 ;; Likewise, transform mov $-1,mem to the shorter or $-1,mem.
2850 [(set (match_operand:SWI248 0 "memory_operand")
2851 (match_operand:SWI248 1 "const_int_operand"))]
2852 "(operands[1] == const0_rtx || operands[1] == constm1_rtx)
2853 && optimize_insn_for_size_p () && optimize_size > 1
2854 && peep2_regno_dead_p (0, FLAGS_REG)"
2855 [(parallel [(set (match_dup 0) (match_dup 1))
2856 (clobber (reg:CC FLAGS_REG))])])
2858 (define_insn "*movhi_internal"
2859 [(set (match_operand:HI 0 "nonimmediate_operand"
2860 "=r,r,r,m ,*k,*k ,r ,m ,*k ,?r,?*v,*Yv,*v,*v,jm,m")
2861 (match_operand:HI 1 "general_operand"
2862 "r ,n,m,rn,r ,*km,*k,*k,CBC,*v,r ,C ,*v,m ,*x,*v"))]
2863 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2864 && ix86_hardreg_mov_ok (operands[0], operands[1])"
2866 switch (get_attr_type (insn))
2869 /* movzwl is faster than movw on p2 due to partial word stalls,
2870 though not as fast as an aligned movl. */
2871 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2874 switch (which_alternative)
2877 return "kmovw\t{%k1, %0|%0, %k1}";
2879 return "kmovw\t{%1, %k0|%k0, %1}";
2882 return "kmovw\t{%1, %0|%0, %1}";
2888 return ix86_output_ssemov (insn, operands);
2891 if (satisfies_constraint_C (operands[1]))
2892 return standard_sse_constant_opcode (insn, operands);
2894 if (SSE_REG_P (operands[0]))
2895 return "%vpinsrw\t{$0, %1, %d0|%d0, %1, 0}";
2897 return "%vpextrw\t{$0, %1, %0|%0, %1, 0}";
2900 if (operands[1] == const0_rtx)
2901 return "kxorw\t%0, %0, %0";
2902 else if (operands[1] == constm1_rtx)
2903 return "kxnorw\t%0, %0, %0";
2907 if (get_attr_mode (insn) == MODE_SI)
2908 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2910 return "mov{w}\t{%1, %0|%0, %1}";
2914 (cond [(eq_attr "alternative" "9,10,11,12,13")
2915 (const_string "sse2")
2916 (eq_attr "alternative" "14")
2917 (const_string "sse4_noavx")
2918 (eq_attr "alternative" "15")
2919 (const_string "avx")
2921 (const_string "*")))
2923 (if_then_else (eq_attr "alternative" "14")
2924 (const_string "gpr16")
2925 (const_string "*")))
2927 (cond [(eq_attr "alternative" "4,5,6,7")
2928 (const_string "mskmov")
2929 (eq_attr "alternative" "8")
2930 (const_string "msklog")
2931 (eq_attr "alternative" "13,14,15")
2932 (if_then_else (match_test "TARGET_AVX512FP16")
2933 (const_string "ssemov")
2934 (const_string "sselog1"))
2935 (eq_attr "alternative" "11")
2936 (const_string "sselog1")
2937 (eq_attr "alternative" "9,10,12")
2938 (const_string "ssemov")
2939 (match_test "optimize_function_for_size_p (cfun)")
2940 (const_string "imov")
2941 (and (eq_attr "alternative" "0")
2942 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2943 (not (match_test "TARGET_HIMODE_MATH"))))
2944 (const_string "imov")
2945 (and (eq_attr "alternative" "1,2")
2946 (match_operand:HI 1 "aligned_operand"))
2947 (const_string "imov")
2948 (and (match_test "TARGET_MOVX")
2949 (eq_attr "alternative" "0,2"))
2950 (const_string "imovx")
2952 (const_string "imov")))
2953 (set (attr "prefix")
2954 (cond [(eq_attr "alternative" "4,5,6,7,8")
2955 (const_string "vex")
2956 (eq_attr "alternative" "9,10,11,12,13,14,15")
2957 (const_string "maybe_evex")
2959 (const_string "orig")))
2961 (cond [(eq_attr "alternative" "9,10")
2962 (if_then_else (match_test "TARGET_AVX512FP16")
2964 (const_string "SI"))
2965 (eq_attr "alternative" "13,14,15")
2966 (if_then_else (match_test "TARGET_AVX512FP16")
2968 (const_string "TI"))
2969 (eq_attr "alternative" "11")
2970 (cond [(match_test "TARGET_AVX")
2972 (ior (not (match_test "TARGET_SSE2"))
2973 (match_test "optimize_function_for_size_p (cfun)"))
2974 (const_string "V4SF")
2976 (const_string "TI"))
2977 (eq_attr "alternative" "12")
2978 (cond [(match_test "TARGET_AVX512VL")
2980 (match_test "TARGET_AVX512FP16")
2982 (match_test "TARGET_AVX512F")
2984 (match_test "TARGET_AVX")
2986 (ior (not (match_test "TARGET_SSE2"))
2987 (match_test "optimize_function_for_size_p (cfun)"))
2988 (const_string "V4SF")
2990 (const_string "TI"))
2991 (eq_attr "type" "imovx")
2993 (and (eq_attr "alternative" "1,2")
2994 (match_operand:HI 1 "aligned_operand"))
2996 (and (eq_attr "alternative" "0")
2997 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2998 (not (match_test "TARGET_HIMODE_MATH"))))
3001 (const_string "HI")))
3002 (set (attr "preferred_for_speed")
3003 (cond [(eq_attr "alternative" "9")
3004 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3005 (eq_attr "alternative" "10")
3006 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3008 (symbol_ref "true")))])
3010 ;; Situation is quite tricky about when to choose full sized (SImode) move
3011 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
3012 ;; partial register dependency machines (such as AMD Athlon), where QImode
3013 ;; moves issue extra dependency and for partial register stalls machines
3014 ;; that don't use QImode patterns (and QImode move cause stall on the next
3017 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
3018 ;; register stall machines with, where we use QImode instructions, since
3019 ;; partial register stall can be caused there. Then we use movzx.
3021 (define_insn "*movqi_internal"
3022 [(set (match_operand:QI 0 "nonimmediate_operand"
3023 "=Q,R,r,q,q,r,r ,?r,m ,*k,*k,*r,*m,*k,*k,*k")
3024 (match_operand:QI 1 "general_operand"
3025 "Q ,R,r,n,m,q,rn, m,qn,*r,*k,*k,*k,*m,C,BC"))]
3026 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3027 && ix86_hardreg_mov_ok (operands[0], operands[1])"
3034 switch (get_attr_type (insn))
3037 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
3038 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
3041 switch (which_alternative)
3044 ops = "kmov%s\t{%%k1, %%0|%%0, %%k1}";
3047 ops = "kmov%s\t{%%1, %%k0|%%k0, %%1}";
3051 gcc_assert (TARGET_AVX512DQ);
3054 ops = "kmov%s\t{%%1, %%0|%%0, %%1}";
3060 suffix = (get_attr_mode (insn) == MODE_HI) ? "w" : "b";
3062 snprintf (buf, sizeof (buf), ops, suffix);
3063 output_asm_insn (buf, operands);
3067 if (operands[1] == const0_rtx)
3069 if (get_attr_mode (insn) == MODE_HI)
3070 return "kxorw\t%0, %0, %0";
3072 return "kxorb\t%0, %0, %0";
3074 else if (operands[1] == constm1_rtx)
3076 gcc_assert (TARGET_AVX512DQ);
3077 return "kxnorb\t%0, %0, %0";
3082 if (get_attr_mode (insn) == MODE_SI)
3083 return "mov{l}\t{%k1, %k0|%k0, %k1}";
3085 return "mov{b}\t{%1, %0|%0, %1}";
3089 (cond [(eq_attr "alternative" "1,2")
3090 (const_string "x64")
3091 (eq_attr "alternative" "12,13,15")
3092 (const_string "avx512dq")
3094 (const_string "*")))
3096 (cond [(eq_attr "alternative" "9,10,11,12,13")
3097 (const_string "mskmov")
3098 (eq_attr "alternative" "14,15")
3099 (const_string "msklog")
3100 (and (eq_attr "alternative" "7")
3101 (not (match_operand:QI 1 "aligned_operand")))
3102 (const_string "imovx")
3103 (match_test "optimize_function_for_size_p (cfun)")
3104 (const_string "imov")
3105 (and (eq_attr "alternative" "5")
3106 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
3107 (not (match_test "TARGET_QIMODE_MATH"))))
3108 (const_string "imov")
3109 (eq_attr "alternative" "5,7")
3110 (const_string "imovx")
3111 (and (match_test "TARGET_MOVX")
3112 (eq_attr "alternative" "4"))
3113 (const_string "imovx")
3115 (const_string "imov")))
3116 (set (attr "prefix")
3117 (if_then_else (eq_attr "alternative" "9,10,11,12,13,14,15")
3118 (const_string "vex")
3119 (const_string "orig")))
3121 (cond [(eq_attr "alternative" "5,6,7")
3123 (eq_attr "alternative" "8")
3125 (and (eq_attr "alternative" "9,10,11,14")
3126 (not (match_test "TARGET_AVX512DQ")))
3128 (eq_attr "type" "imovx")
3130 ;; For -Os, 8-bit immediates are always shorter than 32-bit
3132 (and (eq_attr "type" "imov")
3133 (and (eq_attr "alternative" "3")
3134 (match_test "optimize_function_for_size_p (cfun)")))
3136 ;; For -Os, movl where one or both operands are NON_Q_REGS
3137 ;; and both are LEGACY_REGS is shorter than movb.
3138 ;; Otherwise movb and movl sizes are the same, so decide purely
3139 ;; based on speed factors.
3140 (and (eq_attr "type" "imov")
3141 (and (eq_attr "alternative" "1")
3142 (match_test "optimize_function_for_size_p (cfun)")))
3144 (and (eq_attr "type" "imov")
3145 (and (eq_attr "alternative" "0,1,2,3")
3146 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
3147 (not (match_test "TARGET_PARTIAL_REG_STALL")))))
3149 ;; Avoid partial register stalls when not using QImode arithmetic
3150 (and (eq_attr "type" "imov")
3151 (and (eq_attr "alternative" "0,1,2,3")
3152 (and (match_test "TARGET_PARTIAL_REG_STALL")
3153 (not (match_test "TARGET_QIMODE_MATH")))))
3156 (const_string "QI")))])
3158 /* Reload dislikes loading 0/-1 directly into mask registers.
3159 Try to tidy things up here. */
3161 [(set (match_operand:SWI 0 "general_reg_operand")
3162 (match_operand:SWI 1 "immediate_operand"))
3163 (set (match_operand:SWI 2 "mask_reg_operand")
3165 "peep2_reg_dead_p (2, operands[0])
3166 && (const0_operand (operands[1], <MODE>mode)
3167 || (constm1_operand (operands[1], <MODE>mode)
3168 && (<MODE_SIZE> > 1 || TARGET_AVX512DQ)))"
3169 [(set (match_dup 2) (match_dup 1))])
3171 ;; Stores and loads of ax to arbitrary constant address.
3172 ;; We fake an second form of instruction to force reload to load address
3173 ;; into register when rax is not available
3174 (define_insn "*movabs<mode>_1"
3175 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
3176 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
3177 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
3179 /* Recover the full memory rtx. */
3180 operands[0] = SET_DEST (PATTERN (insn));
3181 switch (which_alternative)
3184 return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}";
3186 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
3191 [(set_attr "type" "imov")
3192 (set_attr "modrm" "0,*")
3193 (set_attr "length_address" "8,0")
3194 (set_attr "length_immediate" "0,*")
3195 (set_attr "memory" "store")
3196 (set_attr "mode" "<MODE>")])
3198 (define_insn "*movabs<mode>_2"
3199 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
3200 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
3201 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
3203 /* Recover the full memory rtx. */
3204 operands[1] = SET_SRC (PATTERN (insn));
3205 switch (which_alternative)
3208 return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}";
3210 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
3215 [(set_attr "type" "imov")
3216 (set_attr "modrm" "0,*")
3217 (set_attr "length_address" "8,0")
3218 (set_attr "length_immediate" "0")
3219 (set_attr "memory" "load")
3220 (set_attr "mode" "<MODE>")])
3222 (define_insn "swap<mode>"
3223 [(set (match_operand:SWI48 0 "register_operand" "+r")
3224 (match_operand:SWI48 1 "register_operand" "+r"))
3228 "xchg{<imodesuffix>}\t%1, %0"
3229 [(set_attr "type" "imov")
3230 (set_attr "mode" "<MODE>")
3231 (set_attr "pent_pair" "np")
3232 (set_attr "athlon_decode" "vector")
3233 (set_attr "amdfam10_decode" "double")
3234 (set_attr "bdver1_decode" "double")])
3236 (define_insn "*swap<mode>"
3237 [(set (match_operand:SWI12 0 "register_operand" "+<r>,r")
3238 (match_operand:SWI12 1 "register_operand" "+<r>,r"))
3243 xchg{<imodesuffix>}\t%1, %0
3245 [(set_attr "type" "imov")
3246 (set_attr "mode" "<MODE>,SI")
3247 (set (attr "preferred_for_size")
3248 (cond [(eq_attr "alternative" "0")
3249 (symbol_ref "false")]
3250 (symbol_ref "true")))
3251 ;; Potential partial reg stall on alternative 1.
3252 (set (attr "preferred_for_speed")
3253 (cond [(eq_attr "alternative" "1")
3254 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
3255 (symbol_ref "true")))
3256 (set_attr "pent_pair" "np")
3257 (set_attr "athlon_decode" "vector")
3258 (set_attr "amdfam10_decode" "double")
3259 (set_attr "bdver1_decode" "double")])
3262 [(set (match_operand:SWI 0 "general_reg_operand")
3263 (match_operand:SWI 1 "general_reg_operand"))
3265 (match_operand:SWI 2 "general_reg_operand"))
3266 (set (match_dup 2) (match_dup 0))]
3267 "peep2_reg_dead_p (3, operands[0])
3268 && optimize_insn_for_size_p ()"
3269 [(parallel [(set (match_dup 1) (match_dup 2))
3270 (set (match_dup 2) (match_dup 1))])])
3272 ;; Convert xchg with a REG_UNUSED note to a mov (variant #1).
3274 [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
3275 (match_operand:SWI 1 "general_reg_operand"))
3276 (set (match_dup 1) (match_dup 0))])]
3277 "((REGNO (operands[0]) != AX_REG
3278 && REGNO (operands[1]) != AX_REG)
3279 || optimize_size < 2
3280 || !optimize_insn_for_size_p ())
3281 && peep2_reg_dead_p (1, operands[0])"
3282 [(set (match_dup 1) (match_dup 0))])
3284 ;; Convert xchg with a REG_UNUSED note to a mov (variant #2).
3286 [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
3287 (match_operand:SWI 1 "general_reg_operand"))
3288 (set (match_dup 1) (match_dup 0))])]
3289 "((REGNO (operands[0]) != AX_REG
3290 && REGNO (operands[1]) != AX_REG)
3291 || optimize_size < 2
3292 || !optimize_insn_for_size_p ())
3293 && peep2_reg_dead_p (1, operands[1])"
3294 [(set (match_dup 0) (match_dup 1))])
3296 ;; Convert moves to/from AX_REG into xchg with -Oz.
3298 [(set (match_operand:SWI48 0 "general_reg_operand")
3299 (match_operand:SWI48 1 "general_reg_operand"))]
3301 && ((REGNO (operands[0]) == AX_REG)
3302 != (REGNO (operands[1]) == AX_REG))
3303 && optimize_insn_for_size_p ()
3304 && peep2_reg_dead_p (1, operands[1])"
3305 [(parallel [(set (match_dup 0) (match_dup 1))
3306 (set (match_dup 1) (match_dup 0))])])
3308 (define_expand "movstrict<mode>"
3309 [(set (strict_low_part (match_operand:SWI12 0 "register_operand"))
3310 (match_operand:SWI12 1 "general_operand"))]
3313 gcc_assert (SUBREG_P (operands[0]));
3314 if ((TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
3315 || !VALID_INT_MODE_P (GET_MODE (SUBREG_REG (operands[0]))))
3319 (define_insn "*movstrict<mode>_1"
3320 [(set (strict_low_part
3321 (match_operand:SWI12 0 "register_operand" "+<r>"))
3322 (match_operand:SWI12 1 "general_operand" "<r>mn"))]
3323 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
3324 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
3325 [(set_attr "type" "imov")
3326 (set_attr "mode" "<MODE>")])
3328 (define_insn "*movstrict<mode>_xor"
3329 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
3330 (match_operand:SWI12 1 "const0_operand"))
3331 (clobber (reg:CC FLAGS_REG))]
3333 "xor{<imodesuffix>}\t%0, %0"
3334 [(set_attr "type" "alu1")
3335 (set_attr "mode" "<MODE>")
3336 (set_attr "length_immediate" "0")])
3338 (define_insn "*movstrictqi_ext<mode>_1"
3339 [(set (strict_low_part
3340 (match_operand:QI 0 "register_operand" "+Q"))
3342 (match_operator:SWI248 2 "extract_operator"
3343 [(match_operand 1 "int248_register_operand" "Q")
3345 (const_int 8)]) 0))]
3346 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
3347 "mov{b}\t{%h1, %0|%0, %h1}"
3348 [(set_attr "type" "imov")
3349 (set_attr "mode" "QI")])
3351 (define_expand "extv<mode>"
3352 [(set (match_operand:SWI24 0 "register_operand")
3353 (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
3354 (match_operand:QI 2 "const_int_operand")
3355 (match_operand:QI 3 "const_int_operand")))]
3358 /* Handle extractions from %ah et al. */
3359 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
3362 unsigned int regno = reg_or_subregno (operands[1]);
3364 /* Be careful to expand only with registers having upper parts. */
3365 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3366 operands[1] = copy_to_reg (operands[1]);
3369 (define_insn "*extv<mode>"
3370 [(set (match_operand:SWI24 0 "register_operand" "=R")
3371 (sign_extract:SWI24 (match_operand 1 "int248_register_operand" "Q")
3375 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
3376 [(set_attr "type" "imovx")
3377 (set_attr "mode" "SI")])
3379 ;; Split sign-extension of single least significant bit as and x,$1;neg x
3380 (define_insn_and_split "*extv<mode>_1_0"
3381 [(set (match_operand:SWI48 0 "register_operand" "=r")
3382 (sign_extract:SWI48 (match_operand:SWI48 1 "register_operand" "0")
3385 (clobber (reg:CC FLAGS_REG))]
3389 [(parallel [(set (match_dup 0) (and:SWI48 (match_dup 1) (const_int 1)))
3390 (clobber (reg:CC FLAGS_REG))])
3391 (parallel [(set (match_dup 0) (neg:SWI48 (match_dup 0)))
3392 (clobber (reg:CC FLAGS_REG))])])
3394 (define_expand "extzv<mode>"
3395 [(set (match_operand:SWI248 0 "register_operand")
3396 (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
3397 (match_operand:QI 2 "const_int_operand")
3398 (match_operand:QI 3 "const_int_operand")))]
3401 if (ix86_expand_pextr (operands))
3404 /* Handle extractions from %ah et al. */
3405 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
3408 unsigned int regno = reg_or_subregno (operands[1]);
3410 /* Be careful to expand only with registers having upper parts. */
3411 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3412 operands[1] = copy_to_reg (operands[1]);
3415 (define_insn "*extzv<mode>"
3416 [(set (match_operand:SWI248 0 "register_operand" "=R")
3417 (zero_extract:SWI248 (match_operand 1 "int248_register_operand" "Q")
3421 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
3422 [(set_attr "type" "imovx")
3423 (set_attr "mode" "SI")])
3425 (define_insn "*extzvqi"
3426 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn,?R")
3428 (match_operator:SWI248 2 "extract_operator"
3429 [(match_operand 1 "int248_register_operand" "Q,Q")
3431 (const_int 8)]) 0))]
3434 switch (get_attr_type (insn))
3437 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
3439 return "mov{b}\t{%h1, %0|%0, %h1}";
3442 [(set_attr "addr" "gpr8,*")
3444 (if_then_else (and (match_operand:QI 0 "register_operand")
3445 (ior (not (match_operand:QI 0 "QIreg_operand"))
3446 (match_test "TARGET_MOVX")))
3447 (const_string "imovx")
3448 (const_string "imov")))
3450 (if_then_else (eq_attr "type" "imovx")
3452 (const_string "QI")))])
3454 (define_expand "insv<mode>"
3455 [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
3456 (match_operand:QI 1 "const_int_operand")
3457 (match_operand:QI 2 "const_int_operand"))
3458 (match_operand:SWI248 3 "register_operand"))]
3463 if (ix86_expand_pinsr (operands))
3466 /* Handle insertions to %ah et al. */
3467 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
3470 unsigned int regno = reg_or_subregno (operands[0]);
3472 /* Be careful to expand only with registers having upper parts. */
3473 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3474 dst = copy_to_reg (operands[0]);
3478 emit_insn (gen_insv_1 (<MODE>mode, dst, operands[3]));
3480 /* Fix up the destination if needed. */
3481 if (dst != operands[0])
3482 emit_move_insn (operands[0], dst);
3487 (define_insn "@insv<mode>_1"
3488 [(set (zero_extract:SWI248
3489 (match_operand 0 "int248_register_operand" "+Q")
3492 (match_operand:SWI248 1 "general_operand" "QnBn"))]
3495 if (CONST_INT_P (operands[1]))
3496 operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
3497 return "mov{b}\t{%b1, %h0|%h0, %b1}";
3499 [(set_attr "addr" "gpr8")
3500 (set_attr "type" "imov")
3501 (set_attr "mode" "QI")])
3503 (define_insn "*insvqi_1"
3504 [(set (zero_extract:SWI248
3505 (match_operand 0 "int248_register_operand" "+Q")
3509 (match_operand:QI 1 "general_operand" "QnBn") 0))]
3511 "mov{b}\t{%1, %h0|%h0, %1}"
3512 [(set_attr "addr" "gpr8")
3513 (set_attr "type" "imov")
3514 (set_attr "mode" "QI")])
3516 ;; Eliminate redundant insv, e.g. xorl %eax,%eax; movb $0, %ah
3518 [(parallel [(set (match_operand:SWI48 0 "general_reg_operand")
3520 (clobber (reg:CC FLAGS_REG))])
3521 (set (zero_extract:SWI248 (match_operand 1 "int248_register_operand")
3525 "REGNO (operands[0]) == REGNO (operands[1])"
3526 [(parallel [(set (match_operand:SWI48 0 "general_reg_operand")
3528 (clobber (reg:CC FLAGS_REG))])])
3530 ;; Combine movl followed by movb.
3532 [(set (match_operand:SWI48 0 "general_reg_operand")
3533 (match_operand:SWI48 1 "const_int_operand"))
3534 (set (zero_extract:SWI248 (match_operand 2 "int248_register_operand")
3537 (match_operand:SWI248 3 "const_int_operand"))]
3538 "REGNO (operands[0]) == REGNO (operands[2])"
3539 [(set (match_operand:SWI48 0 "general_reg_operand")
3542 HOST_WIDE_INT tmp = INTVAL (operands[1]) & ~(HOST_WIDE_INT)0xff00;
3543 tmp |= (INTVAL (operands[3]) & 0xff) << 8;
3544 operands[4] = gen_int_mode (tmp, <SWI48:MODE>mode);
3547 (define_insn "*insvqi_2"
3548 [(set (zero_extract:SWI248
3549 (match_operand 0 "int248_register_operand" "+Q")
3552 (match_operator:SWI248 2 "extract_operator"
3553 [(match_operand 1 "int248_register_operand" "Q")
3557 "mov{b}\t{%h1, %h0|%h0, %h1}"
3558 [(set_attr "type" "imov")
3559 (set_attr "mode" "QI")])
3561 (define_insn "*insvqi_3"
3562 [(set (zero_extract:SWI248
3563 (match_operand 0 "int248_register_operand" "+Q")
3567 (match_operand:SWI248 1 "register_operand" "Q")
3570 "mov{b}\t{%h1, %h0|%h0, %h1}"
3571 [(set_attr "type" "imov")
3572 (set_attr "mode" "QI")])
3574 (define_code_iterator any_or_plus [plus ior xor])
3576 (define_insn_and_split "*insvti_highpart_1"
3577 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro,r,r,&r")
3580 (match_operand:TI 1 "nonimmediate_operand" "r,m,r,m")
3581 (match_operand:TI 3 "const_scalar_int_operand" "n,n,n,n"))
3584 (match_operand:DI 2 "nonimmediate_operand" "r,r,m,m"))
3587 && CONST_WIDE_INT_P (operands[3])
3588 && CONST_WIDE_INT_NUNITS (operands[3]) == 2
3589 && CONST_WIDE_INT_ELT (operands[3], 0) == -1
3590 && CONST_WIDE_INT_ELT (operands[3], 1) == 0"
3592 "&& reload_completed"
3595 operands[4] = gen_lowpart (DImode, operands[1]);
3596 split_double_concat (TImode, operands[0], operands[4], operands[2]);
3600 (define_insn_and_split "*insvti_lowpart_1"
3601 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro,r,r,&r")
3604 (match_operand:TI 1 "nonimmediate_operand" "r,m,r,m")
3605 (match_operand:TI 3 "const_scalar_int_operand" "n,n,n,n"))
3607 (match_operand:DI 2 "nonimmediate_operand" "r,r,m,m"))))]
3609 && CONST_WIDE_INT_P (operands[3])
3610 && CONST_WIDE_INT_NUNITS (operands[3]) == 2
3611 && CONST_WIDE_INT_ELT (operands[3], 0) == 0
3612 && CONST_WIDE_INT_ELT (operands[3], 1) == -1"
3614 "&& reload_completed"
3617 operands[4] = gen_highpart (DImode, operands[1]);
3618 split_double_concat (TImode, operands[0], operands[2], operands[4]);
3622 (define_insn_and_split "*insvdi_lowpart_1"
3623 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro,r,r,&r")
3626 (match_operand:DI 1 "nonimmediate_operand" "r,m,r,m")
3627 (match_operand:DI 3 "const_int_operand" "n,n,n,n"))
3629 (match_operand:SI 2 "nonimmediate_operand" "r,r,m,m"))))]
3631 && CONST_INT_P (operands[3])
3632 && UINTVAL (operands[3]) == 0xffffffff00000000ll"
3634 "&& reload_completed"
3637 operands[4] = gen_highpart (SImode, operands[1]);
3638 split_double_concat (DImode, operands[0], operands[2], operands[4]);
3642 ;; Floating point push instructions.
3644 (define_insn "*pushtf"
3645 [(set (match_operand:TF 0 "push_operand" "=<,<")
3646 (match_operand:TF 1 "general_no_elim_operand" "v,*roC"))]
3647 "TARGET_64BIT || TARGET_SSE"
3649 /* This insn should be already split before reg-stack. */
3652 [(set_attr "isa" "*,x64")
3653 (set_attr "type" "multi")
3654 (set_attr "unit" "sse,*")
3655 (set_attr "mode" "TF,DI")])
3657 ;; %%% Kill this when call knows how to work this out.
3659 [(set (match_operand:TF 0 "push_operand")
3660 (match_operand:TF 1 "sse_reg_operand"))]
3661 "TARGET_SSE && reload_completed"
3662 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3663 (set (match_dup 0) (match_dup 1))]
3665 /* Preserve memory attributes. */
3666 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3669 (define_insn "*pushxf"
3670 [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<")
3671 (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF,oC"))]
3674 /* This insn should be already split before reg-stack. */
3677 [(set_attr "isa" "*,*,*,nox64,x64")
3678 (set_attr "type" "multi")
3679 (set_attr "unit" "i387,*,*,*,*")
3681 (cond [(eq_attr "alternative" "1,2,3,4")
3682 (if_then_else (match_test "TARGET_64BIT")
3684 (const_string "SI"))
3686 (const_string "XF")))
3687 (set (attr "preferred_for_size")
3688 (cond [(eq_attr "alternative" "1")
3689 (symbol_ref "false")]
3690 (symbol_ref "true")))])
3692 ;; %%% Kill this when call knows how to work this out.
3694 [(set (match_operand:XF 0 "push_operand")
3695 (match_operand:XF 1 "fp_register_operand"))]
3697 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3698 (set (match_dup 0) (match_dup 1))]
3700 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (XFmode)));
3701 /* Preserve memory attributes. */
3702 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3705 (define_insn "*pushdf"
3706 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
3707 (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmC,v"))]
3710 /* This insn should be already split before reg-stack. */
3713 [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
3714 (set_attr "type" "multi")
3715 (set_attr "unit" "i387,*,*,*,*,sse")
3716 (set_attr "mode" "DF,SI,SI,SI,DI,DF")
3717 (set (attr "preferred_for_size")
3718 (cond [(eq_attr "alternative" "1")
3719 (symbol_ref "false")]
3720 (symbol_ref "true")))
3721 (set (attr "preferred_for_speed")
3722 (cond [(eq_attr "alternative" "1")
3723 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3724 (symbol_ref "true")))])
3726 ;; %%% Kill this when call knows how to work this out.
3728 [(set (match_operand:DF 0 "push_operand")
3729 (match_operand:DF 1 "any_fp_register_operand"))]
3731 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3732 (set (match_dup 0) (match_dup 1))]
3734 /* Preserve memory attributes. */
3735 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3738 (define_mode_iterator HFBF [HF BF])
3740 (define_insn "*push<mode>_rex64"
3741 [(set (match_operand:HFBF 0 "push_operand" "=X,X")
3742 (match_operand:HFBF 1 "nonmemory_no_elim_operand" "r,x"))]
3745 /* Anything else should be already split before reg-stack. */
3746 gcc_assert (which_alternative == 0);
3747 return "push{q}\t%q1";
3749 [(set_attr "isa" "*,sse4")
3750 (set_attr "type" "push,multi")
3751 (set_attr "mode" "DI,TI")])
3753 (define_insn "*push<mode>"
3754 [(set (match_operand:HFBF 0 "push_operand" "=X,X")
3755 (match_operand:HFBF 1 "general_no_elim_operand" "rmF,x"))]
3758 /* Anything else should be already split before reg-stack. */
3759 gcc_assert (which_alternative == 0);
3760 return "push{l}\t%k1";
3762 [(set_attr "isa" "*,sse4")
3763 (set_attr "type" "push,multi")
3764 (set_attr "mode" "SI,TI")])
3766 (define_insn "push2_di"
3767 [(set (match_operand:TI 0 "push_operand" "=<")
3768 (unspec:TI [(match_operand:DI 1 "register_operand" "r")
3769 (match_operand:DI 2 "register_operand" "r")]
3771 "TARGET_APX_PUSH2POP2"
3773 [(set_attr "mode" "TI")
3774 (set_attr "type" "multi")
3775 (set_attr "prefix" "evex")])
3777 (define_insn "pop2_di"
3778 [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
3779 (unspec:DI [(match_operand:TI 1 "pop_operand" ">")]
3780 UNSPEC_APXPOP2_LOW))
3781 (set (match_operand:DI 2 "register_operand" "=r")
3782 (unspec:DI [(const_int 0)] UNSPEC_APXPOP2_HIGH))])]
3783 "TARGET_APX_PUSH2POP2"
3785 [(set_attr "mode" "TI")
3786 (set_attr "prefix" "evex")])
3788 (define_insn "*pushsf_rex64"
3789 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3790 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,v"))]
3793 /* Anything else should be already split before reg-stack. */
3794 if (which_alternative != 1)
3796 return "push{q}\t%q1";
3798 [(set_attr "type" "multi,push,multi")
3799 (set_attr "unit" "i387,*,*")
3800 (set_attr "mode" "SF,DI,SF")])
3802 (define_insn "*pushsf"
3803 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3804 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,v"))]
3807 /* Anything else should be already split before reg-stack. */
3808 if (which_alternative != 1)
3810 return "push{l}\t%1";
3812 [(set_attr "type" "multi,push,multi")
3813 (set_attr "unit" "i387,*,*")
3814 (set_attr "mode" "SF,SI,SF")])
3816 (define_mode_iterator MODESH [SF HF BF])
3817 ;; %%% Kill this when call knows how to work this out.
3819 [(set (match_operand:MODESH 0 "push_operand")
3820 (match_operand:MODESH 1 "any_fp_register_operand"))]
3822 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3823 (set (match_dup 0) (match_dup 1))]
3825 rtx op = XEXP (operands[0], 0);
3826 if (GET_CODE (op) == PRE_DEC)
3828 gcc_assert (!TARGET_64BIT);
3833 op = XEXP (XEXP (op, 1), 1);
3834 gcc_assert (CONST_INT_P (op));
3837 /* Preserve memory attributes. */
3838 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3842 [(set (match_operand:SF 0 "push_operand")
3843 (match_operand:SF 1 "memory_operand"))]
3845 && find_constant_src (insn)"
3846 [(set (match_dup 0) (match_dup 2))]
3847 "operands[2] = find_constant_src (curr_insn);")
3850 [(set (match_operand 0 "push_operand")
3851 (match_operand 1 "general_gr_operand"))]
3853 && (GET_MODE (operands[0]) == TFmode
3854 || GET_MODE (operands[0]) == XFmode
3855 || GET_MODE (operands[0]) == DFmode)"
3857 "ix86_split_long_move (operands); DONE;")
3859 ;; Floating point move instructions.
3861 (define_expand "movtf"
3862 [(set (match_operand:TF 0 "nonimmediate_operand")
3863 (match_operand:TF 1 "nonimmediate_operand"))]
3864 "TARGET_64BIT || TARGET_SSE"
3865 "ix86_expand_move (TFmode, operands); DONE;")
3867 (define_expand "mov<mode>"
3868 [(set (match_operand:X87MODEFH 0 "nonimmediate_operand")
3869 (match_operand:X87MODEFH 1 "general_operand"))]
3871 "ix86_expand_move (<MODE>mode, operands); DONE;")
3873 (define_insn "*movtf_internal"
3874 [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o")
3875 (match_operand:TF 1 "general_operand" "C ,vm,v,*roF,*rC"))]
3876 "(TARGET_64BIT || TARGET_SSE)
3877 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3878 && (lra_in_progress || reload_completed
3879 || !CONST_DOUBLE_P (operands[1])
3880 || (standard_sse_constant_p (operands[1], TFmode) == 1
3881 && !memory_operand (operands[0], TFmode))
3882 || (!TARGET_MEMORY_MISMATCH_STALL
3883 && memory_operand (operands[0], TFmode)))"
3885 switch (get_attr_type (insn))
3888 return standard_sse_constant_opcode (insn, operands);
3891 return ix86_output_ssemov (insn, operands);
3900 [(set_attr "isa" "*,*,*,x64,x64")
3901 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3902 (set (attr "prefix")
3903 (if_then_else (eq_attr "type" "sselog1,ssemov")
3904 (const_string "maybe_vex")
3905 (const_string "orig")))
3907 (cond [(eq_attr "alternative" "3,4")
3909 (match_test "TARGET_AVX")
3911 (ior (not (match_test "TARGET_SSE2"))
3912 (match_test "optimize_function_for_size_p (cfun)"))
3913 (const_string "V4SF")
3914 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3915 (const_string "V4SF")
3916 (and (eq_attr "alternative" "2")
3917 (match_test "TARGET_SSE_TYPELESS_STORES"))
3918 (const_string "V4SF")
3920 (const_string "TI")))])
3923 [(set (match_operand:TF 0 "nonimmediate_gr_operand")
3924 (match_operand:TF 1 "general_gr_operand"))]
3927 "ix86_split_long_move (operands); DONE;")
3929 ;; Possible store forwarding (partial memory) stall
3930 ;; in alternatives 4, 6, 7 and 8.
3931 (define_insn "*movxf_internal"
3932 [(set (match_operand:XF 0 "nonimmediate_operand"
3933 "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r ,o ,o")
3934 (match_operand:XF 1 "general_operand"
3935 "fm,f,G,roF,r ,*roF,*r,F ,C ,roF,rF,rC"))]
3936 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3937 && (lra_in_progress || reload_completed
3938 || !CONST_DOUBLE_P (operands[1])
3939 || ((optimize_function_for_size_p (cfun)
3940 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3941 && standard_80387_constant_p (operands[1]) > 0
3942 && !memory_operand (operands[0], XFmode))
3943 || (!TARGET_MEMORY_MISMATCH_STALL
3944 && memory_operand (operands[0], XFmode))
3945 || !TARGET_HARD_XF_REGS)"
3947 switch (get_attr_type (insn))
3950 if (which_alternative == 2)
3951 return standard_80387_constant_opcode (operands[1]);
3952 return output_387_reg_move (insn, operands);
3962 (cond [(eq_attr "alternative" "7,10")
3963 (const_string "nox64")
3964 (eq_attr "alternative" "8,11")
3965 (const_string "x64")
3967 (const_string "*")))
3969 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3970 (const_string "multi")
3972 (const_string "fmov")))
3974 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3975 (if_then_else (match_test "TARGET_64BIT")
3977 (const_string "SI"))
3979 (const_string "XF")))
3980 (set (attr "preferred_for_size")
3981 (cond [(eq_attr "alternative" "3,4")
3982 (symbol_ref "false")]
3983 (symbol_ref "true")))
3984 (set (attr "enabled")
3985 (cond [(eq_attr "alternative" "9,10,11")
3987 (match_test "TARGET_HARD_XF_REGS")
3988 (symbol_ref "false")
3990 (not (match_test "TARGET_HARD_XF_REGS"))
3991 (symbol_ref "false")
3993 (const_string "*")))])
3996 [(set (match_operand:XF 0 "nonimmediate_gr_operand")
3997 (match_operand:XF 1 "general_gr_operand"))]
4000 "ix86_split_long_move (operands); DONE;")
4002 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
4003 (define_insn "*movdf_internal"
4004 [(set (match_operand:DF 0 "nonimmediate_operand"
4005 "=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")
4006 (match_operand:DF 1 "general_operand"
4007 "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"))]
4008 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
4009 && (lra_in_progress || reload_completed
4010 || !CONST_DOUBLE_P (operands[1])
4011 || ((optimize_function_for_size_p (cfun)
4012 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
4013 && IS_STACK_MODE (DFmode)
4014 && standard_80387_constant_p (operands[1]) > 0
4015 && !memory_operand (operands[0], DFmode))
4016 || (TARGET_SSE2 && TARGET_SSE_MATH
4017 && standard_sse_constant_p (operands[1], DFmode) == 1
4018 && !memory_operand (operands[0], DFmode))
4019 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
4020 && memory_operand (operands[0], DFmode))
4021 || !TARGET_HARD_DF_REGS)"
4023 switch (get_attr_type (insn))
4026 if (which_alternative == 2)
4027 return standard_80387_constant_opcode (operands[1]);
4028 return output_387_reg_move (insn, operands);
4034 if (get_attr_mode (insn) == MODE_SI)
4035 return "mov{l}\t{%1, %k0|%k0, %1}";
4036 else if (which_alternative == 11)
4037 return "movabs{q}\t{%1, %0|%0, %1}";
4039 return "mov{q}\t{%1, %0|%0, %1}";
4042 return standard_sse_constant_opcode (insn, operands);
4045 return ix86_output_ssemov (insn, operands);
4052 (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
4053 (const_string "nox64")
4054 (eq_attr "alternative" "8,9,10,11,24,25")
4055 (const_string "x64")
4056 (eq_attr "alternative" "12,13,14,15")
4057 (const_string "sse2")
4058 (eq_attr "alternative" "20,21")
4059 (const_string "x64_sse2")
4061 (const_string "*")))
4063 (cond [(eq_attr "alternative" "0,1,2")
4064 (const_string "fmov")
4065 (eq_attr "alternative" "3,4,5,6,7,22,23")
4066 (const_string "multi")
4067 (eq_attr "alternative" "8,9,10,11,24,25")
4068 (const_string "imov")
4069 (eq_attr "alternative" "12,16")
4070 (const_string "sselog1")
4072 (const_string "ssemov")))
4074 (if_then_else (eq_attr "alternative" "11")
4076 (const_string "*")))
4077 (set (attr "length_immediate")
4078 (if_then_else (eq_attr "alternative" "11")
4080 (const_string "*")))
4081 (set (attr "prefix")
4082 (if_then_else (eq_attr "type" "sselog1,ssemov")
4083 (const_string "maybe_vex")
4084 (const_string "orig")))
4085 (set (attr "prefix_data16")
4087 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
4088 (eq_attr "mode" "V1DF"))
4090 (const_string "*")))
4092 (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
4094 (eq_attr "alternative" "8,9,11,20,21,24,25")
4097 /* xorps is one byte shorter for non-AVX targets. */
4098 (eq_attr "alternative" "12,16")
4099 (cond [(match_test "TARGET_AVX")
4100 (const_string "V2DF")
4101 (ior (not (match_test "TARGET_SSE2"))
4102 (match_test "optimize_function_for_size_p (cfun)"))
4103 (const_string "V4SF")
4104 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
4107 (const_string "V2DF"))
4109 /* For architectures resolving dependencies on
4110 whole SSE registers use movapd to break dependency
4111 chains, otherwise use short move to avoid extra work. */
4113 /* movaps is one byte shorter for non-AVX targets. */
4114 (eq_attr "alternative" "13,17")
4115 (cond [(match_test "TARGET_AVX512VL")
4116 (const_string "V2DF")
4117 (match_test "TARGET_AVX512F")
4119 (match_test "TARGET_AVX")
4120 (const_string "V2DF")
4121 (ior (not (match_test "TARGET_SSE2"))
4122 (match_test "optimize_function_for_size_p (cfun)"))
4123 (const_string "V4SF")
4124 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
4125 (const_string "V4SF")
4126 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
4127 (const_string "V2DF")
4129 (const_string "DF"))
4131 /* For architectures resolving dependencies on register
4132 parts we may avoid extra work to zero out upper part
4134 (eq_attr "alternative" "14,18")
4135 (cond [(not (match_test "TARGET_SSE2"))
4136 (const_string "V2SF")
4137 (match_test "TARGET_AVX")
4139 (match_test "TARGET_SSE_SPLIT_REGS")
4140 (const_string "V1DF")
4142 (const_string "DF"))
4144 (and (eq_attr "alternative" "15,19")
4145 (not (match_test "TARGET_SSE2")))
4146 (const_string "V2SF")
4148 (const_string "DF")))
4149 (set (attr "preferred_for_size")
4150 (cond [(eq_attr "alternative" "3,4")
4151 (symbol_ref "false")]
4152 (symbol_ref "true")))
4153 (set (attr "preferred_for_speed")
4154 (cond [(eq_attr "alternative" "3,4")
4155 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")
4156 (eq_attr "alternative" "20")
4157 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4158 (eq_attr "alternative" "21")
4159 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4161 (symbol_ref "true")))
4162 (set (attr "enabled")
4163 (cond [(eq_attr "alternative" "22,23,24,25")
4165 (match_test "TARGET_HARD_DF_REGS")
4166 (symbol_ref "false")
4168 (not (match_test "TARGET_HARD_DF_REGS"))
4169 (symbol_ref "false")
4171 (const_string "*")))])
4174 [(set (match_operand:DF 0 "nonimmediate_gr_operand")
4175 (match_operand:DF 1 "general_gr_operand"))]
4176 "!TARGET_64BIT && reload_completed"
4178 "ix86_split_long_move (operands); DONE;")
4180 (define_insn "*movsf_internal"
4181 [(set (match_operand:SF 0 "nonimmediate_operand"
4182 "=Yf*f,m ,Yf*f,?r ,?m,Yv,v,v,m,?r,?v,!*y,!*y,!m,!r,!*y,r ,m")
4183 (match_operand:SF 1 "general_operand"
4184 "Yf*fm,Yf*f,G ,rmF,rF,C ,v,m,v,v ,r ,*y ,m ,*y,*y,r ,rmF,rF"))]
4185 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
4186 && (lra_in_progress || reload_completed
4187 || !CONST_DOUBLE_P (operands[1])
4188 || ((optimize_function_for_size_p (cfun)
4189 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
4190 && IS_STACK_MODE (SFmode)
4191 && standard_80387_constant_p (operands[1]) > 0)
4192 || (TARGET_SSE && TARGET_SSE_MATH
4193 && standard_sse_constant_p (operands[1], SFmode) == 1)
4194 || memory_operand (operands[0], SFmode)
4195 || !TARGET_HARD_SF_REGS)"
4197 switch (get_attr_type (insn))
4200 if (which_alternative == 2)
4201 return standard_80387_constant_opcode (operands[1]);
4202 return output_387_reg_move (insn, operands);
4205 return "mov{l}\t{%1, %0|%0, %1}";
4208 return standard_sse_constant_opcode (insn, operands);
4211 return ix86_output_ssemov (insn, operands);
4214 switch (get_attr_mode (insn))
4217 return "movq\t{%1, %0|%0, %1}";
4219 return "movd\t{%1, %0|%0, %1}";
4230 (cond [(eq_attr "alternative" "9,10")
4231 (const_string "sse2")
4233 (const_string "*")))
4235 (cond [(eq_attr "alternative" "0,1,2")
4236 (const_string "fmov")
4237 (eq_attr "alternative" "3,4,16,17")
4238 (const_string "imov")
4239 (eq_attr "alternative" "5")
4240 (const_string "sselog1")
4241 (eq_attr "alternative" "11,12,13,14,15")
4242 (const_string "mmxmov")
4244 (const_string "ssemov")))
4245 (set (attr "prefix")
4246 (if_then_else (eq_attr "type" "sselog1,ssemov")
4247 (const_string "maybe_vex")
4248 (const_string "orig")))
4249 (set (attr "prefix_data16")
4250 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
4252 (const_string "*")))
4254 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
4256 (eq_attr "alternative" "11")
4258 (eq_attr "alternative" "5")
4259 (cond [(and (match_test "TARGET_AVX512F && TARGET_EVEX512")
4260 (not (match_test "TARGET_PREFER_AVX256")))
4261 (const_string "V16SF")
4262 (match_test "TARGET_AVX")
4263 (const_string "V4SF")
4264 (ior (not (match_test "TARGET_SSE2"))
4265 (match_test "optimize_function_for_size_p (cfun)"))
4266 (const_string "V4SF")
4267 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
4270 (const_string "V4SF"))
4272 /* For architectures resolving dependencies on
4273 whole SSE registers use APS move to break dependency
4274 chains, otherwise use short move to avoid extra work.
4276 Do the same for architectures resolving dependencies on
4277 the parts. While in DF mode it is better to always handle
4278 just register parts, the SF mode is different due to lack
4279 of instructions to load just part of the register. It is
4280 better to maintain the whole registers in single format
4281 to avoid problems on using packed logical operations. */
4282 (eq_attr "alternative" "6")
4283 (cond [(match_test "TARGET_AVX512VL")
4284 (const_string "V4SF")
4285 (match_test "TARGET_AVX512F")
4287 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
4288 (match_test "TARGET_SSE_SPLIT_REGS"))
4289 (const_string "V4SF")
4291 (const_string "SF"))
4293 (const_string "SF")))
4294 (set (attr "preferred_for_speed")
4295 (cond [(eq_attr "alternative" "9,14")
4296 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4297 (eq_attr "alternative" "10,15")
4298 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4300 (symbol_ref "true")))
4301 (set (attr "enabled")
4302 (cond [(eq_attr "alternative" "16,17")
4304 (match_test "TARGET_HARD_SF_REGS")
4305 (symbol_ref "false")
4307 (not (match_test "TARGET_HARD_SF_REGS"))
4308 (symbol_ref "false")
4310 (const_string "*")))])
4312 (define_mode_attr hfbfconstf
4315 (define_insn "*mov<mode>_internal"
4316 [(set (match_operand:HFBF 0 "nonimmediate_operand"
4317 "=?r,?r,?r,?m ,Yv,v,?r,jm,m,?v,v")
4318 (match_operand:HFBF 1 "general_operand"
4319 "r ,F ,m ,r<hfbfconstf>,C ,v, v,v ,v,r ,m"))]
4320 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
4323 || !CONST_DOUBLE_P (operands[1])
4325 && standard_sse_constant_p (operands[1], <MODE>mode) == 1)
4326 || memory_operand (operands[0], <MODE>mode))"
4328 switch (get_attr_type (insn))
4331 /* movzwl is faster than movw on p2 due to partial word stalls,
4332 though not as fast as an aligned movl. */
4333 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
4336 return ix86_output_ssemov (insn, operands);
4339 if (satisfies_constraint_C (operands[1]))
4340 return standard_sse_constant_opcode (insn, operands);
4342 if (SSE_REG_P (operands[0]))
4343 return "%vpinsrw\t{$0, %1, %d0|%d0, %1, 0}";
4345 return "%vpextrw\t{$0, %1, %0|%0, %1, 0}";
4348 if (get_attr_mode (insn) == MODE_SI)
4349 return "mov{l}\t{%k1, %k0|%k0, %k1}";
4351 return "mov{w}\t{%1, %0|%0, %1}";
4355 (cond [(eq_attr "alternative" "4,5,6,9,10")
4356 (const_string "sse2")
4357 (eq_attr "alternative" "7")
4358 (const_string "sse4_noavx")
4359 (eq_attr "alternative" "8")
4360 (const_string "avx")
4362 (const_string "*")))
4364 (if_then_else (eq_attr "alternative" "7")
4365 (const_string "gpr16")
4366 (const_string "*")))
4368 (cond [(eq_attr "alternative" "4")
4369 (const_string "sselog1")
4370 (eq_attr "alternative" "5,6,9")
4371 (const_string "ssemov")
4372 (eq_attr "alternative" "7,8,10")
4374 (match_test ("TARGET_AVX512FP16"))
4375 (const_string "ssemov")
4376 (const_string "sselog1"))
4377 (match_test "optimize_function_for_size_p (cfun)")
4378 (const_string "imov")
4379 (and (eq_attr "alternative" "0")
4380 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
4381 (not (match_test "TARGET_HIMODE_MATH"))))
4382 (const_string "imov")
4383 (and (eq_attr "alternative" "1,2")
4384 (match_operand:HI 1 "aligned_operand"))
4385 (const_string "imov")
4386 (and (match_test "TARGET_MOVX")
4387 (eq_attr "alternative" "0,2"))
4388 (const_string "imovx")
4390 (const_string "imov")))
4391 (set (attr "prefix")
4392 (cond [(eq_attr "alternative" "4,5,6,7,8,9,10")
4393 (const_string "maybe_vex")
4395 (const_string "orig")))
4397 (cond [(eq_attr "alternative" "4")
4398 (const_string "V4SF")
4399 (eq_attr "alternative" "6,9")
4401 (match_test "TARGET_AVX512FP16")
4403 (const_string "SI"))
4404 (eq_attr "alternative" "7,8,10")
4406 (match_test "TARGET_AVX512FP16")
4408 (const_string "TI"))
4409 (eq_attr "alternative" "5")
4410 (cond [(match_test "TARGET_AVX512VL")
4411 (const_string "V4SF")
4412 (match_test "TARGET_AVX512FP16")
4414 (match_test "TARGET_AVX512F")
4416 (match_test "TARGET_AVX")
4417 (const_string "V4SF")
4418 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
4419 (match_test "TARGET_SSE_SPLIT_REGS"))
4420 (const_string "V4SF")
4422 (const_string "SF"))
4423 (eq_attr "type" "imovx")
4425 (and (eq_attr "alternative" "1,2")
4426 (match_operand:HI 1 "aligned_operand"))
4428 (and (eq_attr "alternative" "0")
4429 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
4430 (not (match_test "TARGET_HIMODE_MATH"))))
4433 (const_string "HI")))
4434 (set (attr "enabled")
4435 (cond [(and (match_test "<MODE>mode == BFmode")
4436 (eq_attr "alternative" "1"))
4437 (symbol_ref "false")
4439 (const_string "*")))])
4442 [(set (match_operand 0 "any_fp_register_operand")
4443 (match_operand 1 "memory_operand"))]
4445 && (GET_MODE (operands[0]) == TFmode
4446 || GET_MODE (operands[0]) == XFmode
4447 || GET_MODE (operands[0]) == DFmode
4448 || GET_MODE (operands[0]) == SFmode)
4449 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
4450 [(set (match_dup 0) (match_dup 2))]
4451 "operands[2] = find_constant_src (curr_insn);")
4454 [(set (match_operand 0 "any_fp_register_operand")
4455 (float_extend (match_operand 1 "memory_operand")))]
4457 && (GET_MODE (operands[0]) == TFmode
4458 || GET_MODE (operands[0]) == XFmode
4459 || GET_MODE (operands[0]) == DFmode)
4460 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
4461 [(set (match_dup 0) (match_dup 2))]
4462 "operands[2] = find_constant_src (curr_insn);")
4464 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
4466 [(set (match_operand:X87MODEF 0 "fp_register_operand")
4467 (match_operand:X87MODEF 1 "immediate_operand"))]
4469 && (standard_80387_constant_p (operands[1]) == 8
4470 || standard_80387_constant_p (operands[1]) == 9)"
4471 [(set (match_dup 0)(match_dup 1))
4473 (neg:X87MODEF (match_dup 0)))]
4475 if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
4476 operands[1] = CONST0_RTX (<MODE>mode);
4478 operands[1] = CONST1_RTX (<MODE>mode);
4481 (define_insn "*swapxf"
4482 [(set (match_operand:XF 0 "register_operand" "+f")
4483 (match_operand:XF 1 "register_operand" "+f"))
4488 if (STACK_TOP_P (operands[0]))
4493 [(set_attr "type" "fxch")
4494 (set_attr "mode" "XF")])
4497 ;; Zero extension instructions
4499 (define_insn_and_split "zero_extendditi2"
4500 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4501 (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "rm,r")))]
4504 "&& reload_completed"
4505 [(set (match_dup 3) (match_dup 1))
4506 (set (match_dup 4) (const_int 0))]
4507 "split_double_mode (TImode, &operands[0], 1, &operands[3], &operands[4]);")
4509 (define_expand "zero_extendsidi2"
4510 [(set (match_operand:DI 0 "nonimmediate_operand")
4511 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
4513 (define_insn "*zero_extendsidi2"
4514 [(set (match_operand:DI 0 "nonimmediate_operand"
4515 "=r,?r,?o,r ,o,?*y,?!*y,$r,$v,$x,*x,*v,*r,*k")
4517 (match_operand:SI 1 "x86_64_zext_operand"
4518 "0 ,rm,r ,rmWz,0,r ,m ,v ,r ,m ,*x,*v,*k,*km")))]
4521 switch (get_attr_type (insn))
4524 if (ix86_use_lea_for_mov (insn, operands))
4525 return "lea{l}\t{%E1, %k0|%k0, %E1}";
4527 return "mov{l}\t{%1, %k0|%k0, %1}";
4533 return "movd\t{%1, %0|%0, %1}";
4536 if (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1]))
4538 if (EXT_REX_SSE_REG_P (operands[0])
4539 || EXT_REX_SSE_REG_P (operands[1]))
4540 return "vpmovzxdq\t{%t1, %g0|%g0, %t1}";
4542 return "%vpmovzxdq\t{%1, %0|%0, %1}";
4545 if (GENERAL_REG_P (operands[0]))
4546 return "%vmovd\t{%1, %k0|%k0, %1}";
4548 return "%vmovd\t{%1, %0|%0, %1}";
4551 return "kmovd\t{%1, %k0|%k0, %1}";
4558 (cond [(eq_attr "alternative" "0,1,2")
4559 (const_string "nox64")
4560 (eq_attr "alternative" "3")
4561 (const_string "x64")
4562 (eq_attr "alternative" "7,8,9")
4563 (const_string "sse2")
4564 (eq_attr "alternative" "10")
4565 (const_string "sse4")
4566 (eq_attr "alternative" "11")
4567 (const_string "avx512f")
4568 (eq_attr "alternative" "12")
4569 (const_string "x64_avx512bw")
4570 (eq_attr "alternative" "13")
4571 (const_string "avx512bw_512")
4573 (const_string "*")))
4574 (set (attr "mmx_isa")
4575 (if_then_else (eq_attr "alternative" "5,6")
4576 (const_string "native")
4577 (const_string "*")))
4579 (cond [(eq_attr "alternative" "0,1,2,4")
4580 (const_string "multi")
4581 (eq_attr "alternative" "5,6")
4582 (const_string "mmxmov")
4583 (eq_attr "alternative" "7")
4584 (if_then_else (match_test "TARGET_64BIT")
4585 (const_string "ssemov")
4586 (const_string "multi"))
4587 (eq_attr "alternative" "8,9,10,11")
4588 (const_string "ssemov")
4589 (eq_attr "alternative" "12,13")
4590 (const_string "mskmov")
4592 (const_string "imovx")))
4593 (set (attr "prefix_extra")
4594 (if_then_else (eq_attr "alternative" "10,11")
4596 (const_string "*")))
4597 (set (attr "prefix")
4598 (if_then_else (eq_attr "type" "ssemov")
4599 (const_string "maybe_vex")
4600 (const_string "orig")))
4601 (set (attr "prefix_0f")
4602 (if_then_else (eq_attr "type" "imovx")
4604 (const_string "*")))
4606 (cond [(eq_attr "alternative" "5,6")
4608 (and (eq_attr "alternative" "7")
4609 (match_test "TARGET_64BIT"))
4611 (eq_attr "alternative" "8,10,11")
4614 (const_string "SI")))
4615 (set (attr "preferred_for_speed")
4616 (cond [(eq_attr "alternative" "7")
4617 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4618 (eq_attr "alternative" "5,8")
4619 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4621 (symbol_ref "true")))])
4624 [(set (match_operand:DI 0 "memory_operand")
4625 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
4627 [(set (match_dup 4) (const_int 0))]
4628 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4631 [(set (match_operand:DI 0 "general_reg_operand")
4632 (zero_extend:DI (match_operand:SI 1 "general_reg_operand")))]
4633 "!TARGET_64BIT && reload_completed
4634 && REGNO (operands[0]) == REGNO (operands[1])"
4635 [(set (match_dup 4) (const_int 0))]
4636 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4639 [(set (match_operand:DI 0 "nonimmediate_gr_operand")
4640 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
4641 "!TARGET_64BIT && reload_completed
4642 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
4643 [(set (match_dup 3) (match_dup 1))
4644 (set (match_dup 4) (const_int 0))]
4645 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4647 (define_mode_attr kmov_isa
4648 [(QI "avx512dq") (HI "avx512f") (SI "avx512bw") (DI "avx512bw_512")])
4650 (define_insn "zero_extend<mode>di2"
4651 [(set (match_operand:DI 0 "register_operand" "=r,*r,*k")
4653 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k,*km")))]
4656 movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}
4657 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}
4658 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}"
4659 [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
4660 (set_attr "type" "imovx,mskmov,mskmov")
4661 (set_attr "mode" "SI,<MODE>,<MODE>")])
4663 (define_expand "zero_extend<mode>si2"
4664 [(set (match_operand:SI 0 "register_operand")
4665 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
4668 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4670 operands[1] = force_reg (<MODE>mode, operands[1]);
4671 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
4676 (define_insn_and_split "zero_extend<mode>si2_and"
4677 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
4679 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
4680 (clobber (reg:CC FLAGS_REG))]
4681 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4683 "&& reload_completed"
4684 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
4685 (clobber (reg:CC FLAGS_REG))])]
4687 if (!REG_P (operands[1])
4688 || REGNO (operands[0]) != REGNO (operands[1]))
4690 ix86_expand_clear (operands[0]);
4692 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4693 emit_insn (gen_rtx_SET
4694 (gen_rtx_STRICT_LOW_PART
4695 (VOIDmode, gen_lowpart (<MODE>mode, operands[0])),
4700 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
4702 [(set_attr "type" "alu1")
4703 (set_attr "mode" "SI")])
4705 (define_insn "*zero_extend<mode>si2"
4706 [(set (match_operand:SI 0 "register_operand" "=r,*r,*k")
4708 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k,*km")))]
4709 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4711 movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}
4712 kmov<mskmodesuffix>\t{%1, %0|%0, %1}
4713 kmov<mskmodesuffix>\t{%1, %0|%0, %1}"
4714 [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
4715 (set_attr "type" "imovx,mskmov,mskmov")
4716 (set_attr "mode" "SI,<MODE>,<MODE>")])
4718 (define_expand "zero_extendqihi2"
4719 [(set (match_operand:HI 0 "register_operand")
4720 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
4723 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4725 operands[1] = force_reg (QImode, operands[1]);
4726 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
4731 (define_insn_and_split "zero_extendqihi2_and"
4732 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
4733 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4734 (clobber (reg:CC FLAGS_REG))]
4735 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4737 "&& reload_completed"
4738 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4739 (clobber (reg:CC FLAGS_REG))])]
4741 if (!REG_P (operands[1])
4742 || REGNO (operands[0]) != REGNO (operands[1]))
4744 ix86_expand_clear (operands[0]);
4746 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4747 emit_insn (gen_rtx_SET
4748 (gen_rtx_STRICT_LOW_PART
4749 (VOIDmode, gen_lowpart (QImode, operands[0])),
4754 operands[0] = gen_lowpart (SImode, operands[0]);
4756 [(set_attr "type" "alu1")
4757 (set_attr "mode" "SI")])
4759 ; zero extend to SImode to avoid partial register stalls
4760 (define_insn "*zero_extendqihi2"
4761 [(set (match_operand:HI 0 "register_operand" "=r,*r,*k")
4762 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,*k,*km")))]
4763 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4765 movz{bl|x}\t{%1, %k0|%k0, %1}
4766 kmovb\t{%1, %k0|%k0, %1}
4767 kmovb\t{%1, %0|%0, %1}"
4768 [(set_attr "isa" "*,avx512dq,avx512dq")
4769 (set_attr "type" "imovx,mskmov,mskmov")
4770 (set_attr "mode" "SI,QI,QI")])
4772 ;; Transform xorl; mov[bw] (set strict_low_part) into movz[bw]l.
4774 [(parallel [(set (match_operand:SWI48 0 "general_reg_operand")
4776 (clobber (reg:CC FLAGS_REG))])
4777 (set (strict_low_part (match_operand:SWI12 1 "general_reg_operand"))
4778 (match_operand:SWI12 2 "nonimmediate_operand"))]
4779 "REGNO (operands[0]) == REGNO (operands[1])
4780 && (<SWI48:MODE>mode != SImode
4781 || !TARGET_ZERO_EXTEND_WITH_AND
4782 || !optimize_function_for_speed_p (cfun))"
4783 [(set (match_dup 0) (zero_extend:SWI48 (match_dup 2)))])
4785 ;; Likewise, but preserving FLAGS_REG.
4787 [(set (match_operand:SWI48 0 "general_reg_operand") (const_int 0))
4788 (set (strict_low_part (match_operand:SWI12 1 "general_reg_operand"))
4789 (match_operand:SWI12 2 "nonimmediate_operand"))]
4790 "REGNO (operands[0]) == REGNO (operands[1])
4791 && (<SWI48:MODE>mode != SImode
4792 || !TARGET_ZERO_EXTEND_WITH_AND
4793 || !optimize_function_for_speed_p (cfun))"
4794 [(set (match_dup 0) (zero_extend:SWI48 (match_dup 2)))])
4796 ;; Sign extension instructions
4798 (define_expand "extendsidi2"
4799 [(set (match_operand:DI 0 "register_operand")
4800 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
4805 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
4810 (define_insn "*extendsidi2_rex64"
4811 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4812 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4816 movs{lq|x}\t{%1, %0|%0, %1}"
4817 [(set_attr "type" "imovx")
4818 (set_attr "mode" "DI")
4819 (set_attr "prefix_0f" "0")
4820 (set_attr "modrm" "0,1")])
4822 (define_insn "extendsidi2_1"
4823 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4824 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4825 (clobber (reg:CC FLAGS_REG))
4826 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4830 (define_insn "extendditi2"
4831 [(set (match_operand:TI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4832 (sign_extend:TI (match_operand:DI 1 "register_operand" "0,0,r,r")))
4833 (clobber (reg:CC FLAGS_REG))
4834 (clobber (match_scratch:DI 2 "=X,X,X,&r"))]
4838 ;; Split the memory case. If the source register doesn't die, it will stay
4839 ;; this way, if it does die, following peephole2s take care of it.
4841 [(set (match_operand:<DWI> 0 "memory_operand")
4842 (sign_extend:<DWI> (match_operand:DWIH 1 "register_operand")))
4843 (clobber (reg:CC FLAGS_REG))
4844 (clobber (match_operand:DWIH 2 "register_operand"))]
4848 rtx bits = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
4850 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
4852 emit_move_insn (operands[3], operands[1]);
4854 /* Generate a cltd if possible and doing so it profitable. */
4855 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4856 && REGNO (operands[1]) == AX_REG
4857 && REGNO (operands[2]) == DX_REG)
4859 emit_insn (gen_ashr<mode>3_cvt (operands[2], operands[1], bits));
4863 emit_move_insn (operands[2], operands[1]);
4864 emit_insn (gen_ashr<mode>3_cvt (operands[2], operands[2], bits));
4866 emit_move_insn (operands[4], operands[2]);
4870 ;; Peepholes for the case where the source register does die, after
4871 ;; being split with the above splitter.
4873 [(set (match_operand:DWIH 0 "memory_operand")
4874 (match_operand:DWIH 1 "general_reg_operand"))
4875 (set (match_operand:DWIH 2 "general_reg_operand") (match_dup 1))
4876 (parallel [(set (match_dup 2)
4877 (ashiftrt:DWIH (match_dup 2)
4878 (match_operand 4 "const_int_operand")))
4879 (clobber (reg:CC FLAGS_REG))])
4880 (set (match_operand:DWIH 3 "memory_operand") (match_dup 2))]
4881 "REGNO (operands[1]) != REGNO (operands[2])
4882 && INTVAL (operands[4]) == (<MODE_SIZE> * BITS_PER_UNIT - 1)
4883 && peep2_reg_dead_p (2, operands[1])
4884 && peep2_reg_dead_p (4, operands[2])
4885 && !reg_mentioned_p (operands[2], operands[3])"
4886 [(set (match_dup 0) (match_dup 1))
4887 (parallel [(set (match_dup 1) (ashiftrt:DWIH (match_dup 1) (match_dup 4)))
4888 (clobber (reg:CC FLAGS_REG))])
4889 (set (match_dup 3) (match_dup 1))])
4892 [(set (match_operand:DWIH 0 "memory_operand")
4893 (match_operand:DWIH 1 "general_reg_operand"))
4894 (parallel [(set (match_operand:DWIH 2 "general_reg_operand")
4895 (ashiftrt:DWIH (match_dup 1)
4896 (match_operand 4 "const_int_operand")))
4897 (clobber (reg:CC FLAGS_REG))])
4898 (set (match_operand:DWIH 3 "memory_operand") (match_dup 2))]
4899 "/* cltd is shorter than sarl $31, %eax */
4900 !optimize_function_for_size_p (cfun)
4901 && REGNO (operands[1]) == AX_REG
4902 && REGNO (operands[2]) == DX_REG
4903 && INTVAL (operands[4]) == (<MODE_SIZE> * BITS_PER_UNIT - 1)
4904 && peep2_reg_dead_p (2, operands[1])
4905 && peep2_reg_dead_p (3, operands[2])
4906 && !reg_mentioned_p (operands[2], operands[3])"
4907 [(set (match_dup 0) (match_dup 1))
4908 (parallel [(set (match_dup 1) (ashiftrt:DWIH (match_dup 1) (match_dup 4)))
4909 (clobber (reg:CC FLAGS_REG))])
4910 (set (match_dup 3) (match_dup 1))])
4912 ;; Extend to register case. Optimize case where source and destination
4913 ;; registers match and cases where we can use cltd.
4915 [(set (match_operand:<DWI> 0 "register_operand")
4916 (sign_extend:<DWI> (match_operand:DWIH 1 "register_operand")))
4917 (clobber (reg:CC FLAGS_REG))
4918 (clobber (match_scratch:DWIH 2))]
4922 rtx bits = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
4924 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
4926 if (REGNO (operands[3]) != REGNO (operands[1]))
4927 emit_move_insn (operands[3], operands[1]);
4929 rtx src = operands[1];
4930 if (REGNO (operands[3]) == AX_REG)
4933 /* Generate a cltd if possible and doing so it profitable. */
4934 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4935 && REGNO (src) == AX_REG
4936 && REGNO (operands[4]) == DX_REG)
4938 emit_insn (gen_ashr<mode>3_cvt (operands[4], src, bits));
4942 if (REGNO (operands[4]) != REGNO (operands[1]))
4943 emit_move_insn (operands[4], operands[1]);
4945 emit_insn (gen_ashr<mode>3_cvt (operands[4], operands[4], bits));
4949 (define_insn "extend<mode>di2"
4950 [(set (match_operand:DI 0 "register_operand" "=r")
4952 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4954 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
4955 [(set_attr "type" "imovx")
4956 (set_attr "mode" "DI")])
4958 (define_insn "extendhisi2"
4959 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4960 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4963 switch (get_attr_prefix_0f (insn))
4966 return "{cwtl|cwde}";
4968 return "movs{wl|x}\t{%1, %0|%0, %1}";
4971 [(set_attr "type" "imovx")
4972 (set_attr "mode" "SI")
4973 (set (attr "prefix_0f")
4974 ;; movsx is short decodable while cwtl is vector decoded.
4975 (if_then_else (and (eq_attr "cpu" "!k6")
4976 (eq_attr "alternative" "0"))
4978 (const_string "1")))
4979 (set (attr "znver1_decode")
4980 (if_then_else (eq_attr "prefix_0f" "0")
4981 (const_string "double")
4982 (const_string "direct")))
4984 (if_then_else (eq_attr "prefix_0f" "0")
4986 (const_string "1")))])
4988 (define_insn "*extendhisi2_zext"
4989 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4992 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4995 switch (get_attr_prefix_0f (insn))
4998 return "{cwtl|cwde}";
5000 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
5003 [(set_attr "type" "imovx")
5004 (set_attr "mode" "SI")
5005 (set (attr "prefix_0f")
5006 ;; movsx is short decodable while cwtl is vector decoded.
5007 (if_then_else (and (eq_attr "cpu" "!k6")
5008 (eq_attr "alternative" "0"))
5010 (const_string "1")))
5012 (if_then_else (eq_attr "prefix_0f" "0")
5014 (const_string "1")))])
5016 (define_insn "extendqisi2"
5017 [(set (match_operand:SI 0 "register_operand" "=r")
5018 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
5020 "movs{bl|x}\t{%1, %0|%0, %1}"
5021 [(set_attr "type" "imovx")
5022 (set_attr "mode" "SI")])
5024 (define_insn "*extendqisi2_zext"
5025 [(set (match_operand:DI 0 "register_operand" "=r")
5027 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
5029 "movs{bl|x}\t{%1, %k0|%k0, %1}"
5030 [(set_attr "type" "imovx")
5031 (set_attr "mode" "SI")])
5033 (define_insn "extendqihi2"
5034 [(set (match_operand:HI 0 "register_operand" "=*a,r")
5035 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
5038 switch (get_attr_prefix_0f (insn))
5041 return "{cbtw|cbw}";
5043 return "movs{bw|x}\t{%1, %0|%0, %1}";
5046 [(set_attr "type" "imovx")
5047 (set_attr "mode" "HI")
5048 (set (attr "prefix_0f")
5049 ;; movsx is short decodable while cwtl is vector decoded.
5050 (if_then_else (and (eq_attr "cpu" "!k6")
5051 (eq_attr "alternative" "0"))
5053 (const_string "1")))
5055 (if_then_else (eq_attr "prefix_0f" "0")
5057 (const_string "1")))])
5059 (define_insn "*extendqi<SWI24:mode>_ext_1"
5060 [(set (match_operand:SWI24 0 "register_operand" "=R")
5063 (match_operator:SWI248 2 "extract_operator"
5064 [(match_operand 1 "int248_register_operand" "Q")
5066 (const_int 8)]) 0)))]
5068 "movs{b<SWI24:imodesuffix>|x}\t{%h1, %0|%0, %h1}"
5069 [(set_attr "type" "imovx")
5070 (set_attr "mode" "<SWI24:MODE>")])
5072 ;; Conversions between float and double.
5074 ;; These are all no-ops in the model used for the 80387.
5075 ;; So just emit moves.
5077 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
5079 [(set (match_operand:DF 0 "push_operand")
5080 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
5082 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
5083 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
5086 [(set (match_operand:XF 0 "push_operand")
5087 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
5089 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
5090 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
5091 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
5093 (define_expand "extendsfdf2"
5094 [(set (match_operand:DF 0 "nonimm_ssenomem_operand")
5095 (float_extend:DF (match_operand:SF 1 "general_operand")))]
5096 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5098 /* ??? Needed for compress_float_constant since all fp constants
5099 are TARGET_LEGITIMATE_CONSTANT_P. */
5100 if (CONST_DOUBLE_P (operands[1]))
5102 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
5103 && standard_80387_constant_p (operands[1]) > 0)
5105 operands[1] = simplify_const_unary_operation
5106 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
5107 emit_move_insn_1 (operands[0], operands[1]);
5110 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
5114 (define_insn "*extendsfdf2"
5115 [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v,v")
5117 (match_operand:SF 1 "nonimmediate_operand" "fm,f,v,m")))]
5118 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5120 switch (which_alternative)
5124 return output_387_reg_move (insn, operands);
5127 return "%vcvtss2sd\t{%d1, %0|%0, %d1}";
5129 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
5135 [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
5136 (set_attr "avx_partial_xmm_update" "false,false,false,true")
5137 (set_attr "prefix" "orig,orig,maybe_vex,maybe_vex")
5138 (set_attr "mode" "SF,XF,DF,DF")
5139 (set (attr "enabled")
5141 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
5143 (eq_attr "alternative" "0,1")
5144 (symbol_ref "TARGET_MIX_SSE_I387")
5145 (symbol_ref "true"))
5147 (eq_attr "alternative" "0,1")
5149 (symbol_ref "false"))))])
5151 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
5153 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
5155 We do the conversion post reload to avoid producing of 128bit spills
5156 that might lead to ICE on 32bit target. The sequence unlikely combine
5159 [(set (match_operand:DF 0 "sse_reg_operand")
5161 (match_operand:SF 1 "nonimmediate_operand")))]
5162 "TARGET_USE_VECTOR_FP_CONVERTS
5163 && optimize_insn_for_speed_p ()
5165 && (!EXT_REX_SSE_REG_P (operands[0])
5166 || TARGET_AVX512VL || TARGET_EVEX512)"
5171 (parallel [(const_int 0) (const_int 1)]))))]
5173 operands[2] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5174 operands[3] = lowpart_subreg (V4SFmode, operands[0], DFmode);
5175 /* Use movss for loading from memory, unpcklps reg, reg for registers.
5176 Try to avoid move when unpacking can be done in source. */
5177 if (REG_P (operands[1]))
5179 /* If it is unsafe to overwrite upper half of source, we need
5180 to move to destination and unpack there. */
5181 if (REGNO (operands[0]) != REGNO (operands[1])
5182 || (EXT_REX_SSE_REG_P (operands[1])
5183 && !TARGET_AVX512VL))
5185 rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode);
5186 emit_move_insn (tmp, operands[1]);
5189 operands[3] = lowpart_subreg (V4SFmode, operands[1], SFmode);
5190 /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
5191 =v, v, then vbroadcastss will be only needed for AVX512F without
5193 if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3])))
5194 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
5198 rtx tmp = lowpart_subreg (V16SFmode, operands[3], V4SFmode);
5199 emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
5203 emit_insn (gen_vec_setv4sf_0 (operands[3],
5204 CONST0_RTX (V4SFmode), operands[1]));
5207 ;; It's more profitable to split and then extend in the same register.
5209 [(set (match_operand:DF 0 "sse_reg_operand")
5211 (match_operand:SF 1 "memory_operand")))]
5212 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
5213 && optimize_insn_for_speed_p ()"
5214 [(set (match_dup 2) (match_dup 1))
5215 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
5216 "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);")
5218 ;; Break partial SSE register dependency stall. This splitter should split
5219 ;; late in the pass sequence (after register rename pass), so allocated
5220 ;; registers won't change anymore
5223 [(set (match_operand:DF 0 "sse_reg_operand")
5225 (match_operand:SF 1 "nonimmediate_operand")))]
5227 && TARGET_SSE_PARTIAL_REG_FP_CONVERTS_DEPENDENCY
5228 && epilogue_completed
5229 && optimize_function_for_speed_p (cfun)
5230 && (!REG_P (operands[1])
5231 || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
5232 && (!EXT_REX_SSE_REG_P (operands[0])
5233 || TARGET_AVX512VL)"
5242 operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5243 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5246 (define_expand "extendhfsf2"
5247 [(set (match_operand:SF 0 "register_operand")
5249 (match_operand:HF 1 "nonimmediate_operand")))]
5250 "TARGET_AVX512FP16 || TARGET_F16C || TARGET_AVX512VL"
5252 if (!TARGET_AVX512FP16)
5254 rtx res = gen_reg_rtx (V4SFmode);
5255 rtx tmp = gen_reg_rtx (V8HFmode);
5256 rtx zero = force_reg (V8HFmode, CONST0_RTX (V8HFmode));
5258 emit_insn (gen_vec_setv8hf_0 (tmp, zero, operands[1]));
5259 emit_insn (gen_vcvtph2ps (res, gen_lowpart (V8HImode, tmp)));
5260 emit_move_insn (operands[0], gen_lowpart (SFmode, res));
5265 (define_expand "extendhfdf2"
5266 [(set (match_operand:DF 0 "register_operand")
5268 (match_operand:HF 1 "nonimmediate_operand")))]
5269 "TARGET_AVX512FP16")
5271 (define_insn "*extendhf<mode>2"
5272 [(set (match_operand:MODEF 0 "register_operand" "=v")
5274 (match_operand:HF 1 "nonimmediate_operand" "vm")))]
5276 "vcvtsh2<ssemodesuffix>\t{%1, %0, %0|%0, %0, %1}"
5277 [(set_attr "type" "ssecvt")
5278 (set_attr "prefix" "evex")
5279 (set_attr "mode" "<MODE>")])
5281 (define_expand "extendbfsf2"
5282 [(set (match_operand:SF 0 "register_operand")
5284 [(match_operand:BF 1 "register_operand")]
5286 "TARGET_SSE2 && !HONOR_NANS (BFmode)")
5288 ;; Don't use float_extend since psrlld doesn't raise
5289 ;; exceptions and turn a sNaN into a qNaN.
5290 (define_insn "extendbfsf2_1"
5291 [(set (match_operand:SF 0 "register_operand" "=x,Yv,v")
5293 [(match_operand:BF 1 "register_operand" " 0,Yv,v")]
5297 pslld\t{$16, %0|%0, 16}
5298 vpslld\t{$16, %1, %0|%0, %1, 16}
5299 vpslld\t{$16, %g1, %g0|%g0, %g1, 16}"
5300 [(set_attr "isa" "noavx,avx,*")
5301 (set_attr "type" "sseishft1")
5302 (set_attr "length_immediate" "1")
5303 (set_attr "prefix_data16" "1,*,*")
5304 (set_attr "prefix" "orig,maybe_evex,evex")
5305 (set_attr "mode" "TI,TI,XI")
5306 (set_attr "memory" "none")
5307 (set (attr "enabled")
5308 (if_then_else (eq_attr "alternative" "2")
5309 (symbol_ref "TARGET_AVX512F && TARGET_EVEX512
5310 && !TARGET_AVX512VL && !TARGET_PREFER_AVX256")
5311 (const_string "*")))])
5313 (define_expand "extend<mode>xf2"
5314 [(set (match_operand:XF 0 "nonimmediate_operand")
5315 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
5318 /* ??? Needed for compress_float_constant since all fp constants
5319 are TARGET_LEGITIMATE_CONSTANT_P. */
5320 if (CONST_DOUBLE_P (operands[1]))
5322 if (standard_80387_constant_p (operands[1]) > 0)
5324 operands[1] = simplify_const_unary_operation
5325 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
5326 emit_move_insn_1 (operands[0], operands[1]);
5329 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
5333 (define_insn "*extend<mode>xf2_i387"
5334 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
5336 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
5338 "* return output_387_reg_move (insn, operands);"
5339 [(set_attr "type" "fmov")
5340 (set_attr "mode" "<MODE>,XF")])
5342 ;; %%% This seems like bad news.
5343 ;; This cannot output into an f-reg because there is no way to be sure
5344 ;; of truncating in that case. Otherwise this is just like a simple move
5345 ;; insn. So we pretend we can output to a reg in order to get better
5346 ;; register preferencing, but we really use a stack slot.
5348 ;; Conversion from DFmode to SFmode.
5350 (define_insn "truncdfsf2"
5351 [(set (match_operand:SF 0 "nonimm_ssenomem_operand" "=m,f,v,v")
5353 (match_operand:DF 1 "register_ssemem_operand" "f,f,v,m")))]
5354 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5356 switch (which_alternative)
5360 return output_387_reg_move (insn, operands);
5363 return "%vcvtsd2ss\t{%d1, %0|%0, %d1}";
5365 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
5371 [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
5372 (set_attr "avx_partial_xmm_update" "false,false,false,true")
5373 (set_attr "mode" "SF")
5374 (set (attr "enabled")
5376 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
5377 (cond [(eq_attr "alternative" "0")
5378 (symbol_ref "TARGET_MIX_SSE_I387")
5379 (eq_attr "alternative" "1")
5380 (symbol_ref "TARGET_MIX_SSE_I387
5381 && flag_unsafe_math_optimizations")
5383 (symbol_ref "true"))
5384 (cond [(eq_attr "alternative" "0")
5386 (eq_attr "alternative" "1")
5387 (symbol_ref "flag_unsafe_math_optimizations")
5389 (symbol_ref "false"))))])
5391 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
5393 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
5395 We do the conversion post reload to avoid producing of 128bit spills
5396 that might lead to ICE on 32bit target. The sequence unlikely combine
5399 [(set (match_operand:SF 0 "sse_reg_operand")
5401 (match_operand:DF 1 "nonimmediate_operand")))]
5402 "TARGET_USE_VECTOR_FP_CONVERTS
5403 && optimize_insn_for_speed_p ()
5405 && (!EXT_REX_SSE_REG_P (operands[0])
5406 || TARGET_AVX512VL)"
5409 (float_truncate:V2SF
5413 operands[2] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5414 operands[3] = CONST0_RTX (V2SFmode);
5415 operands[4] = lowpart_subreg (V2DFmode, operands[0], SFmode);
5416 /* Use movsd for loading from memory, unpcklpd for registers.
5417 Try to avoid move when unpacking can be done in source, or SSE3
5418 movddup is available. */
5419 if (REG_P (operands[1]))
5421 if ((!TARGET_SSE3 && REGNO (operands[0]) != REGNO (operands[1]))
5422 || (EXT_REX_SSE_REG_P (operands[1]) && !TARGET_AVX512VL))
5424 rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode);
5425 emit_move_insn (tmp, operands[1]);
5428 else if (!TARGET_SSE3)
5429 operands[4] = lowpart_subreg (V2DFmode, operands[1], DFmode);
5430 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
5433 emit_insn (gen_vec_concatv2df (operands[4], operands[1],
5434 CONST0_RTX (DFmode)));
5437 ;; It's more profitable to split and then truncate in the same register.
5439 [(set (match_operand:SF 0 "sse_reg_operand")
5441 (match_operand:DF 1 "memory_operand")))]
5442 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
5443 && optimize_insn_for_speed_p ()"
5444 [(set (match_dup 2) (match_dup 1))
5445 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
5446 "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
5448 ;; Break partial SSE register dependency stall. This splitter should split
5449 ;; late in the pass sequence (after register rename pass), so allocated
5450 ;; registers won't change anymore
5453 [(set (match_operand:SF 0 "sse_reg_operand")
5455 (match_operand:DF 1 "nonimmediate_operand")))]
5457 && TARGET_SSE_PARTIAL_REG_FP_CONVERTS_DEPENDENCY
5458 && epilogue_completed
5459 && optimize_function_for_speed_p (cfun)
5460 && (!REG_P (operands[1])
5461 || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
5462 && (!EXT_REX_SSE_REG_P (operands[0])
5463 || TARGET_AVX512VL)"
5472 operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5473 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5476 ;; Conversion from XFmode to {SF,DF}mode
5478 (define_insn "truncxf<mode>2"
5479 [(set (match_operand:MODEF 0 "nonimmediate_operand" "=m,f")
5480 (float_truncate:MODEF
5481 (match_operand:XF 1 "register_operand" "f,f")))]
5483 "* return output_387_reg_move (insn, operands);"
5484 [(set_attr "type" "fmov")
5485 (set_attr "mode" "<MODE>")
5486 (set (attr "enabled")
5487 (cond [(eq_attr "alternative" "1")
5488 (symbol_ref "flag_unsafe_math_optimizations")
5490 (symbol_ref "true")))])
5492 ;; Conversion from {SF,DF}mode to HFmode.
5494 (define_expand "truncsfhf2"
5495 [(set (match_operand:HF 0 "register_operand")
5497 (match_operand:SF 1 "nonimmediate_operand")))]
5498 "TARGET_AVX512FP16 || TARGET_F16C || TARGET_AVX512VL"
5500 if (!TARGET_AVX512FP16)
5502 rtx res = gen_reg_rtx (V8HFmode);
5503 rtx tmp = gen_reg_rtx (V4SFmode);
5504 rtx zero = force_reg (V4SFmode, CONST0_RTX (V4SFmode));
5506 emit_insn (gen_vec_setv4sf_0 (tmp, zero, operands[1]));
5507 emit_insn (gen_vcvtps2ph (gen_lowpart (V8HImode, res), tmp, GEN_INT (4)));
5508 emit_move_insn (operands[0], gen_lowpart (HFmode, res));
5513 (define_expand "truncdfhf2"
5514 [(set (match_operand:HF 0 "register_operand")
5516 (match_operand:DF 1 "nonimmediate_operand")))]
5517 "TARGET_AVX512FP16")
5519 (define_insn "*trunc<mode>hf2"
5520 [(set (match_operand:HF 0 "register_operand" "=v")
5522 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5524 "vcvt<ssemodesuffix>2sh\t{%1, %d0|%d0, %1}"
5525 [(set_attr "type" "ssecvt")
5526 (set_attr "prefix" "evex")
5527 (set_attr "mode" "HF")])
5529 (define_insn "truncsfbf2"
5530 [(set (match_operand:BF 0 "register_operand" "=x, v")
5532 (match_operand:SF 1 "register_operand" "x,v")))]
5533 "((TARGET_AVX512BF16 && TARGET_AVX512VL) || TARGET_AVXNECONVERT)
5534 && !HONOR_NANS (BFmode) && flag_unsafe_math_optimizations"
5536 %{vex%} vcvtneps2bf16\t{%1, %0|%0, %1}
5537 vcvtneps2bf16\t{%1, %0|%0, %1}"
5538 [(set_attr "isa" "avxneconvert,avx512bf16vl")
5539 (set_attr "prefix" "vex,evex")])
5541 ;; Signed conversion to DImode.
5543 (define_expand "fix_truncxfdi2"
5544 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
5545 (fix:DI (match_operand:XF 1 "register_operand")))
5546 (clobber (reg:CC FLAGS_REG))])]
5551 emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
5556 (define_expand "fix_trunc<mode>di2"
5557 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
5558 (fix:DI (match_operand:MODEF 1 "register_operand")))
5559 (clobber (reg:CC FLAGS_REG))])]
5560 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
5563 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
5565 emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
5568 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
5570 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
5571 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
5572 if (out != operands[0])
5573 emit_move_insn (operands[0], out);
5578 (define_insn "fix<fixunssuffix>_trunchf<mode>2"
5579 [(set (match_operand:SWI48 0 "register_operand" "=r")
5581 (match_operand:HF 1 "nonimmediate_operand" "vm")))]
5583 "vcvttsh2<fixsuffix>si\t{%1, %0|%0, %1}"
5584 [(set_attr "type" "sseicvt")
5585 (set_attr "prefix" "evex")
5586 (set_attr "mode" "<MODE>")])
5588 ;; Signed conversion to SImode.
5590 (define_expand "fix_truncxfsi2"
5591 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
5592 (fix:SI (match_operand:XF 1 "register_operand")))
5593 (clobber (reg:CC FLAGS_REG))])]
5598 emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
5603 (define_expand "fix_trunc<mode>si2"
5604 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
5605 (fix:SI (match_operand:MODEF 1 "register_operand")))
5606 (clobber (reg:CC FLAGS_REG))])]
5607 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
5610 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
5612 emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
5615 if (SSE_FLOAT_MODE_P (<MODE>mode))
5617 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
5618 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
5619 if (out != operands[0])
5620 emit_move_insn (operands[0], out);
5625 ;; Signed conversion to HImode.
5627 (define_expand "fix_trunc<mode>hi2"
5628 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
5629 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
5630 (clobber (reg:CC FLAGS_REG))])]
5632 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
5636 emit_insn (gen_fix_trunchi_i387_fisttp (operands[0], operands[1]));
5641 ;; Unsigned conversion to DImode
5643 (define_insn "fixuns_trunc<mode>di2"
5644 [(set (match_operand:DI 0 "register_operand" "=r")
5646 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5647 "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
5648 "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
5649 [(set_attr "type" "sseicvt")
5650 (set_attr "prefix" "evex")
5651 (set_attr "mode" "DI")])
5653 ;; Unsigned conversion to SImode.
5655 (define_expand "fixuns_trunc<mode>si2"
5657 [(set (match_operand:SI 0 "register_operand")
5659 (match_operand:MODEF 1 "nonimmediate_operand")))
5661 (clobber (scratch:<ssevecmode>))
5662 (clobber (scratch:<ssevecmode>))])]
5663 "(!TARGET_64BIT || TARGET_AVX512F) && TARGET_SSE2 && TARGET_SSE_MATH"
5665 machine_mode mode = <MODE>mode;
5666 machine_mode vecmode = <ssevecmode>mode;
5667 REAL_VALUE_TYPE TWO31r;
5672 emit_insn (gen_fixuns_trunc<mode>si2_avx512f (operands[0], operands[1]));
5676 if (optimize_insn_for_size_p ())
5679 real_ldexp (&TWO31r, &dconst1, 31);
5680 two31 = const_double_from_real_value (TWO31r, mode);
5681 two31 = ix86_build_const_vector (vecmode, true, two31);
5682 operands[2] = force_reg (vecmode, two31);
5685 (define_insn "fixuns_trunc<mode>si2_avx512f"
5686 [(set (match_operand:SI 0 "register_operand" "=r")
5688 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5689 "TARGET_AVX512F && TARGET_SSE_MATH"
5690 "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
5691 [(set_attr "type" "sseicvt")
5692 (set_attr "prefix" "evex")
5693 (set_attr "mode" "SI")])
5695 (define_insn "*fixuns_trunchfsi2zext"
5696 [(set (match_operand:DI 0 "register_operand" "=r")
5699 (match_operand:HF 1 "nonimmediate_operand" "vm"))))]
5700 "TARGET_64BIT && TARGET_AVX512FP16"
5701 "vcvttsh2usi\t{%1, %k0|%k0, %1}"
5702 [(set_attr "type" "sseicvt")
5703 (set_attr "prefix" "evex")
5704 (set_attr "mode" "SI")])
5706 (define_insn "*fixuns_trunc<mode>si2_avx512f_zext"
5707 [(set (match_operand:DI 0 "register_operand" "=r")
5710 (match_operand:MODEF 1 "nonimmediate_operand" "vm"))))]
5711 "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
5712 "vcvtt<ssemodesuffix>2usi\t{%1, %k0|%k0, %1}"
5713 [(set_attr "type" "sseicvt")
5714 (set_attr "prefix" "evex")
5715 (set_attr "mode" "SI")])
5717 (define_insn_and_split "*fixuns_trunc<mode>_1"
5718 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
5720 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
5721 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
5722 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
5723 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
5724 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5725 && optimize_function_for_speed_p (cfun)"
5727 "&& reload_completed"
5730 ix86_split_convert_uns_si_sse (operands);
5734 ;; Unsigned conversion to HImode.
5735 ;; Without these patterns, we'll try the unsigned SI conversion which
5736 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
5738 (define_expand "fixuns_trunchfhi2"
5740 (fix:SI (match_operand:HF 1 "nonimmediate_operand")))
5741 (set (match_operand:HI 0 "nonimmediate_operand")
5742 (subreg:HI (match_dup 2) 0))]
5744 "operands[2] = gen_reg_rtx (SImode);")
5746 (define_expand "fixuns_trunc<mode>hi2"
5748 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
5749 (set (match_operand:HI 0 "nonimmediate_operand")
5750 (subreg:HI (match_dup 2) 0))]
5751 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
5752 "operands[2] = gen_reg_rtx (SImode);")
5754 ;; When SSE is available, it is always faster to use it!
5755 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
5756 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
5757 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
5758 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5759 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
5760 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
5761 [(set_attr "type" "sseicvt")
5762 (set_attr "prefix" "maybe_vex")
5763 (set (attr "prefix_rex")
5765 (match_test "<SWI48:MODE>mode == DImode")
5767 (const_string "*")))
5768 (set_attr "mode" "<MODEF:MODE>")
5769 (set_attr "athlon_decode" "double,vector")
5770 (set_attr "amdfam10_decode" "double,double")
5771 (set_attr "bdver1_decode" "double,double")])
5773 ;; Avoid vector decoded forms of the instruction.
5775 [(match_scratch:MODEF 2 "x")
5776 (set (match_operand:SWI48 0 "register_operand")
5777 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
5778 "TARGET_AVOID_VECTOR_DECODE
5779 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5780 && optimize_insn_for_speed_p ()"
5781 [(set (match_dup 2) (match_dup 1))
5782 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
5784 (define_insn "fix_trunc<mode>_i387_fisttp"
5785 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m")
5786 (fix:SWI248x (match_operand 1 "register_operand" "f")))
5787 (clobber (match_scratch:XF 2 "=&f"))]
5788 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5790 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5791 && (TARGET_64BIT || <MODE>mode != DImode))
5792 && TARGET_SSE_MATH)"
5793 "* return output_fix_trunc (insn, operands, true);"
5794 [(set_attr "type" "fisttp")
5795 (set_attr "mode" "<MODE>")])
5797 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5798 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5799 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5800 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5801 ;; function in i386.cc.
5802 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5803 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
5804 (fix:SWI248x (match_operand 1 "register_operand")))
5805 (clobber (reg:CC FLAGS_REG))]
5806 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5808 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5809 && (TARGET_64BIT || <MODE>mode != DImode))
5810 && ix86_pre_reload_split ()"
5815 ix86_optimize_mode_switching[I387_TRUNC] = 1;
5817 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5818 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5820 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5821 operands[2], operands[3]));
5824 [(set_attr "type" "fistp")
5825 (set_attr "i387_cw" "trunc")
5826 (set_attr "mode" "<MODE>")])
5828 (define_insn "fix_truncdi_i387"
5829 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
5830 (fix:DI (match_operand 1 "register_operand" "f")))
5831 (use (match_operand:HI 2 "memory_operand" "m"))
5832 (use (match_operand:HI 3 "memory_operand" "m"))
5833 (clobber (match_scratch:XF 4 "=&f"))]
5834 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5836 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5837 "* return output_fix_trunc (insn, operands, false);"
5838 [(set_attr "type" "fistp")
5839 (set_attr "i387_cw" "trunc")
5840 (set_attr "mode" "DI")])
5842 (define_insn "fix_trunc<mode>_i387"
5843 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
5844 (fix:SWI24 (match_operand 1 "register_operand" "f")))
5845 (use (match_operand:HI 2 "memory_operand" "m"))
5846 (use (match_operand:HI 3 "memory_operand" "m"))]
5847 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5849 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5850 "* return output_fix_trunc (insn, operands, false);"
5851 [(set_attr "type" "fistp")
5852 (set_attr "i387_cw" "trunc")
5853 (set_attr "mode" "<MODE>")])
5855 (define_insn "x86_fnstcw_1"
5856 [(set (match_operand:HI 0 "memory_operand" "=m")
5857 (unspec:HI [(const_int 0)] UNSPEC_FSTCW))]
5860 [(set (attr "length")
5861 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5862 (set_attr "mode" "HI")
5863 (set_attr "unit" "i387")
5864 (set_attr "bdver1_decode" "vector")])
5866 ;; Conversion between fixed point and floating point.
5868 ;; Even though we only accept memory inputs, the backend _really_
5869 ;; wants to be able to do this between registers. Thankfully, LRA
5870 ;; will fix this up for us during register allocation.
5872 (define_insn "floathi<mode>2"
5873 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5874 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
5876 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5877 || TARGET_MIX_SSE_I387)"
5879 [(set_attr "type" "fmov")
5880 (set_attr "mode" "<MODE>")
5881 (set_attr "znver1_decode" "double")
5882 (set_attr "fp_int_src" "true")])
5884 (define_insn "float<SWI48x:mode>xf2"
5885 [(set (match_operand:XF 0 "register_operand" "=f")
5886 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5889 [(set_attr "type" "fmov")
5890 (set_attr "mode" "XF")
5891 (set_attr "znver1_decode" "double")
5892 (set_attr "fp_int_src" "true")])
5894 (define_expand "float<SWI48x:mode><MODEF:mode>2"
5895 [(set (match_operand:MODEF 0 "register_operand")
5896 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand")))]
5897 "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode))
5898 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5899 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT))")
5901 (define_insn "*float<SWI48:mode><MODEF:mode>2"
5902 [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
5904 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
5905 "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
5906 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
5909 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
5910 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5911 [(set_attr "type" "fmov,sseicvt,sseicvt")
5912 (set_attr "avx_partial_xmm_update" "false,true,true")
5913 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5914 (set_attr "mode" "<MODEF:MODE>")
5915 (set (attr "prefix_rex")
5917 (and (eq_attr "prefix" "maybe_vex")
5918 (match_test "<SWI48:MODE>mode == DImode"))
5920 (const_string "*")))
5921 (set_attr "unit" "i387,*,*")
5922 (set_attr "athlon_decode" "*,double,direct")
5923 (set_attr "amdfam10_decode" "*,vector,double")
5924 (set_attr "bdver1_decode" "*,double,direct")
5925 (set_attr "znver1_decode" "double,*,*")
5926 (set_attr "fp_int_src" "true")
5927 (set (attr "enabled")
5929 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
5931 (eq_attr "alternative" "0")
5932 (symbol_ref "TARGET_MIX_SSE_I387
5933 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
5935 (symbol_ref "true"))
5937 (eq_attr "alternative" "0")
5939 (symbol_ref "false"))))
5940 (set (attr "preferred_for_speed")
5941 (cond [(eq_attr "alternative" "1")
5942 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
5943 (symbol_ref "true")))])
5945 (define_insn "float<floatunssuffix><mode>hf2"
5946 [(set (match_operand:HF 0 "register_operand" "=v")
5948 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
5950 "vcvt<floatsuffix>si2sh<rex64suffix>\t{%1, %d0|%d0, %1}"
5951 [(set_attr "type" "sseicvt")
5952 (set_attr "prefix" "evex")
5953 (set_attr "mode" "HF")])
5955 (define_insn "*floatdi<MODEF:mode>2_i387"
5956 [(set (match_operand:MODEF 0 "register_operand" "=f")
5957 (float:MODEF (match_operand:DI 1 "nonimmediate_operand" "m")))]
5959 && TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, DImode)"
5961 [(set_attr "type" "fmov")
5962 (set_attr "mode" "<MODEF:MODE>")
5963 (set_attr "znver1_decode" "double")
5964 (set_attr "fp_int_src" "true")])
5966 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
5967 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
5968 ;; alternative in sse2_loadld.
5970 [(set (match_operand:MODEF 0 "sse_reg_operand")
5971 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5973 && TARGET_USE_VECTOR_CONVERTS
5974 && optimize_function_for_speed_p (cfun)
5976 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
5977 && (!EXT_REX_SSE_REG_P (operands[0])
5978 || TARGET_AVX512VL)"
5981 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode);
5982 operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode);
5984 emit_insn (gen_sse2_loadld (operands[4],
5985 CONST0_RTX (V4SImode), operands[1]));
5987 if (<ssevecmode>mode == V4SFmode)
5988 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5990 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5994 ;; Avoid store forwarding (partial memory) stall penalty
5995 ;; by passing DImode value through XMM registers. */
5998 [(set (match_operand:X87MODEF 0 "register_operand")
6000 (match_operand:DI 1 "register_operand")))]
6001 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
6002 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6003 && TARGET_SSE2 && optimize_function_for_speed_p (cfun)
6004 && can_create_pseudo_p ()"
6007 rtx s = assign_386_stack_local (DImode, SLOT_FLOATxFDI_387);
6008 emit_insn (gen_floatdi<mode>2_i387_with_xmm (operands[0], operands[1], s));
6012 (define_insn_and_split "floatdi<X87MODEF:mode>2_i387_with_xmm"
6013 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
6015 (match_operand:DI 1 "register_operand" "r,r")))
6016 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
6017 (clobber (match_scratch:V4SI 3 "=x,x"))
6018 (clobber (match_scratch:V4SI 4 "=X,x"))]
6019 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
6020 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6021 && TARGET_SSE2 && optimize_function_for_speed_p (cfun)"
6023 "&& reload_completed"
6024 [(set (match_dup 2) (match_dup 3))
6025 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
6027 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
6028 Assemble the 64-bit DImode value in an xmm register. */
6029 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
6030 gen_lowpart (SImode, operands[1])));
6032 emit_insn (gen_sse4_1_pinsrd (operands[3], operands[3],
6033 gen_highpart (SImode, operands[1]),
6037 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
6038 gen_highpart (SImode, operands[1])));
6039 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
6042 operands[3] = gen_lowpart (DImode, operands[3]);
6044 [(set_attr "isa" "sse4,*")
6045 (set_attr "type" "multi")
6046 (set_attr "mode" "<X87MODEF:MODE>")
6047 (set_attr "unit" "i387")
6048 (set_attr "fp_int_src" "true")])
6050 ;; Break partial SSE register dependency stall. This splitter should split
6051 ;; late in the pass sequence (after register rename pass), so allocated
6052 ;; registers won't change anymore
6055 [(set (match_operand:MODEF 0 "sse_reg_operand")
6056 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
6058 && TARGET_SSE_PARTIAL_REG_CONVERTS_DEPENDENCY
6059 && epilogue_completed
6060 && optimize_function_for_speed_p (cfun)
6061 && (!EXT_REX_SSE_REG_P (operands[0])
6062 || TARGET_AVX512VL)"
6064 (vec_merge:<MODEF:ssevecmode>
6065 (vec_duplicate:<MODEF:ssevecmode>
6071 const machine_mode vmode = <MODEF:ssevecmode>mode;
6073 operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode);
6074 emit_move_insn (operands[0], CONST0_RTX (vmode));
6077 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
6078 [(set (match_operand:MODEF 0 "register_operand")
6079 (unsigned_float:MODEF
6080 (match_operand:SWI12 1 "nonimmediate_operand")))]
6082 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
6084 operands[1] = convert_to_mode (SImode, operands[1], 1);
6085 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
6089 (define_insn "*floatuns<SWI48:mode><MODEF:mode>2_avx512"
6090 [(set (match_operand:MODEF 0 "register_operand" "=v")
6091 (unsigned_float:MODEF
6092 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
6093 "TARGET_AVX512F && TARGET_SSE_MATH"
6094 "vcvtusi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %0, %0|%0, %0, %1}"
6095 [(set_attr "type" "sseicvt")
6096 (set_attr "avx_partial_xmm_update" "true")
6097 (set_attr "prefix" "evex")
6098 (set_attr "mode" "<MODEF:MODE>")])
6100 ;; Avoid store forwarding (partial memory) stall penalty by extending
6101 ;; SImode value to DImode through XMM register instead of pushing two
6102 ;; SImode values to stack. Also note that fild loads from memory only.
6104 (define_insn_and_split "floatunssi<mode>2_i387_with_xmm"
6105 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
6106 (unsigned_float:X87MODEF
6107 (match_operand:SI 1 "nonimmediate_operand" "rm")))
6108 (clobber (match_operand:DI 2 "memory_operand" "=m"))
6109 (clobber (match_scratch:DI 3 "=x"))]
6111 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6112 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
6114 "&& reload_completed"
6115 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
6116 (set (match_dup 2) (match_dup 3))
6118 (float:X87MODEF (match_dup 2)))]
6120 [(set_attr "type" "multi")
6121 (set_attr "mode" "<MODE>")])
6123 (define_expand "floatunssi<mode>2"
6124 [(set (match_operand:X87MODEF 0 "register_operand")
6125 (unsigned_float:X87MODEF
6126 (match_operand:SI 1 "nonimmediate_operand")))]
6128 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6129 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
6130 || ((!TARGET_64BIT || TARGET_AVX512F)
6131 && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
6133 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
6135 emit_insn (gen_floatunssi<mode>2_i387_with_xmm
6136 (operands[0], operands[1],
6137 assign_386_stack_local (DImode, SLOT_TEMP)));
6140 if (!TARGET_AVX512F)
6142 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
6147 (define_expand "floatunsdisf2"
6148 [(set (match_operand:SF 0 "register_operand")
6150 (match_operand:DI 1 "nonimmediate_operand")))]
6151 "TARGET_64BIT && TARGET_SSE && TARGET_SSE_MATH"
6153 if (!TARGET_AVX512F)
6155 x86_emit_floatuns (operands);
6160 (define_expand "floatunsdidf2"
6161 [(set (match_operand:DF 0 "register_operand")
6163 (match_operand:DI 1 "nonimmediate_operand")))]
6164 "((TARGET_64BIT && TARGET_AVX512F)
6165 || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
6166 && TARGET_SSE2 && TARGET_SSE_MATH"
6170 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
6173 if (!TARGET_AVX512F)
6175 x86_emit_floatuns (operands);
6180 ;; Load effective address instructions
6182 (define_insn "*lea<mode>"
6183 [(set (match_operand:SWI48 0 "register_operand" "=r")
6184 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
6185 "ix86_hardreg_mov_ok (operands[0], operands[1])"
6187 if (SImode_address_operand (operands[1], VOIDmode))
6189 gcc_assert (TARGET_64BIT);
6190 return "lea{l}\t{%E1, %k0|%k0, %E1}";
6193 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
6195 [(set_attr "type" "lea")
6198 (match_operand 1 "SImode_address_operand")
6200 (const_string "<MODE>")))])
6203 [(set (match_operand:SWI48 0 "register_operand")
6204 (match_operand:SWI48 1 "address_no_seg_operand"))]
6205 "ix86_hardreg_mov_ok (operands[0], operands[1])
6206 && peep2_regno_dead_p (0, FLAGS_REG)
6207 && ix86_avoid_lea_for_addr (peep2_next_insn (0), operands)"
6210 machine_mode mode = <MODE>mode;
6212 /* Emit all operations in SImode for zero-extended addresses. */
6213 if (SImode_address_operand (operands[1], VOIDmode))
6216 ix86_split_lea_for_addr (peep2_next_insn (0), operands, mode);
6218 /* Zero-extend return register to DImode for zero-extended addresses. */
6219 if (mode != <MODE>mode)
6220 emit_insn (gen_zero_extendsidi2 (operands[0],
6221 gen_lowpart (mode, operands[0])));
6226 ;; ix86_split_lea_for_addr emits the shifts as MULT to avoid it from being
6227 ;; peephole2 optimized back into a lea. Split that into the shift during
6228 ;; the following split pass.
6230 [(set (match_operand:SWI48 0 "general_reg_operand")
6231 (mult:SWI48 (match_dup 0) (match_operand:SWI48 1 "const1248_operand")))
6232 (clobber (reg:CC FLAGS_REG))]
6234 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
6235 (clobber (reg:CC FLAGS_REG))])]
6236 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
6240 (define_expand "add<mode>3"
6241 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6242 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6243 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
6245 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
6247 (define_insn_and_split "*add<dwi>3_doubleword"
6248 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
6250 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
6251 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
6252 (clobber (reg:CC FLAGS_REG))]
6253 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
6255 "&& reload_completed"
6256 [(parallel [(set (reg:CCC FLAGS_REG)
6258 (plus:DWIH (match_dup 1) (match_dup 2))
6261 (plus:DWIH (match_dup 1) (match_dup 2)))])
6262 (parallel [(set (match_dup 3)
6265 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6268 (clobber (reg:CC FLAGS_REG))])]
6270 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6271 if (operands[2] == const0_rtx)
6273 if (operands[5] != const0_rtx)
6274 ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]);
6275 else if (!rtx_equal_p (operands[3], operands[4]))
6276 emit_move_insn (operands[3], operands[4]);
6278 emit_note (NOTE_INSN_DELETED);
6283 (define_insn_and_split "*add<dwi>3_doubleword_zext"
6284 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6287 (match_operand:DWIH 2 "nonimmediate_operand" "rm,r"))
6288 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")))
6289 (clobber (reg:CC FLAGS_REG))]
6290 "ix86_binary_operator_ok (UNKNOWN, <DWI>mode, operands)"
6292 "&& reload_completed"
6293 [(parallel [(set (reg:CCC FLAGS_REG)
6295 (plus:DWIH (match_dup 1) (match_dup 2))
6298 (plus:DWIH (match_dup 1) (match_dup 2)))])
6299 (parallel [(set (match_dup 3)
6302 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6305 (clobber (reg:CC FLAGS_REG))])]
6306 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[3]);")
6308 (define_insn_and_split "*add<dwi>3_doubleword_concat"
6309 [(set (match_operand:<DWI> 0 "register_operand" "=&r")
6314 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))
6315 (match_operand:QI 3 "const_int_operand"))
6317 (match_operand:DWIH 4 "nonimmediate_operand" "rm")))
6318 (match_operand:<DWI> 1 "register_operand" "0")))
6319 (clobber (reg:CC FLAGS_REG))]
6320 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
6322 "&& reload_completed"
6323 [(parallel [(set (reg:CCC FLAGS_REG)
6325 (plus:DWIH (match_dup 1) (match_dup 4))
6328 (plus:DWIH (match_dup 1) (match_dup 4)))])
6329 (parallel [(set (match_dup 5)
6332 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6335 (clobber (reg:CC FLAGS_REG))])]
6336 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[5]);")
6338 (define_insn_and_split "*add<dwi>3_doubleword_concat_zext"
6339 [(set (match_operand:<DWI> 0 "register_operand" "=&r")
6344 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))
6345 (match_operand:QI 3 "const_int_operand"))
6347 (match_operand:DWIH 4 "nonimmediate_operand" "rm")))
6349 (match_operand:DWIH 1 "nonimmediate_operand" "rm"))))
6350 (clobber (reg:CC FLAGS_REG))]
6351 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
6353 "&& reload_completed"
6354 [(set (match_dup 0) (match_dup 4))
6355 (set (match_dup 5) (match_dup 2))
6356 (parallel [(set (reg:CCC FLAGS_REG)
6358 (plus:DWIH (match_dup 0) (match_dup 1))
6361 (plus:DWIH (match_dup 0) (match_dup 1)))])
6362 (parallel [(set (match_dup 5)
6365 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6368 (clobber (reg:CC FLAGS_REG))])]
6369 "split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[5]);")
6371 (define_insn "*add<mode>_1"
6372 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,r")
6374 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
6375 (match_operand:SWI48 2 "x86_64_general_operand" "re,BM,0,le")))
6376 (clobber (reg:CC FLAGS_REG))]
6377 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6379 switch (get_attr_type (insn))
6385 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6386 if (operands[2] == const1_rtx)
6387 return "inc{<imodesuffix>}\t%0";
6390 gcc_assert (operands[2] == constm1_rtx);
6391 return "dec{<imodesuffix>}\t%0";
6395 /* For most processors, ADD is faster than LEA. This alternative
6396 was added to use ADD as much as possible. */
6397 if (which_alternative == 2)
6398 std::swap (operands[1], operands[2]);
6400 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6401 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6402 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6404 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6408 (cond [(eq_attr "alternative" "3")
6409 (const_string "lea")
6410 (match_operand:SWI48 2 "incdec_operand")
6411 (const_string "incdec")
6413 (const_string "alu")))
6414 (set (attr "length_immediate")
6416 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6418 (const_string "*")))
6419 (set_attr "mode" "<MODE>")])
6421 ;; It may seem that nonimmediate operand is proper one for operand 1.
6422 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6423 ;; we take care in ix86_binary_operator_ok to not allow two memory
6424 ;; operands so proper swapping will be done in reload. This allow
6425 ;; patterns constructed from addsi_1 to match.
6427 (define_insn "addsi_1_zext"
6428 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6430 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
6431 (match_operand:SI 2 "x86_64_general_operand" "rBMe,0,le"))))
6432 (clobber (reg:CC FLAGS_REG))]
6433 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6435 switch (get_attr_type (insn))
6441 if (operands[2] == const1_rtx)
6442 return "inc{l}\t%k0";
6445 gcc_assert (operands[2] == constm1_rtx);
6446 return "dec{l}\t%k0";
6450 /* For most processors, ADD is faster than LEA. This alternative
6451 was added to use ADD as much as possible. */
6452 if (which_alternative == 1)
6453 std::swap (operands[1], operands[2]);
6455 if (x86_maybe_negate_const_int (&operands[2], SImode))
6456 return "sub{l}\t{%2, %k0|%k0, %2}";
6458 return "add{l}\t{%2, %k0|%k0, %2}";
6462 (cond [(eq_attr "alternative" "2")
6463 (const_string "lea")
6464 (match_operand:SI 2 "incdec_operand")
6465 (const_string "incdec")
6467 (const_string "alu")))
6468 (set (attr "length_immediate")
6470 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6472 (const_string "*")))
6473 (set_attr "mode" "SI")])
6475 (define_insn "*addhi_1"
6476 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
6477 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
6478 (match_operand:HI 2 "general_operand" "rn,m,0,ln")))
6479 (clobber (reg:CC FLAGS_REG))]
6480 "ix86_binary_operator_ok (PLUS, HImode, operands)"
6482 switch (get_attr_type (insn))
6488 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6489 if (operands[2] == const1_rtx)
6490 return "inc{w}\t%0";
6493 gcc_assert (operands[2] == constm1_rtx);
6494 return "dec{w}\t%0";
6498 /* For most processors, ADD is faster than LEA. This alternative
6499 was added to use ADD as much as possible. */
6500 if (which_alternative == 2)
6501 std::swap (operands[1], operands[2]);
6503 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6504 if (x86_maybe_negate_const_int (&operands[2], HImode))
6505 return "sub{w}\t{%2, %0|%0, %2}";
6507 return "add{w}\t{%2, %0|%0, %2}";
6511 (cond [(eq_attr "alternative" "3")
6512 (const_string "lea")
6513 (match_operand:HI 2 "incdec_operand")
6514 (const_string "incdec")
6516 (const_string "alu")))
6517 (set (attr "length_immediate")
6519 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6521 (const_string "*")))
6522 (set_attr "mode" "HI,HI,HI,SI")])
6524 (define_insn "*addqi_1"
6525 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
6526 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
6527 (match_operand:QI 2 "general_operand" "qn,m,0,rn,0,ln")))
6528 (clobber (reg:CC FLAGS_REG))]
6529 "ix86_binary_operator_ok (PLUS, QImode, operands)"
6531 bool widen = (get_attr_mode (insn) != MODE_QI);
6533 switch (get_attr_type (insn))
6539 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6540 if (operands[2] == const1_rtx)
6541 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6544 gcc_assert (operands[2] == constm1_rtx);
6545 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6549 /* For most processors, ADD is faster than LEA. These alternatives
6550 were added to use ADD as much as possible. */
6551 if (which_alternative == 2 || which_alternative == 4)
6552 std::swap (operands[1], operands[2]);
6554 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6555 if (x86_maybe_negate_const_int (&operands[2], QImode))
6558 return "sub{l}\t{%2, %k0|%k0, %2}";
6560 return "sub{b}\t{%2, %0|%0, %2}";
6563 return "add{l}\t{%k2, %k0|%k0, %k2}";
6565 return "add{b}\t{%2, %0|%0, %2}";
6569 (cond [(eq_attr "alternative" "5")
6570 (const_string "lea")
6571 (match_operand:QI 2 "incdec_operand")
6572 (const_string "incdec")
6574 (const_string "alu")))
6575 (set (attr "length_immediate")
6577 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6579 (const_string "*")))
6580 (set_attr "mode" "QI,QI,QI,SI,SI,SI")
6581 ;; Potential partial reg stall on alternatives 3 and 4.
6582 (set (attr "preferred_for_speed")
6583 (cond [(eq_attr "alternative" "3,4")
6584 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
6585 (symbol_ref "true")))])
6587 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
6588 (define_insn_and_split "*add<mode>_1_slp"
6589 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
6590 (plus:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0,!<r>")
6591 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
6592 (clobber (reg:CC FLAGS_REG))]
6593 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6595 if (which_alternative)
6598 switch (get_attr_type (insn))
6601 if (operands[2] == const1_rtx)
6602 return "inc{<imodesuffix>}\t%0";
6605 gcc_assert (operands[2] == constm1_rtx);
6606 return "dec{<imodesuffix>}\t%0";
6610 if (x86_maybe_negate_const_int (&operands[2], QImode))
6611 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6613 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6616 "&& reload_completed
6617 && !(rtx_equal_p (operands[0], operands[1])
6618 || rtx_equal_p (operands[0], operands[2]))"
6619 [(set (strict_low_part (match_dup 0)) (match_dup 1))
6621 [(set (strict_low_part (match_dup 0))
6622 (plus:SWI12 (match_dup 0) (match_dup 2)))
6623 (clobber (reg:CC FLAGS_REG))])]
6626 (if_then_else (match_operand:QI 2 "incdec_operand")
6627 (const_string "incdec")
6628 (const_string "alu")))
6629 (set_attr "mode" "<MODE>")])
6631 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
6632 (define_insn_and_split "*addqi_ext<mode>_1_slp"
6633 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+Q,&Q"))
6636 (match_operator:SWI248 3 "extract_operator"
6637 [(match_operand 2 "int248_register_operand" "Q,Q")
6640 (match_operand:QI 1 "nonimmediate_operand" "0,!qm")))
6641 (clobber (reg:CC FLAGS_REG))]
6642 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6644 add{b}\t{%h2, %0|%0, %h2}
6646 "&& reload_completed
6647 && !rtx_equal_p (operands[0], operands[1])"
6648 [(set (strict_low_part (match_dup 0)) (match_dup 1))
6650 [(set (strict_low_part (match_dup 0))
6654 [(match_dup 2) (const_int 8) (const_int 8)]) 0)
6656 (clobber (reg:CC FLAGS_REG))])]
6658 [(set_attr "type" "alu")
6659 (set_attr "mode" "QI")])
6661 (define_insn_and_split "*addqi_ext<mode>_2_slp"
6662 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+&Q"))
6665 (match_operator:SWI248 3 "extract_operator"
6666 [(match_operand 1 "int248_register_operand" "Q")
6670 (match_operator:SWI248 4 "extract_operator"
6671 [(match_operand 2 "int248_register_operand" "Q")
6673 (const_int 8)]) 0)))
6674 (clobber (reg:CC FLAGS_REG))]
6675 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6677 "&& reload_completed"
6678 [(set (strict_low_part (match_dup 0))
6681 [(match_dup 2) (const_int 8) (const_int 8)]) 0))
6683 [(set (strict_low_part (match_dup 0))
6687 [(match_dup 1) (const_int 8) (const_int 8)]) 0)
6689 (clobber (reg:CC FLAGS_REG))])]
6691 [(set_attr "type" "alu")
6692 (set_attr "mode" "QI")])
6694 ;; Split non destructive adds if we cannot use lea.
6696 [(set (match_operand:SWI48 0 "register_operand")
6697 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
6698 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
6699 (clobber (reg:CC FLAGS_REG))]
6700 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
6701 [(set (match_dup 0) (match_dup 1))
6702 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
6703 (clobber (reg:CC FLAGS_REG))])])
6705 ;; Split non destructive adds if we cannot use lea.
6707 [(set (match_operand:DI 0 "register_operand")
6709 (plus:SI (match_operand:SI 1 "register_operand")
6710 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
6711 (clobber (reg:CC FLAGS_REG))]
6713 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
6714 [(set (match_dup 3) (match_dup 1))
6715 (parallel [(set (match_dup 0)
6716 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
6717 (clobber (reg:CC FLAGS_REG))])]
6718 "operands[3] = gen_lowpart (SImode, operands[0]);")
6720 ;; Convert add to the lea pattern to avoid flags dependency.
6722 [(set (match_operand:SWI 0 "register_operand")
6723 (plus:SWI (match_operand:SWI 1 "register_operand")
6724 (match_operand:SWI 2 "<nonmemory_operand>")))
6725 (clobber (reg:CC FLAGS_REG))]
6726 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
6728 (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
6730 if (<MODE>mode != <LEAMODE>mode)
6732 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
6733 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
6734 operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
6738 ;; Convert add to the lea pattern to avoid flags dependency.
6740 [(set (match_operand:DI 0 "register_operand")
6742 (plus:SI (match_operand:SI 1 "register_operand")
6743 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
6744 (clobber (reg:CC FLAGS_REG))]
6745 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
6747 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
6749 (define_insn "*add<mode>_2"
6750 [(set (reg FLAGS_REG)
6753 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
6754 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,0"))
6756 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,<r>")
6757 (plus:SWI (match_dup 1) (match_dup 2)))]
6758 "ix86_match_ccmode (insn, CCGOCmode)
6759 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6761 switch (get_attr_type (insn))
6764 if (operands[2] == const1_rtx)
6765 return "inc{<imodesuffix>}\t%0";
6768 gcc_assert (operands[2] == constm1_rtx);
6769 return "dec{<imodesuffix>}\t%0";
6773 if (which_alternative == 2)
6774 std::swap (operands[1], operands[2]);
6776 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6777 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6778 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6780 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6784 (if_then_else (match_operand:SWI 2 "incdec_operand")
6785 (const_string "incdec")
6786 (const_string "alu")))
6787 (set (attr "length_immediate")
6789 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6791 (const_string "*")))
6792 (set_attr "mode" "<MODE>")])
6794 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6795 (define_insn "*addsi_2_zext"
6796 [(set (reg FLAGS_REG)
6798 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6799 (match_operand:SI 2 "x86_64_general_operand" "rBMe,0"))
6801 (set (match_operand:DI 0 "register_operand" "=r,r")
6802 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6803 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6804 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6806 switch (get_attr_type (insn))
6809 if (operands[2] == const1_rtx)
6810 return "inc{l}\t%k0";
6813 gcc_assert (operands[2] == constm1_rtx);
6814 return "dec{l}\t%k0";
6818 if (which_alternative == 1)
6819 std::swap (operands[1], operands[2]);
6821 if (x86_maybe_negate_const_int (&operands[2], SImode))
6822 return "sub{l}\t{%2, %k0|%k0, %2}";
6824 return "add{l}\t{%2, %k0|%k0, %2}";
6828 (if_then_else (match_operand:SI 2 "incdec_operand")
6829 (const_string "incdec")
6830 (const_string "alu")))
6831 (set (attr "length_immediate")
6833 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6835 (const_string "*")))
6836 (set_attr "mode" "SI")])
6838 (define_insn "*add<mode>_3"
6839 [(set (reg FLAGS_REG)
6841 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6842 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
6843 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6844 "ix86_match_ccmode (insn, CCZmode)
6845 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6847 switch (get_attr_type (insn))
6850 if (operands[2] == const1_rtx)
6851 return "inc{<imodesuffix>}\t%0";
6854 gcc_assert (operands[2] == constm1_rtx);
6855 return "dec{<imodesuffix>}\t%0";
6859 if (which_alternative == 1)
6860 std::swap (operands[1], operands[2]);
6862 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6863 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6864 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6866 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6870 (if_then_else (match_operand:SWI 2 "incdec_operand")
6871 (const_string "incdec")
6872 (const_string "alu")))
6873 (set (attr "length_immediate")
6875 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6877 (const_string "*")))
6878 (set_attr "mode" "<MODE>")])
6880 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6881 (define_insn "*addsi_3_zext"
6882 [(set (reg FLAGS_REG)
6884 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rBMe,0"))
6885 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
6886 (set (match_operand:DI 0 "register_operand" "=r,r")
6887 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6888 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6889 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6891 switch (get_attr_type (insn))
6894 if (operands[2] == const1_rtx)
6895 return "inc{l}\t%k0";
6898 gcc_assert (operands[2] == constm1_rtx);
6899 return "dec{l}\t%k0";
6903 if (which_alternative == 1)
6904 std::swap (operands[1], operands[2]);
6906 if (x86_maybe_negate_const_int (&operands[2], SImode))
6907 return "sub{l}\t{%2, %k0|%k0, %2}";
6909 return "add{l}\t{%2, %k0|%k0, %2}";
6913 (if_then_else (match_operand:SI 2 "incdec_operand")
6914 (const_string "incdec")
6915 (const_string "alu")))
6916 (set (attr "length_immediate")
6918 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6920 (const_string "*")))
6921 (set_attr "mode" "SI")])
6923 ; For comparisons against 1, -1 and 128, we may generate better code
6924 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6925 ; is matched then. We can't accept general immediate, because for
6926 ; case of overflows, the result is messed up.
6927 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6928 ; only for comparisons not depending on it.
6930 (define_insn "*adddi_4"
6931 [(set (reg FLAGS_REG)
6933 (match_operand:DI 1 "nonimmediate_operand" "0")
6934 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6935 (clobber (match_scratch:DI 0 "=r"))]
6937 && ix86_match_ccmode (insn, CCGCmode)"
6939 switch (get_attr_type (insn))
6942 if (operands[2] == constm1_rtx)
6943 return "inc{q}\t%0";
6946 gcc_assert (operands[2] == const1_rtx);
6947 return "dec{q}\t%0";
6951 if (x86_maybe_negate_const_int (&operands[2], DImode))
6952 return "add{q}\t{%2, %0|%0, %2}";
6954 return "sub{q}\t{%2, %0|%0, %2}";
6958 (if_then_else (match_operand:DI 2 "incdec_operand")
6959 (const_string "incdec")
6960 (const_string "alu")))
6961 (set (attr "length_immediate")
6963 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6965 (const_string "*")))
6966 (set_attr "mode" "DI")])
6968 ; For comparisons against 1, -1 and 128, we may generate better code
6969 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6970 ; is matched then. We can't accept general immediate, because for
6971 ; case of overflows, the result is messed up.
6972 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6973 ; only for comparisons not depending on it.
6975 (define_insn "*add<mode>_4"
6976 [(set (reg FLAGS_REG)
6978 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6979 (match_operand:SWI124 2 "const_int_operand")))
6980 (clobber (match_scratch:SWI124 0 "=<r>"))]
6981 "ix86_match_ccmode (insn, CCGCmode)"
6983 switch (get_attr_type (insn))
6986 if (operands[2] == constm1_rtx)
6987 return "inc{<imodesuffix>}\t%0";
6990 gcc_assert (operands[2] == const1_rtx);
6991 return "dec{<imodesuffix>}\t%0";
6995 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6996 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6998 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
7002 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
7003 (const_string "incdec")
7004 (const_string "alu")))
7005 (set (attr "length_immediate")
7007 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
7009 (const_string "*")))
7010 (set_attr "mode" "<MODE>")])
7012 (define_insn "*add<mode>_5"
7013 [(set (reg FLAGS_REG)
7016 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
7017 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
7019 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
7020 "ix86_match_ccmode (insn, CCGOCmode)
7021 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7023 switch (get_attr_type (insn))
7026 if (operands[2] == const1_rtx)
7027 return "inc{<imodesuffix>}\t%0";
7030 gcc_assert (operands[2] == constm1_rtx);
7031 return "dec{<imodesuffix>}\t%0";
7035 if (which_alternative == 1)
7036 std::swap (operands[1], operands[2]);
7038 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7039 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
7040 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
7042 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
7046 (if_then_else (match_operand:SWI 2 "incdec_operand")
7047 (const_string "incdec")
7048 (const_string "alu")))
7049 (set (attr "length_immediate")
7051 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
7053 (const_string "*")))
7054 (set_attr "mode" "<MODE>")])
7056 (define_insn "*addqi_ext<mode>_0"
7057 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn")
7060 (match_operator:SWI248 3 "extract_operator"
7061 [(match_operand 2 "int248_register_operand" "Q")
7064 (match_operand:QI 1 "nonimmediate_operand" "0")))
7065 (clobber (reg:CC FLAGS_REG))]
7067 "add{b}\t{%h2, %0|%0, %h2}"
7068 [(set_attr "addr" "gpr8")
7069 (set_attr "type" "alu")
7070 (set_attr "mode" "QI")])
7072 (define_expand "addqi_ext_1"
7074 [(set (zero_extract:HI (match_operand:HI 0 "register_operand")
7080 (zero_extract:HI (match_operand:HI 1 "register_operand")
7083 (match_operand:QI 2 "const_int_operand")) 0))
7084 (clobber (reg:CC FLAGS_REG))])])
7086 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
7087 (define_insn_and_split "*addqi_ext<mode>_1"
7088 [(set (zero_extract:SWI248
7089 (match_operand 0 "int248_register_operand" "+Q,&Q")
7095 (match_operator:SWI248 3 "extract_operator"
7096 [(match_operand 1 "int248_register_operand" "0,!Q")
7099 (match_operand:QI 2 "general_operand" "QnBn,QnBn")) 0))
7100 (clobber (reg:CC FLAGS_REG))]
7103 if (which_alternative)
7106 switch (get_attr_type (insn))
7109 if (operands[2] == const1_rtx)
7110 return "inc{b}\t%h0";
7113 gcc_assert (operands[2] == constm1_rtx);
7114 return "dec{b}\t%h0";
7118 return "add{b}\t{%2, %h0|%h0, %2}";
7122 && !rtx_equal_p (operands[0], operands[1])"
7123 [(set (zero_extract:SWI248
7124 (match_dup 0) (const_int 8) (const_int 8))
7125 (zero_extract:SWI248
7126 (match_dup 1) (const_int 8) (const_int 8)))
7128 [(set (zero_extract:SWI248
7129 (match_dup 0) (const_int 8) (const_int 8))
7134 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
7136 (clobber (reg:CC FLAGS_REG))])]
7138 [(set_attr "addr" "gpr8")
7140 (if_then_else (match_operand:QI 2 "incdec_operand")
7141 (const_string "incdec")
7142 (const_string "alu")))
7143 (set_attr "mode" "QI")])
7145 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
7146 (define_insn_and_split "*<insn>qi_ext<mode>_2"
7147 [(set (zero_extract:SWI248
7148 (match_operand 0 "int248_register_operand" "+Q,&Q")
7154 (match_operator:SWI248 3 "extract_operator"
7155 [(match_operand 1 "int248_register_operand" "<comm>0,!Q")
7159 (match_operator:SWI248 4 "extract_operator"
7160 [(match_operand 2 "int248_register_operand" "Q,Q")
7162 (const_int 8)]) 0)) 0))
7163 (clobber (reg:CC FLAGS_REG))]
7166 <insn>{b}\t{%h2, %h0|%h0, %h2}
7169 && !(rtx_equal_p (operands[0], operands[1])
7170 || (<CODE> == PLUS && rtx_equal_p (operands[0], operands[2])))"
7171 [(set (zero_extract:SWI248
7172 (match_dup 0) (const_int 8) (const_int 8))
7173 (zero_extract:SWI248
7174 (match_dup 1) (const_int 8) (const_int 8)))
7176 [(set (zero_extract:SWI248
7177 (match_dup 0) (const_int 8) (const_int 8))
7182 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
7185 [(match_dup 2) (const_int 8) (const_int 8)]) 0)) 0))
7186 (clobber (reg:CC FLAGS_REG))])]
7188 [(set_attr "type" "alu")
7189 (set_attr "mode" "QI")])
7191 ;; Like DWI, but use POImode instead of OImode.
7192 (define_mode_attr DPWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI") (TI "POI")])
7194 ;; Add with jump on overflow.
7195 (define_expand "addv<mode>4"
7196 [(parallel [(set (reg:CCO FLAGS_REG)
7200 (match_operand:SWIDWI 1 "nonimmediate_operand"))
7203 (plus:SWIDWI (match_dup 1)
7204 (match_operand:SWIDWI 2
7205 "<general_hilo_operand>")))))
7206 (set (match_operand:SWIDWI 0 "register_operand")
7207 (plus:SWIDWI (match_dup 1) (match_dup 2)))])
7208 (set (pc) (if_then_else
7209 (eq (reg:CCO FLAGS_REG) (const_int 0))
7210 (label_ref (match_operand 3))
7214 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
7215 if (CONST_SCALAR_INT_P (operands[2]))
7216 operands[4] = operands[2];
7218 operands[4] = gen_rtx_SIGN_EXTEND (<DPWI>mode, operands[2]);
7221 (define_insn "*addv<mode>4"
7222 [(set (reg:CCO FLAGS_REG)
7225 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
7227 (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m")))
7229 (plus:SWI (match_dup 1) (match_dup 2)))))
7230 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7231 (plus:SWI (match_dup 1) (match_dup 2)))]
7232 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7233 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7234 [(set_attr "type" "alu")
7235 (set_attr "mode" "<MODE>")])
7237 (define_insn "addv<mode>4_1"
7238 [(set (reg:CCO FLAGS_REG)
7241 (match_operand:SWI 1 "nonimmediate_operand" "0"))
7242 (match_operand:<DWI> 3 "const_int_operand"))
7246 (match_operand:SWI 2 "x86_64_immediate_operand" "<i>")))))
7247 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
7248 (plus:SWI (match_dup 1) (match_dup 2)))]
7249 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
7250 && CONST_INT_P (operands[2])
7251 && INTVAL (operands[2]) == INTVAL (operands[3])"
7252 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7253 [(set_attr "type" "alu")
7254 (set_attr "mode" "<MODE>")
7255 (set (attr "length_immediate")
7256 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7258 (match_test "<MODE_SIZE> == 8")
7260 (const_string "<MODE_SIZE>")))])
7262 ;; Quad word integer modes as mode attribute.
7263 (define_mode_attr QPWI [(SI "TI") (DI "POI")])
7265 (define_insn_and_split "*addv<dwi>4_doubleword"
7266 [(set (reg:CCO FLAGS_REG)
7270 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0"))
7272 (match_operand:<DWI> 2 "nonimmediate_operand" "r,o")))
7274 (plus:<DWI> (match_dup 1) (match_dup 2)))))
7275 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
7276 (plus:<DWI> (match_dup 1) (match_dup 2)))]
7277 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
7279 "&& reload_completed"
7280 [(parallel [(set (reg:CCC FLAGS_REG)
7282 (plus:DWIH (match_dup 1) (match_dup 2))
7285 (plus:DWIH (match_dup 1) (match_dup 2)))])
7286 (parallel [(set (reg:CCO FLAGS_REG)
7290 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7291 (sign_extend:<DWI> (match_dup 4)))
7292 (sign_extend:<DWI> (match_dup 5)))
7296 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7302 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7306 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7309 (define_insn_and_split "*addv<dwi>4_doubleword_1"
7310 [(set (reg:CCO FLAGS_REG)
7314 (match_operand:<DWI> 1 "nonimmediate_operand" "%0"))
7315 (match_operand:<QPWI> 3 "const_scalar_int_operand" "n"))
7319 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>")))))
7320 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
7321 (plus:<DWI> (match_dup 1) (match_dup 2)))]
7322 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)
7323 && CONST_SCALAR_INT_P (operands[2])
7324 && rtx_equal_p (operands[2], operands[3])"
7326 "&& reload_completed"
7327 [(parallel [(set (reg:CCC FLAGS_REG)
7329 (plus:DWIH (match_dup 1) (match_dup 2))
7332 (plus:DWIH (match_dup 1) (match_dup 2)))])
7333 (parallel [(set (reg:CCO FLAGS_REG)
7337 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7338 (sign_extend:<DWI> (match_dup 4)))
7343 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7349 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7353 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7354 if (operands[2] == const0_rtx)
7356 emit_insn (gen_addv<mode>4_1 (operands[3], operands[4], operands[5],
7362 (define_insn "*addv<mode>4_overflow_1"
7363 [(set (reg:CCO FLAGS_REG)
7367 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7368 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7370 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")))
7372 (match_operand:SWI 2 "<general_sext_operand>" "rWe,m")))
7376 (match_operator:SWI 5 "ix86_carry_flag_operator"
7377 [(match_dup 3) (const_int 0)])
7380 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r")
7383 (match_op_dup 5 [(match_dup 3) (const_int 0)])
7386 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7387 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
7388 [(set_attr "type" "alu")
7389 (set_attr "mode" "<MODE>")])
7391 (define_insn "*addv<mode>4_overflow_2"
7392 [(set (reg:CCO FLAGS_REG)
7396 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7397 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7399 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
7400 (match_operand:<DWI> 6 "const_int_operand" "n"))
7404 (match_operator:SWI 5 "ix86_carry_flag_operator"
7405 [(match_dup 3) (const_int 0)])
7407 (match_operand:SWI 2 "x86_64_immediate_operand" "e")))))
7408 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm")
7411 (match_op_dup 5 [(match_dup 3) (const_int 0)])
7414 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
7415 && CONST_INT_P (operands[2])
7416 && INTVAL (operands[2]) == INTVAL (operands[6])"
7417 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
7418 [(set_attr "type" "alu")
7419 (set_attr "mode" "<MODE>")
7420 (set (attr "length_immediate")
7421 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7423 (const_string "4")))])
7425 (define_expand "uaddv<mode>4"
7426 [(parallel [(set (reg:CCC FLAGS_REG)
7429 (match_operand:SWIDWI 1 "nonimmediate_operand")
7430 (match_operand:SWIDWI 2 "<general_hilo_operand>"))
7432 (set (match_operand:SWIDWI 0 "register_operand")
7433 (plus:SWIDWI (match_dup 1) (match_dup 2)))])
7434 (set (pc) (if_then_else
7435 (ltu (reg:CCC FLAGS_REG) (const_int 0))
7436 (label_ref (match_operand 3))
7439 "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
7441 ;; The lea patterns for modes less than 32 bits need to be matched by
7442 ;; several insns converted to real lea by splitters.
7444 (define_insn_and_split "*lea<mode>_general_1"
7445 [(set (match_operand:SWI12 0 "register_operand" "=r")
7447 (plus:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7448 (match_operand:SWI12 2 "register_operand" "r"))
7449 (match_operand:SWI12 3 "immediate_operand" "i")))]
7450 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7452 "&& reload_completed"
7455 (plus:SI (match_dup 1) (match_dup 2))
7458 operands[0] = gen_lowpart (SImode, operands[0]);
7459 operands[1] = gen_lowpart (SImode, operands[1]);
7460 operands[2] = gen_lowpart (SImode, operands[2]);
7461 operands[3] = gen_lowpart (SImode, operands[3]);
7463 [(set_attr "type" "lea")
7464 (set_attr "mode" "SI")])
7466 (define_insn_and_split "*lea<mode>_general_2"
7467 [(set (match_operand:SWI12 0 "register_operand" "=r")
7469 (mult:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7470 (match_operand 2 "const248_operand" "n"))
7471 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
7472 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7474 "&& reload_completed"
7477 (mult:SI (match_dup 1) (match_dup 2))
7480 operands[0] = gen_lowpart (SImode, operands[0]);
7481 operands[1] = gen_lowpart (SImode, operands[1]);
7482 operands[3] = gen_lowpart (SImode, operands[3]);
7484 [(set_attr "type" "lea")
7485 (set_attr "mode" "SI")])
7487 (define_insn_and_split "*lea<mode>_general_2b"
7488 [(set (match_operand:SWI12 0 "register_operand" "=r")
7490 (ashift:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7491 (match_operand 2 "const123_operand" "n"))
7492 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
7493 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7495 "&& reload_completed"
7498 (ashift:SI (match_dup 1) (match_dup 2))
7501 operands[0] = gen_lowpart (SImode, operands[0]);
7502 operands[1] = gen_lowpart (SImode, operands[1]);
7503 operands[3] = gen_lowpart (SImode, operands[3]);
7505 [(set_attr "type" "lea")
7506 (set_attr "mode" "SI")])
7508 (define_insn_and_split "*lea<mode>_general_3"
7509 [(set (match_operand:SWI12 0 "register_operand" "=r")
7512 (mult:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7513 (match_operand 2 "const248_operand" "n"))
7514 (match_operand:SWI12 3 "register_operand" "r"))
7515 (match_operand:SWI12 4 "immediate_operand" "i")))]
7516 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7518 "&& reload_completed"
7522 (mult:SI (match_dup 1) (match_dup 2))
7526 operands[0] = gen_lowpart (SImode, operands[0]);
7527 operands[1] = gen_lowpart (SImode, operands[1]);
7528 operands[3] = gen_lowpart (SImode, operands[3]);
7529 operands[4] = gen_lowpart (SImode, operands[4]);
7531 [(set_attr "type" "lea")
7532 (set_attr "mode" "SI")])
7534 (define_insn_and_split "*lea<mode>_general_3b"
7535 [(set (match_operand:SWI12 0 "register_operand" "=r")
7538 (ashift:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7539 (match_operand 2 "const123_operand" "n"))
7540 (match_operand:SWI12 3 "register_operand" "r"))
7541 (match_operand:SWI12 4 "immediate_operand" "i")))]
7542 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7544 "&& reload_completed"
7548 (ashift:SI (match_dup 1) (match_dup 2))
7552 operands[0] = gen_lowpart (SImode, operands[0]);
7553 operands[1] = gen_lowpart (SImode, operands[1]);
7554 operands[3] = gen_lowpart (SImode, operands[3]);
7555 operands[4] = gen_lowpart (SImode, operands[4]);
7557 [(set_attr "type" "lea")
7558 (set_attr "mode" "SI")])
7560 (define_insn_and_split "*lea<mode>_general_4"
7561 [(set (match_operand:SWI12 0 "register_operand" "=r")
7564 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7565 (match_operand 2 "const_0_to_3_operand"))
7566 (match_operand 3 "const_int_operand")))]
7567 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7568 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
7569 < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
7571 "&& reload_completed"
7574 (mult:SI (match_dup 1) (match_dup 2))
7577 operands[0] = gen_lowpart (SImode, operands[0]);
7578 operands[1] = gen_lowpart (SImode, operands[1]);
7579 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
7581 [(set_attr "type" "lea")
7582 (set_attr "mode" "SI")])
7584 (define_insn_and_split "*lea<mode>_general_4"
7585 [(set (match_operand:SWI48 0 "register_operand" "=r")
7588 (match_operand:SWI48 1 "register_no_SP_operand" "l")
7589 (match_operand 2 "const_0_to_3_operand"))
7590 (match_operand 3 "const_int_operand")))]
7591 "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
7592 < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
7594 "&& reload_completed"
7597 (mult:SWI48 (match_dup 1) (match_dup 2))
7599 "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
7600 [(set_attr "type" "lea")
7601 (set_attr "mode" "<MODE>")])
7603 ;; Subtract instructions
7605 (define_expand "sub<mode>3"
7606 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
7607 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
7608 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
7610 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
7612 (define_insn_and_split "*sub<dwi>3_doubleword"
7613 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
7615 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7616 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
7617 (clobber (reg:CC FLAGS_REG))]
7618 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7620 "&& reload_completed"
7621 [(parallel [(set (reg:CC FLAGS_REG)
7622 (compare:CC (match_dup 1) (match_dup 2)))
7624 (minus:DWIH (match_dup 1) (match_dup 2)))])
7625 (parallel [(set (match_dup 3)
7629 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7631 (clobber (reg:CC FLAGS_REG))])]
7633 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7634 if (operands[2] == const0_rtx)
7636 ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
7641 (define_insn_and_split "*sub<dwi>3_doubleword_zext"
7642 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
7644 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7646 (match_operand:DWIH 2 "nonimmediate_operand" "rm,r"))))
7647 (clobber (reg:CC FLAGS_REG))]
7648 "ix86_binary_operator_ok (UNKNOWN, <DWI>mode, operands)"
7650 "&& reload_completed"
7651 [(parallel [(set (reg:CC FLAGS_REG)
7652 (compare:CC (match_dup 1) (match_dup 2)))
7654 (minus:DWIH (match_dup 1) (match_dup 2)))])
7655 (parallel [(set (match_dup 3)
7659 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7661 (clobber (reg:CC FLAGS_REG))])]
7662 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[3]);")
7664 (define_insn "*sub<mode>_1"
7665 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7667 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7668 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
7669 (clobber (reg:CC FLAGS_REG))]
7670 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7671 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7672 [(set_attr "type" "alu")
7673 (set_attr "mode" "<MODE>")])
7675 (define_insn "*subsi_1_zext"
7676 [(set (match_operand:DI 0 "register_operand" "=r")
7678 (minus:SI (match_operand:SI 1 "register_operand" "0")
7679 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
7680 (clobber (reg:CC FLAGS_REG))]
7681 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7682 "sub{l}\t{%2, %k0|%k0, %2}"
7683 [(set_attr "type" "alu")
7684 (set_attr "mode" "SI")])
7686 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
7687 (define_insn_and_split "*sub<mode>_1_slp"
7688 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
7689 (minus:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
7690 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
7691 (clobber (reg:CC FLAGS_REG))]
7692 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7694 sub{<imodesuffix>}\t{%2, %0|%0, %2}
7696 "&& reload_completed
7697 && !(rtx_equal_p (operands[0], operands[1]))"
7698 [(set (strict_low_part (match_dup 0)) (match_dup 1))
7700 [(set (strict_low_part (match_dup 0))
7701 (minus:SWI12 (match_dup 0) (match_dup 2)))
7702 (clobber (reg:CC FLAGS_REG))])]
7704 [(set_attr "type" "alu")
7705 (set_attr "mode" "<MODE>")])
7707 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
7708 (define_insn_and_split "*subqi_ext<mode>_1_slp"
7709 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+Q,&Q"))
7711 (match_operand:QI 1 "nonimmediate_operand" "0,!qm")
7713 (match_operator:SWI248 3 "extract_operator"
7714 [(match_operand 2 "int248_register_operand" "Q,Q")
7716 (const_int 8)]) 0)))
7717 (clobber (reg:CC FLAGS_REG))]
7718 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7720 sub{b}\t{%h2, %0|%0, %h2}
7722 "&& reload_completed
7723 && !rtx_equal_p (operands[0], operands[1])"
7724 [(set (strict_low_part (match_dup 0)) (match_dup 1))
7726 [(set (strict_low_part (match_dup 0))
7731 [(match_dup 2) (const_int 8) (const_int 8)]) 0)))
7732 (clobber (reg:CC FLAGS_REG))])]
7734 [(set_attr "type" "alu")
7735 (set_attr "mode" "QI")])
7737 (define_insn_and_split "*subqi_ext<mode>_2_slp"
7738 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+&Q"))
7741 (match_operator:SWI248 3 "extract_operator"
7742 [(match_operand 1 "int248_register_operand" "Q")
7746 (match_operator:SWI248 4 "extract_operator"
7747 [(match_operand 2 "int248_register_operand" "Q")
7749 (const_int 8)]) 0)))
7750 (clobber (reg:CC FLAGS_REG))]
7751 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7753 "&& reload_completed"
7754 [(set (strict_low_part (match_dup 0))
7757 [(match_dup 1) (const_int 8) (const_int 8)]) 0))
7759 [(set (strict_low_part (match_dup 0))
7764 [(match_dup 2) (const_int 8) (const_int 8)]) 0)))
7765 (clobber (reg:CC FLAGS_REG))])]
7767 [(set_attr "type" "alu")
7768 (set_attr "mode" "QI")])
7770 (define_insn "*sub<mode>_2"
7771 [(set (reg FLAGS_REG)
7774 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7775 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
7777 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7778 (minus:SWI (match_dup 1) (match_dup 2)))]
7779 "ix86_match_ccmode (insn, CCGOCmode)
7780 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7781 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7782 [(set_attr "type" "alu")
7783 (set_attr "mode" "<MODE>")])
7785 (define_insn "*subsi_2_zext"
7786 [(set (reg FLAGS_REG)
7788 (minus:SI (match_operand:SI 1 "register_operand" "0")
7789 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
7791 (set (match_operand:DI 0 "register_operand" "=r")
7793 (minus:SI (match_dup 1)
7795 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7796 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7797 "sub{l}\t{%2, %k0|%k0, %2}"
7798 [(set_attr "type" "alu")
7799 (set_attr "mode" "SI")])
7801 (define_insn "*subqi_ext<mode>_0"
7802 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn")
7804 (match_operand:QI 1 "nonimmediate_operand" "0")
7806 (match_operator:SWI248 3 "extract_operator"
7807 [(match_operand 2 "int248_register_operand" "Q")
7809 (const_int 8)]) 0)))
7810 (clobber (reg:CC FLAGS_REG))]
7812 "sub{b}\t{%h2, %0|%0, %h2}"
7813 [(set_attr "addr" "gpr8")
7814 (set_attr "type" "alu")
7815 (set_attr "mode" "QI")])
7817 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
7818 (define_insn_and_split "*subqi_ext<mode>_1"
7819 [(set (zero_extract:SWI248
7820 (match_operand 0 "int248_register_operand" "+Q,&Q")
7826 (match_operator:SWI248 3 "extract_operator"
7827 [(match_operand 1 "int248_register_operand" "0,!Q")
7830 (match_operand:QI 2 "general_operand" "QnBn,QnBn")) 0))
7831 (clobber (reg:CC FLAGS_REG))]
7834 sub{b}\t{%2, %h0|%h0, %2}
7837 && !(rtx_equal_p (operands[0], operands[1]))"
7838 [(set (zero_extract:SWI248
7839 (match_dup 0) (const_int 8) (const_int 8))
7840 (zero_extract:SWI248
7841 (match_dup 1) (const_int 8) (const_int 8)))
7843 [(set (zero_extract:SWI248
7844 (match_dup 0) (const_int 8) (const_int 8))
7849 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
7851 (clobber (reg:CC FLAGS_REG))])]
7853 [(set_attr "addr" "gpr8")
7854 (set_attr "type" "alu")
7855 (set_attr "mode" "QI")])
7857 ;; Subtract with jump on overflow.
7858 (define_expand "subv<mode>4"
7859 [(parallel [(set (reg:CCO FLAGS_REG)
7863 (match_operand:SWIDWI 1 "nonimmediate_operand"))
7866 (minus:SWIDWI (match_dup 1)
7867 (match_operand:SWIDWI 2
7868 "<general_hilo_operand>")))))
7869 (set (match_operand:SWIDWI 0 "register_operand")
7870 (minus:SWIDWI (match_dup 1) (match_dup 2)))])
7871 (set (pc) (if_then_else
7872 (eq (reg:CCO FLAGS_REG) (const_int 0))
7873 (label_ref (match_operand 3))
7877 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
7878 if (CONST_SCALAR_INT_P (operands[2]))
7879 operands[4] = operands[2];
7881 operands[4] = gen_rtx_SIGN_EXTEND (<DPWI>mode, operands[2]);
7884 (define_insn "*subv<mode>4"
7885 [(set (reg:CCO FLAGS_REG)
7886 (eq:CCO (minus:<DWI>
7888 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
7890 (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m")))
7892 (minus:SWI (match_dup 1) (match_dup 2)))))
7893 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7894 (minus:SWI (match_dup 1) (match_dup 2)))]
7895 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7896 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7897 [(set_attr "type" "alu")
7898 (set_attr "mode" "<MODE>")])
7900 (define_insn "subv<mode>4_1"
7901 [(set (reg:CCO FLAGS_REG)
7902 (eq:CCO (minus:<DWI>
7904 (match_operand:SWI 1 "nonimmediate_operand" "0"))
7905 (match_operand:<DWI> 3 "const_int_operand"))
7909 (match_operand:SWI 2 "x86_64_immediate_operand" "<i>")))))
7910 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
7911 (minus:SWI (match_dup 1) (match_dup 2)))]
7912 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7913 && CONST_INT_P (operands[2])
7914 && INTVAL (operands[2]) == INTVAL (operands[3])"
7915 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7916 [(set_attr "type" "alu")
7917 (set_attr "mode" "<MODE>")
7918 (set (attr "length_immediate")
7919 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7921 (match_test "<MODE_SIZE> == 8")
7923 (const_string "<MODE_SIZE>")))])
7925 (define_insn_and_split "*subv<dwi>4_doubleword"
7926 [(set (reg:CCO FLAGS_REG)
7930 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0"))
7932 (match_operand:<DWI> 2 "nonimmediate_operand" "r,o")))
7934 (minus:<DWI> (match_dup 1) (match_dup 2)))))
7935 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
7936 (minus:<DWI> (match_dup 1) (match_dup 2)))]
7937 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7939 "&& reload_completed"
7940 [(parallel [(set (reg:CC FLAGS_REG)
7941 (compare:CC (match_dup 1) (match_dup 2)))
7943 (minus:DWIH (match_dup 1) (match_dup 2)))])
7944 (parallel [(set (reg:CCO FLAGS_REG)
7948 (sign_extend:<DWI> (match_dup 4))
7949 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))
7950 (sign_extend:<DWI> (match_dup 5)))
7955 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7961 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7964 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7967 (define_insn_and_split "*subv<dwi>4_doubleword_1"
7968 [(set (reg:CCO FLAGS_REG)
7972 (match_operand:<DWI> 1 "nonimmediate_operand" "0"))
7973 (match_operand:<QPWI> 3 "const_scalar_int_operand"))
7977 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>")))))
7978 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
7979 (minus:<DWI> (match_dup 1) (match_dup 2)))]
7980 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7981 && CONST_SCALAR_INT_P (operands[2])
7982 && rtx_equal_p (operands[2], operands[3])"
7984 "&& reload_completed"
7985 [(parallel [(set (reg:CC FLAGS_REG)
7986 (compare:CC (match_dup 1) (match_dup 2)))
7988 (minus:DWIH (match_dup 1) (match_dup 2)))])
7989 (parallel [(set (reg:CCO FLAGS_REG)
7993 (sign_extend:<DWI> (match_dup 4))
7994 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))
8000 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
8006 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
8009 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
8010 if (operands[2] == const0_rtx)
8012 emit_insn (gen_subv<mode>4_1 (operands[3], operands[4], operands[5],
8018 (define_insn "*subv<mode>4_overflow_1"
8019 [(set (reg:CCO FLAGS_REG)
8024 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
8025 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8026 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
8028 (match_operand:SWI 2 "<general_sext_operand>" "rWe,m")))
8033 (match_operator:SWI 5 "ix86_carry_flag_operator"
8034 [(match_dup 3) (const_int 0)]))
8036 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r")
8040 (match_op_dup 5 [(match_dup 3) (const_int 0)]))
8042 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
8043 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8044 [(set_attr "type" "alu")
8045 (set_attr "mode" "<MODE>")])
8047 (define_insn "*subv<mode>4_overflow_2"
8048 [(set (reg:CCO FLAGS_REG)
8053 (match_operand:SWI 1 "nonimmediate_operand" "%0"))
8054 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8055 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
8056 (match_operand:<DWI> 6 "const_int_operand" "n"))
8061 (match_operator:SWI 5 "ix86_carry_flag_operator"
8062 [(match_dup 3) (const_int 0)]))
8063 (match_operand:SWI 2 "x86_64_immediate_operand" "e")))))
8064 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm")
8068 (match_op_dup 5 [(match_dup 3) (const_int 0)]))
8070 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
8071 && CONST_INT_P (operands[2])
8072 && INTVAL (operands[2]) == INTVAL (operands[6])"
8073 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8074 [(set_attr "type" "alu")
8075 (set_attr "mode" "<MODE>")
8076 (set (attr "length_immediate")
8077 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
8079 (const_string "4")))])
8081 (define_expand "usubv<mode>4"
8082 [(parallel [(set (reg:CC FLAGS_REG)
8084 (match_operand:SWI 1 "nonimmediate_operand")
8085 (match_operand:SWI 2 "<general_operand>")))
8086 (set (match_operand:SWI 0 "register_operand")
8087 (minus:SWI (match_dup 1) (match_dup 2)))])
8088 (set (pc) (if_then_else
8089 (ltu (reg:CC FLAGS_REG) (const_int 0))
8090 (label_ref (match_operand 3))
8093 "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
8095 (define_insn "*sub<mode>_3"
8096 [(set (reg FLAGS_REG)
8097 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
8098 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
8099 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
8100 (minus:SWI (match_dup 1) (match_dup 2)))]
8101 "ix86_match_ccmode (insn, CCmode)
8102 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
8103 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
8104 [(set_attr "type" "alu")
8105 (set_attr "mode" "<MODE>")])
8109 [(set (reg:CC FLAGS_REG)
8110 (compare:CC (match_operand:SWI 0 "general_reg_operand")
8111 (match_operand:SWI 1 "general_gr_operand")))
8113 (minus:SWI (match_dup 0) (match_dup 1)))])]
8114 "find_regno_note (peep2_next_insn (0), REG_UNUSED, REGNO (operands[0])) != 0"
8115 [(set (reg:CC FLAGS_REG)
8116 (compare:CC (match_dup 0) (match_dup 1)))])
8119 [(set (match_operand:SWI 0 "general_reg_operand")
8120 (match_operand:SWI 1 "memory_operand"))
8121 (parallel [(set (reg:CC FLAGS_REG)
8122 (compare:CC (match_dup 0)
8123 (match_operand:SWI 2 "memory_operand")))
8125 (minus:SWI (match_dup 0) (match_dup 2)))])
8126 (set (match_dup 1) (match_dup 0))]
8127 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8128 && peep2_reg_dead_p (3, operands[0])
8129 && !reg_overlap_mentioned_p (operands[0], operands[1])
8130 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8131 [(set (match_dup 0) (match_dup 2))
8132 (parallel [(set (reg:CC FLAGS_REG)
8133 (compare:CC (match_dup 1) (match_dup 0)))
8135 (minus:SWI (match_dup 1) (match_dup 0)))])])
8137 ;; decl %eax; cmpl $-1, %eax; jne .Lxx; can be optimized into
8138 ;; subl $1, %eax; jnc .Lxx;
8141 [(set (match_operand:SWI 0 "general_reg_operand")
8142 (plus:SWI (match_dup 0) (const_int -1)))
8143 (clobber (reg FLAGS_REG))])
8144 (set (reg:CCZ FLAGS_REG)
8145 (compare:CCZ (match_dup 0) (const_int -1)))
8147 (if_then_else (match_operator 1 "bt_comparison_operator"
8148 [(reg:CCZ FLAGS_REG) (const_int 0)])
8151 "peep2_regno_dead_p (3, FLAGS_REG)"
8153 [(set (reg:CC FLAGS_REG)
8154 (compare:CC (match_dup 0) (const_int 1)))
8156 (minus:SWI (match_dup 0) (const_int 1)))])
8158 (if_then_else (match_dup 3)
8162 rtx cc = gen_rtx_REG (CCmode, FLAGS_REG);
8163 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE
8164 ? GEU : LTU, VOIDmode, cc, const0_rtx);
8167 ;; Help combine use borrow flag to test for -1 after dec (add $-1).
8168 (define_insn_and_split "*dec_cmov<mode>"
8169 [(set (match_operand:SWI248 0 "register_operand" "=r")
8170 (if_then_else:SWI248
8171 (match_operator 1 "bt_comparison_operator"
8172 [(match_operand:SWI248 2 "register_operand" "0") (const_int 0)])
8173 (plus:SWI248 (match_dup 2) (const_int -1))
8174 (match_operand:SWI248 3 "nonimmediate_operand" "rm")))
8175 (clobber (reg:CC FLAGS_REG))]
8178 "&& reload_completed"
8179 [(parallel [(set (reg:CC FLAGS_REG)
8180 (compare:CC (match_dup 2) (const_int 1)))
8181 (set (match_dup 0) (minus:SWI248 (match_dup 2) (const_int 1)))])
8183 (if_then_else:SWI248 (match_dup 4) (match_dup 0) (match_dup 3)))]
8185 rtx cc = gen_rtx_REG (CCCmode, FLAGS_REG);
8186 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE
8187 ? GEU : LTU, VOIDmode, cc, const0_rtx);
8190 (define_insn "*subsi_3_zext"
8191 [(set (reg FLAGS_REG)
8192 (compare (match_operand:SI 1 "register_operand" "0")
8193 (match_operand:SI 2 "x86_64_general_operand" "rBMe")))
8194 (set (match_operand:DI 0 "register_operand" "=r")
8196 (minus:SI (match_dup 1)
8198 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
8199 && ix86_binary_operator_ok (MINUS, SImode, operands)"
8200 "sub{l}\t{%2, %1|%1, %2}"
8201 [(set_attr "type" "alu")
8202 (set_attr "mode" "SI")])
8204 ;; Add with carry and subtract with borrow
8206 (define_insn "@add<mode>3_carry"
8207 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
8210 (match_operator:SWI 4 "ix86_carry_flag_operator"
8211 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8212 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
8213 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
8214 (clobber (reg:CC FLAGS_REG))]
8215 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
8216 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
8217 [(set_attr "type" "alu")
8218 (set_attr "use_carry" "1")
8219 (set_attr "pent_pair" "pu")
8220 (set_attr "mode" "<MODE>")])
8223 [(set (match_operand:SWI 0 "general_reg_operand")
8224 (match_operand:SWI 1 "memory_operand"))
8225 (parallel [(set (match_dup 0)
8228 (match_operator:SWI 4 "ix86_carry_flag_operator"
8229 [(match_operand 3 "flags_reg_operand")
8232 (match_operand:SWI 2 "memory_operand")))
8233 (clobber (reg:CC FLAGS_REG))])
8234 (set (match_dup 1) (match_dup 0))]
8235 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8236 && peep2_reg_dead_p (3, operands[0])
8237 && !reg_overlap_mentioned_p (operands[0], operands[1])
8238 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8239 [(set (match_dup 0) (match_dup 2))
8240 (parallel [(set (match_dup 1)
8241 (plus:SWI (plus:SWI (match_op_dup 4
8242 [(match_dup 3) (const_int 0)])
8245 (clobber (reg:CC FLAGS_REG))])])
8248 [(set (match_operand:SWI 0 "general_reg_operand")
8249 (match_operand:SWI 1 "memory_operand"))
8250 (parallel [(set (match_dup 0)
8253 (match_operator:SWI 4 "ix86_carry_flag_operator"
8254 [(match_operand 3 "flags_reg_operand")
8257 (match_operand:SWI 2 "memory_operand")))
8258 (clobber (reg:CC FLAGS_REG))])
8259 (set (match_operand:SWI 5 "general_reg_operand") (match_dup 0))
8260 (set (match_dup 1) (match_dup 5))]
8261 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8262 && peep2_reg_dead_p (3, operands[0])
8263 && peep2_reg_dead_p (4, operands[5])
8264 && !reg_overlap_mentioned_p (operands[0], operands[1])
8265 && !reg_overlap_mentioned_p (operands[0], operands[2])
8266 && !reg_overlap_mentioned_p (operands[5], operands[1])"
8267 [(set (match_dup 0) (match_dup 2))
8268 (parallel [(set (match_dup 1)
8269 (plus:SWI (plus:SWI (match_op_dup 4
8270 [(match_dup 3) (const_int 0)])
8273 (clobber (reg:CC FLAGS_REG))])])
8275 (define_insn "*add<mode>3_carry_0"
8276 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8278 (match_operator:SWI 2 "ix86_carry_flag_operator"
8279 [(reg FLAGS_REG) (const_int 0)])
8280 (match_operand:SWI 1 "nonimmediate_operand" "0")))
8281 (clobber (reg:CC FLAGS_REG))]
8282 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8283 "adc{<imodesuffix>}\t{$0, %0|%0, 0}"
8284 [(set_attr "type" "alu")
8285 (set_attr "use_carry" "1")
8286 (set_attr "pent_pair" "pu")
8287 (set_attr "mode" "<MODE>")])
8289 (define_insn "*add<mode>3_carry_0r"
8290 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8292 (match_operator:SWI 2 "ix86_carry_flag_unset_operator"
8293 [(reg FLAGS_REG) (const_int 0)])
8294 (match_operand:SWI 1 "nonimmediate_operand" "0")))
8295 (clobber (reg:CC FLAGS_REG))]
8296 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8297 "sbb{<imodesuffix>}\t{$-1, %0|%0, -1}"
8298 [(set_attr "type" "alu")
8299 (set_attr "use_carry" "1")
8300 (set_attr "pent_pair" "pu")
8301 (set_attr "mode" "<MODE>")])
8303 (define_insn "*addsi3_carry_zext"
8304 [(set (match_operand:DI 0 "register_operand" "=r")
8307 (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
8308 [(reg FLAGS_REG) (const_int 0)])
8309 (match_operand:SI 1 "register_operand" "%0"))
8310 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
8311 (clobber (reg:CC FLAGS_REG))]
8312 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
8313 "adc{l}\t{%2, %k0|%k0, %2}"
8314 [(set_attr "type" "alu")
8315 (set_attr "use_carry" "1")
8316 (set_attr "pent_pair" "pu")
8317 (set_attr "mode" "SI")])
8319 (define_insn "*addsi3_carry_zext_0"
8320 [(set (match_operand:DI 0 "register_operand" "=r")
8322 (plus:SI (match_operator:SI 2 "ix86_carry_flag_operator"
8323 [(reg FLAGS_REG) (const_int 0)])
8324 (match_operand:SI 1 "register_operand" "0"))))
8325 (clobber (reg:CC FLAGS_REG))]
8327 "adc{l}\t{$0, %k0|%k0, 0}"
8328 [(set_attr "type" "alu")
8329 (set_attr "use_carry" "1")
8330 (set_attr "pent_pair" "pu")
8331 (set_attr "mode" "SI")])
8333 (define_insn "*addsi3_carry_zext_0r"
8334 [(set (match_operand:DI 0 "register_operand" "=r")
8336 (plus:SI (match_operator:SI 2 "ix86_carry_flag_unset_operator"
8337 [(reg FLAGS_REG) (const_int 0)])
8338 (match_operand:SI 1 "register_operand" "0"))))
8339 (clobber (reg:CC FLAGS_REG))]
8341 "sbb{l}\t{$-1, %k0|%k0, -1}"
8342 [(set_attr "type" "alu")
8343 (set_attr "use_carry" "1")
8344 (set_attr "pent_pair" "pu")
8345 (set_attr "mode" "SI")])
8347 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
8349 (define_insn "addcarry<mode>"
8350 [(set (reg:CCC FLAGS_REG)
8355 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8356 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8357 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0"))
8358 (match_operand:SWI48 2 "nonimmediate_operand" "r,rm")))
8360 (zero_extend:<DWI> (match_dup 2))
8361 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8362 [(match_dup 3) (const_int 0)]))))
8363 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
8364 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8365 [(match_dup 3) (const_int 0)])
8368 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
8369 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
8370 [(set_attr "type" "alu")
8371 (set_attr "use_carry" "1")
8372 (set_attr "pent_pair" "pu")
8373 (set_attr "mode" "<MODE>")])
8376 [(parallel [(set (reg:CCC FLAGS_REG)
8381 (match_operator:SWI48 4 "ix86_carry_flag_operator"
8382 [(match_operand 2 "flags_reg_operand")
8384 (match_operand:SWI48 0 "general_reg_operand"))
8385 (match_operand:SWI48 1 "memory_operand")))
8387 (zero_extend:<DWI> (match_dup 1))
8388 (match_operator:<DWI> 3 "ix86_carry_flag_operator"
8389 [(match_dup 2) (const_int 0)]))))
8391 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8392 [(match_dup 2) (const_int 0)])
8395 (set (match_dup 1) (match_dup 0))]
8396 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8397 && peep2_reg_dead_p (2, operands[0])
8398 && !reg_overlap_mentioned_p (operands[0], operands[1])"
8399 [(parallel [(set (reg:CCC FLAGS_REG)
8405 [(match_dup 2) (const_int 0)])
8409 (zero_extend:<DWI> (match_dup 0))
8411 [(match_dup 2) (const_int 0)]))))
8413 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8414 [(match_dup 2) (const_int 0)])
8419 [(set (match_operand:SWI48 0 "general_reg_operand")
8420 (match_operand:SWI48 1 "memory_operand"))
8421 (parallel [(set (reg:CCC FLAGS_REG)
8426 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8427 [(match_operand 3 "flags_reg_operand")
8430 (match_operand:SWI48 2 "memory_operand")))
8432 (zero_extend:<DWI> (match_dup 2))
8433 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8434 [(match_dup 3) (const_int 0)]))))
8436 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8437 [(match_dup 3) (const_int 0)])
8440 (set (match_dup 1) (match_dup 0))]
8441 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8442 && peep2_reg_dead_p (3, operands[0])
8443 && !reg_overlap_mentioned_p (operands[0], operands[1])
8444 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8445 [(set (match_dup 0) (match_dup 2))
8446 (parallel [(set (reg:CCC FLAGS_REG)
8452 [(match_dup 3) (const_int 0)])
8456 (zero_extend:<DWI> (match_dup 0))
8458 [(match_dup 3) (const_int 0)]))))
8460 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8461 [(match_dup 3) (const_int 0)])
8466 [(parallel [(set (reg:CCC FLAGS_REG)
8471 (match_operator:SWI48 4 "ix86_carry_flag_operator"
8472 [(match_operand 2 "flags_reg_operand")
8474 (match_operand:SWI48 0 "general_reg_operand"))
8475 (match_operand:SWI48 1 "memory_operand")))
8477 (zero_extend:<DWI> (match_dup 1))
8478 (match_operator:<DWI> 3 "ix86_carry_flag_operator"
8479 [(match_dup 2) (const_int 0)]))))
8481 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8482 [(match_dup 2) (const_int 0)])
8485 (set (match_operand:QI 5 "general_reg_operand")
8486 (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8487 (set (match_operand:SWI48 6 "general_reg_operand")
8488 (zero_extend:SWI48 (match_dup 5)))
8489 (set (match_dup 1) (match_dup 0))]
8490 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8491 && peep2_reg_dead_p (4, operands[0])
8492 && !reg_overlap_mentioned_p (operands[0], operands[1])
8493 && !reg_overlap_mentioned_p (operands[0], operands[5])
8494 && !reg_overlap_mentioned_p (operands[5], operands[1])
8495 && !reg_overlap_mentioned_p (operands[0], operands[6])
8496 && !reg_overlap_mentioned_p (operands[6], operands[1])"
8497 [(parallel [(set (reg:CCC FLAGS_REG)
8503 [(match_dup 2) (const_int 0)])
8507 (zero_extend:<DWI> (match_dup 0))
8509 [(match_dup 2) (const_int 0)]))))
8511 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8512 [(match_dup 2) (const_int 0)])
8515 (set (match_dup 5) (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8516 (set (match_dup 6) (zero_extend:SWI48 (match_dup 5)))])
8518 (define_expand "addcarry<mode>_0"
8520 [(set (reg:CCC FLAGS_REG)
8523 (match_operand:SWI48 1 "nonimmediate_operand")
8524 (match_operand:SWI48 2 "x86_64_general_operand"))
8526 (set (match_operand:SWI48 0 "nonimmediate_operand")
8527 (plus:SWI48 (match_dup 1) (match_dup 2)))])]
8528 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)")
8530 (define_insn "*addcarry<mode>_1"
8531 [(set (reg:CCC FLAGS_REG)
8536 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8537 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8538 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
8539 (match_operand:SWI48 2 "x86_64_immediate_operand" "e")))
8541 (match_operand:<DWI> 6 "const_scalar_int_operand")
8542 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8543 [(match_dup 3) (const_int 0)]))))
8544 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
8545 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8546 [(match_dup 3) (const_int 0)])
8549 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
8550 && CONST_INT_P (operands[2])
8551 /* Check that operands[6] is operands[2] zero extended from
8552 <MODE>mode to <DWI>mode. */
8553 && ((<MODE>mode == SImode || INTVAL (operands[2]) >= 0)
8554 ? (CONST_INT_P (operands[6])
8555 && UINTVAL (operands[6]) == (UINTVAL (operands[2])
8556 & GET_MODE_MASK (<MODE>mode)))
8557 : (CONST_WIDE_INT_P (operands[6])
8558 && CONST_WIDE_INT_NUNITS (operands[6]) == 2
8559 && ((unsigned HOST_WIDE_INT) CONST_WIDE_INT_ELT (operands[6], 0)
8560 == UINTVAL (operands[2]))
8561 && CONST_WIDE_INT_ELT (operands[6], 1) == 0))"
8562 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
8563 [(set_attr "type" "alu")
8564 (set_attr "use_carry" "1")
8565 (set_attr "pent_pair" "pu")
8566 (set_attr "mode" "<MODE>")
8567 (set (attr "length_immediate")
8568 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
8570 (const_string "4")))])
8572 (define_insn "@sub<mode>3_carry"
8573 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
8576 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
8577 (match_operator:SWI 4 "ix86_carry_flag_operator"
8578 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
8579 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
8580 (clobber (reg:CC FLAGS_REG))]
8581 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
8582 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8583 [(set_attr "type" "alu")
8584 (set_attr "use_carry" "1")
8585 (set_attr "pent_pair" "pu")
8586 (set_attr "mode" "<MODE>")])
8589 [(set (match_operand:SWI 0 "general_reg_operand")
8590 (match_operand:SWI 1 "memory_operand"))
8591 (parallel [(set (match_dup 0)
8595 (match_operator:SWI 4 "ix86_carry_flag_operator"
8596 [(match_operand 3 "flags_reg_operand")
8598 (match_operand:SWI 2 "memory_operand")))
8599 (clobber (reg:CC FLAGS_REG))])
8600 (set (match_dup 1) (match_dup 0))]
8601 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8602 && peep2_reg_dead_p (3, operands[0])
8603 && !reg_overlap_mentioned_p (operands[0], operands[1])
8604 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8605 [(set (match_dup 0) (match_dup 2))
8606 (parallel [(set (match_dup 1)
8607 (minus:SWI (minus:SWI (match_dup 1)
8609 [(match_dup 3) (const_int 0)]))
8611 (clobber (reg:CC FLAGS_REG))])])
8614 [(set (match_operand:SWI 0 "general_reg_operand")
8615 (match_operand:SWI 1 "memory_operand"))
8616 (parallel [(set (match_dup 0)
8620 (match_operator:SWI 4 "ix86_carry_flag_operator"
8621 [(match_operand 3 "flags_reg_operand")
8623 (match_operand:SWI 2 "memory_operand")))
8624 (clobber (reg:CC FLAGS_REG))])
8625 (set (match_operand:SWI 5 "general_reg_operand") (match_dup 0))
8626 (set (match_dup 1) (match_dup 5))]
8627 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8628 && peep2_reg_dead_p (3, operands[0])
8629 && peep2_reg_dead_p (4, operands[5])
8630 && !reg_overlap_mentioned_p (operands[0], operands[1])
8631 && !reg_overlap_mentioned_p (operands[0], operands[2])
8632 && !reg_overlap_mentioned_p (operands[5], operands[1])"
8633 [(set (match_dup 0) (match_dup 2))
8634 (parallel [(set (match_dup 1)
8635 (minus:SWI (minus:SWI (match_dup 1)
8637 [(match_dup 3) (const_int 0)]))
8639 (clobber (reg:CC FLAGS_REG))])])
8641 (define_insn "*sub<mode>3_carry_0"
8642 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8644 (match_operand:SWI 1 "nonimmediate_operand" "0")
8645 (match_operator:SWI 2 "ix86_carry_flag_operator"
8646 [(reg FLAGS_REG) (const_int 0)])))
8647 (clobber (reg:CC FLAGS_REG))]
8648 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8649 "sbb{<imodesuffix>}\t{$0, %0|%0, 0}"
8650 [(set_attr "type" "alu")
8651 (set_attr "use_carry" "1")
8652 (set_attr "pent_pair" "pu")
8653 (set_attr "mode" "<MODE>")])
8655 (define_insn "*sub<mode>3_carry_0r"
8656 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8658 (match_operand:SWI 1 "nonimmediate_operand" "0")
8659 (match_operator:SWI 2 "ix86_carry_flag_unset_operator"
8660 [(reg FLAGS_REG) (const_int 0)])))
8661 (clobber (reg:CC FLAGS_REG))]
8662 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8663 "adc{<imodesuffix>}\t{$-1, %0|%0, -1}"
8664 [(set_attr "type" "alu")
8665 (set_attr "use_carry" "1")
8666 (set_attr "pent_pair" "pu")
8667 (set_attr "mode" "<MODE>")])
8669 (define_insn "*subsi3_carry_zext"
8670 [(set (match_operand:DI 0 "register_operand" "=r")
8674 (match_operand:SI 1 "register_operand" "0")
8675 (match_operator:SI 3 "ix86_carry_flag_operator"
8676 [(reg FLAGS_REG) (const_int 0)]))
8677 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
8678 (clobber (reg:CC FLAGS_REG))]
8679 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
8680 "sbb{l}\t{%2, %k0|%k0, %2}"
8681 [(set_attr "type" "alu")
8682 (set_attr "use_carry" "1")
8683 (set_attr "pent_pair" "pu")
8684 (set_attr "mode" "SI")])
8686 (define_insn "*subsi3_carry_zext_0"
8687 [(set (match_operand:DI 0 "register_operand" "=r")
8690 (match_operand:SI 1 "register_operand" "0")
8691 (match_operator:SI 2 "ix86_carry_flag_operator"
8692 [(reg FLAGS_REG) (const_int 0)]))))
8693 (clobber (reg:CC FLAGS_REG))]
8695 "sbb{l}\t{$0, %k0|%k0, 0}"
8696 [(set_attr "type" "alu")
8697 (set_attr "use_carry" "1")
8698 (set_attr "pent_pair" "pu")
8699 (set_attr "mode" "SI")])
8701 (define_insn "*subsi3_carry_zext_0r"
8702 [(set (match_operand:DI 0 "register_operand" "=r")
8705 (match_operand:SI 1 "register_operand" "0")
8706 (match_operator:SI 2 "ix86_carry_flag_unset_operator"
8707 [(reg FLAGS_REG) (const_int 0)]))))
8708 (clobber (reg:CC FLAGS_REG))]
8710 "adc{l}\t{$-1, %k0|%k0, -1}"
8711 [(set_attr "type" "alu")
8712 (set_attr "use_carry" "1")
8713 (set_attr "pent_pair" "pu")
8714 (set_attr "mode" "SI")])
8716 (define_insn "@sub<mode>3_carry_ccc"
8717 [(set (reg:CCC FLAGS_REG)
8719 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
8721 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
8723 (match_operand:DWIH 2 "x86_64_sext_operand" "rmWe")))))
8724 (clobber (match_scratch:DWIH 0 "=r"))]
8726 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8727 [(set_attr "type" "alu")
8728 (set_attr "mode" "<MODE>")])
8730 (define_insn "*sub<mode>3_carry_ccc_1"
8731 [(set (reg:CCC FLAGS_REG)
8733 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
8735 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
8736 (match_operand:<DWI> 2 "x86_64_dwzext_immediate_operand" "Wf"))))
8737 (clobber (match_scratch:DWIH 0 "=r"))]
8740 operands[3] = simplify_subreg (<MODE>mode, operands[2], <DWI>mode, 0);
8741 return "sbb{<imodesuffix>}\t{%3, %0|%0, %3}";
8743 [(set_attr "type" "alu")
8744 (set_attr "mode" "<MODE>")])
8746 ;; The sign flag is set from the
8747 ;; (compare (match_dup 1) (plus:DWIH (ltu:DWIH ...) (match_dup 2)))
8748 ;; result, the overflow flag likewise, but the overflow flag is also
8749 ;; set if the (plus:DWIH (ltu:DWIH ...) (match_dup 2)) overflows.
8750 (define_insn "@sub<mode>3_carry_ccgz"
8751 [(set (reg:CCGZ FLAGS_REG)
8752 (unspec:CCGZ [(match_operand:DWIH 1 "register_operand" "0")
8753 (match_operand:DWIH 2 "x86_64_general_operand" "rBMe")
8754 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))]
8756 (clobber (match_scratch:DWIH 0 "=r"))]
8758 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8759 [(set_attr "type" "alu")
8760 (set_attr "mode" "<MODE>")])
8762 (define_insn "subborrow<mode>"
8763 [(set (reg:CCC FLAGS_REG)
8766 (match_operand:SWI48 1 "nonimmediate_operand" "0,0"))
8768 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8769 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8771 (match_operand:SWI48 2 "nonimmediate_operand" "r,rm")))))
8772 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
8773 (minus:SWI48 (minus:SWI48
8775 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8776 [(match_dup 3) (const_int 0)]))
8778 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
8779 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8780 [(set_attr "type" "alu")
8781 (set_attr "use_carry" "1")
8782 (set_attr "pent_pair" "pu")
8783 (set_attr "mode" "<MODE>")])
8786 [(set (match_operand:SWI48 0 "general_reg_operand")
8787 (match_operand:SWI48 1 "memory_operand"))
8788 (parallel [(set (reg:CCC FLAGS_REG)
8790 (zero_extend:<DWI> (match_dup 0))
8792 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8793 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8795 (match_operand:SWI48 2 "memory_operand")))))
8800 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8801 [(match_dup 3) (const_int 0)]))
8803 (set (match_dup 1) (match_dup 0))]
8804 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8805 && peep2_reg_dead_p (3, operands[0])
8806 && !reg_overlap_mentioned_p (operands[0], operands[1])
8807 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8808 [(set (match_dup 0) (match_dup 2))
8809 (parallel [(set (reg:CCC FLAGS_REG)
8811 (zero_extend:<DWI> (match_dup 1))
8812 (plus:<DWI> (match_op_dup 4
8813 [(match_dup 3) (const_int 0)])
8814 (zero_extend:<DWI> (match_dup 0)))))
8816 (minus:SWI48 (minus:SWI48 (match_dup 1)
8818 [(match_dup 3) (const_int 0)]))
8822 [(set (match_operand:SWI48 6 "general_reg_operand")
8823 (match_operand:SWI48 7 "memory_operand"))
8824 (set (match_operand:SWI48 8 "general_reg_operand")
8825 (match_operand:SWI48 9 "memory_operand"))
8826 (parallel [(set (reg:CCC FLAGS_REG)
8829 (match_operand:SWI48 0 "general_reg_operand"))
8831 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8832 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8834 (match_operand:SWI48 2 "general_reg_operand")))))
8839 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8840 [(match_dup 3) (const_int 0)]))
8842 (set (match_operand:SWI48 1 "memory_operand") (match_dup 0))]
8843 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8844 && peep2_reg_dead_p (4, operands[0])
8845 && peep2_reg_dead_p (3, operands[2])
8846 && !reg_overlap_mentioned_p (operands[0], operands[1])
8847 && !reg_overlap_mentioned_p (operands[2], operands[1])
8848 && !reg_overlap_mentioned_p (operands[6], operands[9])
8849 && (rtx_equal_p (operands[6], operands[0])
8850 ? (rtx_equal_p (operands[7], operands[1])
8851 && rtx_equal_p (operands[8], operands[2]))
8852 : (rtx_equal_p (operands[8], operands[0])
8853 && rtx_equal_p (operands[9], operands[1])
8854 && rtx_equal_p (operands[6], operands[2])))"
8855 [(set (match_dup 0) (match_dup 9))
8856 (parallel [(set (reg:CCC FLAGS_REG)
8858 (zero_extend:<DWI> (match_dup 1))
8859 (plus:<DWI> (match_op_dup 4
8860 [(match_dup 3) (const_int 0)])
8861 (zero_extend:<DWI> (match_dup 0)))))
8863 (minus:SWI48 (minus:SWI48 (match_dup 1)
8865 [(match_dup 3) (const_int 0)]))
8868 if (!rtx_equal_p (operands[6], operands[0]))
8869 operands[9] = operands[7];
8873 [(set (match_operand:SWI48 6 "general_reg_operand")
8874 (match_operand:SWI48 7 "memory_operand"))
8875 (set (match_operand:SWI48 8 "general_reg_operand")
8876 (match_operand:SWI48 9 "memory_operand"))
8877 (parallel [(set (reg:CCC FLAGS_REG)
8880 (match_operand:SWI48 0 "general_reg_operand"))
8882 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8883 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8885 (match_operand:SWI48 2 "general_reg_operand")))))
8890 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8891 [(match_dup 3) (const_int 0)]))
8893 (set (match_operand:QI 10 "general_reg_operand")
8894 (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8895 (set (match_operand:SWI48 11 "general_reg_operand")
8896 (zero_extend:SWI48 (match_dup 10)))
8897 (set (match_operand:SWI48 1 "memory_operand") (match_dup 0))]
8898 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8899 && peep2_reg_dead_p (6, operands[0])
8900 && peep2_reg_dead_p (3, operands[2])
8901 && !reg_overlap_mentioned_p (operands[0], operands[1])
8902 && !reg_overlap_mentioned_p (operands[2], operands[1])
8903 && !reg_overlap_mentioned_p (operands[6], operands[9])
8904 && !reg_overlap_mentioned_p (operands[0], operands[10])
8905 && !reg_overlap_mentioned_p (operands[10], operands[1])
8906 && !reg_overlap_mentioned_p (operands[0], operands[11])
8907 && !reg_overlap_mentioned_p (operands[11], operands[1])
8908 && (rtx_equal_p (operands[6], operands[0])
8909 ? (rtx_equal_p (operands[7], operands[1])
8910 && rtx_equal_p (operands[8], operands[2]))
8911 : (rtx_equal_p (operands[8], operands[0])
8912 && rtx_equal_p (operands[9], operands[1])
8913 && rtx_equal_p (operands[6], operands[2])))"
8914 [(set (match_dup 0) (match_dup 9))
8915 (parallel [(set (reg:CCC FLAGS_REG)
8917 (zero_extend:<DWI> (match_dup 1))
8918 (plus:<DWI> (match_op_dup 4
8919 [(match_dup 3) (const_int 0)])
8920 (zero_extend:<DWI> (match_dup 0)))))
8922 (minus:SWI48 (minus:SWI48 (match_dup 1)
8924 [(match_dup 3) (const_int 0)]))
8926 (set (match_dup 10) (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8927 (set (match_dup 11) (zero_extend:SWI48 (match_dup 10)))]
8929 if (!rtx_equal_p (operands[6], operands[0]))
8930 operands[9] = operands[7];
8933 (define_expand "subborrow<mode>_0"
8935 [(set (reg:CC FLAGS_REG)
8937 (match_operand:SWI48 1 "nonimmediate_operand")
8938 (match_operand:SWI48 2 "<general_operand>")))
8939 (set (match_operand:SWI48 0 "register_operand")
8940 (minus:SWI48 (match_dup 1) (match_dup 2)))])]
8941 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)")
8943 (define_expand "uaddc<mode>5"
8944 [(match_operand:SWI48 0 "register_operand")
8945 (match_operand:SWI48 1 "register_operand")
8946 (match_operand:SWI48 2 "register_operand")
8947 (match_operand:SWI48 3 "register_operand")
8948 (match_operand:SWI48 4 "nonmemory_operand")]
8951 rtx cf = gen_rtx_REG (CCCmode, FLAGS_REG), pat, pat2;
8952 if (operands[4] == const0_rtx)
8953 emit_insn (gen_addcarry<mode>_0 (operands[0], operands[2], operands[3]));
8956 ix86_expand_carry (operands[4]);
8957 pat = gen_rtx_LTU (<DWI>mode, cf, const0_rtx);
8958 pat2 = gen_rtx_LTU (<MODE>mode, cf, const0_rtx);
8959 emit_insn (gen_addcarry<mode> (operands[0], operands[2], operands[3],
8962 rtx cc = gen_reg_rtx (QImode);
8963 pat = gen_rtx_LTU (QImode, cf, const0_rtx);
8964 emit_insn (gen_rtx_SET (cc, pat));
8965 emit_insn (gen_zero_extendqi<mode>2 (operands[1], cc));
8969 (define_expand "usubc<mode>5"
8970 [(match_operand:SWI48 0 "register_operand")
8971 (match_operand:SWI48 1 "register_operand")
8972 (match_operand:SWI48 2 "register_operand")
8973 (match_operand:SWI48 3 "register_operand")
8974 (match_operand:SWI48 4 "nonmemory_operand")]
8978 if (operands[4] == const0_rtx)
8980 cf = gen_rtx_REG (CCmode, FLAGS_REG);
8981 emit_insn (gen_subborrow<mode>_0 (operands[0], operands[2],
8986 cf = gen_rtx_REG (CCCmode, FLAGS_REG);
8987 ix86_expand_carry (operands[4]);
8988 pat = gen_rtx_LTU (<DWI>mode, cf, const0_rtx);
8989 pat2 = gen_rtx_LTU (<MODE>mode, cf, const0_rtx);
8990 emit_insn (gen_subborrow<mode> (operands[0], operands[2], operands[3],
8993 rtx cc = gen_reg_rtx (QImode);
8994 pat = gen_rtx_LTU (QImode, cf, const0_rtx);
8995 emit_insn (gen_rtx_SET (cc, pat));
8996 emit_insn (gen_zero_extendqi<mode>2 (operands[1], cc));
9000 (define_mode_iterator CC_CCC [CC CCC])
9002 ;; Pre-reload splitter to optimize
9003 ;; *setcc_qi followed by *addqi3_cconly_overflow_1 with the same QI
9004 ;; operand and no intervening flags modifications into nothing.
9005 (define_insn_and_split "*setcc_qi_addqi3_cconly_overflow_1_<mode>"
9006 [(set (reg:CCC FLAGS_REG)
9007 (compare:CCC (neg:QI (geu:QI (reg:CC_CCC FLAGS_REG) (const_int 0)))
9008 (ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))))]
9009 "ix86_pre_reload_split ()"
9013 "emit_note (NOTE_INSN_DELETED); DONE;")
9015 ;; Set the carry flag from the carry flag.
9016 (define_insn_and_split "*setccc"
9017 [(set (reg:CCC FLAGS_REG)
9018 (reg:CCC FLAGS_REG))]
9019 "ix86_pre_reload_split ()"
9023 "emit_note (NOTE_INSN_DELETED); DONE;")
9025 ;; Set the carry flag from the carry flag.
9026 (define_insn_and_split "*setcc_qi_negqi_ccc_1_<mode>"
9027 [(set (reg:CCC FLAGS_REG)
9028 (ltu:CCC (reg:CC_CCC FLAGS_REG) (const_int 0)))]
9029 "ix86_pre_reload_split ()"
9033 "emit_note (NOTE_INSN_DELETED); DONE;")
9035 ;; Set the carry flag from the carry flag.
9036 (define_insn_and_split "*setcc_qi_negqi_ccc_2_<mode>"
9037 [(set (reg:CCC FLAGS_REG)
9038 (unspec:CCC [(ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))
9039 (const_int 0)] UNSPEC_CC_NE))]
9040 "ix86_pre_reload_split ()"
9044 "emit_note (NOTE_INSN_DELETED); DONE;")
9046 ;; Overflow setting add instructions
9048 (define_expand "addqi3_cconly_overflow"
9050 [(set (reg:CCC FLAGS_REG)
9053 (match_operand:QI 0 "nonimmediate_operand")
9054 (match_operand:QI 1 "general_operand"))
9056 (clobber (scratch:QI))])]
9057 "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
9059 (define_insn "*add<mode>3_cconly_overflow_1"
9060 [(set (reg:CCC FLAGS_REG)
9063 (match_operand:SWI 1 "nonimmediate_operand" "%0")
9064 (match_operand:SWI 2 "<general_operand>" "<g>"))
9066 (clobber (match_scratch:SWI 0 "=<r>"))]
9067 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9068 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
9069 [(set_attr "type" "alu")
9070 (set_attr "mode" "<MODE>")])
9072 (define_insn "@add<mode>3_cc_overflow_1"
9073 [(set (reg:CCC FLAGS_REG)
9076 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
9077 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
9079 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
9080 (plus:SWI (match_dup 1) (match_dup 2)))]
9081 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
9082 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
9083 [(set_attr "type" "alu")
9084 (set_attr "mode" "<MODE>")])
9087 [(parallel [(set (reg:CCC FLAGS_REG)
9089 (plus:SWI (match_operand:SWI 0 "general_reg_operand")
9090 (match_operand:SWI 1 "memory_operand"))
9092 (set (match_dup 0) (plus:SWI (match_dup 0) (match_dup 1)))])
9093 (set (match_dup 1) (match_dup 0))]
9094 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
9095 && peep2_reg_dead_p (2, operands[0])
9096 && !reg_overlap_mentioned_p (operands[0], operands[1])"
9097 [(parallel [(set (reg:CCC FLAGS_REG)
9099 (plus:SWI (match_dup 1) (match_dup 0))
9101 (set (match_dup 1) (plus:SWI (match_dup 1) (match_dup 0)))])])
9104 [(set (match_operand:SWI 0 "general_reg_operand")
9105 (match_operand:SWI 1 "memory_operand"))
9106 (parallel [(set (reg:CCC FLAGS_REG)
9108 (plus:SWI (match_dup 0)
9109 (match_operand:SWI 2 "memory_operand"))
9111 (set (match_dup 0) (plus:SWI (match_dup 0) (match_dup 2)))])
9112 (set (match_dup 1) (match_dup 0))]
9113 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
9114 && peep2_reg_dead_p (3, operands[0])
9115 && !reg_overlap_mentioned_p (operands[0], operands[1])
9116 && !reg_overlap_mentioned_p (operands[0], operands[2])"
9117 [(set (match_dup 0) (match_dup 2))
9118 (parallel [(set (reg:CCC FLAGS_REG)
9120 (plus:SWI (match_dup 1) (match_dup 0))
9122 (set (match_dup 1) (plus:SWI (match_dup 1) (match_dup 0)))])])
9124 (define_insn "*addsi3_zext_cc_overflow_1"
9125 [(set (reg:CCC FLAGS_REG)
9128 (match_operand:SI 1 "nonimmediate_operand" "%0")
9129 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
9131 (set (match_operand:DI 0 "register_operand" "=r")
9132 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
9133 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
9134 "add{l}\t{%2, %k0|%k0, %2}"
9135 [(set_attr "type" "alu")
9136 (set_attr "mode" "SI")])
9138 (define_insn "*add<mode>3_cconly_overflow_2"
9139 [(set (reg:CCC FLAGS_REG)
9142 (match_operand:SWI 1 "nonimmediate_operand" "%0")
9143 (match_operand:SWI 2 "<general_operand>" "<g>"))
9145 (clobber (match_scratch:SWI 0 "=<r>"))]
9146 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9147 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
9148 [(set_attr "type" "alu")
9149 (set_attr "mode" "<MODE>")])
9151 (define_insn "*add<mode>3_cc_overflow_2"
9152 [(set (reg:CCC FLAGS_REG)
9155 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
9156 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
9158 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
9159 (plus:SWI (match_dup 1) (match_dup 2)))]
9160 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
9161 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
9162 [(set_attr "type" "alu")
9163 (set_attr "mode" "<MODE>")])
9165 (define_insn "*addsi3_zext_cc_overflow_2"
9166 [(set (reg:CCC FLAGS_REG)
9169 (match_operand:SI 1 "nonimmediate_operand" "%0")
9170 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
9172 (set (match_operand:DI 0 "register_operand" "=r")
9173 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
9174 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
9175 "add{l}\t{%2, %k0|%k0, %2}"
9176 [(set_attr "type" "alu")
9177 (set_attr "mode" "SI")])
9179 (define_insn_and_split "*add<dwi>3_doubleword_cc_overflow_1"
9180 [(set (reg:CCC FLAGS_REG)
9183 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
9184 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o"))
9186 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
9187 (plus:<DWI> (match_dup 1) (match_dup 2)))]
9188 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
9190 "&& reload_completed"
9191 [(parallel [(set (reg:CCC FLAGS_REG)
9193 (plus:DWIH (match_dup 1) (match_dup 2))
9196 (plus:DWIH (match_dup 1) (match_dup 2)))])
9197 (parallel [(set (reg:CCC FLAGS_REG)
9202 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9207 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))))
9210 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9214 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
9215 if (operands[2] == const0_rtx)
9217 emit_insn (gen_addcarry<mode>_0 (operands[3], operands[4], operands[5]));
9220 if (CONST_INT_P (operands[5]))
9221 operands[6] = simplify_unary_operation (ZERO_EXTEND, <DWI>mode,
9222 operands[5], <MODE>mode);
9224 operands[6] = gen_rtx_ZERO_EXTEND (<DWI>mode, operands[5]);
9227 ;; x == 0 with zero flag test can be done also as x < 1U with carry flag
9228 ;; test, where the latter is preferrable if we have some carry consuming
9230 ;; For x != 0, we need to use x < 1U with negation of carry, i.e.
9232 (define_insn_and_split "*add<mode>3_eq"
9233 [(set (match_operand:SWI 0 "nonimmediate_operand")
9236 (eq:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0))
9237 (match_operand:SWI 1 "nonimmediate_operand"))
9238 (match_operand:SWI 2 "<general_operand>")))
9239 (clobber (reg:CC FLAGS_REG))]
9240 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
9241 && ix86_pre_reload_split ()"
9244 [(set (reg:CC FLAGS_REG)
9245 (compare:CC (match_dup 3) (const_int 1)))
9246 (parallel [(set (match_dup 0)
9248 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9251 (clobber (reg:CC FLAGS_REG))])])
9253 (define_insn_and_split "*add<mode>3_ne"
9254 [(set (match_operand:SWI 0 "nonimmediate_operand")
9257 (ne:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0))
9258 (match_operand:SWI 1 "nonimmediate_operand"))
9259 (match_operand:SWI 2 "<immediate_operand>")))
9260 (clobber (reg:CC FLAGS_REG))]
9261 "CONST_INT_P (operands[2])
9262 && (<MODE>mode != DImode
9263 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
9264 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
9265 && ix86_pre_reload_split ()"
9268 [(set (reg:CC FLAGS_REG)
9269 (compare:CC (match_dup 3) (const_int 1)))
9270 (parallel [(set (match_dup 0)
9272 (minus:SWI (match_dup 1)
9273 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9275 (clobber (reg:CC FLAGS_REG))])]
9277 operands[2] = gen_int_mode (~INTVAL (operands[2]),
9278 <MODE>mode == DImode ? SImode : <MODE>mode);
9281 (define_insn_and_split "*add<mode>3_eq_0"
9282 [(set (match_operand:SWI 0 "nonimmediate_operand")
9284 (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))
9285 (match_operand:SWI 1 "<general_operand>")))
9286 (clobber (reg:CC FLAGS_REG))]
9287 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)
9288 && ix86_pre_reload_split ()"
9291 [(set (reg:CC FLAGS_REG)
9292 (compare:CC (match_dup 2) (const_int 1)))
9293 (parallel [(set (match_dup 0)
9294 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9296 (clobber (reg:CC FLAGS_REG))])]
9298 if (!nonimmediate_operand (operands[1], <MODE>mode))
9299 operands[1] = force_reg (<MODE>mode, operands[1]);
9302 (define_insn_and_split "*add<mode>3_ne_0"
9303 [(set (match_operand:SWI 0 "nonimmediate_operand")
9305 (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))
9306 (match_operand:SWI 1 "<general_operand>")))
9307 (clobber (reg:CC FLAGS_REG))]
9308 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)
9309 && ix86_pre_reload_split ()"
9312 [(set (reg:CC FLAGS_REG)
9313 (compare:CC (match_dup 2) (const_int 1)))
9314 (parallel [(set (match_dup 0)
9315 (minus:SWI (minus:SWI
9317 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9319 (clobber (reg:CC FLAGS_REG))])]
9321 if (!nonimmediate_operand (operands[1], <MODE>mode))
9322 operands[1] = force_reg (<MODE>mode, operands[1]);
9325 (define_insn_and_split "*sub<mode>3_eq"
9326 [(set (match_operand:SWI 0 "nonimmediate_operand")
9329 (match_operand:SWI 1 "nonimmediate_operand")
9330 (eq:SWI (match_operand 3 "int_nonimmediate_operand")
9332 (match_operand:SWI 2 "<general_operand>")))
9333 (clobber (reg:CC FLAGS_REG))]
9334 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
9335 && ix86_pre_reload_split ()"
9338 [(set (reg:CC FLAGS_REG)
9339 (compare:CC (match_dup 3) (const_int 1)))
9340 (parallel [(set (match_dup 0)
9342 (minus:SWI (match_dup 1)
9343 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9345 (clobber (reg:CC FLAGS_REG))])])
9347 (define_insn_and_split "*sub<mode>3_ne"
9348 [(set (match_operand:SWI 0 "nonimmediate_operand")
9351 (match_operand:SWI 1 "nonimmediate_operand")
9352 (ne:SWI (match_operand 3 "int_nonimmediate_operand")
9354 (match_operand:SWI 2 "<immediate_operand>")))
9355 (clobber (reg:CC FLAGS_REG))]
9356 "CONST_INT_P (operands[2])
9357 && (<MODE>mode != DImode
9358 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
9359 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
9360 && ix86_pre_reload_split ()"
9363 [(set (reg:CC FLAGS_REG)
9364 (compare:CC (match_dup 3) (const_int 1)))
9365 (parallel [(set (match_dup 0)
9367 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9370 (clobber (reg:CC FLAGS_REG))])]
9372 operands[2] = gen_int_mode (INTVAL (operands[2]) - 1,
9373 <MODE>mode == DImode ? SImode : <MODE>mode);
9376 (define_insn_and_split "*sub<mode>3_eq_1"
9377 [(set (match_operand:SWI 0 "nonimmediate_operand")
9380 (match_operand:SWI 1 "nonimmediate_operand")
9381 (eq:SWI (match_operand 3 "int_nonimmediate_operand")
9383 (match_operand:SWI 2 "<immediate_operand>")))
9384 (clobber (reg:CC FLAGS_REG))]
9385 "CONST_INT_P (operands[2])
9386 && (<MODE>mode != DImode
9387 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
9388 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
9389 && ix86_pre_reload_split ()"
9392 [(set (reg:CC FLAGS_REG)
9393 (compare:CC (match_dup 3) (const_int 1)))
9394 (parallel [(set (match_dup 0)
9396 (minus:SWI (match_dup 1)
9397 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9399 (clobber (reg:CC FLAGS_REG))])]
9401 operands[2] = gen_int_mode (-INTVAL (operands[2]),
9402 <MODE>mode == DImode ? SImode : <MODE>mode);
9405 (define_insn_and_split "*sub<mode>3_eq_0"
9406 [(set (match_operand:SWI 0 "nonimmediate_operand")
9408 (match_operand:SWI 1 "<general_operand>")
9409 (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))))
9410 (clobber (reg:CC FLAGS_REG))]
9411 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)
9412 && ix86_pre_reload_split ()"
9415 [(set (reg:CC FLAGS_REG)
9416 (compare:CC (match_dup 2) (const_int 1)))
9417 (parallel [(set (match_dup 0)
9418 (minus:SWI (match_dup 1)
9419 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))))
9420 (clobber (reg:CC FLAGS_REG))])]
9422 if (!nonimmediate_operand (operands[1], <MODE>mode))
9423 operands[1] = force_reg (<MODE>mode, operands[1]);
9426 (define_insn_and_split "*sub<mode>3_ne_0"
9427 [(set (match_operand:SWI 0 "nonimmediate_operand")
9429 (match_operand:SWI 1 "<general_operand>")
9430 (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))))
9431 (clobber (reg:CC FLAGS_REG))]
9432 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)
9433 && ix86_pre_reload_split ()"
9436 [(set (reg:CC FLAGS_REG)
9437 (compare:CC (match_dup 2) (const_int 1)))
9438 (parallel [(set (match_dup 0)
9440 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9443 (clobber (reg:CC FLAGS_REG))])]
9445 if (!nonimmediate_operand (operands[1], <MODE>mode))
9446 operands[1] = force_reg (<MODE>mode, operands[1]);
9449 ;; The patterns that match these are at the end of this file.
9451 (define_expand "<insn>xf3"
9452 [(set (match_operand:XF 0 "register_operand")
9454 (match_operand:XF 1 "register_operand")
9455 (match_operand:XF 2 "register_operand")))]
9458 (define_expand "<insn>hf3"
9459 [(set (match_operand:HF 0 "register_operand")
9461 (match_operand:HF 1 "register_operand")
9462 (match_operand:HF 2 "nonimmediate_operand")))]
9463 "TARGET_AVX512FP16")
9465 (define_expand "<insn><mode>3"
9466 [(set (match_operand:MODEF 0 "register_operand")
9468 (match_operand:MODEF 1 "register_operand")
9469 (match_operand:MODEF 2 "nonimmediate_operand")))]
9470 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
9471 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
9473 ;; Multiply instructions
9475 (define_expand "mul<mode>3"
9476 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
9478 (match_operand:SWIM248 1 "register_operand")
9479 (match_operand:SWIM248 2 "<general_operand>")))
9480 (clobber (reg:CC FLAGS_REG))])])
9482 (define_expand "mulqi3"
9483 [(parallel [(set (match_operand:QI 0 "register_operand")
9485 (match_operand:QI 1 "register_operand")
9486 (match_operand:QI 2 "nonimmediate_operand")))
9487 (clobber (reg:CC FLAGS_REG))])]
9488 "TARGET_QIMODE_MATH")
9491 ;; IMUL reg32/64, reg32/64, imm8 Direct
9492 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
9493 ;; IMUL reg32/64, reg32/64, imm32 Direct
9494 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
9495 ;; IMUL reg32/64, reg32/64 Direct
9496 ;; IMUL reg32/64, mem32/64 Direct
9498 ;; On BDVER1, all above IMULs use DirectPath
9501 ;; IMUL reg16, reg16, imm8 VectorPath
9502 ;; IMUL reg16, mem16, imm8 VectorPath
9503 ;; IMUL reg16, reg16, imm16 VectorPath
9504 ;; IMUL reg16, mem16, imm16 VectorPath
9505 ;; IMUL reg16, reg16 Direct
9506 ;; IMUL reg16, mem16 Direct
9508 ;; On BDVER1, all HI MULs use DoublePath
9510 (define_insn "*mul<mode>3_1"
9511 [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
9513 (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
9514 (match_operand:SWIM248 2 "<general_operand>" "K,<i>,<m>r")))
9515 (clobber (reg:CC FLAGS_REG))]
9516 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9518 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9519 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9520 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
9521 [(set_attr "type" "imul")
9522 (set_attr "prefix_0f" "0,0,1")
9523 (set (attr "athlon_decode")
9524 (cond [(eq_attr "cpu" "athlon")
9525 (const_string "vector")
9526 (eq_attr "alternative" "1")
9527 (const_string "vector")
9528 (and (eq_attr "alternative" "2")
9529 (ior (match_test "<MODE>mode == HImode")
9530 (match_operand 1 "memory_operand")))
9531 (const_string "vector")]
9532 (const_string "direct")))
9533 (set (attr "amdfam10_decode")
9534 (cond [(and (eq_attr "alternative" "0,1")
9535 (ior (match_test "<MODE>mode == HImode")
9536 (match_operand 1 "memory_operand")))
9537 (const_string "vector")]
9538 (const_string "direct")))
9539 (set (attr "bdver1_decode")
9541 (match_test "<MODE>mode == HImode")
9542 (const_string "double")
9543 (const_string "direct")))
9544 (set_attr "mode" "<MODE>")])
9546 (define_insn "*mulsi3_1_zext"
9547 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9549 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
9550 (match_operand:SI 2 "x86_64_general_operand" "K,e,BMr"))))
9551 (clobber (reg:CC FLAGS_REG))]
9553 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9555 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
9556 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
9557 imul{l}\t{%2, %k0|%k0, %2}"
9558 [(set_attr "type" "imul")
9559 (set_attr "prefix_0f" "0,0,1")
9560 (set (attr "athlon_decode")
9561 (cond [(eq_attr "cpu" "athlon")
9562 (const_string "vector")
9563 (eq_attr "alternative" "1")
9564 (const_string "vector")
9565 (and (eq_attr "alternative" "2")
9566 (match_operand 1 "memory_operand"))
9567 (const_string "vector")]
9568 (const_string "direct")))
9569 (set (attr "amdfam10_decode")
9570 (cond [(and (eq_attr "alternative" "0,1")
9571 (match_operand 1 "memory_operand"))
9572 (const_string "vector")]
9573 (const_string "direct")))
9574 (set_attr "bdver1_decode" "direct")
9575 (set_attr "mode" "SI")])
9577 ;;On AMDFAM10 and BDVER1
9581 (define_insn "*mulqi3_1"
9582 [(set (match_operand:QI 0 "register_operand" "=a")
9583 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9584 (match_operand:QI 2 "nonimmediate_operand" "qm")))
9585 (clobber (reg:CC FLAGS_REG))]
9587 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9589 [(set_attr "type" "imul")
9590 (set_attr "length_immediate" "0")
9591 (set (attr "athlon_decode")
9592 (if_then_else (eq_attr "cpu" "athlon")
9593 (const_string "vector")
9594 (const_string "direct")))
9595 (set_attr "amdfam10_decode" "direct")
9596 (set_attr "bdver1_decode" "direct")
9597 (set_attr "mode" "QI")])
9599 ;; Multiply with jump on overflow.
9600 (define_expand "mulv<mode>4"
9601 [(parallel [(set (reg:CCO FLAGS_REG)
9604 (match_operand:SWI248 1 "register_operand"))
9607 (mult:SWI248 (match_dup 1)
9608 (match_operand:SWI248 2
9609 "<general_operand>")))))
9610 (set (match_operand:SWI248 0 "register_operand")
9611 (mult:SWI248 (match_dup 1) (match_dup 2)))])
9612 (set (pc) (if_then_else
9613 (eq (reg:CCO FLAGS_REG) (const_int 0))
9614 (label_ref (match_operand 3))
9618 if (CONST_INT_P (operands[2]))
9619 operands[4] = operands[2];
9621 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
9624 (define_insn "*mulv<mode>4"
9625 [(set (reg:CCO FLAGS_REG)
9628 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
9630 (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
9632 (mult:SWI48 (match_dup 1) (match_dup 2)))))
9633 (set (match_operand:SWI48 0 "register_operand" "=r,r")
9634 (mult:SWI48 (match_dup 1) (match_dup 2)))]
9635 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9637 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9638 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
9639 [(set_attr "type" "imul")
9640 (set_attr "prefix_0f" "0,1")
9641 (set (attr "athlon_decode")
9642 (cond [(eq_attr "cpu" "athlon")
9643 (const_string "vector")
9644 (eq_attr "alternative" "0")
9645 (const_string "vector")
9646 (and (eq_attr "alternative" "1")
9647 (match_operand 1 "memory_operand"))
9648 (const_string "vector")]
9649 (const_string "direct")))
9650 (set (attr "amdfam10_decode")
9651 (cond [(and (eq_attr "alternative" "1")
9652 (match_operand 1 "memory_operand"))
9653 (const_string "vector")]
9654 (const_string "direct")))
9655 (set_attr "bdver1_decode" "direct")
9656 (set_attr "mode" "<MODE>")])
9658 (define_insn "*mulvhi4"
9659 [(set (reg:CCO FLAGS_REG)
9662 (match_operand:HI 1 "nonimmediate_operand" "%0"))
9664 (match_operand:HI 2 "nonimmediate_operand" "mr")))
9666 (mult:HI (match_dup 1) (match_dup 2)))))
9667 (set (match_operand:HI 0 "register_operand" "=r")
9668 (mult:HI (match_dup 1) (match_dup 2)))]
9669 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9670 "imul{w}\t{%2, %0|%0, %2}"
9671 [(set_attr "type" "imul")
9672 (set_attr "prefix_0f" "1")
9673 (set_attr "athlon_decode" "vector")
9674 (set_attr "amdfam10_decode" "direct")
9675 (set_attr "bdver1_decode" "double")
9676 (set_attr "mode" "HI")])
9678 (define_insn "*mulv<mode>4_1"
9679 [(set (reg:CCO FLAGS_REG)
9682 (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
9683 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
9685 (mult:SWI248 (match_dup 1)
9686 (match_operand:SWI248 2
9687 "<immediate_operand>" "K,<i>")))))
9688 (set (match_operand:SWI248 0 "register_operand" "=r,r")
9689 (mult:SWI248 (match_dup 1) (match_dup 2)))]
9690 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
9691 && CONST_INT_P (operands[2])
9692 && INTVAL (operands[2]) == INTVAL (operands[3])"
9693 "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
9694 [(set_attr "type" "imul")
9695 (set (attr "prefix_0f")
9697 (match_test "<MODE>mode == HImode")
9699 (const_string "*")))
9700 (set (attr "athlon_decode")
9701 (cond [(eq_attr "cpu" "athlon")
9702 (const_string "vector")
9703 (eq_attr "alternative" "1")
9704 (const_string "vector")]
9705 (const_string "direct")))
9706 (set (attr "amdfam10_decode")
9707 (cond [(ior (match_test "<MODE>mode == HImode")
9708 (match_operand 1 "memory_operand"))
9709 (const_string "vector")]
9710 (const_string "direct")))
9711 (set (attr "bdver1_decode")
9713 (match_test "<MODE>mode == HImode")
9714 (const_string "double")
9715 (const_string "direct")))
9716 (set_attr "mode" "<MODE>")
9717 (set (attr "length_immediate")
9718 (cond [(eq_attr "alternative" "0")
9720 (match_test "<MODE_SIZE> == 8")
9722 (const_string "<MODE_SIZE>")))])
9724 (define_expand "umulv<mode>4"
9725 [(parallel [(set (reg:CCO FLAGS_REG)
9728 (match_operand:SWI248 1
9729 "nonimmediate_operand"))
9731 (match_operand:SWI248 2
9732 "nonimmediate_operand")))
9734 (mult:SWI248 (match_dup 1) (match_dup 2)))))
9735 (set (match_operand:SWI248 0 "register_operand")
9736 (mult:SWI248 (match_dup 1) (match_dup 2)))
9737 (clobber (scratch:SWI248))])
9738 (set (pc) (if_then_else
9739 (eq (reg:CCO FLAGS_REG) (const_int 0))
9740 (label_ref (match_operand 3))
9744 if (MEM_P (operands[1]) && MEM_P (operands[2]))
9745 operands[1] = force_reg (<MODE>mode, operands[1]);
9748 (define_insn "*umulv<mode>4"
9749 [(set (reg:CCO FLAGS_REG)
9752 (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
9754 (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
9756 (mult:SWI248 (match_dup 1) (match_dup 2)))))
9757 (set (match_operand:SWI248 0 "register_operand" "=a")
9758 (mult:SWI248 (match_dup 1) (match_dup 2)))
9759 (clobber (match_scratch:SWI248 3 "=d"))]
9760 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9761 "mul{<imodesuffix>}\t%2"
9762 [(set_attr "type" "imul")
9763 (set_attr "length_immediate" "0")
9764 (set (attr "athlon_decode")
9765 (if_then_else (eq_attr "cpu" "athlon")
9766 (const_string "vector")
9767 (const_string "double")))
9768 (set_attr "amdfam10_decode" "double")
9769 (set_attr "bdver1_decode" "direct")
9770 (set_attr "mode" "<MODE>")])
9772 (define_expand "<u>mulvqi4"
9773 [(parallel [(set (reg:CCO FLAGS_REG)
9776 (match_operand:QI 1 "nonimmediate_operand"))
9778 (match_operand:QI 2 "nonimmediate_operand")))
9780 (mult:QI (match_dup 1) (match_dup 2)))))
9781 (set (match_operand:QI 0 "register_operand")
9782 (mult:QI (match_dup 1) (match_dup 2)))])
9783 (set (pc) (if_then_else
9784 (eq (reg:CCO FLAGS_REG) (const_int 0))
9785 (label_ref (match_operand 3))
9787 "TARGET_QIMODE_MATH"
9789 if (MEM_P (operands[1]) && MEM_P (operands[2]))
9790 operands[1] = force_reg (QImode, operands[1]);
9793 (define_insn "*<u>mulvqi4"
9794 [(set (reg:CCO FLAGS_REG)
9797 (match_operand:QI 1 "nonimmediate_operand" "%0"))
9799 (match_operand:QI 2 "nonimmediate_operand" "qm")))
9801 (mult:QI (match_dup 1) (match_dup 2)))))
9802 (set (match_operand:QI 0 "register_operand" "=a")
9803 (mult:QI (match_dup 1) (match_dup 2)))]
9805 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9806 "<sgnprefix>mul{b}\t%2"
9807 [(set_attr "type" "imul")
9808 (set_attr "length_immediate" "0")
9809 (set (attr "athlon_decode")
9810 (if_then_else (eq_attr "cpu" "athlon")
9811 (const_string "vector")
9812 (const_string "direct")))
9813 (set_attr "amdfam10_decode" "direct")
9814 (set_attr "bdver1_decode" "direct")
9815 (set_attr "mode" "QI")])
9817 (define_expand "<u>mul<mode><dwi>3"
9818 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
9821 (match_operand:DWIH 1 "register_operand"))
9823 (match_operand:DWIH 2 "nonimmediate_operand"))))
9824 (clobber (reg:CC FLAGS_REG))])])
9826 (define_expand "<u>mulqihi3"
9827 [(parallel [(set (match_operand:HI 0 "register_operand")
9830 (match_operand:QI 1 "register_operand"))
9832 (match_operand:QI 2 "nonimmediate_operand"))))
9833 (clobber (reg:CC FLAGS_REG))])]
9834 "TARGET_QIMODE_MATH")
9836 (define_insn "*bmi2_umul<mode><dwi>3_1"
9837 [(set (match_operand:DWIH 0 "register_operand" "=r")
9839 (match_operand:DWIH 2 "register_operand" "%d")
9840 (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
9841 (set (match_operand:DWIH 1 "register_operand" "=r")
9842 (umul_highpart:DWIH (match_dup 2) (match_dup 3)))]
9844 "mulx\t{%3, %0, %1|%1, %0, %3}"
9845 [(set_attr "type" "imulx")
9846 (set_attr "prefix" "vex")
9847 (set_attr "mode" "<MODE>")])
9849 ;; Tweak *bmi2_umul<mode><dwi>3_1 to eliminate following mov.
9851 [(parallel [(set (match_operand:DWIH 0 "general_reg_operand")
9852 (mult:DWIH (match_operand:DWIH 2 "register_operand")
9853 (match_operand:DWIH 3 "nonimmediate_operand")))
9854 (set (match_operand:DWIH 1 "general_reg_operand")
9855 (umul_highpart:DWIH (match_dup 2) (match_dup 3)))])
9856 (set (match_operand:DWIH 4 "general_reg_operand")
9857 (match_operand:DWIH 5 "general_reg_operand"))]
9859 && ((REGNO (operands[5]) == REGNO (operands[0])
9860 && REGNO (operands[1]) != REGNO (operands[4]))
9861 || (REGNO (operands[5]) == REGNO (operands[1])
9862 && REGNO (operands[0]) != REGNO (operands[4])))
9863 && peep2_reg_dead_p (2, operands[5])"
9864 [(parallel [(set (match_dup 0) (mult:DWIH (match_dup 2) (match_dup 3)))
9866 (umul_highpart:DWIH (match_dup 2) (match_dup 3)))])]
9868 if (REGNO (operands[5]) == REGNO (operands[0]))
9869 operands[0] = operands[4];
9871 operands[1] = operands[4];
9874 (define_insn "*umul<mode><dwi>3_1"
9875 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
9878 (match_operand:DWIH 1 "register_operand" "%d,a"))
9880 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
9881 (clobber (reg:CC FLAGS_REG))]
9882 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9885 mul{<imodesuffix>}\t%2"
9886 [(set_attr "isa" "bmi2,*")
9887 (set_attr "type" "imulx,imul")
9888 (set_attr "length_immediate" "*,0")
9889 (set (attr "athlon_decode")
9890 (cond [(eq_attr "alternative" "1")
9891 (if_then_else (eq_attr "cpu" "athlon")
9892 (const_string "vector")
9893 (const_string "double"))]
9894 (const_string "*")))
9895 (set_attr "amdfam10_decode" "*,double")
9896 (set_attr "bdver1_decode" "*,direct")
9897 (set_attr "prefix" "vex,orig")
9898 (set_attr "mode" "<MODE>")])
9900 ;; Convert mul to the mulx pattern to avoid flags dependency.
9902 [(set (match_operand:<DWI> 0 "register_operand")
9905 (match_operand:DWIH 1 "register_operand"))
9907 (match_operand:DWIH 2 "nonimmediate_operand"))))
9908 (clobber (reg:CC FLAGS_REG))]
9909 "TARGET_BMI2 && reload_completed
9910 && REGNO (operands[1]) == DX_REG"
9911 [(parallel [(set (match_dup 3)
9912 (mult:DWIH (match_dup 1) (match_dup 2)))
9914 (umul_highpart:DWIH (match_dup 1) (match_dup 2)))])]
9916 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
9918 operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
9921 (define_insn "*mul<mode><dwi>3_1"
9922 [(set (match_operand:<DWI> 0 "register_operand" "=A")
9925 (match_operand:DWIH 1 "register_operand" "%a"))
9927 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
9928 (clobber (reg:CC FLAGS_REG))]
9929 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9930 "imul{<imodesuffix>}\t%2"
9931 [(set_attr "type" "imul")
9932 (set_attr "length_immediate" "0")
9933 (set (attr "athlon_decode")
9934 (if_then_else (eq_attr "cpu" "athlon")
9935 (const_string "vector")
9936 (const_string "double")))
9937 (set_attr "amdfam10_decode" "double")
9938 (set_attr "bdver1_decode" "direct")
9939 (set_attr "mode" "<MODE>")])
9941 (define_insn "*<u>mulqihi3_1"
9942 [(set (match_operand:HI 0 "register_operand" "=a")
9945 (match_operand:QI 1 "register_operand" "%0"))
9947 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
9948 (clobber (reg:CC FLAGS_REG))]
9950 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9951 "<sgnprefix>mul{b}\t%2"
9952 [(set_attr "type" "imul")
9953 (set_attr "length_immediate" "0")
9954 (set (attr "athlon_decode")
9955 (if_then_else (eq_attr "cpu" "athlon")
9956 (const_string "vector")
9957 (const_string "direct")))
9958 (set_attr "amdfam10_decode" "direct")
9959 (set_attr "bdver1_decode" "direct")
9960 (set_attr "mode" "QI")])
9962 ;; Widening multiplication peephole2s to tweak register allocation.
9963 ;; mov imm,%rdx; mov %rdi,%rax; mulq %rdx -> mov imm,%rax; mulq %rdi
9965 [(set (match_operand:DWIH 0 "general_reg_operand")
9966 (match_operand:DWIH 1 "immediate_operand"))
9967 (set (match_operand:DWIH 2 "general_reg_operand")
9968 (match_operand:DWIH 3 "general_reg_operand"))
9969 (parallel [(set (match_operand:<DWI> 4 "general_reg_operand")
9970 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
9971 (zero_extend:<DWI> (match_dup 0))))
9972 (clobber (reg:CC FLAGS_REG))])]
9973 "REGNO (operands[3]) != AX_REG
9974 && REGNO (operands[0]) != REGNO (operands[2])
9975 && REGNO (operands[0]) != REGNO (operands[3])
9976 && (REGNO (operands[0]) == REGNO (operands[4])
9977 || REGNO (operands[0]) == DX_REG
9978 || peep2_reg_dead_p (3, operands[0]))"
9979 [(set (match_dup 2) (match_dup 1))
9980 (parallel [(set (match_dup 4)
9981 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
9982 (zero_extend:<DWI> (match_dup 3))))
9983 (clobber (reg:CC FLAGS_REG))])])
9985 ;; mov imm,%rax; mov %rdi,%rdx; mulx %rax -> mov imm,%rdx; mulx %rdi
9987 [(set (match_operand:DWIH 0 "general_reg_operand")
9988 (match_operand:DWIH 1 "immediate_operand"))
9989 (set (match_operand:DWIH 2 "general_reg_operand")
9990 (match_operand:DWIH 3 "general_reg_operand"))
9991 (parallel [(set (match_operand:DWIH 4 "general_reg_operand")
9992 (mult:DWIH (match_dup 2) (match_dup 0)))
9993 (set (match_operand:DWIH 5 "general_reg_operand")
9994 (umul_highpart:DWIH (match_dup 2) (match_dup 0)))])]
9995 "REGNO (operands[3]) != DX_REG
9996 && REGNO (operands[0]) != REGNO (operands[2])
9997 && REGNO (operands[0]) != REGNO (operands[3])
9998 && (REGNO (operands[0]) == REGNO (operands[4])
9999 || REGNO (operands[0]) == REGNO (operands[5])
10000 || peep2_reg_dead_p (3, operands[0]))
10001 && (REGNO (operands[2]) == REGNO (operands[4])
10002 || REGNO (operands[2]) == REGNO (operands[5])
10003 || peep2_reg_dead_p (3, operands[2]))"
10004 [(set (match_dup 2) (match_dup 1))
10005 (parallel [(set (match_dup 4)
10006 (mult:DWIH (match_dup 2) (match_dup 3)))
10008 (umul_highpart:DWIH (match_dup 2) (match_dup 3)))])])
10010 ;; Highpart multiplication patterns
10011 (define_insn "<s>mul<mode>3_highpart"
10012 [(set (match_operand:DWIH 0 "register_operand" "=d")
10013 (any_mul_highpart:DWIH
10014 (match_operand:DWIH 1 "register_operand" "%a")
10015 (match_operand:DWIH 2 "nonimmediate_operand" "rm")))
10016 (clobber (match_scratch:DWIH 3 "=1"))
10017 (clobber (reg:CC FLAGS_REG))]
10019 "<sgnprefix>mul{<imodesuffix>}\t%2"
10020 [(set_attr "type" "imul")
10021 (set_attr "length_immediate" "0")
10022 (set (attr "athlon_decode")
10023 (if_then_else (eq_attr "cpu" "athlon")
10024 (const_string "vector")
10025 (const_string "double")))
10026 (set_attr "amdfam10_decode" "double")
10027 (set_attr "bdver1_decode" "direct")
10028 (set_attr "mode" "<MODE>")])
10030 (define_insn "*<s>mulsi3_highpart_zext"
10031 [(set (match_operand:DI 0 "register_operand" "=d")
10033 (any_mul_highpart:SI
10034 (match_operand:SI 1 "register_operand" "%a")
10035 (match_operand:SI 2 "nonimmediate_operand" "rm"))))
10036 (clobber (match_scratch:SI 3 "=1"))
10037 (clobber (reg:CC FLAGS_REG))]
10039 "<sgnprefix>mul{l}\t%2"
10040 [(set_attr "type" "imul")
10041 (set_attr "length_immediate" "0")
10042 (set (attr "athlon_decode")
10043 (if_then_else (eq_attr "cpu" "athlon")
10044 (const_string "vector")
10045 (const_string "double")))
10046 (set_attr "amdfam10_decode" "double")
10047 (set_attr "bdver1_decode" "direct")
10048 (set_attr "mode" "SI")])
10050 (define_insn "*<s>muldi3_highpart_1"
10051 [(set (match_operand:DI 0 "register_operand" "=d")
10056 (match_operand:DI 1 "nonimmediate_operand" "%a"))
10058 (match_operand:DI 2 "nonimmediate_operand" "rm")))
10060 (clobber (match_scratch:DI 3 "=1"))
10061 (clobber (reg:CC FLAGS_REG))]
10063 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10064 "<sgnprefix>mul{q}\t%2"
10065 [(set_attr "type" "imul")
10066 (set_attr "length_immediate" "0")
10067 (set (attr "athlon_decode")
10068 (if_then_else (eq_attr "cpu" "athlon")
10069 (const_string "vector")
10070 (const_string "double")))
10071 (set_attr "amdfam10_decode" "double")
10072 (set_attr "bdver1_decode" "direct")
10073 (set_attr "mode" "DI")])
10075 (define_insn "*<s>mulsi3_highpart_zext"
10076 [(set (match_operand:DI 0 "register_operand" "=d")
10077 (zero_extend:DI (truncate:SI
10079 (mult:DI (any_extend:DI
10080 (match_operand:SI 1 "nonimmediate_operand" "%a"))
10082 (match_operand:SI 2 "nonimmediate_operand" "rm")))
10084 (clobber (match_scratch:SI 3 "=1"))
10085 (clobber (reg:CC FLAGS_REG))]
10087 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10088 "<sgnprefix>mul{l}\t%2"
10089 [(set_attr "type" "imul")
10090 (set_attr "length_immediate" "0")
10091 (set (attr "athlon_decode")
10092 (if_then_else (eq_attr "cpu" "athlon")
10093 (const_string "vector")
10094 (const_string "double")))
10095 (set_attr "amdfam10_decode" "double")
10096 (set_attr "bdver1_decode" "direct")
10097 (set_attr "mode" "SI")])
10099 (define_insn "*<s>mulsi3_highpart_1"
10100 [(set (match_operand:SI 0 "register_operand" "=d")
10105 (match_operand:SI 1 "nonimmediate_operand" "%a"))
10107 (match_operand:SI 2 "nonimmediate_operand" "rm")))
10109 (clobber (match_scratch:SI 3 "=1"))
10110 (clobber (reg:CC FLAGS_REG))]
10111 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
10112 "<sgnprefix>mul{l}\t%2"
10113 [(set_attr "type" "imul")
10114 (set_attr "length_immediate" "0")
10115 (set (attr "athlon_decode")
10116 (if_then_else (eq_attr "cpu" "athlon")
10117 (const_string "vector")
10118 (const_string "double")))
10119 (set_attr "amdfam10_decode" "double")
10120 (set_attr "bdver1_decode" "direct")
10121 (set_attr "mode" "SI")])
10123 ;; Highpart multiplication peephole2s to tweak register allocation.
10124 ;; mov imm,%rdx; mov %rdi,%rax; imulq %rdx -> mov imm,%rax; imulq %rdi
10126 [(set (match_operand:SWI48 0 "general_reg_operand")
10127 (match_operand:SWI48 1 "immediate_operand"))
10128 (set (match_operand:SWI48 2 "general_reg_operand")
10129 (match_operand:SWI48 3 "general_reg_operand"))
10130 (parallel [(set (match_operand:SWI48 4 "general_reg_operand")
10131 (any_mul_highpart:SWI48 (match_dup 2) (match_dup 0)))
10132 (clobber (match_dup 2))
10133 (clobber (reg:CC FLAGS_REG))])]
10134 "REGNO (operands[3]) != AX_REG
10135 && REGNO (operands[0]) != REGNO (operands[2])
10136 && REGNO (operands[0]) != REGNO (operands[3])
10137 && (REGNO (operands[0]) == REGNO (operands[4])
10138 || peep2_reg_dead_p (3, operands[0]))"
10139 [(set (match_dup 2) (match_dup 1))
10140 (parallel [(set (match_dup 4)
10141 (any_mul_highpart:SWI48 (match_dup 2) (match_dup 3)))
10142 (clobber (match_dup 2))
10143 (clobber (reg:CC FLAGS_REG))])])
10146 [(set (match_operand:SI 0 "general_reg_operand")
10147 (match_operand:SI 1 "immediate_operand"))
10148 (set (match_operand:SI 2 "general_reg_operand")
10149 (match_operand:SI 3 "general_reg_operand"))
10150 (parallel [(set (match_operand:DI 4 "general_reg_operand")
10152 (any_mul_highpart:SI (match_dup 2) (match_dup 0))))
10153 (clobber (match_dup 2))
10154 (clobber (reg:CC FLAGS_REG))])]
10156 && REGNO (operands[3]) != AX_REG
10157 && REGNO (operands[0]) != REGNO (operands[2])
10158 && REGNO (operands[2]) != REGNO (operands[3])
10159 && REGNO (operands[0]) != REGNO (operands[3])
10160 && (REGNO (operands[0]) == REGNO (operands[4])
10161 || peep2_reg_dead_p (3, operands[0]))"
10162 [(set (match_dup 2) (match_dup 1))
10163 (parallel [(set (match_dup 4)
10165 (any_mul_highpart:SI (match_dup 2) (match_dup 3))))
10166 (clobber (match_dup 2))
10167 (clobber (reg:CC FLAGS_REG))])])
10169 ;; The patterns that match these are at the end of this file.
10171 (define_expand "mulxf3"
10172 [(set (match_operand:XF 0 "register_operand")
10173 (mult:XF (match_operand:XF 1 "register_operand")
10174 (match_operand:XF 2 "register_operand")))]
10177 (define_expand "mulhf3"
10178 [(set (match_operand:HF 0 "register_operand")
10179 (mult:HF (match_operand:HF 1 "register_operand")
10180 (match_operand:HF 2 "nonimmediate_operand")))]
10181 "TARGET_AVX512FP16")
10183 (define_expand "mul<mode>3"
10184 [(set (match_operand:MODEF 0 "register_operand")
10185 (mult:MODEF (match_operand:MODEF 1 "register_operand")
10186 (match_operand:MODEF 2 "nonimmediate_operand")))]
10187 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
10188 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
10190 ;; Divide instructions
10192 ;; The patterns that match these are at the end of this file.
10194 (define_expand "divxf3"
10195 [(set (match_operand:XF 0 "register_operand")
10196 (div:XF (match_operand:XF 1 "register_operand")
10197 (match_operand:XF 2 "register_operand")))]
10200 /* There is no more precision loss than Newton-Rhapson approximation
10201 when using HFmode rcp/rsqrt, so do the transformation directly under
10202 TARGET_RECIP_DIV and fast-math. */
10203 (define_expand "divhf3"
10204 [(set (match_operand:HF 0 "register_operand")
10205 (div:HF (match_operand:HF 1 "register_operand")
10206 (match_operand:HF 2 "nonimmediate_operand")))]
10207 "TARGET_AVX512FP16"
10209 if (TARGET_RECIP_DIV
10210 && optimize_insn_for_speed_p ()
10211 && flag_finite_math_only && !flag_trapping_math
10212 && flag_unsafe_math_optimizations)
10214 rtx op = gen_reg_rtx (HFmode);
10215 operands[2] = force_reg (HFmode, operands[2]);
10216 emit_insn (gen_rcphf2 (op, operands[2]));
10217 emit_insn (gen_mulhf3 (operands[0], operands[1], op));
10222 (define_expand "div<mode>3"
10223 [(set (match_operand:MODEF 0 "register_operand")
10224 (div:MODEF (match_operand:MODEF 1 "register_operand")
10225 (match_operand:MODEF 2 "nonimmediate_operand")))]
10226 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
10227 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10229 if (<MODE>mode == SFmode
10230 && TARGET_SSE && TARGET_SSE_MATH
10231 && TARGET_RECIP_DIV
10232 && optimize_insn_for_speed_p ()
10233 && flag_finite_math_only && !flag_trapping_math
10234 && flag_unsafe_math_optimizations)
10236 ix86_emit_swdivsf (operands[0], operands[1],
10237 operands[2], SFmode);
10242 ;; Divmod instructions.
10244 (define_code_iterator any_div [div udiv])
10245 (define_code_attr paired_mod [(div "mod") (udiv "umod")])
10247 (define_expand "<u>divmod<mode>4"
10248 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
10250 (match_operand:SWIM248 1 "register_operand")
10251 (match_operand:SWIM248 2 "nonimmediate_operand")))
10252 (set (match_operand:SWIM248 3 "register_operand")
10253 (<paired_mod>:SWIM248 (match_dup 1) (match_dup 2)))
10254 (clobber (reg:CC FLAGS_REG))])])
10256 ;; Split with 8bit unsigned divide:
10257 ;; if (dividend an divisor are in [0-255])
10258 ;; use 8bit unsigned integer divide
10260 ;; use original integer divide
10262 [(set (match_operand:SWI48 0 "register_operand")
10263 (any_div:SWI48 (match_operand:SWI48 2 "register_operand")
10264 (match_operand:SWI48 3 "nonimmediate_operand")))
10265 (set (match_operand:SWI48 1 "register_operand")
10266 (<paired_mod>:SWI48 (match_dup 2) (match_dup 3)))
10267 (clobber (reg:CC FLAGS_REG))]
10268 "TARGET_USE_8BIT_IDIV
10269 && TARGET_QIMODE_MATH
10270 && can_create_pseudo_p ()
10271 && !optimize_insn_for_size_p ()"
10273 "ix86_split_idivmod (<MODE>mode, operands, <u_bool>); DONE;")
10276 [(set (match_operand:DI 0 "register_operand")
10278 (any_div:SI (match_operand:SI 2 "register_operand")
10279 (match_operand:SI 3 "nonimmediate_operand"))))
10280 (set (match_operand:SI 1 "register_operand")
10281 (<paired_mod>:SI (match_dup 2) (match_dup 3)))
10282 (clobber (reg:CC FLAGS_REG))]
10284 && TARGET_USE_8BIT_IDIV
10285 && TARGET_QIMODE_MATH
10286 && can_create_pseudo_p ()
10287 && !optimize_insn_for_size_p ()"
10289 "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
10292 [(set (match_operand:DI 1 "register_operand")
10294 (<paired_mod>:SI (match_operand:SI 2 "register_operand")
10295 (match_operand:SI 3 "nonimmediate_operand"))))
10296 (set (match_operand:SI 0 "register_operand")
10297 (any_div:SI (match_dup 2) (match_dup 3)))
10298 (clobber (reg:CC FLAGS_REG))]
10300 && TARGET_USE_8BIT_IDIV
10301 && TARGET_QIMODE_MATH
10302 && can_create_pseudo_p ()
10303 && !optimize_insn_for_size_p ()"
10305 "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
10307 (define_insn_and_split "divmod<mode>4_1"
10308 [(set (match_operand:SWI48 0 "register_operand" "=a")
10309 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
10310 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
10311 (set (match_operand:SWI48 1 "register_operand" "=&d")
10312 (mod:SWI48 (match_dup 2) (match_dup 3)))
10313 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10314 (clobber (reg:CC FLAGS_REG))]
10318 [(parallel [(set (match_dup 1)
10319 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
10320 (clobber (reg:CC FLAGS_REG))])
10321 (parallel [(set (match_dup 0)
10322 (div:SWI48 (match_dup 2) (match_dup 3)))
10324 (mod:SWI48 (match_dup 2) (match_dup 3)))
10325 (use (match_dup 1))
10326 (clobber (reg:CC FLAGS_REG))])]
10328 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
10330 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10331 operands[4] = operands[2];
10334 /* Avoid use of cltd in favor of a mov+shift. */
10335 emit_move_insn (operands[1], operands[2]);
10336 operands[4] = operands[1];
10339 [(set_attr "type" "multi")
10340 (set_attr "mode" "<MODE>")])
10342 (define_insn_and_split "udivmod<mode>4_1"
10343 [(set (match_operand:SWI48 0 "register_operand" "=a")
10344 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
10345 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
10346 (set (match_operand:SWI48 1 "register_operand" "=&d")
10347 (umod:SWI48 (match_dup 2) (match_dup 3)))
10348 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10349 (clobber (reg:CC FLAGS_REG))]
10353 [(set (match_dup 1) (const_int 0))
10354 (parallel [(set (match_dup 0)
10355 (udiv:SWI48 (match_dup 2) (match_dup 3)))
10357 (umod:SWI48 (match_dup 2) (match_dup 3)))
10358 (use (match_dup 1))
10359 (clobber (reg:CC FLAGS_REG))])]
10361 [(set_attr "type" "multi")
10362 (set_attr "mode" "<MODE>")])
10364 (define_insn_and_split "divmodsi4_zext_1"
10365 [(set (match_operand:DI 0 "register_operand" "=a")
10367 (div:SI (match_operand:SI 2 "register_operand" "0")
10368 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10369 (set (match_operand:SI 1 "register_operand" "=&d")
10370 (mod:SI (match_dup 2) (match_dup 3)))
10371 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10372 (clobber (reg:CC FLAGS_REG))]
10375 "&& reload_completed"
10376 [(parallel [(set (match_dup 1)
10377 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10378 (clobber (reg:CC FLAGS_REG))])
10379 (parallel [(set (match_dup 0)
10380 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
10382 (mod:SI (match_dup 2) (match_dup 3)))
10383 (use (match_dup 1))
10384 (clobber (reg:CC FLAGS_REG))])]
10386 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10388 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10389 operands[4] = operands[2];
10392 /* Avoid use of cltd in favor of a mov+shift. */
10393 emit_move_insn (operands[1], operands[2]);
10394 operands[4] = operands[1];
10397 [(set_attr "type" "multi")
10398 (set_attr "mode" "SI")])
10400 (define_insn_and_split "udivmodsi4_zext_1"
10401 [(set (match_operand:DI 0 "register_operand" "=a")
10403 (udiv:SI (match_operand:SI 2 "register_operand" "0")
10404 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10405 (set (match_operand:SI 1 "register_operand" "=&d")
10406 (umod:SI (match_dup 2) (match_dup 3)))
10407 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10408 (clobber (reg:CC FLAGS_REG))]
10411 "&& reload_completed"
10412 [(set (match_dup 1) (const_int 0))
10413 (parallel [(set (match_dup 0)
10414 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
10416 (umod:SI (match_dup 2) (match_dup 3)))
10417 (use (match_dup 1))
10418 (clobber (reg:CC FLAGS_REG))])]
10420 [(set_attr "type" "multi")
10421 (set_attr "mode" "SI")])
10423 (define_insn_and_split "divmodsi4_zext_2"
10424 [(set (match_operand:DI 1 "register_operand" "=&d")
10426 (mod:SI (match_operand:SI 2 "register_operand" "0")
10427 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10428 (set (match_operand:SI 0 "register_operand" "=a")
10429 (div:SI (match_dup 2) (match_dup 3)))
10430 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10431 (clobber (reg:CC FLAGS_REG))]
10434 "&& reload_completed"
10435 [(parallel [(set (match_dup 6)
10436 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10437 (clobber (reg:CC FLAGS_REG))])
10438 (parallel [(set (match_dup 1)
10439 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
10441 (div:SI (match_dup 2) (match_dup 3)))
10442 (use (match_dup 6))
10443 (clobber (reg:CC FLAGS_REG))])]
10445 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10446 operands[6] = gen_lowpart (SImode, operands[1]);
10448 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10449 operands[4] = operands[2];
10452 /* Avoid use of cltd in favor of a mov+shift. */
10453 emit_move_insn (operands[6], operands[2]);
10454 operands[4] = operands[6];
10457 [(set_attr "type" "multi")
10458 (set_attr "mode" "SI")])
10460 (define_insn_and_split "udivmodsi4_zext_2"
10461 [(set (match_operand:DI 1 "register_operand" "=&d")
10463 (umod:SI (match_operand:SI 2 "register_operand" "0")
10464 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10465 (set (match_operand:SI 0 "register_operand" "=a")
10466 (udiv:SI (match_dup 2) (match_dup 3)))
10467 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10468 (clobber (reg:CC FLAGS_REG))]
10471 "&& reload_completed"
10472 [(set (match_dup 4) (const_int 0))
10473 (parallel [(set (match_dup 1)
10474 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
10476 (udiv:SI (match_dup 2) (match_dup 3)))
10477 (use (match_dup 4))
10478 (clobber (reg:CC FLAGS_REG))])]
10479 "operands[4] = gen_lowpart (SImode, operands[1]);"
10480 [(set_attr "type" "multi")
10481 (set_attr "mode" "SI")])
10483 (define_insn_and_split "*divmod<mode>4"
10484 [(set (match_operand:SWIM248 0 "register_operand" "=a")
10485 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
10486 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
10487 (set (match_operand:SWIM248 1 "register_operand" "=&d")
10488 (mod:SWIM248 (match_dup 2) (match_dup 3)))
10489 (clobber (reg:CC FLAGS_REG))]
10493 [(parallel [(set (match_dup 1)
10494 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
10495 (clobber (reg:CC FLAGS_REG))])
10496 (parallel [(set (match_dup 0)
10497 (div:SWIM248 (match_dup 2) (match_dup 3)))
10499 (mod:SWIM248 (match_dup 2) (match_dup 3)))
10500 (use (match_dup 1))
10501 (clobber (reg:CC FLAGS_REG))])]
10503 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
10505 if (<MODE>mode != HImode
10506 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
10507 operands[4] = operands[2];
10510 /* Avoid use of cltd in favor of a mov+shift. */
10511 emit_move_insn (operands[1], operands[2]);
10512 operands[4] = operands[1];
10515 [(set_attr "type" "multi")
10516 (set_attr "mode" "<MODE>")])
10518 (define_insn_and_split "*udivmod<mode>4"
10519 [(set (match_operand:SWIM248 0 "register_operand" "=a")
10520 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
10521 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
10522 (set (match_operand:SWIM248 1 "register_operand" "=&d")
10523 (umod:SWIM248 (match_dup 2) (match_dup 3)))
10524 (clobber (reg:CC FLAGS_REG))]
10528 [(set (match_dup 1) (const_int 0))
10529 (parallel [(set (match_dup 0)
10530 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
10532 (umod:SWIM248 (match_dup 2) (match_dup 3)))
10533 (use (match_dup 1))
10534 (clobber (reg:CC FLAGS_REG))])]
10536 [(set_attr "type" "multi")
10537 (set_attr "mode" "<MODE>")])
10539 ;; Optimize division or modulo by constant power of 2, if the constant
10540 ;; materializes only after expansion.
10541 (define_insn_and_split "*udivmod<mode>4_pow2"
10542 [(set (match_operand:SWI48 0 "register_operand" "=r")
10543 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
10544 (match_operand:SWI48 3 "const_int_operand")))
10545 (set (match_operand:SWI48 1 "register_operand" "=r")
10546 (umod:SWI48 (match_dup 2) (match_dup 3)))
10547 (clobber (reg:CC FLAGS_REG))]
10548 "IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
10550 "&& reload_completed"
10551 [(set (match_dup 1) (match_dup 2))
10552 (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
10553 (clobber (reg:CC FLAGS_REG))])
10554 (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
10555 (clobber (reg:CC FLAGS_REG))])]
10557 int v = exact_log2 (UINTVAL (operands[3]));
10558 operands[4] = GEN_INT (v);
10559 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
10561 [(set_attr "type" "multi")
10562 (set_attr "mode" "<MODE>")])
10564 (define_insn_and_split "*divmodsi4_zext_1"
10565 [(set (match_operand:DI 0 "register_operand" "=a")
10567 (div:SI (match_operand:SI 2 "register_operand" "0")
10568 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10569 (set (match_operand:SI 1 "register_operand" "=&d")
10570 (mod:SI (match_dup 2) (match_dup 3)))
10571 (clobber (reg:CC FLAGS_REG))]
10574 "&& reload_completed"
10575 [(parallel [(set (match_dup 1)
10576 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10577 (clobber (reg:CC FLAGS_REG))])
10578 (parallel [(set (match_dup 0)
10579 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
10581 (mod:SI (match_dup 2) (match_dup 3)))
10582 (use (match_dup 1))
10583 (clobber (reg:CC FLAGS_REG))])]
10585 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10587 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10588 operands[4] = operands[2];
10591 /* Avoid use of cltd in favor of a mov+shift. */
10592 emit_move_insn (operands[1], operands[2]);
10593 operands[4] = operands[1];
10596 [(set_attr "type" "multi")
10597 (set_attr "mode" "SI")])
10599 (define_insn_and_split "*udivmodsi4_zext_1"
10600 [(set (match_operand:DI 0 "register_operand" "=a")
10602 (udiv:SI (match_operand:SI 2 "register_operand" "0")
10603 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10604 (set (match_operand:SI 1 "register_operand" "=&d")
10605 (umod:SI (match_dup 2) (match_dup 3)))
10606 (clobber (reg:CC FLAGS_REG))]
10609 "&& reload_completed"
10610 [(set (match_dup 1) (const_int 0))
10611 (parallel [(set (match_dup 0)
10612 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
10614 (umod:SI (match_dup 2) (match_dup 3)))
10615 (use (match_dup 1))
10616 (clobber (reg:CC FLAGS_REG))])]
10618 [(set_attr "type" "multi")
10619 (set_attr "mode" "SI")])
10621 (define_insn_and_split "*udivmodsi4_pow2_zext_1"
10622 [(set (match_operand:DI 0 "register_operand" "=r")
10624 (udiv:SI (match_operand:SI 2 "register_operand" "0")
10625 (match_operand:SI 3 "const_int_operand"))))
10626 (set (match_operand:SI 1 "register_operand" "=r")
10627 (umod:SI (match_dup 2) (match_dup 3)))
10628 (clobber (reg:CC FLAGS_REG))]
10630 && IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
10632 "&& reload_completed"
10633 [(set (match_dup 1) (match_dup 2))
10634 (parallel [(set (match_dup 0)
10635 (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4))))
10636 (clobber (reg:CC FLAGS_REG))])
10637 (parallel [(set (match_dup 1) (and:SI (match_dup 1) (match_dup 5)))
10638 (clobber (reg:CC FLAGS_REG))])]
10640 int v = exact_log2 (UINTVAL (operands[3]));
10641 operands[4] = GEN_INT (v);
10642 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
10644 [(set_attr "type" "multi")
10645 (set_attr "mode" "SI")])
10647 (define_insn_and_split "*divmodsi4_zext_2"
10648 [(set (match_operand:DI 1 "register_operand" "=&d")
10650 (mod:SI (match_operand:SI 2 "register_operand" "0")
10651 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10652 (set (match_operand:SI 0 "register_operand" "=a")
10653 (div:SI (match_dup 2) (match_dup 3)))
10654 (clobber (reg:CC FLAGS_REG))]
10657 "&& reload_completed"
10658 [(parallel [(set (match_dup 6)
10659 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10660 (clobber (reg:CC FLAGS_REG))])
10661 (parallel [(set (match_dup 1)
10662 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
10664 (div:SI (match_dup 2) (match_dup 3)))
10665 (use (match_dup 6))
10666 (clobber (reg:CC FLAGS_REG))])]
10668 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10669 operands[6] = gen_lowpart (SImode, operands[1]);
10671 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10672 operands[4] = operands[2];
10675 /* Avoid use of cltd in favor of a mov+shift. */
10676 emit_move_insn (operands[6], operands[2]);
10677 operands[4] = operands[6];
10680 [(set_attr "type" "multi")
10681 (set_attr "mode" "SI")])
10683 (define_insn_and_split "*udivmodsi4_zext_2"
10684 [(set (match_operand:DI 1 "register_operand" "=&d")
10686 (umod:SI (match_operand:SI 2 "register_operand" "0")
10687 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10688 (set (match_operand:SI 0 "register_operand" "=a")
10689 (udiv:SI (match_dup 2) (match_dup 3)))
10690 (clobber (reg:CC FLAGS_REG))]
10693 "&& reload_completed"
10694 [(set (match_dup 4) (const_int 0))
10695 (parallel [(set (match_dup 1)
10696 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
10698 (udiv:SI (match_dup 2) (match_dup 3)))
10699 (use (match_dup 4))
10700 (clobber (reg:CC FLAGS_REG))])]
10701 "operands[4] = gen_lowpart (SImode, operands[1]);"
10702 [(set_attr "type" "multi")
10703 (set_attr "mode" "SI")])
10705 (define_insn_and_split "*udivmodsi4_pow2_zext_2"
10706 [(set (match_operand:DI 1 "register_operand" "=r")
10708 (umod:SI (match_operand:SI 2 "register_operand" "0")
10709 (match_operand:SI 3 "const_int_operand"))))
10710 (set (match_operand:SI 0 "register_operand" "=r")
10711 (udiv:SI (match_dup 2) (match_dup 3)))
10712 (clobber (reg:CC FLAGS_REG))]
10714 && IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
10716 "&& reload_completed"
10717 [(set (match_dup 1) (match_dup 2))
10718 (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4)))
10719 (clobber (reg:CC FLAGS_REG))])
10720 (parallel [(set (match_dup 1)
10721 (zero_extend:DI (and:SI (match_dup 1) (match_dup 5))))
10722 (clobber (reg:CC FLAGS_REG))])]
10724 int v = exact_log2 (UINTVAL (operands[3]));
10725 operands[4] = GEN_INT (v);
10726 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
10728 [(set_attr "type" "multi")
10729 (set_attr "mode" "SI")])
10731 (define_insn "*<u>divmod<mode>4_noext"
10732 [(set (match_operand:SWIM248 0 "register_operand" "=a")
10734 (match_operand:SWIM248 2 "register_operand" "0")
10735 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
10736 (set (match_operand:SWIM248 1 "register_operand" "=d")
10737 (<paired_mod>:SWIM248 (match_dup 2) (match_dup 3)))
10738 (use (match_operand:SWIM248 4 "register_operand" "1"))
10739 (clobber (reg:CC FLAGS_REG))]
10741 "<sgnprefix>div{<imodesuffix>}\t%3"
10742 [(set_attr "type" "idiv")
10743 (set_attr "mode" "<MODE>")])
10745 (define_insn "*<u>divmodsi4_noext_zext_1"
10746 [(set (match_operand:DI 0 "register_operand" "=a")
10748 (any_div:SI (match_operand:SI 2 "register_operand" "0")
10749 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10750 (set (match_operand:SI 1 "register_operand" "=d")
10751 (<paired_mod>:SI (match_dup 2) (match_dup 3)))
10752 (use (match_operand:SI 4 "register_operand" "1"))
10753 (clobber (reg:CC FLAGS_REG))]
10755 "<sgnprefix>div{l}\t%3"
10756 [(set_attr "type" "idiv")
10757 (set_attr "mode" "SI")])
10759 (define_insn "*<u>divmodsi4_noext_zext_2"
10760 [(set (match_operand:DI 1 "register_operand" "=d")
10762 (<paired_mod>:SI (match_operand:SI 2 "register_operand" "0")
10763 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10764 (set (match_operand:SI 0 "register_operand" "=a")
10765 (any_div:SI (match_dup 2) (match_dup 3)))
10766 (use (match_operand:SI 4 "register_operand" "1"))
10767 (clobber (reg:CC FLAGS_REG))]
10769 "<sgnprefix>div{l}\t%3"
10770 [(set_attr "type" "idiv")
10771 (set_attr "mode" "SI")])
10773 ;; Avoid sign-extension (using cdq) for constant numerators.
10774 (define_insn_and_split "*divmodsi4_const"
10775 [(set (match_operand:SI 0 "register_operand" "=&a")
10776 (div:SI (match_operand:SI 2 "const_int_operand")
10777 (match_operand:SI 3 "nonimmediate_operand" "rm")))
10778 (set (match_operand:SI 1 "register_operand" "=&d")
10779 (mod:SI (match_dup 2) (match_dup 3)))
10780 (clobber (reg:CC FLAGS_REG))]
10781 "!optimize_function_for_size_p (cfun)"
10783 "&& reload_completed"
10784 [(set (match_dup 0) (match_dup 2))
10785 (set (match_dup 1) (match_dup 4))
10786 (parallel [(set (match_dup 0)
10787 (div:SI (match_dup 0) (match_dup 3)))
10789 (mod:SI (match_dup 0) (match_dup 3)))
10790 (use (match_dup 1))
10791 (clobber (reg:CC FLAGS_REG))])]
10793 operands[4] = INTVAL (operands[2]) < 0 ? constm1_rtx : const0_rtx;
10795 [(set_attr "type" "multi")
10796 (set_attr "mode" "SI")])
10798 (define_expand "divmodqi4"
10799 [(parallel [(set (match_operand:QI 0 "register_operand")
10801 (match_operand:QI 1 "register_operand")
10802 (match_operand:QI 2 "nonimmediate_operand")))
10803 (set (match_operand:QI 3 "register_operand")
10804 (mod:QI (match_dup 1) (match_dup 2)))
10805 (clobber (reg:CC FLAGS_REG))])]
10806 "TARGET_QIMODE_MATH"
10811 tmp0 = gen_reg_rtx (HImode);
10812 tmp1 = gen_reg_rtx (HImode);
10814 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
10815 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
10816 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
10818 /* Extract remainder from AH. */
10819 tmp1 = gen_rtx_ZERO_EXTRACT (HImode, tmp0, GEN_INT (8), GEN_INT (8));
10820 tmp1 = lowpart_subreg (QImode, tmp1, HImode);
10821 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
10823 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
10824 set_unique_reg_note (insn, REG_EQUAL, mod);
10826 /* Extract quotient from AL. */
10827 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
10829 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
10830 set_unique_reg_note (insn, REG_EQUAL, div);
10835 (define_expand "udivmodqi4"
10836 [(parallel [(set (match_operand:QI 0 "register_operand")
10838 (match_operand:QI 1 "register_operand")
10839 (match_operand:QI 2 "nonimmediate_operand")))
10840 (set (match_operand:QI 3 "register_operand")
10841 (umod:QI (match_dup 1) (match_dup 2)))
10842 (clobber (reg:CC FLAGS_REG))])]
10843 "TARGET_QIMODE_MATH"
10848 tmp0 = gen_reg_rtx (HImode);
10849 tmp1 = gen_reg_rtx (HImode);
10851 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
10852 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
10853 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
10855 /* Extract remainder from AH. */
10856 tmp1 = gen_rtx_ZERO_EXTRACT (HImode, tmp0, GEN_INT (8), GEN_INT (8));
10857 tmp1 = lowpart_subreg (QImode, tmp1, HImode);
10858 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
10860 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
10861 set_unique_reg_note (insn, REG_EQUAL, mod);
10863 /* Extract quotient from AL. */
10864 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
10866 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
10867 set_unique_reg_note (insn, REG_EQUAL, div);
10872 ;; Divide AX by r/m8, with result stored in
10875 ;; Change div/mod to HImode and extend the second argument to HImode
10876 ;; so that mode of div/mod matches with mode of arguments. Otherwise
10877 ;; combine may fail.
10878 (define_insn "<u>divmodhiqi3"
10879 [(set (match_operand:HI 0 "register_operand" "=a")
10884 (mod:HI (match_operand:HI 1 "register_operand" "0")
10886 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
10890 (div:HI (match_dup 1) (any_extend:HI (match_dup 2)))))))
10891 (clobber (reg:CC FLAGS_REG))]
10892 "TARGET_QIMODE_MATH"
10893 "<sgnprefix>div{b}\t%2"
10894 [(set_attr "type" "idiv")
10895 (set_attr "mode" "QI")])
10897 ;; We cannot use div/idiv for double division, because it causes
10898 ;; "division by zero" on the overflow and that's not what we expect
10899 ;; from truncate. Because true (non truncating) double division is
10900 ;; never generated, we can't create this insn anyway.
10903 ; [(set (match_operand:SI 0 "register_operand" "=a")
10905 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
10907 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
10908 ; (set (match_operand:SI 3 "register_operand" "=d")
10910 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
10911 ; (clobber (reg:CC FLAGS_REG))]
10913 ; "div{l}\t{%2, %0|%0, %2}"
10914 ; [(set_attr "type" "idiv")])
10916 ;;- Logical AND instructions
10918 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
10919 ;; Note that this excludes ah.
10921 (define_expand "@test<mode>_ccno_1"
10922 [(set (reg:CCNO FLAGS_REG)
10925 (match_operand:SWI48 0 "nonimmediate_operand")
10926 (match_operand:SWI48 1 "<nonmemory_szext_operand>"))
10929 (define_expand "testqi_ccz_1"
10930 [(set (reg:CCZ FLAGS_REG)
10933 (match_operand:QI 0 "nonimmediate_operand")
10934 (match_operand:QI 1 "nonmemory_operand"))
10937 (define_insn "*testdi_1"
10938 [(set (reg FLAGS_REG)
10941 (match_operand:DI 0 "nonimmediate_operand" "%r,rm")
10942 (match_operand:DI 1 "x86_64_szext_nonmemory_operand" "Z,re"))
10945 && ix86_match_ccmode
10947 /* If we are going to emit testl instead of testq, and the operands[1]
10948 constant might have the SImode sign bit set, make sure the sign
10949 flag isn't tested, because the instruction will set the sign flag
10950 based on bit 31 rather than bit 63. If it isn't CONST_INT,
10951 conservatively assume it might have bit 31 set. */
10952 (satisfies_constraint_Z (operands[1])
10953 && (!CONST_INT_P (operands[1])
10954 || val_signbit_known_set_p (SImode, INTVAL (operands[1]))))
10955 ? CCZmode : CCNOmode)"
10957 test{l}\t{%k1, %k0|%k0, %k1}
10958 test{q}\t{%1, %0|%0, %1}"
10959 [(set_attr "type" "test")
10960 (set_attr "mode" "SI,DI")])
10962 (define_insn "*testqi_1_maybe_si"
10963 [(set (reg FLAGS_REG)
10966 (match_operand:QI 0 "nonimmediate_operand" "%qm,qm,r")
10967 (match_operand:QI 1 "nonmemory_operand" "q,n,n"))
10969 "ix86_match_ccmode (insn,
10970 CONST_INT_P (operands[1])
10971 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
10973 if (get_attr_mode (insn) == MODE_SI)
10975 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
10976 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
10977 return "test{l}\t{%1, %k0|%k0, %1}";
10979 return "test{b}\t{%1, %0|%0, %1}";
10981 [(set_attr "type" "test")
10983 (cond [(eq_attr "alternative" "2")
10984 (const_string "SI")
10985 (and (match_test "optimize_insn_for_size_p ()")
10986 (and (match_operand 0 "ext_QIreg_operand")
10987 (match_operand 1 "const_0_to_127_operand")))
10988 (const_string "SI")
10990 (const_string "QI")))
10991 (set_attr "pent_pair" "uv,np,np")])
10993 (define_insn "*test<mode>_1"
10994 [(set (reg FLAGS_REG)
10997 (match_operand:SWI124 0 "nonimmediate_operand" "%<r>m,*a,<r>m")
10998 (match_operand:SWI124 1 "<nonmemory_szext_operand>" "<r>,<i>,<i>"))
11000 "ix86_match_ccmode (insn, CCNOmode)"
11001 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
11002 [(set_attr "type" "test")
11003 (set_attr "mode" "<MODE>")
11004 (set_attr "pent_pair" "uv,uv,np")])
11006 (define_expand "testqi_ext_1_ccno"
11007 [(set (reg:CCNO FLAGS_REG)
11012 (match_operand:HI 0 "register_operand")
11015 (match_operand:QI 1 "const_int_operand"))
11018 (define_insn "*testqi_ext<mode>_1"
11019 [(set (reg FLAGS_REG)
11023 (match_operator:SWI248 2 "extract_operator"
11024 [(match_operand 0 "int248_register_operand" "Q")
11027 (match_operand:QI 1 "general_operand" "QnBn"))
11029 "ix86_match_ccmode (insn, CCNOmode)"
11030 "test{b}\t{%1, %h0|%h0, %1}"
11031 [(set_attr "addr" "gpr8")
11032 (set_attr "type" "test")
11033 (set_attr "mode" "QI")])
11035 (define_insn "*testqi_ext<mode>_2"
11036 [(set (reg FLAGS_REG)
11040 (match_operator:SWI248 2 "extract_operator"
11041 [(match_operand 0 "int248_register_operand" "Q")
11045 (match_operator:SWI248 3 "extract_operator"
11046 [(match_operand 1 "int248_register_operand" "Q")
11048 (const_int 8)]) 0))
11050 "ix86_match_ccmode (insn, CCNOmode)"
11051 "test{b}\t{%h1, %h0|%h0, %h1}"
11052 [(set_attr "type" "test")
11053 (set_attr "mode" "QI")])
11055 ;; Provide a *testti instruction that STV can implement using ptest.
11056 ;; This pattern splits into *andti3_doubleword and *cmpti_doubleword.
11057 (define_insn_and_split "*testti_doubleword"
11058 [(set (reg:CCZ FLAGS_REG)
11060 (and:TI (match_operand:TI 0 "register_operand")
11061 (match_operand:TI 1 "general_operand"))
11064 && ix86_pre_reload_split ()"
11067 [(parallel [(set (match_dup 2) (and:TI (match_dup 0) (match_dup 1)))
11068 (clobber (reg:CC FLAGS_REG))])
11069 (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 2) (const_int 0)))]
11071 operands[2] = gen_reg_rtx (TImode);
11072 if (!x86_64_hilo_general_operand (operands[1], TImode))
11073 operands[1] = force_reg (TImode, operands[1]);
11076 ;; Combine likes to form bit extractions for some tests. Humor it.
11077 (define_insn_and_split "*testqi_ext_3"
11078 [(set (match_operand 0 "flags_reg_operand")
11079 (match_operator 1 "compare_operator"
11080 [(zero_extract:SWI248
11081 (match_operand 2 "int_nonimmediate_operand" "rm")
11082 (match_operand:QI 3 "const_int_operand")
11083 (match_operand:QI 4 "const_int_operand"))
11085 "/* Ensure that resulting mask is zero or sign extended operand. */
11086 INTVAL (operands[4]) >= 0
11087 && ((INTVAL (operands[3]) > 0
11088 && INTVAL (operands[3]) + INTVAL (operands[4]) <= 32)
11089 || (<MODE>mode == DImode
11090 && INTVAL (operands[3]) > 32
11091 && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))
11092 && ix86_match_ccmode (insn,
11093 /* If zero_extract mode precision is the same
11094 as len, the SF of the zero_extract
11095 comparison will be the most significant
11096 extracted bit, but this could be matched
11097 after splitting only for pos 0 len all bits
11098 trivial extractions. Require CCZmode. */
11099 (GET_MODE_PRECISION (<MODE>mode)
11100 == INTVAL (operands[3]))
11101 /* Otherwise, require CCZmode if we'd use a mask
11102 with the most significant bit set and can't
11103 widen it to wider mode. *testdi_1 also
11104 requires CCZmode if the mask has bit
11105 31 set and all bits above it clear. */
11106 || (INTVAL (operands[3]) + INTVAL (operands[4])
11108 /* We can't widen also if val is not a REG. */
11109 || (INTVAL (operands[3]) + INTVAL (operands[4])
11110 == GET_MODE_PRECISION (GET_MODE (operands[2]))
11111 && !register_operand (operands[2],
11112 GET_MODE (operands[2])))
11113 /* And we shouldn't widen if
11114 TARGET_PARTIAL_REG_STALL. */
11115 || (TARGET_PARTIAL_REG_STALL
11116 && (INTVAL (operands[3]) + INTVAL (operands[4])
11117 >= (paradoxical_subreg_p (operands[2])
11119 (GET_MODE (SUBREG_REG (operands[2])))
11121 ? GET_MODE_PRECISION
11122 (GET_MODE (SUBREG_REG (operands[2])))
11123 : GET_MODE_PRECISION
11124 (GET_MODE (operands[2])))))
11125 ? CCZmode : CCNOmode)"
11128 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11130 rtx val = operands[2];
11131 HOST_WIDE_INT len = INTVAL (operands[3]);
11132 HOST_WIDE_INT pos = INTVAL (operands[4]);
11133 machine_mode mode = GET_MODE (val);
11135 if (SUBREG_P (val))
11137 machine_mode submode = GET_MODE (SUBREG_REG (val));
11139 /* Narrow paradoxical subregs to prevent partial register stalls. */
11140 if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)
11141 && GET_MODE_CLASS (submode) == MODE_INT
11142 && (GET_MODE (operands[0]) == CCZmode
11143 || pos + len < GET_MODE_PRECISION (submode)
11144 || REG_P (SUBREG_REG (val))))
11146 val = SUBREG_REG (val);
11151 /* Small HImode tests can be converted to QImode. */
11153 && register_operand (val, HImode))
11155 rtx nval = gen_lowpart (QImode, val);
11157 || GET_MODE (operands[0]) == CCZmode
11165 gcc_assert (pos + len <= GET_MODE_PRECISION (mode));
11167 /* If the mask is going to have the sign bit set in the mode
11168 we want to do the comparison in and user isn't interested just
11169 in the zero flag, then we must widen the target mode. */
11170 if (pos + len == GET_MODE_PRECISION (mode)
11171 && GET_MODE (operands[0]) != CCZmode)
11173 gcc_assert (pos + len < 32 && !MEM_P (val));
11175 val = gen_lowpart (mode, val);
11179 = wi::shifted_mask (pos, len, false, GET_MODE_PRECISION (mode));
11181 operands[2] = gen_rtx_AND (mode, val, immed_wide_int_const (mask, mode));
11184 ;; Split and;cmp (as optimized by combine) into not;test
11185 ;; Except when TARGET_BMI provides andn (*andn_<mode>_ccno).
11186 (define_insn_and_split "*test<mode>_not"
11187 [(set (reg:CCZ FLAGS_REG)
11190 (not:SWI (match_operand:SWI 0 "register_operand"))
11191 (match_operand:SWI 1 "<nonmemory_szext_operand>"))
11193 "ix86_pre_reload_split ()
11194 && (!TARGET_BMI || !REG_P (operands[1]))"
11197 [(set (match_dup 2) (not:SWI (match_dup 0)))
11198 (set (reg:CCZ FLAGS_REG)
11199 (compare:CCZ (and:SWI (match_dup 2) (match_dup 1))
11201 "operands[2] = gen_reg_rtx (<MODE>mode);")
11203 ;; Split and;cmp (as optimized by combine) into andn;cmp $0
11204 (define_insn_and_split "*test<mode>_not_doubleword"
11205 [(set (reg:CCZ FLAGS_REG)
11208 (not:DWI (match_operand:DWI 0 "nonimmediate_operand"))
11209 (match_operand:DWI 1 "nonimmediate_operand"))
11211 "ix86_pre_reload_split ()"
11215 [(set (match_dup 2) (and:DWI (not:DWI (match_dup 0)) (match_dup 1)))
11216 (clobber (reg:CC FLAGS_REG))])
11217 (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 2) (const_int 0)))]
11219 operands[0] = force_reg (<MODE>mode, operands[0]);
11220 operands[2] = gen_reg_rtx (<MODE>mode);
11223 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
11224 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
11225 ;; this is relatively important trick.
11226 ;; Do the conversion only post-reload to avoid limiting of the register class
11229 [(set (match_operand 0 "flags_reg_operand")
11230 (match_operator 1 "compare_operator"
11231 [(and (match_operand 2 "QIreg_operand")
11232 (match_operand 3 "const_int_operand"))
11235 && GET_MODE (operands[2]) != QImode
11236 && ((ix86_match_ccmode (insn, CCZmode)
11237 && !(INTVAL (operands[3]) & ~(255 << 8)))
11238 || (ix86_match_ccmode (insn, CCNOmode)
11239 && !(INTVAL (operands[3]) & ~(127 << 8))))"
11240 [(set (match_dup 0)
11244 (zero_extract:HI (match_dup 2)
11250 operands[2] = gen_lowpart (HImode, operands[2]);
11251 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, QImode);
11255 [(set (match_operand 0 "flags_reg_operand")
11256 (match_operator 1 "compare_operator"
11257 [(and (match_operand 2 "nonimmediate_operand")
11258 (match_operand 3 "const_int_operand"))
11261 && GET_MODE (operands[2]) != QImode
11262 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
11263 && ((ix86_match_ccmode (insn, CCZmode)
11264 && !(INTVAL (operands[3]) & ~255))
11265 || (ix86_match_ccmode (insn, CCNOmode)
11266 && !(INTVAL (operands[3]) & ~127)))"
11267 [(set (match_dup 0)
11268 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
11271 operands[2] = gen_lowpart (QImode, operands[2]);
11272 operands[3] = gen_int_mode (INTVAL (operands[3]), QImode);
11275 ;; Narrow test instructions with immediate operands that test
11276 ;; memory locations for zero. E.g. testl $0x00aa0000, mem can be
11277 ;; converted to testb $0xaa, mem+2. Reject volatile locations and
11278 ;; targets where reading (possibly unaligned) part of memory
11279 ;; location after a large write to the same address causes
11280 ;; store-to-load forwarding stall.
11282 [(set (reg:CCZ FLAGS_REG)
11284 (and:SWI248 (match_operand:SWI248 0 "memory_operand")
11285 (match_operand 1 "const_int_operand"))
11287 "!TARGET_PARTIAL_MEMORY_READ_STALL && !MEM_VOLATILE_P (operands[0])"
11288 [(set (reg:CCZ FLAGS_REG)
11289 (compare:CCZ (match_dup 2) (const_int 0)))]
11291 unsigned HOST_WIDE_INT ival = UINTVAL (operands[1]);
11292 int first_nonzero_byte, bitsize;
11293 rtx new_addr, new_const;
11294 machine_mode new_mode;
11299 /* Clear bits outside mode width. */
11300 ival &= GET_MODE_MASK (<MODE>mode);
11302 first_nonzero_byte = ctz_hwi (ival) / BITS_PER_UNIT;
11304 ival >>= first_nonzero_byte * BITS_PER_UNIT;
11306 bitsize = sizeof (ival) * BITS_PER_UNIT - clz_hwi (ival);
11308 if (bitsize <= GET_MODE_BITSIZE (QImode))
11310 else if (bitsize <= GET_MODE_BITSIZE (HImode))
11312 else if (bitsize <= GET_MODE_BITSIZE (SImode))
11317 if (GET_MODE_SIZE (new_mode) >= GET_MODE_SIZE (<MODE>mode))
11320 new_addr = adjust_address (operands[0], new_mode, first_nonzero_byte);
11321 new_const = gen_int_mode (ival, new_mode);
11323 operands[2] = gen_rtx_AND (new_mode, new_addr, new_const);
11326 ;; %%% This used to optimize known byte-wide and operations to memory,
11327 ;; and sometimes to QImode registers. If this is considered useful,
11328 ;; it should be done with splitters.
11330 (define_expand "and<mode>3"
11331 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
11332 (and:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
11333 (match_operand:SDWIM 2 "<general_szext_operand>")))]
11336 machine_mode mode = <MODE>mode;
11338 if (GET_MODE_SIZE (<MODE>mode) > UNITS_PER_WORD
11339 && !x86_64_hilo_general_operand (operands[2], <MODE>mode))
11340 operands[2] = force_reg (<MODE>mode, operands[2]);
11342 if (GET_MODE_SIZE (<MODE>mode) <= UNITS_PER_WORD
11343 && const_int_operand (operands[2], <MODE>mode)
11344 && register_operand (operands[0], <MODE>mode)
11345 && !(TARGET_ZERO_EXTEND_WITH_AND
11346 && optimize_function_for_speed_p (cfun)))
11348 unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
11350 if (ival == GET_MODE_MASK (SImode))
11352 else if (ival == GET_MODE_MASK (HImode))
11354 else if (ival == GET_MODE_MASK (QImode))
11358 if (mode != <MODE>mode)
11359 emit_insn (gen_extend_insn
11360 (operands[0], gen_lowpart (mode, operands[1]),
11361 <MODE>mode, mode, 1));
11363 ix86_expand_binary_operator (AND, <MODE>mode, operands);
11368 (define_insn_and_split "*and<dwi>3_doubleword"
11369 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
11371 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
11372 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
11373 (clobber (reg:CC FLAGS_REG))]
11374 "ix86_binary_operator_ok (AND, <DWI>mode, operands)"
11376 "&& reload_completed"
11377 [(const_int:DWIH 0)]
11379 bool emit_insn_deleted_note_p = false;
11381 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
11383 if (operands[2] == const0_rtx)
11384 emit_move_insn (operands[0], const0_rtx);
11385 else if (operands[2] == constm1_rtx)
11386 emit_insn_deleted_note_p = true;
11388 ix86_expand_binary_operator (AND, <MODE>mode, &operands[0]);
11390 if (operands[5] == const0_rtx)
11391 emit_move_insn (operands[3], const0_rtx);
11392 else if (operands[5] == constm1_rtx)
11394 if (emit_insn_deleted_note_p)
11395 emit_note (NOTE_INSN_DELETED);
11398 ix86_expand_binary_operator (AND, <MODE>mode, &operands[3]);
11403 (define_insn "*anddi_1"
11404 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,?k")
11406 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
11407 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m,L,k")))
11408 (clobber (reg:CC FLAGS_REG))]
11409 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
11411 and{l}\t{%k2, %k0|%k0, %k2}
11412 and{q}\t{%2, %0|%0, %2}
11413 and{q}\t{%2, %0|%0, %2}
11416 [(set_attr "isa" "x64,x64,x64,x64,avx512bw_512")
11417 (set_attr "type" "alu,alu,alu,imovx,msklog")
11418 (set_attr "length_immediate" "*,*,*,0,*")
11419 (set (attr "prefix_rex")
11421 (and (eq_attr "type" "imovx")
11422 (and (match_test "INTVAL (operands[2]) == 0xff")
11423 (match_operand 1 "ext_QIreg_operand")))
11425 (const_string "*")))
11426 (set_attr "mode" "SI,DI,DI,SI,DI")])
11428 (define_insn_and_split "*anddi_1_btr"
11429 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11431 (match_operand:DI 1 "nonimmediate_operand" "%0")
11432 (match_operand:DI 2 "const_int_operand" "n")))
11433 (clobber (reg:CC FLAGS_REG))]
11434 "TARGET_64BIT && TARGET_USE_BT
11435 && ix86_binary_operator_ok (AND, DImode, operands)
11436 && IN_RANGE (exact_log2 (~INTVAL (operands[2])), 31, 63)"
11438 "&& reload_completed"
11439 [(parallel [(set (zero_extract:DI (match_dup 0)
11443 (clobber (reg:CC FLAGS_REG))])]
11444 "operands[3] = GEN_INT (exact_log2 (~INTVAL (operands[2])));"
11445 [(set_attr "type" "alu1")
11446 (set_attr "prefix_0f" "1")
11447 (set_attr "znver1_decode" "double")
11448 (set_attr "mode" "DI")])
11450 ;; Turn *anddi_1 into *andsi_1_zext if possible.
11452 [(set (match_operand:DI 0 "register_operand")
11453 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
11454 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
11455 (clobber (reg:CC FLAGS_REG))]
11457 [(parallel [(set (match_dup 0)
11458 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
11459 (clobber (reg:CC FLAGS_REG))])]
11461 if (GET_CODE (operands[2]) == SYMBOL_REF
11462 || GET_CODE (operands[2]) == LABEL_REF)
11464 operands[2] = shallow_copy_rtx (operands[2]);
11465 PUT_MODE (operands[2], SImode);
11467 else if (GET_CODE (operands[2]) == CONST)
11469 /* (const:DI (plus:DI (symbol_ref:DI ("...")) (const_int N))) */
11470 operands[2] = copy_rtx (operands[2]);
11471 PUT_MODE (operands[2], SImode);
11472 PUT_MODE (XEXP (operands[2], 0), SImode);
11473 PUT_MODE (XEXP (XEXP (operands[2], 0), 0), SImode);
11476 operands[2] = gen_lowpart (SImode, operands[2]);
11479 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
11480 (define_insn "*andsi_1_zext"
11481 [(set (match_operand:DI 0 "register_operand" "=r")
11483 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
11484 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
11485 (clobber (reg:CC FLAGS_REG))]
11486 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
11487 "and{l}\t{%2, %k0|%k0, %2}"
11488 [(set_attr "type" "alu")
11489 (set_attr "mode" "SI")])
11491 (define_insn "*and<mode>_1"
11492 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya,?k")
11493 (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm,k")
11494 (match_operand:SWI24 2 "<general_operand>" "r<i>,<m>,L,k")))
11495 (clobber (reg:CC FLAGS_REG))]
11496 "ix86_binary_operator_ok (AND, <MODE>mode, operands)"
11498 and{<imodesuffix>}\t{%2, %0|%0, %2}
11499 and{<imodesuffix>}\t{%2, %0|%0, %2}
11503 (cond [(eq_attr "alternative" "3")
11504 (if_then_else (eq_attr "mode" "SI")
11505 (const_string "avx512bw")
11506 (const_string "avx512f"))
11508 (const_string "*")))
11509 (set_attr "type" "alu,alu,imovx,msklog")
11510 (set_attr "length_immediate" "*,*,0,*")
11511 (set (attr "prefix_rex")
11513 (and (eq_attr "type" "imovx")
11514 (and (match_test "INTVAL (operands[2]) == 0xff")
11515 (match_operand 1 "ext_QIreg_operand")))
11517 (const_string "*")))
11518 (set_attr "mode" "<MODE>,<MODE>,SI,<MODE>")])
11520 (define_insn "*andqi_1"
11521 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,?k")
11522 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
11523 (match_operand:QI 2 "general_operand" "qn,m,rn,k")))
11524 (clobber (reg:CC FLAGS_REG))]
11525 "ix86_binary_operator_ok (AND, QImode, operands)"
11527 and{b}\t{%2, %0|%0, %2}
11528 and{b}\t{%2, %0|%0, %2}
11529 and{l}\t{%k2, %k0|%k0, %k2}
11531 [(set_attr "type" "alu,alu,alu,msklog")
11533 (cond [(eq_attr "alternative" "2")
11534 (const_string "SI")
11535 (and (eq_attr "alternative" "3")
11536 (match_test "!TARGET_AVX512DQ"))
11537 (const_string "HI")
11539 (const_string "QI")))
11540 ;; Potential partial reg stall on alternative 2.
11541 (set (attr "preferred_for_speed")
11542 (cond [(eq_attr "alternative" "2")
11543 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
11544 (symbol_ref "true")))])
11546 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
11547 (define_insn_and_split "*<code><mode>_1_slp"
11548 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
11549 (any_logic:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0,!<r>")
11550 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
11551 (clobber (reg:CC FLAGS_REG))]
11552 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
11554 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
11556 "&& reload_completed
11557 && !(rtx_equal_p (operands[0], operands[1])
11558 || rtx_equal_p (operands[0], operands[2]))"
11559 [(set (strict_low_part (match_dup 0)) (match_dup 1))
11561 [(set (strict_low_part (match_dup 0))
11562 (any_logic:SWI12 (match_dup 0) (match_dup 2)))
11563 (clobber (reg:CC FLAGS_REG))])]
11565 [(set_attr "type" "alu")
11566 (set_attr "mode" "<MODE>")])
11568 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
11569 (define_insn_and_split "*<code>qi_ext<mode>_1_slp"
11570 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+Q,&Q"))
11573 (match_operator:SWI248 3 "extract_operator"
11574 [(match_operand 2 "int248_register_operand" "Q,Q")
11577 (match_operand:QI 1 "nonimmediate_operand" "0,!qm")))
11578 (clobber (reg:CC FLAGS_REG))]
11579 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
11581 <logic>{b}\t{%h2, %0|%0, %h2}
11583 "&& reload_completed
11584 && !rtx_equal_p (operands[0], operands[1])"
11585 [(set (strict_low_part (match_dup 0)) (match_dup 1))
11587 [(set (strict_low_part (match_dup 0))
11591 [(match_dup 2) (const_int 8) (const_int 8)]) 0)
11593 (clobber (reg:CC FLAGS_REG))])]
11595 [(set_attr "type" "alu")
11596 (set_attr "mode" "QI")])
11598 (define_insn_and_split "*<code>qi_ext<mode>_2_slp"
11599 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+&Q"))
11602 (match_operator:SWI248 3 "extract_operator"
11603 [(match_operand 1 "int248_register_operand" "Q")
11607 (match_operator:SWI248 4 "extract_operator"
11608 [(match_operand 2 "int248_register_operand" "Q")
11610 (const_int 8)]) 0)))
11611 (clobber (reg:CC FLAGS_REG))]
11612 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
11614 "&& reload_completed"
11615 [(set (strict_low_part (match_dup 0))
11618 [(match_dup 2) (const_int 8) (const_int 8)]) 0))
11620 [(set (strict_low_part (match_dup 0))
11624 [(match_dup 1) (const_int 8) (const_int 8)]) 0)
11626 (clobber (reg:CC FLAGS_REG))])]
11628 [(set_attr "type" "alu")
11629 (set_attr "mode" "QI")])
11632 [(set (match_operand:SWI248 0 "register_operand")
11633 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
11634 (match_operand:SWI248 2 "const_int_operand")))
11635 (clobber (reg:CC FLAGS_REG))]
11637 && (!REG_P (operands[1])
11638 || REGNO (operands[0]) != REGNO (operands[1]))"
11641 unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
11644 if (ival == GET_MODE_MASK (SImode))
11646 else if (ival == GET_MODE_MASK (HImode))
11648 else if (ival == GET_MODE_MASK (QImode))
11651 gcc_unreachable ();
11653 /* Zero extend to SImode to avoid partial register stalls. */
11654 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
11655 operands[0] = gen_lowpart (SImode, operands[0]);
11657 emit_insn (gen_extend_insn
11658 (operands[0], gen_lowpart (mode, operands[1]),
11659 GET_MODE (operands[0]), mode, 1));
11664 [(set (match_operand:SWI48 0 "register_operand")
11665 (and:SWI48 (match_dup 0)
11666 (const_int -65536)))
11667 (clobber (reg:CC FLAGS_REG))]
11668 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
11669 || optimize_function_for_size_p (cfun)"
11670 [(set (strict_low_part (match_dup 1)) (const_int 0))]
11671 "operands[1] = gen_lowpart (HImode, operands[0]);")
11674 [(set (match_operand:SWI248 0 "any_QIreg_operand")
11675 (and:SWI248 (match_dup 0)
11677 (clobber (reg:CC FLAGS_REG))]
11678 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11679 && reload_completed"
11680 [(set (strict_low_part (match_dup 1)) (const_int 0))]
11681 "operands[1] = gen_lowpart (QImode, operands[0]);")
11684 [(set (match_operand:SWI248 0 "QIreg_operand")
11685 (and:SWI248 (match_dup 0)
11686 (const_int -65281)))
11687 (clobber (reg:CC FLAGS_REG))]
11688 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11689 && reload_completed"
11691 [(set (zero_extract:HI (match_dup 0)
11697 (zero_extract:HI (match_dup 0)
11701 (zero_extract:HI (match_dup 0)
11703 (const_int 8)) 0)) 0))
11704 (clobber (reg:CC FLAGS_REG))])]
11705 "operands[0] = gen_lowpart (HImode, operands[0]);")
11707 (define_insn "*anddi_2"
11708 [(set (reg FLAGS_REG)
11711 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
11712 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m"))
11714 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
11715 (and:DI (match_dup 1) (match_dup 2)))]
11717 && ix86_match_ccmode
11719 /* If we are going to emit andl instead of andq, and the operands[2]
11720 constant might have the SImode sign bit set, make sure the sign
11721 flag isn't tested, because the instruction will set the sign flag
11722 based on bit 31 rather than bit 63. If it isn't CONST_INT,
11723 conservatively assume it might have bit 31 set. */
11724 (satisfies_constraint_Z (operands[2])
11725 && (!CONST_INT_P (operands[2])
11726 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
11727 ? CCZmode : CCNOmode)
11728 && ix86_binary_operator_ok (AND, DImode, operands)"
11730 and{l}\t{%k2, %k0|%k0, %k2}
11731 and{q}\t{%2, %0|%0, %2}
11732 and{q}\t{%2, %0|%0, %2}"
11733 [(set_attr "type" "alu")
11734 (set_attr "mode" "SI,DI,DI")])
11736 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
11737 (define_insn "*andsi_2_zext"
11738 [(set (reg FLAGS_REG)
11740 (match_operand:SI 1 "nonimmediate_operand" "%0")
11741 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
11743 (set (match_operand:DI 0 "register_operand" "=r")
11744 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
11745 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
11746 && ix86_binary_operator_ok (AND, SImode, operands)"
11747 "and{l}\t{%2, %k0|%k0, %2}"
11748 [(set_attr "type" "alu")
11749 (set_attr "mode" "SI")])
11751 (define_insn "*andqi_2_maybe_si"
11752 [(set (reg FLAGS_REG)
11754 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
11755 (match_operand:QI 2 "general_operand" "qn,m,n"))
11757 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
11758 (and:QI (match_dup 1) (match_dup 2)))]
11759 "ix86_binary_operator_ok (AND, QImode, operands)
11760 && ix86_match_ccmode (insn,
11761 CONST_INT_P (operands[2])
11762 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
11764 if (get_attr_mode (insn) == MODE_SI)
11766 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
11767 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
11768 return "and{l}\t{%2, %k0|%k0, %2}";
11770 return "and{b}\t{%2, %0|%0, %2}";
11772 [(set_attr "type" "alu")
11774 (cond [(eq_attr "alternative" "2")
11775 (const_string "SI")
11776 (and (match_test "optimize_insn_for_size_p ()")
11777 (and (match_operand 0 "ext_QIreg_operand")
11778 (match_operand 2 "const_0_to_127_operand")))
11779 (const_string "SI")
11781 (const_string "QI")))
11782 ;; Potential partial reg stall on alternative 2.
11783 (set (attr "preferred_for_speed")
11784 (cond [(eq_attr "alternative" "2")
11785 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
11786 (symbol_ref "true")))])
11788 (define_insn "*and<mode>_2"
11789 [(set (reg FLAGS_REG)
11790 (compare (and:SWI124
11791 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
11792 (match_operand:SWI124 2 "<general_operand>" "<r><i>,<m>"))
11794 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>m,<r>")
11795 (and:SWI124 (match_dup 1) (match_dup 2)))]
11796 "ix86_match_ccmode (insn, CCNOmode)
11797 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
11798 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
11799 [(set_attr "type" "alu")
11800 (set_attr "mode" "<MODE>")])
11802 (define_insn "*<code>qi_ext<mode>_0"
11803 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn")
11806 (match_operator:SWI248 3 "extract_operator"
11807 [(match_operand 2 "int248_register_operand" "Q")
11810 (match_operand:QI 1 "nonimmediate_operand" "0")))
11811 (clobber (reg:CC FLAGS_REG))]
11813 "<logic>{b}\t{%h2, %0|%0, %h2}"
11814 [(set_attr "addr" "gpr8")
11815 (set_attr "type" "alu")
11816 (set_attr "mode" "QI")])
11818 (define_expand "andqi_ext_1"
11820 [(set (zero_extract:HI (match_operand:HI 0 "register_operand")
11826 (zero_extract:HI (match_operand:HI 1 "register_operand")
11829 (match_operand:QI 2 "const_int_operand")) 0))
11830 (clobber (reg:CC FLAGS_REG))])])
11832 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
11833 (define_insn_and_split "*<code>qi_ext<mode>_1"
11834 [(set (zero_extract:SWI248
11835 (match_operand 0 "int248_register_operand" "+Q,&Q")
11841 (match_operator:SWI248 3 "extract_operator"
11842 [(match_operand 1 "int248_register_operand" "0,!Q")
11845 (match_operand:QI 2 "general_operand" "QnBn,QnBn")) 0))
11846 (clobber (reg:CC FLAGS_REG))]
11849 <logic>{b}\t{%2, %h0|%h0, %2}
11852 && !(rtx_equal_p (operands[0], operands[1]))"
11853 [(set (zero_extract:SWI248
11854 (match_dup 0) (const_int 8) (const_int 8))
11855 (zero_extract:SWI248
11856 (match_dup 1) (const_int 8) (const_int 8)))
11858 [(set (zero_extract:SWI248
11859 (match_dup 0) (const_int 8) (const_int 8))
11864 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
11866 (clobber (reg:CC FLAGS_REG))])]
11868 [(set_attr "addr" "gpr8")
11869 (set_attr "type" "alu")
11870 (set_attr "mode" "QI")])
11872 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
11873 (define_insn_and_split "*<code>qi_ext<mode>_1_cc"
11874 [(set (match_operand 4 "flags_reg_operand")
11875 (match_operator 5 "compare_operator"
11878 (match_operator:SWI248 3 "extract_operator"
11879 [(match_operand 1 "int248_register_operand" "0,!Q")
11882 (match_operand:QI 2 "general_operand" "QnBn,QnBn"))
11884 (set (zero_extract:SWI248
11885 (match_operand 0 "int248_register_operand" "+Q,&Q")
11892 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
11893 (match_dup 2)) 0))]
11894 "ix86_match_ccmode (insn, CCNOmode)"
11896 <logic>{b}\t{%2, %h0|%h0, %2}
11898 "&& reload_completed
11899 && !(rtx_equal_p (operands[0], operands[1]))"
11900 [(set (zero_extract:SWI248
11901 (match_dup 0) (const_int 8) (const_int 8))
11902 (zero_extract:SWI248
11903 (match_dup 1) (const_int 8) (const_int 8)))
11905 [(set (match_dup 4)
11910 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
11913 (set (zero_extract:SWI248
11914 (match_dup 0) (const_int 8) (const_int 8))
11919 [(match_dup 1) (const_int 8) (const_int 8)]) 0)
11920 (match_dup 2)) 0))])]
11922 [(set_attr "addr" "gpr8")
11923 (set_attr "type" "alu")
11924 (set_attr "mode" "QI")])
11926 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
11927 (define_insn_and_split "*<code>qi_ext<mode>_2"
11928 [(set (zero_extract:SWI248
11929 (match_operand 0 "int248_register_operand" "+Q,&Q")
11935 (match_operator:SWI248 3 "extract_operator"
11936 [(match_operand 1 "int248_register_operand" "%0,!Q")
11940 (match_operator:SWI248 4 "extract_operator"
11941 [(match_operand 2 "int248_register_operand" "Q,Q")
11943 (const_int 8)]) 0)) 0))
11944 (clobber (reg:CC FLAGS_REG))]
11947 <logic>{b}\t{%h2, %h0|%h0, %h2}
11950 && !(rtx_equal_p (operands[0], operands[1])
11951 || rtx_equal_p (operands[0], operands[2]))"
11952 [(set (zero_extract:SWI248
11953 (match_dup 0) (const_int 8) (const_int 8))
11954 (zero_extract:SWI248
11955 (match_dup 1) (const_int 8) (const_int 8)))
11957 [(set (zero_extract:SWI248
11958 (match_dup 0) (const_int 8) (const_int 8))
11963 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
11966 [(match_dup 2) (const_int 8) (const_int 8)]) 0)) 0))
11967 (clobber (reg:CC FLAGS_REG))])]
11969 [(set_attr "type" "alu")
11970 (set_attr "mode" "QI")])
11972 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
11973 (define_insn_and_split "*<code>qi_ext<mode>_3"
11974 [(set (zero_extract:SWI248
11975 (match_operand 0 "int248_register_operand" "+Q,&Q")
11978 (match_operator:SWI248 3 "extract_operator"
11980 (match_operand 1 "int248_register_operand" "%0,!Q")
11981 (match_operand 2 "int248_register_operand" "Q,Q"))
11984 (clobber (reg:CC FLAGS_REG))]
11985 "GET_MODE (operands[1]) == GET_MODE (operands[2])"
11987 <logic>{b}\t{%h2, %h0|%h0, %h2}
11989 "&& reload_completed
11990 && !(rtx_equal_p (operands[0], operands[1])
11991 || rtx_equal_p (operands[0], operands[2]))"
11992 [(set (zero_extract:SWI248
11993 (match_dup 0) (const_int 8) (const_int 8))
11994 (zero_extract:SWI248
11995 (match_dup 1) (const_int 8) (const_int 8)))
11997 [(set (zero_extract:SWI248
11998 (match_dup 0) (const_int 8) (const_int 8))
12000 [(any_logic (match_dup 4) (match_dup 2))
12001 (const_int 8) (const_int 8)]))
12002 (clobber (reg:CC FLAGS_REG))])]
12003 "operands[4] = gen_lowpart (GET_MODE (operands[1]), operands[0]);"
12004 [(set_attr "type" "alu")
12005 (set_attr "mode" "QI")])
12007 ;; Convert wide AND instructions with immediate operand to shorter QImode
12008 ;; equivalents when possible.
12009 ;; Don't do the splitting with memory operands, since it introduces risk
12010 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
12011 ;; for size, but that can (should?) be handled by generic code instead.
12013 [(set (match_operand:SWI248 0 "QIreg_operand")
12014 (and:SWI248 (match_operand:SWI248 1 "register_operand")
12015 (match_operand:SWI248 2 "const_int_operand")))
12016 (clobber (reg:CC FLAGS_REG))]
12018 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12019 && !(~INTVAL (operands[2]) & ~(255 << 8))"
12021 [(set (zero_extract:HI (match_dup 0)
12027 (zero_extract:HI (match_dup 1)
12031 (clobber (reg:CC FLAGS_REG))])]
12033 operands[0] = gen_lowpart (HImode, operands[0]);
12034 operands[1] = gen_lowpart (HImode, operands[1]);
12035 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
12038 ;; Since AND can be encoded with sign extended immediate, this is only
12039 ;; profitable when 7th bit is not set.
12041 [(set (match_operand:SWI248 0 "any_QIreg_operand")
12042 (and:SWI248 (match_operand:SWI248 1 "general_operand")
12043 (match_operand:SWI248 2 "const_int_operand")))
12044 (clobber (reg:CC FLAGS_REG))]
12046 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12047 && !(~INTVAL (operands[2]) & ~255)
12048 && !(INTVAL (operands[2]) & 128)"
12049 [(parallel [(set (strict_low_part (match_dup 0))
12050 (and:QI (match_dup 1)
12052 (clobber (reg:CC FLAGS_REG))])]
12054 operands[0] = gen_lowpart (QImode, operands[0]);
12055 operands[1] = gen_lowpart (QImode, operands[1]);
12056 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
12059 (define_insn_and_split "*andn<dwi>3_doubleword_bmi"
12060 [(set (match_operand:<DWI> 0 "register_operand" "=&r,r,r")
12062 (not:<DWI> (match_operand:<DWI> 1 "register_operand" "r,0,r"))
12063 (match_operand:<DWI> 2 "nonimmediate_operand" "ro,ro,0")))
12064 (clobber (reg:CC FLAGS_REG))]
12067 "&& reload_completed"
12068 [(parallel [(set (match_dup 0)
12069 (and:DWIH (not:DWIH (match_dup 1)) (match_dup 2)))
12070 (clobber (reg:CC FLAGS_REG))])
12071 (parallel [(set (match_dup 3)
12072 (and:DWIH (not:DWIH (match_dup 4)) (match_dup 5)))
12073 (clobber (reg:CC FLAGS_REG))])]
12074 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
12076 (define_insn_and_split "*andn<mode>3_doubleword"
12077 [(set (match_operand:DWI 0 "register_operand")
12079 (not:DWI (match_operand:DWI 1 "register_operand"))
12080 (match_operand:DWI 2 "nonimmediate_operand")))
12081 (clobber (reg:CC FLAGS_REG))]
12083 && ix86_pre_reload_split ()"
12086 [(set (match_dup 3) (not:DWI (match_dup 1)))
12087 (parallel [(set (match_dup 0)
12088 (and:DWI (match_dup 3) (match_dup 2)))
12089 (clobber (reg:CC FLAGS_REG))])]
12090 "operands[3] = gen_reg_rtx (<MODE>mode);")
12092 (define_insn "*andn<mode>_1"
12093 [(set (match_operand:SWI48 0 "register_operand" "=r,r,?k")
12095 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r,k"))
12096 (match_operand:SWI48 2 "nonimmediate_operand" "r,m,k")))
12097 (clobber (reg:CC FLAGS_REG))]
12099 || (TARGET_AVX512BW && (<MODE>mode == SImode || TARGET_EVEX512))"
12101 andn\t{%2, %1, %0|%0, %1, %2}
12102 andn\t{%2, %1, %0|%0, %1, %2}
12104 [(set_attr "isa" "bmi,bmi,<kmov_isa>")
12105 (set_attr "type" "bitmanip,bitmanip,msklog")
12106 (set_attr "btver2_decode" "direct, double,*")
12107 (set_attr "mode" "<MODE>")])
12109 (define_insn "*andn<mode>_1"
12110 [(set (match_operand:SWI12 0 "register_operand" "=r,?k")
12112 (not:SWI12 (match_operand:SWI12 1 "register_operand" "r,k"))
12113 (match_operand:SWI12 2 "register_operand" "r,k")))
12114 (clobber (reg:CC FLAGS_REG))]
12115 "TARGET_BMI || TARGET_AVX512BW"
12117 andn\t{%k2, %k1, %k0|%k0, %k1, %k2}
12119 [(set_attr "isa" "bmi,avx512f")
12120 (set_attr "type" "bitmanip,msklog")
12121 (set_attr "btver2_decode" "direct,*")
12123 (cond [(eq_attr "alternative" "0")
12124 (const_string "SI")
12125 (and (eq_attr "alternative" "1")
12126 (match_test "!TARGET_AVX512DQ"))
12127 (const_string "HI")
12129 (const_string "<MODE>")))])
12131 (define_insn "*andn_<mode>_ccno"
12132 [(set (reg FLAGS_REG)
12135 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
12136 (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
12138 (clobber (match_scratch:SWI48 0 "=r,r"))]
12139 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
12140 "andn\t{%2, %1, %0|%0, %1, %2}"
12141 [(set_attr "type" "bitmanip")
12142 (set_attr "btver2_decode" "direct, double")
12143 (set_attr "mode" "<MODE>")])
12145 ;; Split *andnsi_1 after reload with -Oz when not;and is shorter.
12147 [(set (match_operand:SI 0 "register_operand")
12148 (and:SI (not:SI (match_operand:SI 1 "register_operand"))
12149 (match_operand:SI 2 "nonimmediate_operand")))
12150 (clobber (reg:CC FLAGS_REG))]
12152 && optimize_insn_for_size_p () && optimize_size > 1
12153 && REGNO (operands[0]) == REGNO (operands[1])
12154 && LEGACY_INT_REG_P (operands[0])
12155 && !REX_INT_REG_P (operands[2])
12156 && !reg_overlap_mentioned_p (operands[0], operands[2])"
12157 [(set (match_dup 0) (not:SI (match_dup 1)))
12158 (parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
12159 (clobber (reg:CC FLAGS_REG))])])
12161 ;; Split *andn_si_ccno with -Oz when not;test is shorter.
12163 [(set (match_operand 0 "flags_reg_operand")
12164 (match_operator 1 "compare_operator"
12165 [(and:SI (not:SI (match_operand:SI 2 "general_reg_operand"))
12166 (match_operand:SI 3 "nonimmediate_operand"))
12168 (clobber (match_dup 2))]
12170 && optimize_insn_for_size_p () && optimize_size > 1
12171 && LEGACY_INT_REG_P (operands[2])
12172 && !REX_INT_REG_P (operands[3])
12173 && !reg_overlap_mentioned_p (operands[2], operands[3])"
12174 [(set (match_dup 2) (not:SI (match_dup 2)))
12175 (set (match_dup 0) (match_op_dup 1
12176 [(and:SI (match_dup 3) (match_dup 2))
12179 ;; Variant 1 of 4: Split ((A | B) ^ A) ^ C as (B & ~A) ^ C.
12181 [(set (match_operand:SWI48 0 "register_operand")
12184 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
12185 (match_operand:SWI48 2 "nonimmediate_operand"))
12187 (match_operand:SWI48 3 "nonimmediate_operand")))
12188 (clobber (reg:CC FLAGS_REG))]
12191 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 1)) (match_dup 2)))
12192 (clobber (reg:CC FLAGS_REG))])
12194 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
12195 (clobber (reg:CC FLAGS_REG))])]
12196 "operands[4] = gen_reg_rtx (<MODE>mode);")
12198 ;; Variant 2 of 4: Split ((A | B) ^ B) ^ C as (A & ~B) ^ C.
12200 [(set (match_operand:SWI48 0 "register_operand")
12203 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
12204 (match_operand:SWI48 2 "register_operand"))
12206 (match_operand:SWI48 3 "nonimmediate_operand")))
12207 (clobber (reg:CC FLAGS_REG))]
12210 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 2)) (match_dup 1)))
12211 (clobber (reg:CC FLAGS_REG))])
12213 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
12214 (clobber (reg:CC FLAGS_REG))])]
12215 "operands[4] = gen_reg_rtx (<MODE>mode);")
12217 ;; Variant 3 of 4: Split ((A | B) ^ C) ^ A as (B & ~A) ^ C.
12219 [(set (match_operand:SWI48 0 "register_operand")
12222 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
12223 (match_operand:SWI48 2 "nonimmediate_operand"))
12224 (match_operand:SWI48 3 "nonimmediate_operand"))
12226 (clobber (reg:CC FLAGS_REG))]
12229 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 1)) (match_dup 2)))
12230 (clobber (reg:CC FLAGS_REG))])
12232 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
12233 (clobber (reg:CC FLAGS_REG))])]
12234 "operands[4] = gen_reg_rtx (<MODE>mode);")
12236 ;; Variant 4 of 4: Split ((A | B) ^ C) ^ B as (A & ~B) ^ C.
12238 [(set (match_operand:SWI48 0 "register_operand")
12241 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
12242 (match_operand:SWI48 2 "register_operand"))
12243 (match_operand:SWI48 3 "nonimmediate_operand"))
12245 (clobber (reg:CC FLAGS_REG))]
12248 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 2)) (match_dup 1)))
12249 (clobber (reg:CC FLAGS_REG))])
12251 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
12252 (clobber (reg:CC FLAGS_REG))])]
12253 "operands[4] = gen_reg_rtx (<MODE>mode);")
12255 ;; Logical inclusive and exclusive OR instructions
12257 ;; %%% This used to optimize known byte-wide and operations to memory.
12258 ;; If this is considered useful, it should be done with splitters.
12260 (define_expand "<code><mode>3"
12261 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
12262 (any_or:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
12263 (match_operand:SDWIM 2 "<general_operand>")))]
12266 if (GET_MODE_SIZE (<MODE>mode) > UNITS_PER_WORD
12267 && !x86_64_hilo_general_operand (operands[2], <MODE>mode))
12268 operands[2] = force_reg (<MODE>mode, operands[2]);
12270 ix86_expand_binary_operator (<CODE>, <MODE>mode, operands);
12274 (define_insn_and_split "*<code><dwi>3_doubleword"
12275 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
12277 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
12278 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
12279 (clobber (reg:CC FLAGS_REG))]
12280 "ix86_binary_operator_ok (<CODE>, <DWI>mode, operands)"
12282 "&& reload_completed"
12283 [(const_int:DWIH 0)]
12285 /* This insn may disappear completely when operands[2] == const0_rtx
12286 and operands[0] == operands[1], which requires a NOTE_INSN_DELETED. */
12287 bool emit_insn_deleted_note_p = false;
12289 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
12291 if (operands[2] == const0_rtx)
12292 emit_insn_deleted_note_p = true;
12293 else if (operands[2] == constm1_rtx)
12296 emit_move_insn (operands[0], constm1_rtx);
12298 ix86_expand_unary_operator (NOT, <MODE>mode, &operands[0]);
12301 ix86_expand_binary_operator (<CODE>, <MODE>mode, &operands[0]);
12303 if (operands[5] == const0_rtx)
12305 if (emit_insn_deleted_note_p)
12306 emit_note (NOTE_INSN_DELETED);
12308 else if (operands[5] == constm1_rtx)
12311 emit_move_insn (operands[3], constm1_rtx);
12313 ix86_expand_unary_operator (NOT, <MODE>mode, &operands[3]);
12316 ix86_expand_binary_operator (<CODE>, <MODE>mode, &operands[3]);
12321 (define_insn "*<code><mode>_1"
12322 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,?k")
12324 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,k")
12325 (match_operand:SWI248 2 "<general_operand>" "r<i>,<m>,k")))
12326 (clobber (reg:CC FLAGS_REG))]
12327 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
12329 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
12330 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
12332 [(set_attr "isa" "*,*,<kmov_isa>")
12333 (set_attr "type" "alu, alu, msklog")
12334 (set_attr "mode" "<MODE>")])
12336 (define_insn_and_split "*notxor<mode>_1"
12337 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,?k")
12340 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,k")
12341 (match_operand:SWI248 2 "<general_operand>" "r<i>,<m>,k"))))
12342 (clobber (reg:CC FLAGS_REG))]
12343 "ix86_binary_operator_ok (XOR, <MODE>mode, operands)"
12345 "&& reload_completed"
12347 [(set (match_dup 0)
12348 (xor:SWI248 (match_dup 1) (match_dup 2)))
12349 (clobber (reg:CC FLAGS_REG))])
12351 (not:SWI248 (match_dup 0)))]
12353 if (MASK_REG_P (operands[0]))
12355 emit_insn (gen_kxnor<mode> (operands[0], operands[1], operands[2]));
12359 [(set_attr "isa" "*,*,<kmov_isa>")
12360 (set_attr "type" "alu, alu, msklog")
12361 (set_attr "mode" "<MODE>")])
12363 (define_insn_and_split "*iordi_1_bts"
12364 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12366 (match_operand:DI 1 "nonimmediate_operand" "%0")
12367 (match_operand:DI 2 "const_int_operand" "n")))
12368 (clobber (reg:CC FLAGS_REG))]
12369 "TARGET_64BIT && TARGET_USE_BT
12370 && ix86_binary_operator_ok (IOR, DImode, operands)
12371 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
12373 "&& reload_completed"
12374 [(parallel [(set (zero_extract:DI (match_dup 0)
12378 (clobber (reg:CC FLAGS_REG))])]
12379 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
12380 [(set_attr "type" "alu1")
12381 (set_attr "prefix_0f" "1")
12382 (set_attr "znver1_decode" "double")
12383 (set_attr "mode" "DI")])
12385 (define_insn_and_split "*xordi_1_btc"
12386 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12388 (match_operand:DI 1 "nonimmediate_operand" "%0")
12389 (match_operand:DI 2 "const_int_operand" "n")))
12390 (clobber (reg:CC FLAGS_REG))]
12391 "TARGET_64BIT && TARGET_USE_BT
12392 && ix86_binary_operator_ok (XOR, DImode, operands)
12393 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
12395 "&& reload_completed"
12396 [(parallel [(set (zero_extract:DI (match_dup 0)
12399 (not:DI (zero_extract:DI (match_dup 0)
12402 (clobber (reg:CC FLAGS_REG))])]
12403 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
12404 [(set_attr "type" "alu1")
12405 (set_attr "prefix_0f" "1")
12406 (set_attr "znver1_decode" "double")
12407 (set_attr "mode" "DI")])
12409 ;; Optimize a ^ ((a ^ b) & mask) to (~mask & a) | (b & mask)
12410 (define_insn_and_split "*xor2andn"
12411 [(set (match_operand:SWI248 0 "register_operand")
12415 (match_operand:SWI248 1 "nonimmediate_operand")
12416 (match_operand:SWI248 2 "nonimmediate_operand"))
12417 (match_operand:SWI248 3 "nonimmediate_operand"))
12419 (clobber (reg:CC FLAGS_REG))]
12420 "TARGET_BMI && ix86_pre_reload_split ()"
12423 [(parallel [(set (match_dup 4)
12428 (clobber (reg:CC FLAGS_REG))])
12429 (parallel [(set (match_dup 5)
12433 (clobber (reg:CC FLAGS_REG))])
12434 (parallel [(set (match_dup 0)
12438 (clobber (reg:CC FLAGS_REG))])]
12440 operands[1] = force_reg (<MODE>mode, operands[1]);
12441 operands[3] = force_reg (<MODE>mode, operands[3]);
12442 operands[4] = gen_reg_rtx (<MODE>mode);
12443 operands[5] = gen_reg_rtx (<MODE>mode);
12446 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
12447 (define_insn "*<code>si_1_zext"
12448 [(set (match_operand:DI 0 "register_operand" "=r")
12450 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
12451 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
12452 (clobber (reg:CC FLAGS_REG))]
12453 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12454 "<logic>{l}\t{%2, %k0|%k0, %2}"
12455 [(set_attr "type" "alu")
12456 (set_attr "mode" "SI")])
12458 (define_insn "*<code>si_1_zext_imm"
12459 [(set (match_operand:DI 0 "register_operand" "=r")
12461 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
12462 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
12463 (clobber (reg:CC FLAGS_REG))]
12464 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12465 "<logic>{l}\t{%2, %k0|%k0, %2}"
12466 [(set_attr "type" "alu")
12467 (set_attr "mode" "SI")])
12469 (define_insn "*<code>qi_1"
12470 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,?k")
12471 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
12472 (match_operand:QI 2 "general_operand" "qn,m,rn,k")))
12473 (clobber (reg:CC FLAGS_REG))]
12474 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
12476 <logic>{b}\t{%2, %0|%0, %2}
12477 <logic>{b}\t{%2, %0|%0, %2}
12478 <logic>{l}\t{%k2, %k0|%k0, %k2}
12480 [(set_attr "isa" "*,*,*,avx512f")
12481 (set_attr "type" "alu,alu,alu,msklog")
12483 (cond [(eq_attr "alternative" "2")
12484 (const_string "SI")
12485 (and (eq_attr "alternative" "3")
12486 (match_test "!TARGET_AVX512DQ"))
12487 (const_string "HI")
12489 (const_string "QI")))
12490 ;; Potential partial reg stall on alternative 2.
12491 (set (attr "preferred_for_speed")
12492 (cond [(eq_attr "alternative" "2")
12493 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
12494 (symbol_ref "true")))])
12496 (define_insn_and_split "*notxorqi_1"
12497 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,?k")
12499 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
12500 (match_operand:QI 2 "general_operand" "qn,m,rn,k"))))
12501 (clobber (reg:CC FLAGS_REG))]
12502 "ix86_binary_operator_ok (XOR, QImode, operands)"
12504 "&& reload_completed"
12506 [(set (match_dup 0)
12507 (xor:QI (match_dup 1) (match_dup 2)))
12508 (clobber (reg:CC FLAGS_REG))])
12510 (not:QI (match_dup 0)))]
12512 if (mask_reg_operand (operands[0], QImode))
12514 emit_insn (gen_kxnorqi (operands[0], operands[1], operands[2]));
12518 [(set_attr "isa" "*,*,*,avx512f")
12519 (set_attr "type" "alu,alu,alu,msklog")
12521 (cond [(eq_attr "alternative" "2")
12522 (const_string "SI")
12523 (and (eq_attr "alternative" "3")
12524 (match_test "!TARGET_AVX512DQ"))
12525 (const_string "HI")
12527 (const_string "QI")))
12528 ;; Potential partial reg stall on alternative 2.
12529 (set (attr "preferred_for_speed")
12530 (cond [(eq_attr "alternative" "2")
12531 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
12532 (symbol_ref "true")))])
12534 ;; convert (sign_extend:WIDE (any_logic:NARROW (memory, immediate)))
12535 ;; to (any_logic:WIDE (sign_extend (memory)), (sign_extend (immediate))).
12536 ;; This eliminates sign extension after logic operation.
12539 [(set (match_operand:SWI248 0 "register_operand")
12540 (sign_extend:SWI248
12541 (any_logic:QI (match_operand:QI 1 "memory_operand")
12542 (match_operand:QI 2 "const_int_operand"))))]
12544 [(set (match_dup 3) (sign_extend:SWI248 (match_dup 1)))
12545 (set (match_dup 0) (any_logic:SWI248 (match_dup 3) (match_dup 2)))]
12546 "operands[3] = gen_reg_rtx (<MODE>mode);")
12549 [(set (match_operand:SWI48 0 "register_operand")
12551 (any_logic:HI (match_operand:HI 1 "memory_operand")
12552 (match_operand:HI 2 "const_int_operand"))))]
12554 [(set (match_dup 3) (sign_extend:SWI48 (match_dup 1)))
12555 (set (match_dup 0) (any_logic:SWI48 (match_dup 3) (match_dup 2)))]
12556 "operands[3] = gen_reg_rtx (<MODE>mode);")
12559 [(set (match_operand:DI 0 "register_operand")
12561 (any_logic:SI (match_operand:SI 1 "memory_operand")
12562 (match_operand:SI 2 "const_int_operand"))))]
12564 [(set (match_dup 3) (sign_extend:DI (match_dup 1)))
12565 (set (match_dup 0) (any_logic:DI (match_dup 3) (match_dup 2)))]
12566 "operands[3] = gen_reg_rtx (DImode);")
12568 (define_insn "*<code><mode>_2"
12569 [(set (reg FLAGS_REG)
12570 (compare (any_or:SWI
12571 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
12572 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
12574 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
12575 (any_or:SWI (match_dup 1) (match_dup 2)))]
12576 "ix86_match_ccmode (insn, CCNOmode)
12577 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
12578 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
12579 [(set_attr "type" "alu")
12580 (set_attr "mode" "<MODE>")])
12582 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
12583 ;; ??? Special case for immediate operand is missing - it is tricky.
12584 (define_insn "*<code>si_2_zext"
12585 [(set (reg FLAGS_REG)
12586 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
12587 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
12589 (set (match_operand:DI 0 "register_operand" "=r")
12590 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
12591 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
12592 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12593 "<logic>{l}\t{%2, %k0|%k0, %2}"
12594 [(set_attr "type" "alu")
12595 (set_attr "mode" "SI")])
12597 (define_insn "*<code>si_2_zext_imm"
12598 [(set (reg FLAGS_REG)
12599 (compare (any_or:SI
12600 (match_operand:SI 1 "nonimmediate_operand" "%0")
12601 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
12603 (set (match_operand:DI 0 "register_operand" "=r")
12604 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12605 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
12606 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12607 "<logic>{l}\t{%2, %k0|%k0, %2}"
12608 [(set_attr "type" "alu")
12609 (set_attr "mode" "SI")])
12611 (define_insn "*<code><mode>_3"
12612 [(set (reg FLAGS_REG)
12613 (compare (any_or:SWI
12614 (match_operand:SWI 1 "nonimmediate_operand" "%0")
12615 (match_operand:SWI 2 "<general_operand>" "<g>"))
12617 (clobber (match_scratch:SWI 0 "=<r>"))]
12618 "ix86_match_ccmode (insn, CCNOmode)
12619 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12620 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
12621 [(set_attr "type" "alu")
12622 (set_attr "mode" "<MODE>")])
12624 ;; Convert wide OR instructions with immediate operand to shorter QImode
12625 ;; equivalents when possible.
12626 ;; Don't do the splitting with memory operands, since it introduces risk
12627 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
12628 ;; for size, but that can (should?) be handled by generic code instead.
12630 [(set (match_operand:SWI248 0 "QIreg_operand")
12631 (any_or:SWI248 (match_operand:SWI248 1 "register_operand")
12632 (match_operand:SWI248 2 "const_int_operand")))
12633 (clobber (reg:CC FLAGS_REG))]
12635 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12636 && !(INTVAL (operands[2]) & ~(255 << 8))"
12638 [(set (zero_extract:HI (match_dup 0)
12644 (zero_extract:HI (match_dup 1)
12648 (clobber (reg:CC FLAGS_REG))])]
12650 /* Handle the case where INTVAL (operands[2]) == 0. */
12651 if (operands[2] == const0_rtx)
12653 if (!rtx_equal_p (operands[0], operands[1]))
12654 emit_move_insn (operands[0], operands[1]);
12656 emit_note (NOTE_INSN_DELETED);
12659 operands[0] = gen_lowpart (HImode, operands[0]);
12660 operands[1] = gen_lowpart (HImode, operands[1]);
12661 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
12664 ;; Since OR can be encoded with sign extended immediate, this is only
12665 ;; profitable when 7th bit is set.
12667 [(set (match_operand:SWI248 0 "any_QIreg_operand")
12668 (any_or:SWI248 (match_operand:SWI248 1 "general_operand")
12669 (match_operand:SWI248 2 "const_int_operand")))
12670 (clobber (reg:CC FLAGS_REG))]
12672 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12673 && !(INTVAL (operands[2]) & ~255)
12674 && (INTVAL (operands[2]) & 128)"
12675 [(parallel [(set (strict_low_part (match_dup 0))
12676 (any_or:QI (match_dup 1)
12678 (clobber (reg:CC FLAGS_REG))])]
12680 operands[0] = gen_lowpart (QImode, operands[0]);
12681 operands[1] = gen_lowpart (QImode, operands[1]);
12682 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
12685 (define_expand "xorqi_ext_1_cc"
12687 [(set (reg:CCNO FLAGS_REG)
12691 (zero_extract:HI (match_operand:HI 1 "register_operand")
12694 (match_operand:QI 2 "const_int_operand"))
12696 (set (zero_extract:HI (match_operand:HI 0 "register_operand")
12702 (zero_extract:HI (match_dup 1)
12705 (match_dup 2)) 0))])])
12707 ;; Peephole2 rega = 0; rega op= regb into rega = regb.
12709 [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
12711 (clobber (reg:CC FLAGS_REG))])
12712 (parallel [(set (match_dup 0)
12713 (any_or_plus:SWI (match_dup 0)
12714 (match_operand:SWI 1 "<general_operand>")))
12715 (clobber (reg:CC FLAGS_REG))])]
12716 "!reg_mentioned_p (operands[0], operands[1])"
12717 [(set (match_dup 0) (match_dup 1))])
12719 ;; Peephole2 dead instruction in rega = 0; rega op= rega.
12721 [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
12723 (clobber (reg:CC FLAGS_REG))])
12724 (parallel [(set (match_dup 0)
12725 (any_or_plus:SWI (match_dup 0) (match_dup 0)))
12726 (clobber (reg:CC FLAGS_REG))])]
12728 [(parallel [(set (match_dup 0) (const_int 0))
12729 (clobber (reg:CC FLAGS_REG))])])
12731 ;; Split DST = (HI<<32)|LO early to minimize register usage.
12732 (define_insn_and_split "*concat<mode><dwi>3_1"
12733 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
12735 (ashift:<DWI> (match_operand:<DWI> 1 "register_operand" "r,r")
12736 (match_operand:QI 2 "const_int_operand"))
12738 (match_operand:DWIH 3 "nonimmediate_operand" "r,m"))))]
12739 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT"
12741 "&& reload_completed"
12744 split_double_concat (<DWI>mode, operands[0], operands[3],
12745 gen_lowpart (<MODE>mode, operands[1]));
12749 (define_insn_and_split "*concat<mode><dwi>3_2"
12750 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
12753 (match_operand:DWIH 1 "nonimmediate_operand" "r,m"))
12754 (ashift:<DWI> (match_operand:<DWI> 2 "register_operand" "r,r")
12755 (match_operand:QI 3 "const_int_operand"))))]
12756 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12758 "&& reload_completed"
12761 split_double_concat (<DWI>mode, operands[0], operands[1],
12762 gen_lowpart (<MODE>mode, operands[2]));
12766 (define_insn_and_split "*concat<mode><dwi>3_3"
12767 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,r,&r,x")
12771 (match_operand:DWIH 1 "nonimmediate_operand" "r,m,r,m,x"))
12772 (match_operand:QI 2 "const_int_operand"))
12774 (match_operand:DWIH 3 "nonimmediate_operand" "r,r,m,m,0"))))]
12775 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT"
12777 "&& reload_completed"
12780 if (SSE_REG_P (operands[0]))
12782 rtx tmp = gen_rtx_REG (V2DImode, REGNO (operands[0]));
12783 emit_insn (gen_vec_concatv2di (tmp, operands[3], operands[1]));
12786 split_double_concat (<DWI>mode, operands[0], operands[3], operands[1]);
12789 [(set_attr "isa" "*,*,*,x64,x64")])
12791 (define_insn_and_split "*concat<mode><dwi>3_4"
12792 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,r,&r")
12795 (match_operand:DWIH 1 "nonimmediate_operand" "r,m,r,m"))
12798 (match_operand:DWIH 2 "nonimmediate_operand" "r,r,m,m"))
12799 (match_operand:QI 3 "const_int_operand"))))]
12800 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12802 "&& reload_completed"
12805 split_double_concat (<DWI>mode, operands[0], operands[1], operands[2]);
12808 [(set_attr "isa" "*,*,*,x64")])
12810 (define_insn_and_split "*concat<half><mode>3_5"
12811 [(set (match_operand:DWI 0 "nonimmediate_operand" "=r,o,o")
12813 (ashift:DWI (match_operand:DWI 1 "register_operand" "r,r,r")
12814 (match_operand:QI 2 "const_int_operand"))
12815 (match_operand:DWI 3 "const_scalar_int_operand" "n,n,Wd")))]
12816 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT / 2
12817 && (<MODE>mode == DImode
12818 ? CONST_INT_P (operands[3])
12819 && (UINTVAL (operands[3]) & ~GET_MODE_MASK (SImode)) == 0
12820 : CONST_INT_P (operands[3])
12821 ? INTVAL (operands[3]) >= 0
12822 : CONST_WIDE_INT_NUNITS (operands[3]) == 2
12823 && CONST_WIDE_INT_ELT (operands[3], 1) == 0)
12824 && !(CONST_INT_P (operands[3])
12825 ? ix86_endbr_immediate_operand (operands[3], VOIDmode)
12826 : ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[3],
12830 "&& reload_completed"
12833 rtx op3 = simplify_subreg (<HALF>mode, operands[3], <MODE>mode, 0);
12834 split_double_concat (<MODE>mode, operands[0], op3,
12835 gen_lowpart (<HALF>mode, operands[1]));
12838 [(set_attr "isa" "*,nox64,x64")])
12840 (define_insn_and_split "*concat<mode><dwi>3_6"
12841 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,o,r")
12845 (match_operand:DWIH 1 "nonimmediate_operand" "r,r,r,m"))
12846 (match_operand:QI 2 "const_int_operand"))
12847 (match_operand:<DWI> 3 "const_scalar_int_operand" "n,n,Wd,n")))]
12848 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT
12849 && (<DWI>mode == DImode
12850 ? CONST_INT_P (operands[3])
12851 && (UINTVAL (operands[3]) & ~GET_MODE_MASK (SImode)) == 0
12852 : CONST_INT_P (operands[3])
12853 ? INTVAL (operands[3]) >= 0
12854 : CONST_WIDE_INT_NUNITS (operands[3]) == 2
12855 && CONST_WIDE_INT_ELT (operands[3], 1) == 0)
12856 && !(CONST_INT_P (operands[3])
12857 ? ix86_endbr_immediate_operand (operands[3], VOIDmode)
12858 : ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[3],
12862 "&& reload_completed"
12865 rtx op3 = simplify_subreg (<MODE>mode, operands[3], <DWI>mode, 0);
12866 split_double_concat (<DWI>mode, operands[0], op3, operands[1]);
12869 [(set_attr "isa" "*,nox64,x64,*")])
12871 (define_insn_and_split "*concat<mode><dwi>3_7"
12872 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,o,r")
12875 (match_operand:DWIH 1 "nonimmediate_operand" "r,r,r,m"))
12876 (match_operand:<DWI> 2 "const_scalar_int_operand" "n,n,Wd,n")))]
12877 "<DWI>mode == DImode
12878 ? CONST_INT_P (operands[2])
12879 && (UINTVAL (operands[2]) & GET_MODE_MASK (SImode)) == 0
12880 && !ix86_endbr_immediate_operand (operands[2], VOIDmode)
12881 : CONST_WIDE_INT_P (operands[2])
12882 && CONST_WIDE_INT_NUNITS (operands[2]) == 2
12883 && CONST_WIDE_INT_ELT (operands[2], 0) == 0
12884 && !ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[2],
12888 "&& reload_completed"
12892 if (<DWI>mode == DImode)
12893 op2 = gen_int_mode (INTVAL (operands[2]) >> 32, <MODE>mode);
12895 op2 = gen_int_mode (CONST_WIDE_INT_ELT (operands[2], 1), <MODE>mode);
12896 split_double_concat (<DWI>mode, operands[0], operands[1], op2);
12899 [(set_attr "isa" "*,nox64,x64,*")])
12901 ;; Negation instructions
12903 (define_expand "neg<mode>2"
12904 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
12905 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
12907 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
12909 (define_insn_and_split "*neg<dwi>2_doubleword"
12910 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
12911 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
12912 (clobber (reg:CC FLAGS_REG))]
12913 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
12915 "&& reload_completed"
12917 [(set (reg:CCC FLAGS_REG)
12918 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
12919 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
12921 [(set (match_dup 2)
12922 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
12925 (clobber (reg:CC FLAGS_REG))])
12927 [(set (match_dup 2)
12928 (neg:DWIH (match_dup 2)))
12929 (clobber (reg:CC FLAGS_REG))])]
12930 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
12943 [(set (match_operand:SWI48 0 "general_reg_operand")
12944 (match_operand:SWI48 1 "nonimmediate_gr_operand"))
12946 [(set (reg:CCC FLAGS_REG)
12947 (unspec:CCC [(match_operand:SWI48 2 "general_reg_operand")
12948 (const_int 0)] UNSPEC_CC_NE))
12949 (set (match_dup 2) (neg:SWI48 (match_dup 2)))])
12951 [(set (match_dup 0)
12952 (plus:SWI48 (plus:SWI48
12953 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
12956 (clobber (reg:CC FLAGS_REG))])
12958 [(set (match_dup 0)
12959 (neg:SWI48 (match_dup 0)))
12960 (clobber (reg:CC FLAGS_REG))])]
12961 "REGNO (operands[0]) != REGNO (operands[2])
12962 && !reg_mentioned_p (operands[0], operands[1])
12963 && !reg_mentioned_p (operands[2], operands[1])"
12965 [(set (reg:CCC FLAGS_REG)
12966 (unspec:CCC [(match_dup 2) (const_int 0)] UNSPEC_CC_NE))
12967 (set (match_dup 2) (neg:SWI48 (match_dup 2)))])
12969 [(set (match_dup 0)
12970 (minus:SWI48 (minus:SWI48
12972 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0)))
12974 (clobber (reg:CC FLAGS_REG))])]
12975 "ix86_expand_clear (operands[0]);")
12984 ;; sbbl %edx, %edx // *x86_mov<mode>cc_0_m1
12988 [(set (match_operand:SWI48 0 "general_reg_operand") (const_int 0))
12989 (clobber (reg:CC FLAGS_REG))])
12991 [(set (reg:CCC FLAGS_REG)
12992 (unspec:CCC [(match_operand:SWI48 1 "general_reg_operand")
12993 (const_int 0)] UNSPEC_CC_NE))
12994 (set (match_dup 1) (neg:SWI48 (match_dup 1)))])
12996 [(set (match_dup 0)
12997 (plus:SWI48 (plus:SWI48
12998 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
13001 (clobber (reg:CC FLAGS_REG))])
13003 [(set (match_dup 0)
13004 (neg:SWI48 (match_dup 0)))
13005 (clobber (reg:CC FLAGS_REG))])]
13006 "REGNO (operands[0]) != REGNO (operands[1])"
13008 [(set (reg:CCC FLAGS_REG)
13009 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
13010 (set (match_dup 1) (neg:SWI48 (match_dup 1)))])
13012 [(set (match_dup 0)
13013 (if_then_else:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
13016 (clobber (reg:CC FLAGS_REG))])])
13018 (define_insn "*neg<mode>_1"
13019 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
13020 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
13021 (clobber (reg:CC FLAGS_REG))]
13022 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
13023 "neg{<imodesuffix>}\t%0"
13024 [(set_attr "type" "negnot")
13025 (set_attr "mode" "<MODE>")])
13027 (define_insn "*negsi_1_zext"
13028 [(set (match_operand:DI 0 "register_operand" "=r")
13030 (neg:SI (match_operand:SI 1 "register_operand" "0"))))
13031 (clobber (reg:CC FLAGS_REG))]
13032 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
13034 [(set_attr "type" "negnot")
13035 (set_attr "mode" "SI")])
13037 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
13038 (define_insn_and_split "*neg<mode>_1_slp"
13039 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
13040 (neg:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")))
13041 (clobber (reg:CC FLAGS_REG))]
13042 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
13044 neg{<imodesuffix>}\t%0
13046 "&& reload_completed
13047 && !(rtx_equal_p (operands[0], operands[1]))"
13048 [(set (strict_low_part (match_dup 0)) (match_dup 1))
13050 [(set (strict_low_part (match_dup 0))
13051 (neg:SWI12 (match_dup 0)))
13052 (clobber (reg:CC FLAGS_REG))])]
13054 [(set_attr "type" "negnot")
13055 (set_attr "mode" "<MODE>")])
13057 (define_insn "*neg<mode>_2"
13058 [(set (reg FLAGS_REG)
13060 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
13062 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
13063 (neg:SWI (match_dup 1)))]
13064 "ix86_match_ccmode (insn, CCGOCmode)
13065 && ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
13066 "neg{<imodesuffix>}\t%0"
13067 [(set_attr "type" "negnot")
13068 (set_attr "mode" "<MODE>")])
13070 (define_insn "*negsi_2_zext"
13071 [(set (reg FLAGS_REG)
13073 (neg:SI (match_operand:SI 1 "register_operand" "0"))
13075 (set (match_operand:DI 0 "register_operand" "=r")
13077 (neg:SI (match_dup 1))))]
13078 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
13079 && ix86_unary_operator_ok (NEG, SImode, operands)"
13081 [(set_attr "type" "negnot")
13082 (set_attr "mode" "SI")])
13084 (define_insn "*neg<mode>_ccc_1"
13085 [(set (reg:CCC FLAGS_REG)
13087 [(match_operand:SWI 1 "nonimmediate_operand" "0")
13088 (const_int 0)] UNSPEC_CC_NE))
13089 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
13090 (neg:SWI (match_dup 1)))]
13092 "neg{<imodesuffix>}\t%0"
13093 [(set_attr "type" "negnot")
13094 (set_attr "mode" "<MODE>")])
13096 (define_insn "*neg<mode>_ccc_2"
13097 [(set (reg:CCC FLAGS_REG)
13099 [(match_operand:SWI 1 "nonimmediate_operand" "0")
13100 (const_int 0)] UNSPEC_CC_NE))
13101 (clobber (match_scratch:SWI 0 "=<r>"))]
13103 "neg{<imodesuffix>}\t%0"
13104 [(set_attr "type" "negnot")
13105 (set_attr "mode" "<MODE>")])
13107 (define_expand "x86_neg<mode>_ccc"
13109 [(set (reg:CCC FLAGS_REG)
13110 (unspec:CCC [(match_operand:SWI48 1 "register_operand")
13111 (const_int 0)] UNSPEC_CC_NE))
13112 (set (match_operand:SWI48 0 "register_operand")
13113 (neg:SWI48 (match_dup 1)))])])
13115 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
13116 (define_insn_and_split "*negqi_ext<mode>_1"
13117 [(set (zero_extract:SWI248
13118 (match_operand 0 "int248_register_operand" "+Q,&Q")
13124 (match_operator:SWI248 2 "extract_operator"
13125 [(match_operand 1 "int248_register_operand" "0,!Q")
13127 (const_int 8)]) 0)) 0))
13128 (clobber (reg:CC FLAGS_REG))]
13134 && !(rtx_equal_p (operands[0], operands[1]))"
13135 [(set (zero_extract:SWI248
13136 (match_dup 0) (const_int 8) (const_int 8))
13137 (zero_extract:SWI248
13138 (match_dup 1) (const_int 8) (const_int 8)))
13140 [(set (zero_extract:SWI248
13141 (match_dup 0) (const_int 8) (const_int 8))
13146 [(match_dup 0) (const_int 8) (const_int 8)]) 0)) 0))
13147 (clobber (reg:CC FLAGS_REG))])]
13149 [(set_attr "type" "negnot")
13150 (set_attr "mode" "QI")])
13152 ;; Negate with jump on overflow.
13153 (define_expand "negv<mode>3"
13154 [(parallel [(set (reg:CCO FLAGS_REG)
13156 [(match_operand:SWI 1 "register_operand")
13157 (match_dup 3)] UNSPEC_CC_NE))
13158 (set (match_operand:SWI 0 "register_operand")
13159 (neg:SWI (match_dup 1)))])
13160 (set (pc) (if_then_else
13161 (eq (reg:CCO FLAGS_REG) (const_int 0))
13162 (label_ref (match_operand 2))
13167 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
13171 (define_insn "*negv<mode>3"
13172 [(set (reg:CCO FLAGS_REG)
13173 (unspec:CCO [(match_operand:SWI 1 "nonimmediate_operand" "0")
13174 (match_operand:SWI 2 "const_int_operand")]
13176 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
13177 (neg:SWI (match_dup 1)))]
13178 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
13179 && mode_signbit_p (<MODE>mode, operands[2])"
13180 "neg{<imodesuffix>}\t%0"
13181 [(set_attr "type" "negnot")
13182 (set_attr "mode" "<MODE>")])
13184 ;; Optimize *negsi_1 followed by *cmpsi_ccno_1 (PR target/91384)
13186 [(set (match_operand:SWI 0 "general_reg_operand")
13187 (match_operand:SWI 1 "general_reg_operand"))
13188 (parallel [(set (match_dup 0) (neg:SWI (match_dup 0)))
13189 (clobber (reg:CC FLAGS_REG))])
13190 (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))]
13192 [(set (match_dup 0) (match_dup 1))
13193 (parallel [(set (reg:CCZ FLAGS_REG)
13194 (compare:CCZ (neg:SWI (match_dup 0)) (const_int 0)))
13195 (set (match_dup 0) (neg:SWI (match_dup 0)))])])
13197 ;; Special expand pattern to handle integer mode abs
13199 (define_expand "abs<mode>2"
13201 [(set (match_operand:SDWIM 0 "register_operand")
13203 (match_operand:SDWIM 1 "general_operand")))
13204 (clobber (reg:CC FLAGS_REG))])]
13206 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)"
13208 if (TARGET_EXPAND_ABS)
13210 machine_mode mode = <MODE>mode;
13211 operands[1] = force_reg (mode, operands[1]);
13213 /* Generate rtx abs using:
13214 abs (x) = (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)) */
13216 rtx shift_amount = gen_int_mode (GET_MODE_PRECISION (mode) - 1, QImode);
13217 rtx shift_dst = expand_simple_binop (mode, ASHIFTRT, operands[1],
13218 shift_amount, NULL_RTX,
13220 rtx xor_dst = expand_simple_binop (mode, XOR, shift_dst, operands[1],
13221 operands[0], 0, OPTAB_DIRECT);
13222 rtx minus_dst = expand_simple_binop (mode, MINUS, xor_dst, shift_dst,
13223 operands[0], 0, OPTAB_DIRECT);
13224 if (!rtx_equal_p (minus_dst, operands[0]))
13225 emit_move_insn (operands[0], minus_dst);
13230 (define_insn_and_split "*abs<dwi>2_doubleword"
13231 [(set (match_operand:<DWI> 0 "register_operand")
13233 (match_operand:<DWI> 1 "general_operand")))
13234 (clobber (reg:CC FLAGS_REG))]
13236 && ix86_pre_reload_split ()"
13240 [(set (reg:CCC FLAGS_REG)
13241 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
13242 (set (match_dup 2) (neg:DWIH (match_dup 1)))])
13244 [(set (match_dup 5)
13245 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
13248 (clobber (reg:CC FLAGS_REG))])
13250 [(set (reg:CCGOC FLAGS_REG)
13252 (neg:DWIH (match_dup 5))
13255 (neg:DWIH (match_dup 5)))])
13258 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
13263 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
13267 operands[1] = force_reg (<DWI>mode, operands[1]);
13268 operands[2] = gen_reg_rtx (<DWI>mode);
13270 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
13273 (define_insn_and_split "*nabs<dwi>2_doubleword"
13274 [(set (match_operand:<DWI> 0 "register_operand")
13277 (match_operand:<DWI> 1 "general_operand"))))
13278 (clobber (reg:CC FLAGS_REG))]
13280 && ix86_pre_reload_split ()"
13284 [(set (reg:CCC FLAGS_REG)
13285 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
13286 (set (match_dup 2) (neg:DWIH (match_dup 1)))])
13288 [(set (match_dup 5)
13289 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
13292 (clobber (reg:CC FLAGS_REG))])
13294 [(set (reg:CCGOC FLAGS_REG)
13296 (neg:DWIH (match_dup 5))
13299 (neg:DWIH (match_dup 5)))])
13302 (lt (reg:CCGOC FLAGS_REG) (const_int 0))
13307 (lt (reg:CCGOC FLAGS_REG) (const_int 0))
13311 operands[1] = force_reg (<DWI>mode, operands[1]);
13312 operands[2] = gen_reg_rtx (<DWI>mode);
13314 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
13317 (define_insn_and_split "*abs<mode>2_1"
13318 [(set (match_operand:SWI 0 "register_operand")
13320 (match_operand:SWI 1 "general_operand")))
13321 (clobber (reg:CC FLAGS_REG))]
13323 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
13324 && ix86_pre_reload_split ()"
13328 [(set (reg:CCGOC FLAGS_REG)
13330 (neg:SWI (match_dup 1))
13333 (neg:SWI (match_dup 1)))])
13336 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
13340 operands[1] = force_reg (<MODE>mode, operands[1]);
13341 operands[2] = gen_reg_rtx (<MODE>mode);
13344 (define_insn_and_split "*nabs<mode>2_1"
13345 [(set (match_operand:SWI 0 "register_operand")
13348 (match_operand:SWI 1 "general_operand"))))
13349 (clobber (reg:CC FLAGS_REG))]
13351 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
13352 && ix86_pre_reload_split ()"
13356 [(set (reg:CCGOC FLAGS_REG)
13358 (neg:SWI (match_dup 1))
13361 (neg:SWI (match_dup 1)))])
13364 (lt (reg:CCGOC FLAGS_REG) (const_int 0))
13368 operands[1] = force_reg (<MODE>mode, operands[1]);
13369 operands[2] = gen_reg_rtx (<MODE>mode);
13372 (define_expand "<code>tf2"
13373 [(set (match_operand:TF 0 "register_operand")
13374 (absneg:TF (match_operand:TF 1 "register_operand")))]
13376 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
13378 (define_insn_and_split "*<code>tf2_1"
13379 [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
13381 (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m")))
13382 (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))]
13385 "&& reload_completed"
13386 [(set (match_dup 0)
13387 (<absneg_op>:TF (match_dup 1) (match_dup 2)))]
13391 if (MEM_P (operands[1]))
13392 std::swap (operands[1], operands[2]);
13396 if (operands_match_p (operands[0], operands[2]))
13397 std::swap (operands[1], operands[2]);
13400 [(set_attr "isa" "noavx,noavx,avx,avx")])
13402 (define_insn_and_split "*nabstf2_1"
13403 [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
13406 (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m"))))
13407 (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))]
13410 "&& reload_completed"
13411 [(set (match_dup 0)
13412 (ior:TF (match_dup 1) (match_dup 2)))]
13416 if (MEM_P (operands[1]))
13417 std::swap (operands[1], operands[2]);
13421 if (operands_match_p (operands[0], operands[2]))
13422 std::swap (operands[1], operands[2]);
13425 [(set_attr "isa" "noavx,noavx,avx,avx")])
13427 (define_expand "<code>hf2"
13428 [(set (match_operand:HF 0 "register_operand")
13429 (absneg:HF (match_operand:HF 1 "register_operand")))]
13430 "TARGET_AVX512FP16"
13431 "ix86_expand_fp_absneg_operator (<CODE>, HFmode, operands); DONE;")
13433 (define_expand "<code><mode>2"
13434 [(set (match_operand:X87MODEF 0 "register_operand")
13435 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
13436 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13437 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
13439 ;; Changing of sign for FP values is doable using integer unit too.
13440 (define_insn "*<code><mode>2_i387_1"
13441 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
13443 (match_operand:X87MODEF 1 "register_operand" "0,0")))
13444 (clobber (reg:CC FLAGS_REG))]
13445 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13449 [(set (match_operand:X87MODEF 0 "fp_register_operand")
13450 (absneg:X87MODEF (match_operand:X87MODEF 1 "fp_register_operand")))
13451 (clobber (reg:CC FLAGS_REG))]
13452 "TARGET_80387 && reload_completed"
13453 [(set (match_dup 0) (absneg:X87MODEF (match_dup 1)))])
13456 [(set (match_operand:X87MODEF 0 "general_reg_operand")
13457 (absneg:X87MODEF (match_operand:X87MODEF 1 "general_reg_operand")))
13458 (clobber (reg:CC FLAGS_REG))]
13459 "TARGET_80387 && reload_completed"
13461 "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
13463 (define_insn_and_split "*<code>hf2_1"
13464 [(set (match_operand:HF 0 "register_operand" "=Yv")
13466 (match_operand:HF 1 "register_operand" "Yv")))
13467 (use (match_operand:V8HF 2 "vector_operand" "Yvm"))
13468 (clobber (reg:CC FLAGS_REG))]
13469 "TARGET_AVX512FP16"
13471 "&& reload_completed"
13472 [(set (match_dup 0)
13473 (<absneg_op>:V8HF (match_dup 1) (match_dup 2)))]
13475 operands[0] = lowpart_subreg (V8HFmode, operands[0], HFmode);
13476 operands[1] = lowpart_subreg (V8HFmode, operands[1], HFmode);
13479 (define_insn "*<code><mode>2_1"
13480 [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv,f,!r")
13482 (match_operand:MODEF 1 "register_operand" "0,x,Yv,0,0")))
13483 (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm,X,X"))
13484 (clobber (reg:CC FLAGS_REG))]
13485 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13487 [(set_attr "isa" "noavx,noavx,avx,*,*")
13488 (set (attr "enabled")
13490 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
13492 (eq_attr "alternative" "3,4")
13493 (symbol_ref "TARGET_MIX_SSE_I387")
13494 (const_string "*"))
13496 (eq_attr "alternative" "3,4")
13497 (symbol_ref "true")
13498 (symbol_ref "false"))))])
13501 [(set (match_operand:MODEF 0 "sse_reg_operand")
13503 (match_operand:MODEF 1 "sse_reg_operand")))
13504 (use (match_operand:<ssevecmodef> 2 "vector_operand"))
13505 (clobber (reg:CC FLAGS_REG))]
13506 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13507 && reload_completed"
13508 [(set (match_dup 0)
13509 (<absneg_op>:<ssevecmodef> (match_dup 1) (match_dup 2)))]
13511 machine_mode mode = <MODE>mode;
13512 machine_mode vmode = <ssevecmodef>mode;
13514 operands[0] = lowpart_subreg (vmode, operands[0], mode);
13515 operands[1] = lowpart_subreg (vmode, operands[1], mode);
13517 if (!TARGET_AVX && operands_match_p (operands[0], operands[2]))
13518 std::swap (operands[1], operands[2]);
13522 [(set (match_operand:MODEF 0 "fp_register_operand")
13523 (absneg:MODEF (match_operand:MODEF 1 "fp_register_operand")))
13524 (use (match_operand 2))
13525 (clobber (reg:CC FLAGS_REG))]
13526 "TARGET_80387 && reload_completed"
13527 [(set (match_dup 0) (absneg:MODEF (match_dup 1)))])
13530 [(set (match_operand:MODEF 0 "general_reg_operand")
13531 (absneg:MODEF (match_operand:MODEF 1 "general_reg_operand")))
13532 (use (match_operand 2))
13533 (clobber (reg:CC FLAGS_REG))]
13534 "TARGET_80387 && reload_completed"
13536 "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
13538 (define_insn_and_split "*nabs<mode>2_1"
13539 [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv")
13542 (match_operand:MODEF 1 "register_operand" "0,x,Yv"))))
13543 (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm"))]
13544 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13546 "&& reload_completed"
13547 [(set (match_dup 0)
13548 (ior:<ssevecmodef> (match_dup 1) (match_dup 2)))]
13550 machine_mode mode = <MODE>mode;
13551 machine_mode vmode = <ssevecmodef>mode;
13553 operands[0] = lowpart_subreg (vmode, operands[0], mode);
13554 operands[1] = lowpart_subreg (vmode, operands[1], mode);
13556 if (!TARGET_AVX && operands_match_p (operands[0], operands[2]))
13557 std::swap (operands[1], operands[2]);
13559 [(set_attr "isa" "noavx,noavx,avx")])
13561 ;; Conditionalize these after reload. If they match before reload, we
13562 ;; lose the clobber and ability to use integer instructions.
13564 (define_insn "*<code><mode>2_i387"
13565 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
13566 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
13567 "TARGET_80387 && reload_completed"
13568 "<absneg_mnemonic>"
13569 [(set_attr "type" "fsgn")
13570 (set_attr "mode" "<MODE>")])
13572 ;; Copysign instructions
13574 (define_expand "copysign<mode>3"
13575 [(match_operand:SSEMODEF 0 "register_operand")
13576 (match_operand:SSEMODEF 1 "nonmemory_operand")
13577 (match_operand:SSEMODEF 2 "register_operand")]
13578 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13579 || (TARGET_SSE && (<MODE>mode == TFmode))
13580 || (TARGET_AVX512FP16 && (<MODE>mode ==HFmode))"
13581 "ix86_expand_copysign (operands); DONE;")
13583 (define_expand "xorsign<mode>3"
13584 [(match_operand:MODEFH 0 "register_operand")
13585 (match_operand:MODEFH 1 "register_operand")
13586 (match_operand:MODEFH 2 "register_operand")]
13587 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13588 || <MODE>mode == HFmode"
13590 if (rtx_equal_p (operands[1], operands[2]))
13591 emit_insn (gen_abs<mode>2 (operands[0], operands[1]));
13593 ix86_expand_xorsign (operands);
13597 ;; One complement instructions
13599 (define_expand "one_cmpl<mode>2"
13600 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
13601 (not:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
13603 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
13605 (define_insn_and_split "*one_cmpl<dwi>2_doubleword"
13606 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
13607 (not:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))]
13608 "ix86_unary_operator_ok (NOT, <DWI>mode, operands)"
13610 "&& reload_completed"
13611 [(set (match_dup 0)
13612 (not:DWIH (match_dup 1)))
13614 (not:DWIH (match_dup 3)))]
13615 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
13617 (define_insn "*one_cmpl<mode>2_1"
13618 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,?k")
13619 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0,k")))]
13620 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
13622 not{<imodesuffix>}\t%0
13624 [(set_attr "isa" "*,<kmov_isa>")
13625 (set_attr "type" "negnot,msklog")
13626 (set_attr "mode" "<MODE>")])
13628 (define_insn "*one_cmplsi2_1_zext"
13629 [(set (match_operand:DI 0 "register_operand" "=r,?k")
13631 (not:SI (match_operand:SI 1 "register_operand" "0,k"))))]
13632 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
13636 [(set_attr "isa" "x64,avx512bw_512")
13637 (set_attr "type" "negnot,msklog")
13638 (set_attr "mode" "SI,SI")])
13640 (define_insn "*one_cmplqi2_1"
13641 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,?k")
13642 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
13643 "ix86_unary_operator_ok (NOT, QImode, operands)"
13648 [(set_attr "isa" "*,*,avx512f")
13649 (set_attr "type" "negnot,negnot,msklog")
13651 (cond [(eq_attr "alternative" "1")
13652 (const_string "SI")
13653 (and (eq_attr "alternative" "2")
13654 (match_test "!TARGET_AVX512DQ"))
13655 (const_string "HI")
13657 (const_string "QI")))
13658 ;; Potential partial reg stall on alternative 1.
13659 (set (attr "preferred_for_speed")
13660 (cond [(eq_attr "alternative" "1")
13661 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
13662 (symbol_ref "true")))])
13664 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
13665 (define_insn_and_split "*one_cmpl<mode>_1_slp"
13666 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
13667 (not:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")))]
13668 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
13670 not{<imodesuffix>}\t%0
13672 "&& reload_completed
13673 && !(rtx_equal_p (operands[0], operands[1]))"
13674 [(set (strict_low_part (match_dup 0)) (match_dup 1))
13675 (set (strict_low_part (match_dup 0))
13676 (not:SWI12 (match_dup 0)))]
13678 [(set_attr "type" "negnot")
13679 (set_attr "mode" "<MODE>")])
13681 (define_insn "*one_cmpl<mode>2_2"
13682 [(set (reg FLAGS_REG)
13683 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
13685 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
13686 (not:SWI (match_dup 1)))]
13687 "ix86_match_ccmode (insn, CCNOmode)
13688 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
13690 [(set_attr "type" "alu1")
13691 (set_attr "mode" "<MODE>")])
13694 [(set (match_operand 0 "flags_reg_operand")
13695 (match_operator 2 "compare_operator"
13696 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
13698 (set (match_operand:SWI 1 "nonimmediate_operand")
13699 (not:SWI (match_dup 3)))]
13700 "ix86_match_ccmode (insn, CCNOmode)"
13701 [(parallel [(set (match_dup 0)
13702 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
13705 (xor:SWI (match_dup 3) (const_int -1)))])])
13707 (define_insn "*one_cmplsi2_2_zext"
13708 [(set (reg FLAGS_REG)
13709 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
13711 (set (match_operand:DI 0 "register_operand" "=r")
13712 (zero_extend:DI (not:SI (match_dup 1))))]
13713 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
13714 && ix86_unary_operator_ok (NOT, SImode, operands)"
13716 [(set_attr "type" "alu1")
13717 (set_attr "mode" "SI")])
13720 [(set (match_operand 0 "flags_reg_operand")
13721 (match_operator 2 "compare_operator"
13722 [(not:SI (match_operand:SI 3 "register_operand"))
13724 (set (match_operand:DI 1 "register_operand")
13725 (zero_extend:DI (not:SI (match_dup 3))))]
13726 "ix86_match_ccmode (insn, CCNOmode)"
13727 [(parallel [(set (match_dup 0)
13728 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
13731 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
13733 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
13734 (define_insn_and_split "*one_cmplqi_ext<mode>_1"
13735 [(set (zero_extract:SWI248
13736 (match_operand 0 "int248_register_operand" "+Q,&Q")
13742 (match_operator:SWI248 2 "extract_operator"
13743 [(match_operand 1 "int248_register_operand" "0,!Q")
13745 (const_int 8)]) 0)) 0))]
13751 && !(rtx_equal_p (operands[0], operands[1]))"
13752 [(set (zero_extract:SWI248
13753 (match_dup 0) (const_int 8) (const_int 8))
13754 (zero_extract:SWI248
13755 (match_dup 1) (const_int 8) (const_int 8)))
13756 (set (zero_extract:SWI248
13757 (match_dup 0) (const_int 8) (const_int 8))
13762 [(match_dup 0) (const_int 8) (const_int 8)]) 0)) 0))]
13764 [(set_attr "type" "negnot")
13765 (set_attr "mode" "QI")])
13767 ;; Shift instructions
13769 ;; DImode shifts are implemented using the i386 "shift double" opcode,
13770 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
13771 ;; is variable, then the count is in %cl and the "imm" operand is dropped
13772 ;; from the assembler input.
13774 ;; This instruction shifts the target reg/mem as usual, but instead of
13775 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
13776 ;; is a left shift double, bits are taken from the high order bits of
13777 ;; reg, else if the insn is a shift right double, bits are taken from the
13778 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
13779 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
13781 ;; Since sh[lr]d does not change the `reg' operand, that is done
13782 ;; separately, making all shifts emit pairs of shift double and normal
13783 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
13784 ;; support a 63 bit shift, each shift where the count is in a reg expands
13785 ;; to a pair of shifts, a branch, a shift by 32 and a label.
13787 ;; If the shift count is a constant, we need never emit more than one
13788 ;; shift pair, instead using moves and sign extension for counts greater
13791 (define_expand "ashl<mode>3"
13792 [(set (match_operand:SDWIM 0 "<shift_operand>")
13793 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
13794 (match_operand:QI 2 "nonmemory_operand")))]
13796 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
13798 (define_insn_and_split "*ashl<dwi>3_doubleword_mask"
13799 [(set (match_operand:<DWI> 0 "register_operand")
13801 (match_operand:<DWI> 1 "register_operand")
13804 (match_operand 2 "int248_register_operand" "c")
13805 (match_operand 3 "const_int_operand")) 0)))
13806 (clobber (reg:CC FLAGS_REG))]
13807 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
13808 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
13809 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
13810 && ix86_pre_reload_split ()"
13814 [(set (match_dup 6)
13815 (ior:DWIH (ashift:DWIH (match_dup 6)
13816 (and:QI (match_dup 2) (match_dup 8)))
13818 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
13819 (minus:QI (match_dup 9)
13820 (and:QI (match_dup 2) (match_dup 8)))) 0)))
13821 (clobber (reg:CC FLAGS_REG))])
13823 [(set (match_dup 4)
13824 (ashift:DWIH (match_dup 5) (match_dup 2)))
13825 (clobber (reg:CC FLAGS_REG))])]
13827 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
13829 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
13830 operands[2] = gen_lowpart (QImode, operands[2]);
13831 emit_insn (gen_ashl<dwi>3_doubleword (operands[0], operands[1],
13836 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
13838 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
13839 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
13841 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13842 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13845 xops[0] = gen_reg_rtx (GET_MODE (operands[2]));
13846 xops[1] = operands[2];
13847 xops[2] = GEN_INT (INTVAL (operands[3])
13848 & ((<MODE_SIZE> * BITS_PER_UNIT) - 1));
13849 ix86_expand_binary_operator (AND, GET_MODE (operands[2]), xops);
13850 operands[2] = xops[0];
13853 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
13854 operands[2] = gen_lowpart (QImode, operands[2]);
13856 if (!rtx_equal_p (operands[6], operands[7]))
13857 emit_move_insn (operands[6], operands[7]);
13860 (define_insn_and_split "*ashl<dwi>3_doubleword_mask_1"
13861 [(set (match_operand:<DWI> 0 "register_operand")
13863 (match_operand:<DWI> 1 "register_operand")
13865 (match_operand:QI 2 "register_operand" "c")
13866 (match_operand:QI 3 "const_int_operand"))))
13867 (clobber (reg:CC FLAGS_REG))]
13868 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
13869 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
13870 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
13871 && ix86_pre_reload_split ()"
13875 [(set (match_dup 6)
13876 (ior:DWIH (ashift:DWIH (match_dup 6)
13877 (and:QI (match_dup 2) (match_dup 8)))
13879 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
13880 (minus:QI (match_dup 9)
13881 (and:QI (match_dup 2) (match_dup 8)))) 0)))
13882 (clobber (reg:CC FLAGS_REG))])
13884 [(set (match_dup 4)
13885 (ashift:DWIH (match_dup 5) (match_dup 2)))
13886 (clobber (reg:CC FLAGS_REG))])]
13888 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
13890 emit_insn (gen_ashl<dwi>3_doubleword (operands[0], operands[1],
13895 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
13897 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
13898 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
13900 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13901 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13903 rtx tem = gen_reg_rtx (QImode);
13904 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
13908 if (!rtx_equal_p (operands[6], operands[7]))
13909 emit_move_insn (operands[6], operands[7]);
13912 (define_insn "ashl<mode>3_doubleword"
13913 [(set (match_operand:DWI 0 "register_operand" "=&r")
13914 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n")
13915 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
13916 (clobber (reg:CC FLAGS_REG))]
13919 [(set_attr "type" "multi")])
13922 [(set (match_operand:DWI 0 "register_operand")
13923 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
13924 (match_operand:QI 2 "nonmemory_operand")))
13925 (clobber (reg:CC FLAGS_REG))]
13926 "epilogue_completed"
13928 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
13930 ;; By default we don't ask for a scratch register, because when DWImode
13931 ;; values are manipulated, registers are already at a premium. But if
13932 ;; we have one handy, we won't turn it away.
13935 [(match_scratch:DWIH 3 "r")
13936 (parallel [(set (match_operand:<DWI> 0 "register_operand")
13938 (match_operand:<DWI> 1 "nonmemory_operand")
13939 (match_operand:QI 2 "nonmemory_operand")))
13940 (clobber (reg:CC FLAGS_REG))])
13944 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
13946 (define_insn_and_split "*ashl<dwi>3_doubleword_highpart"
13947 [(set (match_operand:<DWI> 0 "register_operand" "=r")
13949 (any_extend:<DWI> (match_operand:DWIH 1 "nonimmediate_operand" "rm"))
13950 (match_operand:QI 2 "const_int_operand")))
13951 (clobber (reg:CC FLAGS_REG))]
13952 "INTVAL (operands[2]) >= <MODE_SIZE> * BITS_PER_UNIT
13953 && INTVAL (operands[2]) < <MODE_SIZE> * BITS_PER_UNIT * 2"
13955 "&& reload_completed"
13958 split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[3]);
13959 int bits = INTVAL (operands[2]) - (<MODE_SIZE> * BITS_PER_UNIT);
13960 if (!rtx_equal_p (operands[3], operands[1]))
13961 emit_move_insn (operands[3], operands[1]);
13963 emit_insn (gen_ashl<mode>3 (operands[3], operands[3], GEN_INT (bits)));
13964 ix86_expand_clear (operands[0]);
13968 (define_insn "x86_64_shld"
13969 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
13970 (ior:DI (ashift:DI (match_dup 0)
13971 (and:QI (match_operand:QI 2 "nonmemory_operand" "Jc")
13976 (match_operand:DI 1 "register_operand" "r"))
13977 (minus:QI (const_int 64)
13978 (and:QI (match_dup 2) (const_int 63)))) 0)))
13979 (clobber (reg:CC FLAGS_REG))]
13981 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
13982 [(set_attr "type" "ishift")
13983 (set_attr "prefix_0f" "1")
13984 (set_attr "mode" "DI")
13985 (set_attr "athlon_decode" "vector")
13986 (set_attr "amdfam10_decode" "vector")
13987 (set_attr "bdver1_decode" "vector")])
13989 (define_insn "x86_64_shld_1"
13990 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
13991 (ior:DI (ashift:DI (match_dup 0)
13992 (match_operand:QI 2 "const_0_to_63_operand"))
13996 (match_operand:DI 1 "register_operand" "r"))
13997 (match_operand:QI 3 "const_0_to_255_operand")) 0)))
13998 (clobber (reg:CC FLAGS_REG))]
14000 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])"
14001 "shld{q}\t{%2, %1, %0|%0, %1, %2}"
14002 [(set_attr "type" "ishift")
14003 (set_attr "prefix_0f" "1")
14004 (set_attr "mode" "DI")
14005 (set_attr "length_immediate" "1")
14006 (set_attr "athlon_decode" "vector")
14007 (set_attr "amdfam10_decode" "vector")
14008 (set_attr "bdver1_decode" "vector")])
14010 (define_insn_and_split "*x86_64_shld_shrd_1_nozext"
14011 [(set (match_operand:DI 0 "nonimmediate_operand")
14012 (ior:DI (ashift:DI (match_operand:DI 4 "nonimmediate_operand")
14013 (match_operand:QI 2 "const_0_to_63_operand"))
14015 (match_operand:DI 1 "nonimmediate_operand")
14016 (match_operand:QI 3 "const_0_to_63_operand"))))
14017 (clobber (reg:CC FLAGS_REG))]
14019 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])
14020 && ix86_pre_reload_split ()"
14025 if (rtx_equal_p (operands[4], operands[0]))
14027 operands[1] = force_reg (DImode, operands[1]);
14028 emit_insn (gen_x86_64_shld_1 (operands[0], operands[1], operands[2], operands[3]));
14030 else if (rtx_equal_p (operands[1], operands[0]))
14032 operands[4] = force_reg (DImode, operands[4]);
14033 emit_insn (gen_x86_64_shrd_1 (operands[0], operands[4], operands[3], operands[2]));
14037 operands[1] = force_reg (DImode, operands[1]);
14038 rtx tmp = gen_reg_rtx (DImode);
14039 emit_move_insn (tmp, operands[4]);
14040 emit_insn (gen_x86_64_shld_1 (tmp, operands[1], operands[2], operands[3]));
14041 emit_move_insn (operands[0], tmp);
14046 (define_insn_and_split "*x86_64_shld_2"
14047 [(set (match_operand:DI 0 "nonimmediate_operand")
14048 (ior:DI (ashift:DI (match_dup 0)
14049 (match_operand:QI 2 "nonmemory_operand"))
14050 (lshiftrt:DI (match_operand:DI 1 "register_operand")
14051 (minus:QI (const_int 64) (match_dup 2)))))
14052 (clobber (reg:CC FLAGS_REG))]
14053 "TARGET_64BIT && ix86_pre_reload_split ()"
14056 [(parallel [(set (match_dup 0)
14057 (ior:DI (ashift:DI (match_dup 0)
14058 (and:QI (match_dup 2) (const_int 63)))
14061 (zero_extend:TI (match_dup 1))
14062 (minus:QI (const_int 64)
14063 (and:QI (match_dup 2)
14064 (const_int 63)))) 0)))
14065 (clobber (reg:CC FLAGS_REG))])])
14067 (define_insn "x86_shld"
14068 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
14069 (ior:SI (ashift:SI (match_dup 0)
14070 (and:QI (match_operand:QI 2 "nonmemory_operand" "Ic")
14075 (match_operand:SI 1 "register_operand" "r"))
14076 (minus:QI (const_int 32)
14077 (and:QI (match_dup 2) (const_int 31)))) 0)))
14078 (clobber (reg:CC FLAGS_REG))]
14080 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
14081 [(set_attr "type" "ishift")
14082 (set_attr "prefix_0f" "1")
14083 (set_attr "mode" "SI")
14084 (set_attr "pent_pair" "np")
14085 (set_attr "athlon_decode" "vector")
14086 (set_attr "amdfam10_decode" "vector")
14087 (set_attr "bdver1_decode" "vector")])
14089 (define_insn "x86_shld_1"
14090 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
14091 (ior:SI (ashift:SI (match_dup 0)
14092 (match_operand:QI 2 "const_0_to_31_operand"))
14096 (match_operand:SI 1 "register_operand" "r"))
14097 (match_operand:QI 3 "const_0_to_63_operand")) 0)))
14098 (clobber (reg:CC FLAGS_REG))]
14099 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])"
14100 "shld{l}\t{%2, %1, %0|%0, %1, %2}"
14101 [(set_attr "type" "ishift")
14102 (set_attr "prefix_0f" "1")
14103 (set_attr "length_immediate" "1")
14104 (set_attr "mode" "SI")
14105 (set_attr "pent_pair" "np")
14106 (set_attr "athlon_decode" "vector")
14107 (set_attr "amdfam10_decode" "vector")
14108 (set_attr "bdver1_decode" "vector")])
14110 (define_insn_and_split "*x86_shld_shrd_1_nozext"
14111 [(set (match_operand:SI 0 "nonimmediate_operand")
14112 (ior:SI (ashift:SI (match_operand:SI 4 "nonimmediate_operand")
14113 (match_operand:QI 2 "const_0_to_31_operand"))
14115 (match_operand:SI 1 "nonimmediate_operand")
14116 (match_operand:QI 3 "const_0_to_31_operand"))))
14117 (clobber (reg:CC FLAGS_REG))]
14118 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])
14119 && ix86_pre_reload_split ()"
14124 if (rtx_equal_p (operands[4], operands[0]))
14126 operands[1] = force_reg (SImode, operands[1]);
14127 emit_insn (gen_x86_shld_1 (operands[0], operands[1], operands[2], operands[3]));
14129 else if (rtx_equal_p (operands[1], operands[0]))
14131 operands[4] = force_reg (SImode, operands[4]);
14132 emit_insn (gen_x86_shrd_1 (operands[0], operands[4], operands[3], operands[2]));
14136 operands[1] = force_reg (SImode, operands[1]);
14137 rtx tmp = gen_reg_rtx (SImode);
14138 emit_move_insn (tmp, operands[4]);
14139 emit_insn (gen_x86_shld_1 (tmp, operands[1], operands[2], operands[3]));
14140 emit_move_insn (operands[0], tmp);
14145 (define_insn_and_split "*x86_shld_2"
14146 [(set (match_operand:SI 0 "nonimmediate_operand")
14147 (ior:SI (ashift:SI (match_dup 0)
14148 (match_operand:QI 2 "nonmemory_operand"))
14149 (lshiftrt:SI (match_operand:SI 1 "register_operand")
14150 (minus:QI (const_int 32) (match_dup 2)))))
14151 (clobber (reg:CC FLAGS_REG))]
14152 "TARGET_64BIT && ix86_pre_reload_split ()"
14155 [(parallel [(set (match_dup 0)
14156 (ior:SI (ashift:SI (match_dup 0)
14157 (and:QI (match_dup 2) (const_int 31)))
14160 (zero_extend:DI (match_dup 1))
14161 (minus:QI (const_int 32)
14162 (and:QI (match_dup 2)
14163 (const_int 31)))) 0)))
14164 (clobber (reg:CC FLAGS_REG))])])
14166 (define_expand "@x86_shift<mode>_adj_1"
14167 [(set (reg:CCZ FLAGS_REG)
14168 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
14171 (set (match_operand:SWI48 0 "register_operand")
14172 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
14173 (match_operand:SWI48 1 "register_operand")
14176 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
14177 (match_operand:SWI48 3 "register_operand")
14180 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
14182 (define_expand "@x86_shift<mode>_adj_2"
14183 [(use (match_operand:SWI48 0 "register_operand"))
14184 (use (match_operand:SWI48 1 "register_operand"))
14185 (use (match_operand:QI 2 "register_operand"))]
14188 rtx_code_label *label = gen_label_rtx ();
14191 emit_insn (gen_testqi_ccz_1 (operands[2],
14192 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
14194 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
14195 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
14196 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
14197 gen_rtx_LABEL_REF (VOIDmode, label),
14199 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
14200 JUMP_LABEL (tmp) = label;
14202 emit_move_insn (operands[0], operands[1]);
14203 ix86_expand_clear (operands[1]);
14205 emit_label (label);
14206 LABEL_NUSES (label) = 1;
14211 ;; Avoid useless masking of count operand.
14212 (define_insn_and_split "*ashl<mode>3_mask"
14213 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14215 (match_operand:SWI48 1 "nonimmediate_operand")
14218 (match_operand 2 "int248_register_operand" "c,r")
14219 (match_operand 3 "const_int_operand")) 0)))
14220 (clobber (reg:CC FLAGS_REG))]
14221 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
14222 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
14223 == GET_MODE_BITSIZE (<MODE>mode)-1
14224 && ix86_pre_reload_split ()"
14228 [(set (match_dup 0)
14229 (ashift:SWI48 (match_dup 1)
14231 (clobber (reg:CC FLAGS_REG))])]
14233 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14234 operands[2] = gen_lowpart (QImode, operands[2]);
14236 [(set_attr "isa" "*,bmi2")])
14238 (define_insn_and_split "*ashl<mode>3_mask_1"
14239 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14241 (match_operand:SWI48 1 "nonimmediate_operand")
14243 (match_operand:QI 2 "register_operand" "c,r")
14244 (match_operand:QI 3 "const_int_operand"))))
14245 (clobber (reg:CC FLAGS_REG))]
14246 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
14247 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
14248 == GET_MODE_BITSIZE (<MODE>mode)-1
14249 && ix86_pre_reload_split ()"
14253 [(set (match_dup 0)
14254 (ashift:SWI48 (match_dup 1)
14256 (clobber (reg:CC FLAGS_REG))])]
14258 [(set_attr "isa" "*,bmi2")])
14260 (define_insn "*bmi2_ashl<mode>3_1"
14261 [(set (match_operand:SWI48 0 "register_operand" "=r")
14262 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14263 (match_operand:SWI48 2 "register_operand" "r")))]
14265 "shlx\t{%2, %1, %0|%0, %1, %2}"
14266 [(set_attr "type" "ishiftx")
14267 (set_attr "mode" "<MODE>")])
14269 (define_insn "*ashl<mode>3_1"
14270 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,?k")
14271 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm,k")
14272 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r,<KS>")))
14273 (clobber (reg:CC FLAGS_REG))]
14274 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
14276 switch (get_attr_type (insn))
14284 gcc_assert (operands[2] == const1_rtx);
14285 gcc_assert (rtx_equal_p (operands[0], operands[1]));
14286 return "add{<imodesuffix>}\t%0, %0";
14289 if (operands[2] == const1_rtx
14290 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14291 return "sal{<imodesuffix>}\t%0";
14293 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14296 [(set_attr "isa" "*,*,bmi2,<kmov_isa>")
14298 (cond [(eq_attr "alternative" "1")
14299 (const_string "lea")
14300 (eq_attr "alternative" "2")
14301 (const_string "ishiftx")
14302 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14303 (match_operand 0 "register_operand"))
14304 (match_operand 2 "const1_operand"))
14305 (const_string "alu")
14306 (eq_attr "alternative" "3")
14307 (const_string "msklog")
14309 (const_string "ishift")))
14310 (set (attr "length_immediate")
14312 (ior (eq_attr "type" "alu")
14313 (and (eq_attr "type" "ishift")
14314 (and (match_operand 2 "const1_operand")
14315 (ior (match_test "TARGET_SHIFT1")
14316 (match_test "optimize_function_for_size_p (cfun)")))))
14318 (const_string "*")))
14319 (set_attr "mode" "<MODE>")])
14321 ;; Convert shift to the shiftx pattern to avoid flags dependency.
14323 [(set (match_operand:SWI48 0 "register_operand")
14324 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
14325 (match_operand:QI 2 "register_operand")))
14326 (clobber (reg:CC FLAGS_REG))]
14327 "TARGET_BMI2 && reload_completed"
14328 [(set (match_dup 0)
14329 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
14330 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
14332 (define_insn "*bmi2_ashlsi3_1_zext"
14333 [(set (match_operand:DI 0 "register_operand" "=r")
14335 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
14336 (match_operand:SI 2 "register_operand" "r"))))]
14337 "TARGET_64BIT && TARGET_BMI2"
14338 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
14339 [(set_attr "type" "ishiftx")
14340 (set_attr "mode" "SI")])
14342 (define_insn "*ashlsi3_1_zext"
14343 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
14345 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
14346 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
14347 (clobber (reg:CC FLAGS_REG))]
14348 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
14350 switch (get_attr_type (insn))
14357 gcc_assert (operands[2] == const1_rtx);
14358 return "add{l}\t%k0, %k0";
14361 if (operands[2] == const1_rtx
14362 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14363 return "sal{l}\t%k0";
14365 return "sal{l}\t{%2, %k0|%k0, %2}";
14368 [(set_attr "isa" "*,*,bmi2")
14370 (cond [(eq_attr "alternative" "1")
14371 (const_string "lea")
14372 (eq_attr "alternative" "2")
14373 (const_string "ishiftx")
14374 (and (match_test "TARGET_DOUBLE_WITH_ADD")
14375 (match_operand 2 "const1_operand"))
14376 (const_string "alu")
14378 (const_string "ishift")))
14379 (set (attr "length_immediate")
14381 (ior (eq_attr "type" "alu")
14382 (and (eq_attr "type" "ishift")
14383 (and (match_operand 2 "const1_operand")
14384 (ior (match_test "TARGET_SHIFT1")
14385 (match_test "optimize_function_for_size_p (cfun)")))))
14387 (const_string "*")))
14388 (set_attr "mode" "SI")])
14390 ;; Convert shift to the shiftx pattern to avoid flags dependency.
14392 [(set (match_operand:DI 0 "register_operand")
14394 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
14395 (match_operand:QI 2 "register_operand"))))
14396 (clobber (reg:CC FLAGS_REG))]
14397 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
14398 [(set (match_dup 0)
14399 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
14400 "operands[2] = gen_lowpart (SImode, operands[2]);")
14402 (define_insn "*ashlhi3_1"
14403 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp,?k")
14404 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l,k")
14405 (match_operand:QI 2 "nonmemory_operand" "cI,M,Ww")))
14406 (clobber (reg:CC FLAGS_REG))]
14407 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
14409 switch (get_attr_type (insn))
14416 gcc_assert (operands[2] == const1_rtx);
14417 return "add{w}\t%0, %0";
14420 if (operands[2] == const1_rtx
14421 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14422 return "sal{w}\t%0";
14424 return "sal{w}\t{%2, %0|%0, %2}";
14427 [(set_attr "isa" "*,*,avx512f")
14429 (cond [(eq_attr "alternative" "1")
14430 (const_string "lea")
14431 (eq_attr "alternative" "2")
14432 (const_string "msklog")
14433 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14434 (match_operand 0 "register_operand"))
14435 (match_operand 2 "const1_operand"))
14436 (const_string "alu")
14438 (const_string "ishift")))
14439 (set (attr "length_immediate")
14441 (ior (eq_attr "type" "alu")
14442 (and (eq_attr "type" "ishift")
14443 (and (match_operand 2 "const1_operand")
14444 (ior (match_test "TARGET_SHIFT1")
14445 (match_test "optimize_function_for_size_p (cfun)")))))
14447 (const_string "*")))
14448 (set_attr "mode" "HI,SI,HI")])
14450 (define_insn "*ashlqi3_1"
14451 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp,?k")
14452 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l,k")
14453 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M,Wb")))
14454 (clobber (reg:CC FLAGS_REG))]
14455 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
14457 switch (get_attr_type (insn))
14464 gcc_assert (operands[2] == const1_rtx);
14465 if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
14466 return "add{l}\t%k0, %k0";
14468 return "add{b}\t%0, %0";
14471 if (operands[2] == const1_rtx
14472 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14474 if (get_attr_mode (insn) == MODE_SI)
14475 return "sal{l}\t%k0";
14477 return "sal{b}\t%0";
14481 if (get_attr_mode (insn) == MODE_SI)
14482 return "sal{l}\t{%2, %k0|%k0, %2}";
14484 return "sal{b}\t{%2, %0|%0, %2}";
14488 [(set_attr "isa" "*,*,*,avx512dq")
14490 (cond [(eq_attr "alternative" "2")
14491 (const_string "lea")
14492 (eq_attr "alternative" "3")
14493 (const_string "msklog")
14494 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14495 (match_operand 0 "register_operand"))
14496 (match_operand 2 "const1_operand"))
14497 (const_string "alu")
14499 (const_string "ishift")))
14500 (set (attr "length_immediate")
14502 (ior (eq_attr "type" "alu")
14503 (and (eq_attr "type" "ishift")
14504 (and (match_operand 2 "const1_operand")
14505 (ior (match_test "TARGET_SHIFT1")
14506 (match_test "optimize_function_for_size_p (cfun)")))))
14508 (const_string "*")))
14509 (set_attr "mode" "QI,SI,SI,QI")
14510 ;; Potential partial reg stall on alternative 1.
14511 (set (attr "preferred_for_speed")
14512 (cond [(eq_attr "alternative" "1")
14513 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
14514 (symbol_ref "true")))])
14516 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
14517 (define_insn_and_split "*ashl<mode>3_1_slp"
14518 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
14519 (ashift:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
14520 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
14521 (clobber (reg:CC FLAGS_REG))]
14522 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
14524 if (which_alternative)
14527 switch (get_attr_type (insn))
14530 gcc_assert (operands[2] == const1_rtx);
14531 return "add{<imodesuffix>}\t%0, %0";
14534 if (operands[2] == const1_rtx
14535 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14536 return "sal{<imodesuffix>}\t%0";
14538 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14541 "&& reload_completed
14542 && !(rtx_equal_p (operands[0], operands[1]))"
14543 [(set (strict_low_part (match_dup 0)) (match_dup 1))
14545 [(set (strict_low_part (match_dup 0))
14546 (ashift:SWI12 (match_dup 0) (match_dup 2)))
14547 (clobber (reg:CC FLAGS_REG))])]
14549 [(set (attr "type")
14550 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
14551 (match_operand 2 "const1_operand"))
14552 (const_string "alu")
14554 (const_string "ishift")))
14555 (set (attr "length_immediate")
14557 (ior (eq_attr "type" "alu")
14558 (and (eq_attr "type" "ishift")
14559 (and (match_operand 2 "const1_operand")
14560 (ior (match_test "TARGET_SHIFT1")
14561 (match_test "optimize_function_for_size_p (cfun)")))))
14563 (const_string "*")))
14564 (set_attr "mode" "<MODE>")])
14566 ;; Convert ashift to the lea pattern to avoid flags dependency.
14568 [(set (match_operand:SWI 0 "general_reg_operand")
14569 (ashift:SWI (match_operand:SWI 1 "index_reg_operand")
14570 (match_operand 2 "const_0_to_3_operand")))
14571 (clobber (reg:CC FLAGS_REG))]
14573 && REGNO (operands[0]) != REGNO (operands[1])"
14574 [(set (match_dup 0)
14575 (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
14577 if (<MODE>mode != <LEAMODE>mode)
14579 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
14580 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
14582 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
14585 ;; Convert ashift to the lea pattern to avoid flags dependency.
14587 [(set (match_operand:DI 0 "general_reg_operand")
14589 (ashift:SI (match_operand:SI 1 "index_reg_operand")
14590 (match_operand 2 "const_0_to_3_operand"))))
14591 (clobber (reg:CC FLAGS_REG))]
14592 "TARGET_64BIT && reload_completed
14593 && REGNO (operands[0]) != REGNO (operands[1])"
14594 [(set (match_dup 0)
14595 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
14597 operands[1] = gen_lowpart (SImode, operands[1]);
14598 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
14601 ;; This pattern can't accept a variable shift count, since shifts by
14602 ;; zero don't affect the flags. We assume that shifts by constant
14603 ;; zero are optimized away.
14604 (define_insn "*ashl<mode>3_cmp"
14605 [(set (reg FLAGS_REG)
14607 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
14608 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
14610 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
14611 (ashift:SWI (match_dup 1) (match_dup 2)))]
14612 "(optimize_function_for_size_p (cfun)
14613 || !TARGET_PARTIAL_FLAG_REG_STALL
14614 || (operands[2] == const1_rtx
14616 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
14617 && ix86_match_ccmode (insn, CCGOCmode)
14618 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
14620 switch (get_attr_type (insn))
14623 gcc_assert (operands[2] == const1_rtx);
14624 return "add{<imodesuffix>}\t%0, %0";
14627 if (operands[2] == const1_rtx
14628 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14629 return "sal{<imodesuffix>}\t%0";
14631 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14634 [(set (attr "type")
14635 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14636 (match_operand 0 "register_operand"))
14637 (match_operand 2 "const1_operand"))
14638 (const_string "alu")
14640 (const_string "ishift")))
14641 (set (attr "length_immediate")
14643 (ior (eq_attr "type" "alu")
14644 (and (eq_attr "type" "ishift")
14645 (and (match_operand 2 "const1_operand")
14646 (ior (match_test "TARGET_SHIFT1")
14647 (match_test "optimize_function_for_size_p (cfun)")))))
14649 (const_string "*")))
14650 (set_attr "mode" "<MODE>")])
14652 (define_insn "*ashlsi3_cmp_zext"
14653 [(set (reg FLAGS_REG)
14655 (ashift:SI (match_operand:SI 1 "register_operand" "0")
14656 (match_operand:QI 2 "const_1_to_31_operand"))
14658 (set (match_operand:DI 0 "register_operand" "=r")
14659 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
14661 && (optimize_function_for_size_p (cfun)
14662 || !TARGET_PARTIAL_FLAG_REG_STALL
14663 || (operands[2] == const1_rtx
14665 || TARGET_DOUBLE_WITH_ADD)))
14666 && ix86_match_ccmode (insn, CCGOCmode)
14667 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
14669 switch (get_attr_type (insn))
14672 gcc_assert (operands[2] == const1_rtx);
14673 return "add{l}\t%k0, %k0";
14676 if (operands[2] == const1_rtx
14677 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14678 return "sal{l}\t%k0";
14680 return "sal{l}\t{%2, %k0|%k0, %2}";
14683 [(set (attr "type")
14684 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
14685 (match_operand 2 "const1_operand"))
14686 (const_string "alu")
14688 (const_string "ishift")))
14689 (set (attr "length_immediate")
14691 (ior (eq_attr "type" "alu")
14692 (and (eq_attr "type" "ishift")
14693 (and (match_operand 2 "const1_operand")
14694 (ior (match_test "TARGET_SHIFT1")
14695 (match_test "optimize_function_for_size_p (cfun)")))))
14697 (const_string "*")))
14698 (set_attr "mode" "SI")])
14700 (define_insn "*ashl<mode>3_cconly"
14701 [(set (reg FLAGS_REG)
14703 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
14704 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
14706 (clobber (match_scratch:SWI 0 "=<r>"))]
14707 "(optimize_function_for_size_p (cfun)
14708 || !TARGET_PARTIAL_FLAG_REG_STALL
14709 || (operands[2] == const1_rtx
14711 || TARGET_DOUBLE_WITH_ADD)))
14712 && ix86_match_ccmode (insn, CCGOCmode)"
14714 switch (get_attr_type (insn))
14717 gcc_assert (operands[2] == const1_rtx);
14718 return "add{<imodesuffix>}\t%0, %0";
14721 if (operands[2] == const1_rtx
14722 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14723 return "sal{<imodesuffix>}\t%0";
14725 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14728 [(set (attr "type")
14729 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14730 (match_operand 0 "register_operand"))
14731 (match_operand 2 "const1_operand"))
14732 (const_string "alu")
14734 (const_string "ishift")))
14735 (set (attr "length_immediate")
14737 (ior (eq_attr "type" "alu")
14738 (and (eq_attr "type" "ishift")
14739 (and (match_operand 2 "const1_operand")
14740 (ior (match_test "TARGET_SHIFT1")
14741 (match_test "optimize_function_for_size_p (cfun)")))))
14743 (const_string "*")))
14744 (set_attr "mode" "<MODE>")])
14746 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
14747 (define_insn_and_split "*ashlqi_ext<mode>_1"
14748 [(set (zero_extract:SWI248
14749 (match_operand 0 "int248_register_operand" "+Q,&Q")
14755 (match_operator:SWI248 3 "extract_operator"
14756 [(match_operand 1 "int248_register_operand" "0,!Q")
14759 (match_operand:QI 2 "nonmemory_operand" "cI,cI")) 0))
14760 (clobber (reg:CC FLAGS_REG))]
14763 if (which_alternative)
14766 switch (get_attr_type (insn))
14769 gcc_assert (operands[2] == const1_rtx);
14770 return "add{b}\t%h0, %h0";
14773 if (operands[2] == const1_rtx
14774 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14775 return "sal{b}\t%h0";
14777 return "sal{b}\t{%2, %h0|%h0, %2}";
14781 && !(rtx_equal_p (operands[0], operands[1]))"
14782 [(set (zero_extract:SWI248
14783 (match_dup 0) (const_int 8) (const_int 8))
14786 [(set (zero_extract:SWI248
14787 (match_dup 0) (const_int 8) (const_int 8))
14792 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
14794 (clobber (reg:CC FLAGS_REG))])]
14796 [(set (attr "type")
14797 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
14798 (match_operand 2 "const1_operand"))
14799 (const_string "alu")
14801 (const_string "ishift")))
14802 (set (attr "length_immediate")
14804 (ior (eq_attr "type" "alu")
14805 (and (eq_attr "type" "ishift")
14806 (and (match_operand 2 "const1_operand")
14807 (ior (match_test "TARGET_SHIFT1")
14808 (match_test "optimize_function_for_size_p (cfun)")))))
14810 (const_string "*")))
14811 (set_attr "mode" "QI")])
14813 ;; See comment above `ashl<mode>3' about how this works.
14815 (define_expand "<insn><mode>3"
14816 [(set (match_operand:SDWIM 0 "<shift_operand>")
14817 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
14818 (match_operand:QI 2 "nonmemory_operand")))]
14820 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
14822 ;; Avoid useless masking of count operand.
14823 (define_insn_and_split "*<insn><mode>3_mask"
14824 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14826 (match_operand:SWI48 1 "nonimmediate_operand")
14829 (match_operand 2 "int248_register_operand" "c,r")
14830 (match_operand 3 "const_int_operand")) 0)))
14831 (clobber (reg:CC FLAGS_REG))]
14832 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
14833 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
14834 == GET_MODE_BITSIZE (<MODE>mode)-1
14835 && ix86_pre_reload_split ()"
14839 [(set (match_dup 0)
14840 (any_shiftrt:SWI48 (match_dup 1)
14842 (clobber (reg:CC FLAGS_REG))])]
14844 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14845 operands[2] = gen_lowpart (QImode, operands[2]);
14847 [(set_attr "isa" "*,bmi2")])
14849 (define_insn_and_split "*<insn><mode>3_mask_1"
14850 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14852 (match_operand:SWI48 1 "nonimmediate_operand")
14854 (match_operand:QI 2 "register_operand" "c,r")
14855 (match_operand:QI 3 "const_int_operand"))))
14856 (clobber (reg:CC FLAGS_REG))]
14857 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
14858 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
14859 == GET_MODE_BITSIZE (<MODE>mode)-1
14860 && ix86_pre_reload_split ()"
14864 [(set (match_dup 0)
14865 (any_shiftrt:SWI48 (match_dup 1)
14867 (clobber (reg:CC FLAGS_REG))])]
14869 [(set_attr "isa" "*,bmi2")])
14871 (define_insn_and_split "*<insn><dwi>3_doubleword_mask"
14872 [(set (match_operand:<DWI> 0 "register_operand")
14874 (match_operand:<DWI> 1 "register_operand")
14877 (match_operand 2 "int248_register_operand" "c")
14878 (match_operand 3 "const_int_operand")) 0)))
14879 (clobber (reg:CC FLAGS_REG))]
14880 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
14881 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
14882 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
14883 && ix86_pre_reload_split ()"
14887 [(set (match_dup 4)
14888 (ior:DWIH (lshiftrt:DWIH (match_dup 4)
14889 (and:QI (match_dup 2) (match_dup 8)))
14891 (ashift:<DWI> (zero_extend:<DWI> (match_dup 7))
14892 (minus:QI (match_dup 9)
14893 (and:QI (match_dup 2) (match_dup 8)))) 0)))
14894 (clobber (reg:CC FLAGS_REG))])
14896 [(set (match_dup 6)
14897 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
14898 (clobber (reg:CC FLAGS_REG))])]
14900 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
14902 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14903 operands[2] = gen_lowpart (QImode, operands[2]);
14904 emit_insn (gen_<insn><dwi>3_doubleword (operands[0], operands[1],
14909 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
14911 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
14912 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
14914 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14915 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14918 xops[0] = gen_reg_rtx (GET_MODE (operands[2]));
14919 xops[1] = operands[2];
14920 xops[2] = GEN_INT (INTVAL (operands[3])
14921 & ((<MODE_SIZE> * BITS_PER_UNIT) - 1));
14922 ix86_expand_binary_operator (AND, GET_MODE (operands[2]), xops);
14923 operands[2] = xops[0];
14926 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14927 operands[2] = gen_lowpart (QImode, operands[2]);
14929 if (!rtx_equal_p (operands[4], operands[5]))
14930 emit_move_insn (operands[4], operands[5]);
14933 (define_insn_and_split "*<insn><dwi>3_doubleword_mask_1"
14934 [(set (match_operand:<DWI> 0 "register_operand")
14936 (match_operand:<DWI> 1 "register_operand")
14938 (match_operand:QI 2 "register_operand" "c")
14939 (match_operand:QI 3 "const_int_operand"))))
14940 (clobber (reg:CC FLAGS_REG))]
14941 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
14942 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
14943 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
14944 && ix86_pre_reload_split ()"
14948 [(set (match_dup 4)
14949 (ior:DWIH (lshiftrt:DWIH (match_dup 4)
14950 (and:QI (match_dup 2) (match_dup 8)))
14952 (ashift:<DWI> (zero_extend:<DWI> (match_dup 7))
14953 (minus:QI (match_dup 9)
14954 (and:QI (match_dup 2) (match_dup 8)))) 0)))
14955 (clobber (reg:CC FLAGS_REG))])
14957 [(set (match_dup 6)
14958 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
14959 (clobber (reg:CC FLAGS_REG))])]
14961 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
14963 emit_insn (gen_<insn><dwi>3_doubleword (operands[0], operands[1],
14968 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
14970 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
14971 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
14973 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14974 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14976 rtx tem = gen_reg_rtx (QImode);
14977 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
14981 if (!rtx_equal_p (operands[4], operands[5]))
14982 emit_move_insn (operands[4], operands[5]);
14985 (define_insn_and_split "<insn><mode>3_doubleword"
14986 [(set (match_operand:DWI 0 "register_operand" "=&r")
14987 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
14988 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
14989 (clobber (reg:CC FLAGS_REG))]
14992 "epilogue_completed"
14994 "ix86_split_<insn> (operands, NULL_RTX, <MODE>mode); DONE;"
14995 [(set_attr "type" "multi")])
14997 ;; By default we don't ask for a scratch register, because when DWImode
14998 ;; values are manipulated, registers are already at a premium. But if
14999 ;; we have one handy, we won't turn it away.
15002 [(match_scratch:DWIH 3 "r")
15003 (parallel [(set (match_operand:<DWI> 0 "register_operand")
15005 (match_operand:<DWI> 1 "register_operand")
15006 (match_operand:QI 2 "nonmemory_operand")))
15007 (clobber (reg:CC FLAGS_REG))])
15011 "ix86_split_<insn> (operands, operands[3], <DWI>mode); DONE;")
15013 ;; Split truncations of double word right shifts into x86_shrd_1.
15014 (define_insn_and_split "<insn><dwi>3_doubleword_lowpart"
15015 [(set (match_operand:DWIH 0 "register_operand" "=&r")
15017 (any_shiftrt:<DWI> (match_operand:<DWI> 1 "register_operand" "r")
15018 (match_operand:QI 2 "const_int_operand")) 0))
15019 (clobber (reg:CC FLAGS_REG))]
15020 "UINTVAL (operands[2]) < <MODE_SIZE> * BITS_PER_UNIT"
15022 "&& reload_completed"
15024 [(set (match_dup 0)
15025 (ior:DWIH (lshiftrt:DWIH (match_dup 0) (match_dup 2))
15027 (ashift:<DWI> (zero_extend:<DWI> (match_dup 3))
15028 (match_dup 4)) 0)))
15029 (clobber (reg:CC FLAGS_REG))])]
15031 split_double_mode (<DWI>mode, &operands[1], 1, &operands[1], &operands[3]);
15032 operands[4] = GEN_INT ((<MODE_SIZE> * BITS_PER_UNIT) - INTVAL (operands[2]));
15033 if (!rtx_equal_p (operands[0], operands[1]))
15034 emit_move_insn (operands[0], operands[1]);
15037 (define_insn "x86_64_shrd"
15038 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
15039 (ior:DI (lshiftrt:DI (match_dup 0)
15040 (and:QI (match_operand:QI 2 "nonmemory_operand" "Jc")
15045 (match_operand:DI 1 "register_operand" "r"))
15046 (minus:QI (const_int 64)
15047 (and:QI (match_dup 2) (const_int 63)))) 0)))
15048 (clobber (reg:CC FLAGS_REG))]
15050 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
15051 [(set_attr "type" "ishift")
15052 (set_attr "prefix_0f" "1")
15053 (set_attr "mode" "DI")
15054 (set_attr "athlon_decode" "vector")
15055 (set_attr "amdfam10_decode" "vector")
15056 (set_attr "bdver1_decode" "vector")])
15058 (define_insn "x86_64_shrd_1"
15059 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
15060 (ior:DI (lshiftrt:DI (match_dup 0)
15061 (match_operand:QI 2 "const_0_to_63_operand"))
15065 (match_operand:DI 1 "register_operand" "r"))
15066 (match_operand:QI 3 "const_0_to_255_operand")) 0)))
15067 (clobber (reg:CC FLAGS_REG))]
15069 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])"
15070 "shrd{q}\t{%2, %1, %0|%0, %1, %2}"
15071 [(set_attr "type" "ishift")
15072 (set_attr "prefix_0f" "1")
15073 (set_attr "length_immediate" "1")
15074 (set_attr "mode" "DI")
15075 (set_attr "athlon_decode" "vector")
15076 (set_attr "amdfam10_decode" "vector")
15077 (set_attr "bdver1_decode" "vector")])
15079 (define_insn_and_split "*x86_64_shrd_shld_1_nozext"
15080 [(set (match_operand:DI 0 "nonimmediate_operand")
15081 (ior:DI (lshiftrt:DI (match_operand:DI 4 "nonimmediate_operand")
15082 (match_operand:QI 2 "const_0_to_63_operand"))
15084 (match_operand:DI 1 "nonimmediate_operand")
15085 (match_operand:QI 3 "const_0_to_63_operand"))))
15086 (clobber (reg:CC FLAGS_REG))]
15088 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])
15089 && ix86_pre_reload_split ()"
15094 if (rtx_equal_p (operands[4], operands[0]))
15096 operands[1] = force_reg (DImode, operands[1]);
15097 emit_insn (gen_x86_64_shrd_1 (operands[0], operands[1], operands[2], operands[3]));
15099 else if (rtx_equal_p (operands[1], operands[0]))
15101 operands[4] = force_reg (DImode, operands[4]);
15102 emit_insn (gen_x86_64_shld_1 (operands[0], operands[4], operands[3], operands[2]));
15106 operands[1] = force_reg (DImode, operands[1]);
15107 rtx tmp = gen_reg_rtx (DImode);
15108 emit_move_insn (tmp, operands[4]);
15109 emit_insn (gen_x86_64_shrd_1 (tmp, operands[1], operands[2], operands[3]));
15110 emit_move_insn (operands[0], tmp);
15115 (define_insn_and_split "*x86_64_shrd_2"
15116 [(set (match_operand:DI 0 "nonimmediate_operand")
15117 (ior:DI (lshiftrt:DI (match_dup 0)
15118 (match_operand:QI 2 "nonmemory_operand"))
15119 (ashift:DI (match_operand:DI 1 "register_operand")
15120 (minus:QI (const_int 64) (match_dup 2)))))
15121 (clobber (reg:CC FLAGS_REG))]
15122 "TARGET_64BIT && ix86_pre_reload_split ()"
15125 [(parallel [(set (match_dup 0)
15126 (ior:DI (lshiftrt:DI (match_dup 0)
15127 (and:QI (match_dup 2) (const_int 63)))
15130 (zero_extend:TI (match_dup 1))
15131 (minus:QI (const_int 64)
15132 (and:QI (match_dup 2)
15133 (const_int 63)))) 0)))
15134 (clobber (reg:CC FLAGS_REG))])])
15136 (define_insn "x86_shrd"
15137 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
15138 (ior:SI (lshiftrt:SI (match_dup 0)
15139 (and:QI (match_operand:QI 2 "nonmemory_operand" "Ic")
15144 (match_operand:SI 1 "register_operand" "r"))
15145 (minus:QI (const_int 32)
15146 (and:QI (match_dup 2) (const_int 31)))) 0)))
15147 (clobber (reg:CC FLAGS_REG))]
15149 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
15150 [(set_attr "type" "ishift")
15151 (set_attr "prefix_0f" "1")
15152 (set_attr "mode" "SI")
15153 (set_attr "pent_pair" "np")
15154 (set_attr "athlon_decode" "vector")
15155 (set_attr "amdfam10_decode" "vector")
15156 (set_attr "bdver1_decode" "vector")])
15158 (define_insn "x86_shrd_1"
15159 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
15160 (ior:SI (lshiftrt:SI (match_dup 0)
15161 (match_operand:QI 2 "const_0_to_31_operand"))
15165 (match_operand:SI 1 "register_operand" "r"))
15166 (match_operand:QI 3 "const_0_to_63_operand")) 0)))
15167 (clobber (reg:CC FLAGS_REG))]
15168 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])"
15169 "shrd{l}\t{%2, %1, %0|%0, %1, %2}"
15170 [(set_attr "type" "ishift")
15171 (set_attr "prefix_0f" "1")
15172 (set_attr "length_immediate" "1")
15173 (set_attr "mode" "SI")
15174 (set_attr "pent_pair" "np")
15175 (set_attr "athlon_decode" "vector")
15176 (set_attr "amdfam10_decode" "vector")
15177 (set_attr "bdver1_decode" "vector")])
15179 (define_insn_and_split "*x86_shrd_shld_1_nozext"
15180 [(set (match_operand:SI 0 "nonimmediate_operand")
15181 (ior:SI (lshiftrt:SI (match_operand:SI 4 "nonimmediate_operand")
15182 (match_operand:QI 2 "const_0_to_31_operand"))
15184 (match_operand:SI 1 "nonimmediate_operand")
15185 (match_operand:QI 3 "const_0_to_31_operand"))))
15186 (clobber (reg:CC FLAGS_REG))]
15187 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])
15188 && ix86_pre_reload_split ()"
15193 if (rtx_equal_p (operands[4], operands[0]))
15195 operands[1] = force_reg (SImode, operands[1]);
15196 emit_insn (gen_x86_shrd_1 (operands[0], operands[1], operands[2], operands[3]));
15198 else if (rtx_equal_p (operands[1], operands[0]))
15200 operands[4] = force_reg (SImode, operands[4]);
15201 emit_insn (gen_x86_shld_1 (operands[0], operands[4], operands[3], operands[2]));
15205 operands[1] = force_reg (SImode, operands[1]);
15206 rtx tmp = gen_reg_rtx (SImode);
15207 emit_move_insn (tmp, operands[4]);
15208 emit_insn (gen_x86_shrd_1 (tmp, operands[1], operands[2], operands[3]));
15209 emit_move_insn (operands[0], tmp);
15214 (define_insn_and_split "*x86_shrd_2"
15215 [(set (match_operand:SI 0 "nonimmediate_operand")
15216 (ior:SI (lshiftrt:SI (match_dup 0)
15217 (match_operand:QI 2 "nonmemory_operand"))
15218 (ashift:SI (match_operand:SI 1 "register_operand")
15219 (minus:QI (const_int 32) (match_dup 2)))))
15220 (clobber (reg:CC FLAGS_REG))]
15221 "TARGET_64BIT && ix86_pre_reload_split ()"
15224 [(parallel [(set (match_dup 0)
15225 (ior:SI (lshiftrt:SI (match_dup 0)
15226 (and:QI (match_dup 2) (const_int 31)))
15229 (zero_extend:DI (match_dup 1))
15230 (minus:QI (const_int 32)
15231 (and:QI (match_dup 2)
15232 (const_int 31)))) 0)))
15233 (clobber (reg:CC FLAGS_REG))])])
15235 ;; Base name for insn mnemonic.
15236 (define_mode_attr cvt_mnemonic
15237 [(SI "{cltd|cdq}") (DI "{cqto|cqo}")])
15239 (define_insn "ashr<mode>3_cvt"
15240 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=*d,rm")
15242 (match_operand:SWI48 1 "nonimmediate_operand" "*a,0")
15243 (match_operand:QI 2 "const_int_operand")))
15244 (clobber (reg:CC FLAGS_REG))]
15245 "INTVAL (operands[2]) == GET_MODE_BITSIZE (<MODE>mode)-1
15246 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
15247 && ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
15250 sar{<imodesuffix>}\t{%2, %0|%0, %2}"
15251 [(set_attr "type" "imovx,ishift")
15252 (set_attr "prefix_0f" "0,*")
15253 (set_attr "length_immediate" "0,*")
15254 (set_attr "modrm" "0,1")
15255 (set_attr "mode" "<MODE>")])
15257 (define_insn "*ashrsi3_cvt_zext"
15258 [(set (match_operand:DI 0 "register_operand" "=*d,r")
15260 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
15261 (match_operand:QI 2 "const_int_operand"))))
15262 (clobber (reg:CC FLAGS_REG))]
15263 "TARGET_64BIT && INTVAL (operands[2]) == 31
15264 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
15265 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
15268 sar{l}\t{%2, %k0|%k0, %2}"
15269 [(set_attr "type" "imovx,ishift")
15270 (set_attr "prefix_0f" "0,*")
15271 (set_attr "length_immediate" "0,*")
15272 (set_attr "modrm" "0,1")
15273 (set_attr "mode" "SI")])
15275 (define_expand "@x86_shift<mode>_adj_3"
15276 [(use (match_operand:SWI48 0 "register_operand"))
15277 (use (match_operand:SWI48 1 "register_operand"))
15278 (use (match_operand:QI 2 "register_operand"))]
15281 rtx_code_label *label = gen_label_rtx ();
15284 emit_insn (gen_testqi_ccz_1 (operands[2],
15285 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
15287 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
15288 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
15289 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
15290 gen_rtx_LABEL_REF (VOIDmode, label),
15292 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
15293 JUMP_LABEL (tmp) = label;
15295 emit_move_insn (operands[0], operands[1]);
15296 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
15297 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
15298 emit_label (label);
15299 LABEL_NUSES (label) = 1;
15304 (define_insn "*bmi2_<insn><mode>3_1"
15305 [(set (match_operand:SWI48 0 "register_operand" "=r")
15306 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
15307 (match_operand:SWI48 2 "register_operand" "r")))]
15309 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
15310 [(set_attr "type" "ishiftx")
15311 (set_attr "mode" "<MODE>")])
15313 (define_insn "*ashr<mode>3_1"
15314 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
15316 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
15317 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
15318 (clobber (reg:CC FLAGS_REG))]
15319 "ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
15321 switch (get_attr_type (insn))
15327 if (operands[2] == const1_rtx
15328 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15329 return "sar{<imodesuffix>}\t%0";
15331 return "sar{<imodesuffix>}\t{%2, %0|%0, %2}";
15334 [(set_attr "isa" "*,bmi2")
15335 (set_attr "type" "ishift,ishiftx")
15336 (set (attr "length_immediate")
15338 (and (match_operand 2 "const1_operand")
15339 (ior (match_test "TARGET_SHIFT1")
15340 (match_test "optimize_function_for_size_p (cfun)")))
15342 (const_string "*")))
15343 (set_attr "mode" "<MODE>")])
15345 ;; Specialization of *lshr<mode>3_1 below, extracting the SImode
15346 ;; highpart of a DI to be extracted, but allowing it to be clobbered.
15347 (define_insn_and_split "*highpartdisi2"
15348 [(set (subreg:DI (match_operand:SI 0 "register_operand" "=r,x,?k") 0)
15349 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0,k")
15351 (clobber (reg:CC FLAGS_REG))]
15354 "&& reload_completed"
15356 [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 32)))
15357 (clobber (reg:CC FLAGS_REG))])]
15359 if (SSE_REG_P (operands[0]))
15361 rtx tmp = gen_rtx_REG (V4SImode, REGNO (operands[0]));
15362 emit_insn (gen_sse_shufps_v4si (tmp, tmp, tmp,
15363 const1_rtx, const1_rtx,
15364 GEN_INT (5), GEN_INT (5)));
15367 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
15370 (define_insn "*lshr<mode>3_1"
15371 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,?k")
15373 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm,k")
15374 (match_operand:QI 2 "nonmemory_operand" "c<S>,r,<KS>")))
15375 (clobber (reg:CC FLAGS_REG))]
15376 "ix86_binary_operator_ok (LSHIFTRT, <MODE>mode, operands)"
15378 switch (get_attr_type (insn))
15385 if (operands[2] == const1_rtx
15386 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15387 return "shr{<imodesuffix>}\t%0";
15389 return "shr{<imodesuffix>}\t{%2, %0|%0, %2}";
15392 [(set_attr "isa" "*,bmi2,<kmov_isa>")
15393 (set_attr "type" "ishift,ishiftx,msklog")
15394 (set (attr "length_immediate")
15396 (and (and (match_operand 2 "const1_operand")
15397 (eq_attr "alternative" "0"))
15398 (ior (match_test "TARGET_SHIFT1")
15399 (match_test "optimize_function_for_size_p (cfun)")))
15401 (const_string "*")))
15402 (set_attr "mode" "<MODE>")])
15404 ;; Convert shift to the shiftx pattern to avoid flags dependency.
15406 [(set (match_operand:SWI48 0 "register_operand")
15407 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
15408 (match_operand:QI 2 "register_operand")))
15409 (clobber (reg:CC FLAGS_REG))]
15410 "TARGET_BMI2 && reload_completed"
15411 [(set (match_dup 0)
15412 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
15413 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
15415 (define_insn "*bmi2_<insn>si3_1_zext"
15416 [(set (match_operand:DI 0 "register_operand" "=r")
15418 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
15419 (match_operand:SI 2 "register_operand" "r"))))]
15420 "TARGET_64BIT && TARGET_BMI2"
15421 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
15422 [(set_attr "type" "ishiftx")
15423 (set_attr "mode" "SI")])
15425 (define_insn "*<insn>si3_1_zext"
15426 [(set (match_operand:DI 0 "register_operand" "=r,r")
15428 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
15429 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
15430 (clobber (reg:CC FLAGS_REG))]
15431 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
15433 switch (get_attr_type (insn))
15439 if (operands[2] == const1_rtx
15440 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15441 return "<shift>{l}\t%k0";
15443 return "<shift>{l}\t{%2, %k0|%k0, %2}";
15446 [(set_attr "isa" "*,bmi2")
15447 (set_attr "type" "ishift,ishiftx")
15448 (set (attr "length_immediate")
15450 (and (match_operand 2 "const1_operand")
15451 (ior (match_test "TARGET_SHIFT1")
15452 (match_test "optimize_function_for_size_p (cfun)")))
15454 (const_string "*")))
15455 (set_attr "mode" "SI")])
15457 ;; Convert shift to the shiftx pattern to avoid flags dependency.
15459 [(set (match_operand:DI 0 "register_operand")
15461 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
15462 (match_operand:QI 2 "register_operand"))))
15463 (clobber (reg:CC FLAGS_REG))]
15464 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
15465 [(set (match_dup 0)
15466 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
15467 "operands[2] = gen_lowpart (SImode, operands[2]);")
15469 (define_insn "*ashr<mode>3_1"
15470 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
15472 (match_operand:SWI12 1 "nonimmediate_operand" "0")
15473 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
15474 (clobber (reg:CC FLAGS_REG))]
15475 "ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
15477 if (operands[2] == const1_rtx
15478 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15479 return "sar{<imodesuffix>}\t%0";
15481 return "sar{<imodesuffix>}\t{%2, %0|%0, %2}";
15483 [(set_attr "type" "ishift")
15484 (set (attr "length_immediate")
15486 (and (match_operand 2 "const1_operand")
15487 (ior (match_test "TARGET_SHIFT1")
15488 (match_test "optimize_function_for_size_p (cfun)")))
15490 (const_string "*")))
15491 (set_attr "mode" "<MODE>")])
15493 (define_insn "*lshrqi3_1"
15494 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,?k")
15496 (match_operand:QI 1 "nonimmediate_operand" "0, k")
15497 (match_operand:QI 2 "nonmemory_operand" "cI,Wb")))
15498 (clobber (reg:CC FLAGS_REG))]
15499 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
15501 switch (get_attr_type (insn))
15504 if (operands[2] == const1_rtx
15505 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15506 return "shr{b}\t%0";
15508 return "shr{b}\t{%2, %0|%0, %2}";
15512 gcc_unreachable ();
15515 [(set_attr "isa" "*,avx512dq")
15516 (set_attr "type" "ishift,msklog")
15517 (set (attr "length_immediate")
15519 (and (and (match_operand 2 "const1_operand")
15520 (eq_attr "alternative" "0"))
15521 (ior (match_test "TARGET_SHIFT1")
15522 (match_test "optimize_function_for_size_p (cfun)")))
15524 (const_string "*")))
15525 (set_attr "mode" "QI")])
15527 (define_insn "*lshrhi3_1"
15528 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm, ?k")
15530 (match_operand:HI 1 "nonimmediate_operand" "0, k")
15531 (match_operand:QI 2 "nonmemory_operand" "cI, Ww")))
15532 (clobber (reg:CC FLAGS_REG))]
15533 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
15535 switch (get_attr_type (insn))
15538 if (operands[2] == const1_rtx
15539 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15540 return "shr{w}\t%0";
15542 return "shr{w}\t{%2, %0|%0, %2}";
15546 gcc_unreachable ();
15549 [(set_attr "isa" "*, avx512f")
15550 (set_attr "type" "ishift,msklog")
15551 (set (attr "length_immediate")
15553 (and (and (match_operand 2 "const1_operand")
15554 (eq_attr "alternative" "0"))
15555 (ior (match_test "TARGET_SHIFT1")
15556 (match_test "optimize_function_for_size_p (cfun)")))
15558 (const_string "*")))
15559 (set_attr "mode" "HI")])
15561 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
15562 (define_insn_and_split "*<insn><mode>3_1_slp"
15563 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
15564 (any_shiftrt:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
15565 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
15566 (clobber (reg:CC FLAGS_REG))]
15567 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
15569 if (which_alternative)
15572 if (operands[2] == const1_rtx
15573 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15574 return "<shift>{<imodesuffix>}\t%0";
15576 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
15578 "&& reload_completed
15579 && !(rtx_equal_p (operands[0], operands[1]))"
15580 [(set (strict_low_part (match_dup 0)) (match_dup 1))
15582 [(set (strict_low_part (match_dup 0))
15583 (any_shiftrt:SWI12 (match_dup 0) (match_dup 2)))
15584 (clobber (reg:CC FLAGS_REG))])]
15586 [(set_attr "type" "ishift")
15587 (set (attr "length_immediate")
15589 (and (match_operand 2 "const1_operand")
15590 (ior (match_test "TARGET_SHIFT1")
15591 (match_test "optimize_function_for_size_p (cfun)")))
15593 (const_string "*")))
15594 (set_attr "mode" "<MODE>")])
15596 ;; This pattern can't accept a variable shift count, since shifts by
15597 ;; zero don't affect the flags. We assume that shifts by constant
15598 ;; zero are optimized away.
15599 (define_insn "*<insn><mode>3_cmp"
15600 [(set (reg FLAGS_REG)
15603 (match_operand:SWI 1 "nonimmediate_operand" "0")
15604 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
15606 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
15607 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
15608 "(optimize_function_for_size_p (cfun)
15609 || !TARGET_PARTIAL_FLAG_REG_STALL
15610 || (operands[2] == const1_rtx
15612 && ix86_match_ccmode (insn, CCGOCmode)
15613 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
15615 if (operands[2] == const1_rtx
15616 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15617 return "<shift>{<imodesuffix>}\t%0";
15619 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
15621 [(set_attr "type" "ishift")
15622 (set (attr "length_immediate")
15624 (and (match_operand 2 "const1_operand")
15625 (ior (match_test "TARGET_SHIFT1")
15626 (match_test "optimize_function_for_size_p (cfun)")))
15628 (const_string "*")))
15629 (set_attr "mode" "<MODE>")])
15631 (define_insn "*<insn>si3_cmp_zext"
15632 [(set (reg FLAGS_REG)
15634 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
15635 (match_operand:QI 2 "const_1_to_31_operand"))
15637 (set (match_operand:DI 0 "register_operand" "=r")
15638 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
15640 && (optimize_function_for_size_p (cfun)
15641 || !TARGET_PARTIAL_FLAG_REG_STALL
15642 || (operands[2] == const1_rtx
15644 && ix86_match_ccmode (insn, CCGOCmode)
15645 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
15647 if (operands[2] == const1_rtx
15648 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15649 return "<shift>{l}\t%k0";
15651 return "<shift>{l}\t{%2, %k0|%k0, %2}";
15653 [(set_attr "type" "ishift")
15654 (set (attr "length_immediate")
15656 (and (match_operand 2 "const1_operand")
15657 (ior (match_test "TARGET_SHIFT1")
15658 (match_test "optimize_function_for_size_p (cfun)")))
15660 (const_string "*")))
15661 (set_attr "mode" "SI")])
15663 (define_insn "*<insn><mode>3_cconly"
15664 [(set (reg FLAGS_REG)
15667 (match_operand:SWI 1 "register_operand" "0")
15668 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
15670 (clobber (match_scratch:SWI 0 "=<r>"))]
15671 "(optimize_function_for_size_p (cfun)
15672 || !TARGET_PARTIAL_FLAG_REG_STALL
15673 || (operands[2] == const1_rtx
15675 && ix86_match_ccmode (insn, CCGOCmode)"
15677 if (operands[2] == const1_rtx
15678 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15679 return "<shift>{<imodesuffix>}\t%0";
15681 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
15683 [(set_attr "type" "ishift")
15684 (set (attr "length_immediate")
15686 (and (match_operand 2 "const1_operand")
15687 (ior (match_test "TARGET_SHIFT1")
15688 (match_test "optimize_function_for_size_p (cfun)")))
15690 (const_string "*")))
15691 (set_attr "mode" "<MODE>")])
15693 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
15694 (define_insn_and_split "*<insn>qi_ext<mode>_1"
15695 [(set (zero_extract:SWI248
15696 (match_operand 0 "int248_register_operand" "+Q,&Q")
15702 (match_operator:SWI248 3 "extract_operator"
15703 [(match_operand 1 "int248_register_operand" "0,!Q")
15706 (match_operand:QI 2 "nonmemory_operand" "cI,cI")) 0))
15707 (clobber (reg:CC FLAGS_REG))]
15710 if (which_alternative)
15713 if (operands[2] == const1_rtx
15714 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15715 return "<shift>{b}\t%h0";
15717 return "<shift>{b}\t{%2, %h0|%h0, %2}";
15720 && !(rtx_equal_p (operands[0], operands[1]))"
15721 [(set (zero_extract:SWI248
15722 (match_dup 0) (const_int 8) (const_int 8))
15725 [(set (zero_extract:SWI248
15726 (match_dup 0) (const_int 8) (const_int 8))
15731 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
15733 (clobber (reg:CC FLAGS_REG))])]
15735 [(set_attr "type" "ishift")
15736 (set (attr "length_immediate")
15738 (and (match_operand 2 "const1_operand")
15739 (ior (match_test "TARGET_SHIFT1")
15740 (match_test "optimize_function_for_size_p (cfun)")))
15742 (const_string "*")))
15743 (set_attr "mode" "QI")])
15745 (define_insn_and_split "*extend<dwi>2_doubleword_highpart"
15746 [(set (match_operand:<DWI> 0 "register_operand" "=r")
15748 (ashift:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")
15749 (match_operand:QI 2 "const_int_operand"))
15750 (match_operand:QI 3 "const_int_operand")))
15751 (clobber (reg:CC FLAGS_REG))]
15752 "INTVAL (operands[2]) == INTVAL (operands[3])
15753 && UINTVAL (operands[2]) < <MODE_SIZE> * BITS_PER_UNIT"
15755 "&& reload_completed"
15756 [(parallel [(set (match_dup 4)
15757 (ashift:DWIH (match_dup 4) (match_dup 2)))
15758 (clobber (reg:CC FLAGS_REG))])
15759 (parallel [(set (match_dup 4)
15760 (ashiftrt:DWIH (match_dup 4) (match_dup 2)))
15761 (clobber (reg:CC FLAGS_REG))])]
15762 "split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[4]);")
15764 (define_insn_and_split "*extendv2di2_highpart_stv"
15765 [(set (match_operand:V2DI 0 "register_operand" "=v")
15767 (ashift:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "vm")
15768 (match_operand:QI 2 "const_int_operand"))
15769 (match_operand:QI 3 "const_int_operand")))]
15770 "!TARGET_64BIT && TARGET_STV && TARGET_AVX512VL
15771 && INTVAL (operands[2]) == INTVAL (operands[3])
15772 && UINTVAL (operands[2]) < 32"
15774 "&& reload_completed"
15775 [(set (match_dup 0)
15776 (ashift:V2DI (match_dup 1) (match_dup 2)))
15778 (ashiftrt:V2DI (match_dup 0) (match_dup 2)))])
15780 ;; Rotate instructions
15782 (define_expand "<insn>ti3"
15783 [(set (match_operand:TI 0 "register_operand")
15784 (any_rotate:TI (match_operand:TI 1 "register_operand")
15785 (match_operand:QI 2 "nonmemory_operand")))]
15788 if (const_1_to_63_operand (operands[2], VOIDmode))
15789 emit_insn (gen_ix86_<insn>ti3_doubleword
15790 (operands[0], operands[1], operands[2]));
15791 else if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 64)
15793 operands[1] = force_reg (TImode, operands[1]);
15794 emit_insn (gen_<insn>64ti2_doubleword (operands[0], operands[1]));
15798 rtx amount = force_reg (QImode, operands[2]);
15799 rtx src_lo = gen_lowpart (DImode, operands[1]);
15800 rtx src_hi = gen_highpart (DImode, operands[1]);
15801 rtx tmp_lo = gen_reg_rtx (DImode);
15802 rtx tmp_hi = gen_reg_rtx (DImode);
15803 emit_move_insn (tmp_lo, src_lo);
15804 emit_move_insn (tmp_hi, src_hi);
15805 rtx (*shiftd) (rtx, rtx, rtx)
15806 = (<CODE> == ROTATE) ? gen_x86_64_shld : gen_x86_64_shrd;
15807 emit_insn (shiftd (tmp_lo, src_hi, amount));
15808 emit_insn (shiftd (tmp_hi, src_lo, amount));
15809 rtx dst_lo = gen_lowpart (DImode, operands[0]);
15810 rtx dst_hi = gen_highpart (DImode, operands[0]);
15811 emit_move_insn (dst_lo, tmp_lo);
15812 emit_move_insn (dst_hi, tmp_hi);
15813 emit_insn (gen_x86_shiftdi_adj_1 (dst_lo, dst_hi, amount, tmp_lo));
15818 (define_expand "<insn>di3"
15819 [(set (match_operand:DI 0 "shiftdi_operand")
15820 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
15821 (match_operand:QI 2 "nonmemory_operand")))]
15825 ix86_expand_binary_operator (<CODE>, DImode, operands);
15826 else if (const_1_to_31_operand (operands[2], VOIDmode))
15827 emit_insn (gen_ix86_<insn>di3_doubleword
15828 (operands[0], operands[1], operands[2]));
15829 else if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 32)
15831 operands[1] = force_reg (DImode, operands[1]);
15832 emit_insn (gen_<insn>32di2_doubleword (operands[0], operands[1]));
15840 (define_expand "<insn><mode>3"
15841 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
15842 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
15843 (match_operand:QI 2 "nonmemory_operand")))]
15845 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
15847 ;; Avoid useless masking of count operand.
15848 (define_insn_and_split "*<insn><mode>3_mask"
15849 [(set (match_operand:SWI 0 "nonimmediate_operand")
15851 (match_operand:SWI 1 "nonimmediate_operand")
15854 (match_operand 2 "int248_register_operand" "c")
15855 (match_operand 3 "const_int_operand")) 0)))
15856 (clobber (reg:CC FLAGS_REG))]
15857 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
15858 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15859 == GET_MODE_BITSIZE (<MODE>mode)-1
15860 && ix86_pre_reload_split ()"
15864 [(set (match_dup 0)
15865 (any_rotate:SWI (match_dup 1)
15867 (clobber (reg:CC FLAGS_REG))])]
15869 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
15870 operands[2] = gen_lowpart (QImode, operands[2]);
15874 [(set (match_operand:SWI 0 "register_operand")
15876 (match_operand:SWI 1 "const_int_operand")
15879 (match_operand 2 "int248_register_operand")
15880 (match_operand 3 "const_int_operand")) 0)))]
15881 "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode) - 1))
15882 == GET_MODE_BITSIZE (<MODE>mode) - 1"
15883 [(set (match_dup 4) (match_dup 1))
15885 (any_rotate:SWI (match_dup 4)
15886 (subreg:QI (match_dup 2) 0)))]
15887 "operands[4] = gen_reg_rtx (<MODE>mode);")
15889 (define_insn_and_split "*<insn><mode>3_mask_1"
15890 [(set (match_operand:SWI 0 "nonimmediate_operand")
15892 (match_operand:SWI 1 "nonimmediate_operand")
15894 (match_operand:QI 2 "register_operand" "c")
15895 (match_operand:QI 3 "const_int_operand"))))
15896 (clobber (reg:CC FLAGS_REG))]
15897 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
15898 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15899 == GET_MODE_BITSIZE (<MODE>mode)-1
15900 && ix86_pre_reload_split ()"
15904 [(set (match_dup 0)
15905 (any_rotate:SWI (match_dup 1)
15907 (clobber (reg:CC FLAGS_REG))])])
15910 [(set (match_operand:SWI 0 "register_operand")
15912 (match_operand:SWI 1 "const_int_operand")
15914 (match_operand:QI 2 "register_operand")
15915 (match_operand:QI 3 "const_int_operand"))))]
15916 "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode) - 1))
15917 == GET_MODE_BITSIZE (<MODE>mode) - 1"
15918 [(set (match_dup 4) (match_dup 1))
15920 (any_rotate:SWI (match_dup 4) (match_dup 2)))]
15921 "operands[4] = gen_reg_rtx (<MODE>mode);")
15923 ;; Implement rotation using two double-precision
15924 ;; shift instructions and a scratch register.
15926 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
15927 [(set (match_operand:<DWI> 0 "register_operand" "=r")
15928 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
15929 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
15930 (clobber (reg:CC FLAGS_REG))
15931 (clobber (match_scratch:DWIH 3 "=&r"))]
15935 [(set (match_dup 3) (match_dup 4))
15937 [(set (match_dup 4)
15938 (ior:DWIH (ashift:DWIH (match_dup 4)
15939 (and:QI (match_dup 2) (match_dup 6)))
15941 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
15942 (minus:QI (match_dup 7)
15943 (and:QI (match_dup 2)
15944 (match_dup 6)))) 0)))
15945 (clobber (reg:CC FLAGS_REG))])
15947 [(set (match_dup 5)
15948 (ior:DWIH (ashift:DWIH (match_dup 5)
15949 (and:QI (match_dup 2) (match_dup 6)))
15951 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 3))
15952 (minus:QI (match_dup 7)
15953 (and:QI (match_dup 2)
15954 (match_dup 6)))) 0)))
15955 (clobber (reg:CC FLAGS_REG))])]
15957 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
15958 operands[7] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
15960 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
15963 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
15964 [(set (match_operand:<DWI> 0 "register_operand" "=r")
15965 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
15966 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
15967 (clobber (reg:CC FLAGS_REG))
15968 (clobber (match_scratch:DWIH 3 "=&r"))]
15972 [(set (match_dup 3) (match_dup 4))
15974 [(set (match_dup 4)
15975 (ior:DWIH (lshiftrt:DWIH (match_dup 4)
15976 (and:QI (match_dup 2) (match_dup 6)))
15978 (ashift:<DWI> (zero_extend:<DWI> (match_dup 5))
15979 (minus:QI (match_dup 7)
15980 (and:QI (match_dup 2)
15981 (match_dup 6)))) 0)))
15982 (clobber (reg:CC FLAGS_REG))])
15984 [(set (match_dup 5)
15985 (ior:DWIH (lshiftrt:DWIH (match_dup 5)
15986 (and:QI (match_dup 2) (match_dup 6)))
15988 (ashift:<DWI> (zero_extend:<DWI> (match_dup 3))
15989 (minus:QI (match_dup 7)
15990 (and:QI (match_dup 2)
15991 (match_dup 6)))) 0)))
15992 (clobber (reg:CC FLAGS_REG))])]
15994 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
15995 operands[7] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
15997 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
16000 (define_insn_and_split "<insn>32di2_doubleword"
16001 [(set (match_operand:DI 0 "register_operand" "=r,r")
16002 (any_rotate:DI (match_operand:DI 1 "register_operand" "0,r")
16006 "&& reload_completed"
16007 [(set (match_dup 0) (match_dup 3))
16008 (set (match_dup 2) (match_dup 1))]
16010 split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);
16011 if (rtx_equal_p (operands[0], operands[1]))
16013 emit_insn (gen_swapsi (operands[0], operands[2]));
16018 (define_insn_and_split "<insn>64ti2_doubleword"
16019 [(set (match_operand:TI 0 "register_operand" "=r,r")
16020 (any_rotate:TI (match_operand:TI 1 "register_operand" "0,r")
16024 "&& reload_completed"
16025 [(set (match_dup 0) (match_dup 3))
16026 (set (match_dup 2) (match_dup 1))]
16028 split_double_mode (TImode, &operands[0], 2, &operands[0], &operands[2]);
16029 if (rtx_equal_p (operands[0], operands[1]))
16031 emit_insn (gen_swapdi (operands[0], operands[2]));
16036 (define_mode_attr rorx_immediate_operand
16037 [(SI "const_0_to_31_operand")
16038 (DI "const_0_to_63_operand")])
16040 (define_insn "*bmi2_rorx<mode>3_1"
16041 [(set (match_operand:SWI48 0 "register_operand" "=r")
16043 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
16044 (match_operand:QI 2 "<rorx_immediate_operand>" "<S>")))]
16045 "TARGET_BMI2 && !optimize_function_for_size_p (cfun)"
16046 "rorx\t{%2, %1, %0|%0, %1, %2}"
16047 [(set_attr "type" "rotatex")
16048 (set_attr "mode" "<MODE>")])
16050 (define_insn "*<insn><mode>3_1"
16051 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
16053 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
16054 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
16055 (clobber (reg:CC FLAGS_REG))]
16056 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
16058 switch (get_attr_type (insn))
16064 if (operands[2] == const1_rtx
16065 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
16066 return "<rotate>{<imodesuffix>}\t%0";
16068 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
16071 [(set_attr "isa" "*,bmi2")
16072 (set_attr "type" "rotate,rotatex")
16073 (set (attr "preferred_for_size")
16074 (cond [(eq_attr "alternative" "0")
16075 (symbol_ref "true")]
16076 (symbol_ref "false")))
16077 (set (attr "length_immediate")
16079 (and (eq_attr "type" "rotate")
16080 (and (match_operand 2 "const1_operand")
16081 (ior (match_test "TARGET_SHIFT1")
16082 (match_test "optimize_function_for_size_p (cfun)"))))
16084 (const_string "*")))
16085 (set_attr "mode" "<MODE>")])
16087 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
16089 [(set (match_operand:SWI48 0 "register_operand")
16090 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
16091 (match_operand:QI 2 "const_int_operand")))
16092 (clobber (reg:CC FLAGS_REG))]
16093 "TARGET_BMI2 && reload_completed && !optimize_function_for_size_p (cfun)"
16094 [(set (match_dup 0)
16095 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
16097 int bitsize = GET_MODE_BITSIZE (<MODE>mode);
16099 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
16103 [(set (match_operand:SWI48 0 "register_operand")
16104 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
16105 (match_operand:QI 2 "const_int_operand")))
16106 (clobber (reg:CC FLAGS_REG))]
16107 "TARGET_BMI2 && reload_completed && !optimize_function_for_size_p (cfun)"
16108 [(set (match_dup 0)
16109 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
16111 (define_insn "*bmi2_rorxsi3_1_zext"
16112 [(set (match_operand:DI 0 "register_operand" "=r")
16114 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
16115 (match_operand:QI 2 "const_0_to_31_operand"))))]
16116 "TARGET_64BIT && TARGET_BMI2 && !optimize_function_for_size_p (cfun)"
16117 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
16118 [(set_attr "type" "rotatex")
16119 (set_attr "mode" "SI")])
16121 (define_insn "*<insn>si3_1_zext"
16122 [(set (match_operand:DI 0 "register_operand" "=r,r")
16124 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
16125 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
16126 (clobber (reg:CC FLAGS_REG))]
16127 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
16129 switch (get_attr_type (insn))
16135 if (operands[2] == const1_rtx
16136 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
16137 return "<rotate>{l}\t%k0";
16139 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
16142 [(set_attr "isa" "*,bmi2")
16143 (set_attr "type" "rotate,rotatex")
16144 (set (attr "preferred_for_size")
16145 (cond [(eq_attr "alternative" "0")
16146 (symbol_ref "true")]
16147 (symbol_ref "false")))
16148 (set (attr "length_immediate")
16150 (and (eq_attr "type" "rotate")
16151 (and (match_operand 2 "const1_operand")
16152 (ior (match_test "TARGET_SHIFT1")
16153 (match_test "optimize_function_for_size_p (cfun)"))))
16155 (const_string "*")))
16156 (set_attr "mode" "SI")])
16158 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
16160 [(set (match_operand:DI 0 "register_operand")
16162 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
16163 (match_operand:QI 2 "const_int_operand"))))
16164 (clobber (reg:CC FLAGS_REG))]
16165 "TARGET_64BIT && TARGET_BMI2 && reload_completed
16166 && !optimize_function_for_size_p (cfun)"
16167 [(set (match_dup 0)
16168 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
16170 int bitsize = GET_MODE_BITSIZE (SImode);
16172 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
16176 [(set (match_operand:DI 0 "register_operand")
16178 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
16179 (match_operand:QI 2 "const_int_operand"))))
16180 (clobber (reg:CC FLAGS_REG))]
16181 "TARGET_64BIT && TARGET_BMI2 && reload_completed
16182 && !optimize_function_for_size_p (cfun)"
16183 [(set (match_dup 0)
16184 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
16186 (define_insn "*<insn><mode>3_1"
16187 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
16188 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
16189 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
16190 (clobber (reg:CC FLAGS_REG))]
16191 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
16193 if (operands[2] == const1_rtx
16194 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
16195 return "<rotate>{<imodesuffix>}\t%0";
16197 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
16199 [(set_attr "type" "rotate")
16200 (set (attr "length_immediate")
16202 (and (match_operand 2 "const1_operand")
16203 (ior (match_test "TARGET_SHIFT1")
16204 (match_test "optimize_function_for_size_p (cfun)")))
16206 (const_string "*")))
16207 (set_attr "mode" "<MODE>")])
16209 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
16210 (define_insn_and_split "*<insn><mode>3_1_slp"
16211 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
16212 (any_rotate:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
16213 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
16214 (clobber (reg:CC FLAGS_REG))]
16215 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
16217 if (which_alternative)
16220 if (operands[2] == const1_rtx
16221 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
16222 return "<rotate>{<imodesuffix>}\t%0";
16224 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
16226 "&& reload_completed
16227 && !(rtx_equal_p (operands[0], operands[1]))"
16228 [(set (strict_low_part (match_dup 0)) (match_dup 1))
16230 [(set (strict_low_part (match_dup 0))
16231 (any_rotate:SWI12 (match_dup 0) (match_dup 2)))
16232 (clobber (reg:CC FLAGS_REG))])]
16234 [(set_attr "type" "rotate")
16235 (set (attr "length_immediate")
16237 (and (match_operand 2 "const1_operand")
16238 (ior (match_test "TARGET_SHIFT1")
16239 (match_test "optimize_function_for_size_p (cfun)")))
16241 (const_string "*")))
16242 (set_attr "mode" "<MODE>")])
16245 [(set (match_operand:HI 0 "QIreg_operand")
16246 (any_rotate:HI (match_dup 0) (const_int 8)))
16247 (clobber (reg:CC FLAGS_REG))]
16249 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
16250 [(parallel [(set (strict_low_part (match_dup 0))
16251 (bswap:HI (match_dup 0)))
16252 (clobber (reg:CC FLAGS_REG))])])
16254 ;; Rotations through carry flag
16255 (define_insn "rcrsi2"
16256 [(set (match_operand:SI 0 "register_operand" "=r")
16258 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
16260 (ashift:SI (ltu:SI (reg:CCC FLAGS_REG) (const_int 0))
16262 (clobber (reg:CC FLAGS_REG))]
16265 [(set_attr "type" "ishift1")
16266 (set_attr "memory" "none")
16267 (set_attr "length_immediate" "0")
16268 (set_attr "mode" "SI")])
16270 (define_insn "rcrdi2"
16271 [(set (match_operand:DI 0 "register_operand" "=r")
16273 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
16275 (ashift:DI (ltu:DI (reg:CCC FLAGS_REG) (const_int 0))
16277 (clobber (reg:CC FLAGS_REG))]
16280 [(set_attr "type" "ishift1")
16281 (set_attr "length_immediate" "0")
16282 (set_attr "mode" "DI")])
16284 ;; Versions of sar and shr that set the carry flag.
16285 (define_insn "<insn><mode>3_carry"
16286 [(set (reg:CCC FLAGS_REG)
16287 (unspec:CCC [(and:SWI48 (match_operand:SWI48 1 "register_operand" "0")
16289 (const_int 0)] UNSPEC_CC_NE))
16290 (set (match_operand:SWI48 0 "register_operand" "=r")
16291 (any_shiftrt:SWI48 (match_dup 1) (const_int 1)))]
16294 if (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
16295 return "<shift>{<imodesuffix>}\t%0";
16296 return "<shift>{<imodesuffix>}\t{1, %0|%0, 1}";
16298 [(set_attr "type" "ishift1")
16299 (set (attr "length_immediate")
16301 (ior (match_test "TARGET_SHIFT1")
16302 (match_test "optimize_function_for_size_p (cfun)"))
16304 (const_string "*")))
16305 (set_attr "mode" "<MODE>")])
16307 ;; Bit set / bit test instructions
16309 ;; %%% bts, btr, btc
16311 ;; These instructions are *slow* when applied to memory.
16313 (define_code_attr btsc [(ior "bts") (xor "btc")])
16315 (define_insn "*<btsc><mode>"
16316 [(set (match_operand:SWI48 0 "register_operand" "=r")
16318 (ashift:SWI48 (const_int 1)
16319 (match_operand:QI 2 "register_operand" "r"))
16320 (match_operand:SWI48 1 "register_operand" "0")))
16321 (clobber (reg:CC FLAGS_REG))]
16323 "<btsc>{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
16324 [(set_attr "type" "alu1")
16325 (set_attr "prefix_0f" "1")
16326 (set_attr "znver1_decode" "double")
16327 (set_attr "mode" "<MODE>")])
16329 ;; Avoid useless masking of count operand.
16330 (define_insn_and_split "*<btsc><mode>_mask"
16331 [(set (match_operand:SWI48 0 "register_operand")
16337 (match_operand 1 "int248_register_operand")
16338 (match_operand 2 "const_int_operand")) 0))
16339 (match_operand:SWI48 3 "register_operand")))
16340 (clobber (reg:CC FLAGS_REG))]
16342 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16343 == GET_MODE_BITSIZE (<MODE>mode)-1
16344 && ix86_pre_reload_split ()"
16348 [(set (match_dup 0)
16350 (ashift:SWI48 (const_int 1)
16353 (clobber (reg:CC FLAGS_REG))])]
16355 operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
16356 operands[1] = gen_lowpart (QImode, operands[1]);
16359 (define_insn_and_split "*<btsc><mode>_mask_1"
16360 [(set (match_operand:SWI48 0 "register_operand")
16365 (match_operand:QI 1 "register_operand")
16366 (match_operand:QI 2 "const_int_operand")))
16367 (match_operand:SWI48 3 "register_operand")))
16368 (clobber (reg:CC FLAGS_REG))]
16370 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16371 == GET_MODE_BITSIZE (<MODE>mode)-1
16372 && ix86_pre_reload_split ()"
16376 [(set (match_dup 0)
16378 (ashift:SWI48 (const_int 1)
16381 (clobber (reg:CC FLAGS_REG))])])
16383 (define_insn "*btr<mode>"
16384 [(set (match_operand:SWI48 0 "register_operand" "=r")
16386 (rotate:SWI48 (const_int -2)
16387 (match_operand:QI 2 "register_operand" "r"))
16388 (match_operand:SWI48 1 "register_operand" "0")))
16389 (clobber (reg:CC FLAGS_REG))]
16391 "btr{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
16392 [(set_attr "type" "alu1")
16393 (set_attr "prefix_0f" "1")
16394 (set_attr "znver1_decode" "double")
16395 (set_attr "mode" "<MODE>")])
16397 ;; Avoid useless masking of count operand.
16398 (define_insn_and_split "*btr<mode>_mask"
16399 [(set (match_operand:SWI48 0 "register_operand")
16405 (match_operand 1 "int248_register_operand")
16406 (match_operand 2 "const_int_operand")) 0))
16407 (match_operand:SWI48 3 "register_operand")))
16408 (clobber (reg:CC FLAGS_REG))]
16410 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16411 == GET_MODE_BITSIZE (<MODE>mode)-1
16412 && ix86_pre_reload_split ()"
16416 [(set (match_dup 0)
16418 (rotate:SWI48 (const_int -2)
16421 (clobber (reg:CC FLAGS_REG))])]
16423 operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
16424 operands[1] = gen_lowpart (QImode, operands[1]);
16427 (define_insn_and_split "*btr<mode>_mask_1"
16428 [(set (match_operand:SWI48 0 "register_operand")
16433 (match_operand:QI 1 "register_operand")
16434 (match_operand:QI 2 "const_int_operand")))
16435 (match_operand:SWI48 3 "register_operand")))
16436 (clobber (reg:CC FLAGS_REG))]
16438 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16439 == GET_MODE_BITSIZE (<MODE>mode)-1
16440 && ix86_pre_reload_split ()"
16444 [(set (match_dup 0)
16446 (rotate:SWI48 (const_int -2)
16449 (clobber (reg:CC FLAGS_REG))])])
16451 (define_insn_and_split "*btr<mode>_1"
16452 [(set (match_operand:SWI12 0 "register_operand")
16455 (rotate:SI (const_int -2)
16456 (match_operand:QI 2 "register_operand")) 0)
16457 (match_operand:SWI12 1 "nonimmediate_operand")))
16458 (clobber (reg:CC FLAGS_REG))]
16459 "TARGET_USE_BT && ix86_pre_reload_split ()"
16463 [(set (match_dup 0)
16464 (and:SI (rotate:SI (const_int -2) (match_dup 2))
16466 (clobber (reg:CC FLAGS_REG))])]
16468 operands[0] = lowpart_subreg (SImode, operands[0], <MODE>mode);
16469 operands[1] = force_reg (<MODE>mode, operands[1]);
16470 operands[1] = lowpart_subreg (SImode, operands[1], <MODE>mode);
16473 (define_insn_and_split "*btr<mode>_2"
16474 [(set (zero_extract:HI
16475 (match_operand:SWI12 0 "nonimmediate_operand")
16477 (match_operand:QI 1 "register_operand"))
16479 (clobber (reg:CC FLAGS_REG))]
16480 "TARGET_USE_BT && ix86_pre_reload_split ()"
16482 "&& MEM_P (operands[0])"
16483 [(set (match_dup 2) (match_dup 0))
16485 [(set (match_dup 3)
16486 (and:SI (rotate:SI (const_int -2) (match_dup 1))
16488 (clobber (reg:CC FLAGS_REG))])
16489 (set (match_dup 0) (match_dup 5))]
16491 operands[2] = gen_reg_rtx (<MODE>mode);
16492 operands[5] = gen_reg_rtx (<MODE>mode);
16493 operands[3] = lowpart_subreg (SImode, operands[5], <MODE>mode);
16494 operands[4] = lowpart_subreg (SImode, operands[2], <MODE>mode);
16498 [(set (zero_extract:HI
16499 (match_operand:SWI12 0 "register_operand")
16501 (match_operand:QI 1 "register_operand"))
16503 (clobber (reg:CC FLAGS_REG))]
16504 "TARGET_USE_BT && ix86_pre_reload_split ()"
16506 [(set (match_dup 0)
16507 (and:SI (rotate:SI (const_int -2) (match_dup 1))
16509 (clobber (reg:CC FLAGS_REG))])]
16511 operands[2] = lowpart_subreg (SImode, operands[0], <MODE>mode);
16512 operands[0] = lowpart_subreg (SImode, operands[0], <MODE>mode);
16515 ;; These instructions are never faster than the corresponding
16516 ;; and/ior/xor operations when using immediate operand, so with
16517 ;; 32-bit there's no point. But in 64-bit, we can't hold the
16518 ;; relevant immediates within the instruction itself, so operating
16519 ;; on bits in the high 32-bits of a register becomes easier.
16521 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
16522 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
16523 ;; negdf respectively, so they can never be disabled entirely.
16525 (define_insn "*btsq_imm"
16526 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
16528 (match_operand:QI 1 "const_0_to_63_operand"))
16530 (clobber (reg:CC FLAGS_REG))]
16531 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
16532 "bts{q}\t{%1, %0|%0, %1}"
16533 [(set_attr "type" "alu1")
16534 (set_attr "prefix_0f" "1")
16535 (set_attr "znver1_decode" "double")
16536 (set_attr "mode" "DI")])
16538 (define_insn "*btrq_imm"
16539 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
16541 (match_operand:QI 1 "const_0_to_63_operand"))
16543 (clobber (reg:CC FLAGS_REG))]
16544 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
16545 "btr{q}\t{%1, %0|%0, %1}"
16546 [(set_attr "type" "alu1")
16547 (set_attr "prefix_0f" "1")
16548 (set_attr "znver1_decode" "double")
16549 (set_attr "mode" "DI")])
16551 (define_insn "*btcq_imm"
16552 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
16554 (match_operand:QI 1 "const_0_to_63_operand"))
16555 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
16556 (clobber (reg:CC FLAGS_REG))]
16557 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
16558 "btc{q}\t{%1, %0|%0, %1}"
16559 [(set_attr "type" "alu1")
16560 (set_attr "prefix_0f" "1")
16561 (set_attr "znver1_decode" "double")
16562 (set_attr "mode" "DI")])
16564 ;; Allow Nocona to avoid these instructions if a register is available.
16567 [(match_scratch:DI 2 "r")
16568 (parallel [(set (zero_extract:DI
16569 (match_operand:DI 0 "nonimmediate_operand")
16571 (match_operand:QI 1 "const_0_to_63_operand"))
16573 (clobber (reg:CC FLAGS_REG))])]
16574 "TARGET_64BIT && !TARGET_USE_BT"
16575 [(parallel [(set (match_dup 0)
16576 (ior:DI (match_dup 0) (match_dup 3)))
16577 (clobber (reg:CC FLAGS_REG))])]
16579 int i = INTVAL (operands[1]);
16581 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
16583 if (!x86_64_immediate_operand (operands[3], DImode))
16585 emit_move_insn (operands[2], operands[3]);
16586 operands[3] = operands[2];
16591 [(match_scratch:DI 2 "r")
16592 (parallel [(set (zero_extract:DI
16593 (match_operand:DI 0 "nonimmediate_operand")
16595 (match_operand:QI 1 "const_0_to_63_operand"))
16597 (clobber (reg:CC FLAGS_REG))])]
16598 "TARGET_64BIT && !TARGET_USE_BT"
16599 [(parallel [(set (match_dup 0)
16600 (and:DI (match_dup 0) (match_dup 3)))
16601 (clobber (reg:CC FLAGS_REG))])]
16603 int i = INTVAL (operands[1]);
16605 operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
16607 if (!x86_64_immediate_operand (operands[3], DImode))
16609 emit_move_insn (operands[2], operands[3]);
16610 operands[3] = operands[2];
16615 [(match_scratch:DI 2 "r")
16616 (parallel [(set (zero_extract:DI
16617 (match_operand:DI 0 "nonimmediate_operand")
16619 (match_operand:QI 1 "const_0_to_63_operand"))
16620 (not:DI (zero_extract:DI
16621 (match_dup 0) (const_int 1) (match_dup 1))))
16622 (clobber (reg:CC FLAGS_REG))])]
16623 "TARGET_64BIT && !TARGET_USE_BT"
16624 [(parallel [(set (match_dup 0)
16625 (xor:DI (match_dup 0) (match_dup 3)))
16626 (clobber (reg:CC FLAGS_REG))])]
16628 int i = INTVAL (operands[1]);
16630 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
16632 if (!x86_64_immediate_operand (operands[3], DImode))
16634 emit_move_insn (operands[2], operands[3]);
16635 operands[3] = operands[2];
16641 (define_insn "*bt<mode>"
16642 [(set (reg:CCC FLAGS_REG)
16644 (zero_extract:SWI48
16645 (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
16647 (match_operand:QI 1 "nonmemory_operand" "q<S>,<S>"))
16651 switch (get_attr_mode (insn))
16654 return "bt{l}\t{%k1, %k0|%k0, %k1}";
16657 return "bt{q}\t{%q1, %0|%0, %q1}";
16660 gcc_unreachable ();
16663 [(set_attr "type" "alu1")
16664 (set_attr "prefix_0f" "1")
16667 (and (match_test "CONST_INT_P (operands[1])")
16668 (match_test "INTVAL (operands[1]) < 32"))
16669 (const_string "SI")
16670 (const_string "<MODE>")))])
16672 (define_insn_and_split "*bt<SWI48:mode>_mask"
16673 [(set (reg:CCC FLAGS_REG)
16675 (zero_extract:SWI48
16676 (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
16680 (match_operand:SWI248 1 "register_operand")
16681 (match_operand 2 "const_int_operand")) 0))
16684 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<SWI48:MODE>mode)-1))
16685 == GET_MODE_BITSIZE (<SWI48:MODE>mode)-1
16686 && ix86_pre_reload_split ()"
16689 [(set (reg:CCC FLAGS_REG)
16691 (zero_extract:SWI48 (match_dup 0) (const_int 1) (match_dup 1))
16693 "operands[1] = gen_lowpart (QImode, operands[1]);")
16695 (define_insn_and_split "*jcc_bt<mode>"
16697 (if_then_else (match_operator 0 "bt_comparison_operator"
16698 [(zero_extract:SWI48
16699 (match_operand:SWI48 1 "nonimmediate_operand")
16701 (match_operand:QI 2 "nonmemory_operand"))
16703 (label_ref (match_operand 3))
16705 (clobber (reg:CC FLAGS_REG))]
16706 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
16707 && (CONST_INT_P (operands[2])
16708 ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
16709 && INTVAL (operands[2])
16710 >= (optimize_function_for_size_p (cfun) ? 8 : 32))
16711 : !memory_operand (operands[1], <MODE>mode))
16712 && ix86_pre_reload_split ()"
16715 [(set (reg:CCC FLAGS_REG)
16717 (zero_extract:SWI48
16723 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16724 (label_ref (match_dup 3))
16727 operands[0] = shallow_copy_rtx (operands[0]);
16728 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16731 ;; Avoid useless masking of bit offset operand.
16732 (define_insn_and_split "*jcc_bt<mode>_mask"
16734 (if_then_else (match_operator 0 "bt_comparison_operator"
16735 [(zero_extract:SWI48
16736 (match_operand:SWI48 1 "register_operand")
16739 (match_operand:QI 2 "register_operand")
16740 (match_operand 3 "const_int_operand")))])
16741 (label_ref (match_operand 4))
16743 (clobber (reg:CC FLAGS_REG))]
16744 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
16745 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16746 == GET_MODE_BITSIZE (<MODE>mode)-1
16747 && ix86_pre_reload_split ()"
16750 [(set (reg:CCC FLAGS_REG)
16752 (zero_extract:SWI48
16758 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16759 (label_ref (match_dup 4))
16762 operands[0] = shallow_copy_rtx (operands[0]);
16763 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16766 ;; Avoid useless masking of bit offset operand.
16767 (define_insn_and_split "*jcc_bt<SWI48:mode>_mask_1"
16769 (if_then_else (match_operator 0 "bt_comparison_operator"
16770 [(zero_extract:SWI48
16771 (match_operand:SWI48 1 "register_operand")
16775 (match_operand:SWI248 2 "register_operand")
16776 (match_operand 3 "const_int_operand")) 0))])
16777 (label_ref (match_operand 4))
16779 (clobber (reg:CC FLAGS_REG))]
16780 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
16781 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<SWI48:MODE>mode)-1))
16782 == GET_MODE_BITSIZE (<SWI48:MODE>mode)-1
16783 && ix86_pre_reload_split ()"
16786 [(set (reg:CCC FLAGS_REG)
16788 (zero_extract:SWI48
16794 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16795 (label_ref (match_dup 4))
16798 operands[0] = shallow_copy_rtx (operands[0]);
16799 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16800 operands[2] = gen_lowpart (QImode, operands[2]);
16803 ;; Help combine recognize bt followed by cmov
16805 [(set (match_operand:SWI248 0 "register_operand")
16806 (if_then_else:SWI248
16807 (match_operator 5 "bt_comparison_operator"
16808 [(zero_extract:SWI48
16809 (match_operand:SWI48 1 "register_operand")
16811 (match_operand:QI 2 "register_operand"))
16813 (match_operand:SWI248 3 "nonimmediate_operand")
16814 (match_operand:SWI248 4 "nonimmediate_operand")))]
16815 "TARGET_USE_BT && TARGET_CMOVE
16816 && !(MEM_P (operands[3]) && MEM_P (operands[4]))
16817 && ix86_pre_reload_split ()"
16818 [(set (reg:CCC FLAGS_REG)
16820 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16823 (if_then_else:SWI248 (eq (reg:CCC FLAGS_REG) (const_int 0))
16827 if (GET_CODE (operands[5]) == EQ)
16828 std::swap (operands[3], operands[4]);
16831 ;; Help combine recognize bt followed by setc
16832 (define_insn_and_split "*bt<mode>_setcqi"
16833 [(set (subreg:SWI48 (match_operand:QI 0 "register_operand") 0)
16834 (zero_extract:SWI48
16835 (match_operand:SWI48 1 "register_operand")
16837 (match_operand:QI 2 "register_operand")))
16838 (clobber (reg:CC FLAGS_REG))]
16839 "TARGET_USE_BT && ix86_pre_reload_split ()"
16842 [(set (reg:CCC FLAGS_REG)
16844 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16847 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))])
16849 ;; Help combine recognize bt followed by setnc
16850 (define_insn_and_split "*bt<mode>_setncqi"
16851 [(set (match_operand:QI 0 "register_operand")
16855 (lshiftrt:SWI48 (match_operand:SWI48 1 "register_operand")
16856 (match_operand:QI 2 "register_operand")) 0))
16858 (clobber (reg:CC FLAGS_REG))]
16859 "TARGET_USE_BT && ix86_pre_reload_split ()"
16862 [(set (reg:CCC FLAGS_REG)
16864 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16867 (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))])
16869 (define_insn_and_split "*bt<mode>_setnc<mode>"
16870 [(set (match_operand:SWI48 0 "register_operand")
16873 (lshiftrt:SWI48 (match_operand:SWI48 1 "register_operand")
16874 (match_operand:QI 2 "register_operand")))
16876 (clobber (reg:CC FLAGS_REG))]
16877 "TARGET_USE_BT && ix86_pre_reload_split ()"
16880 [(set (reg:CCC FLAGS_REG)
16882 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16885 (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))
16886 (set (match_dup 0) (zero_extend:SWI48 (match_dup 3)))]
16887 "operands[3] = gen_reg_rtx (QImode);")
16889 ;; Help combine recognize bt followed by setnc (PR target/110588)
16890 (define_insn_and_split "*bt<mode>_setncqi_2"
16891 [(set (match_operand:QI 0 "register_operand")
16893 (zero_extract:SWI48
16894 (match_operand:SWI48 1 "register_operand")
16896 (match_operand:QI 2 "register_operand"))
16898 (clobber (reg:CC FLAGS_REG))]
16899 "TARGET_USE_BT && ix86_pre_reload_split ()"
16902 [(set (reg:CCC FLAGS_REG)
16904 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16907 (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))])
16909 ;; Help combine recognize bt followed by setc
16910 (define_insn_and_split "*bt<mode>_setc<mode>_mask"
16911 [(set (match_operand:SWI48 0 "register_operand")
16912 (zero_extract:SWI48
16913 (match_operand:SWI48 1 "register_operand")
16917 (match_operand:SWI48 2 "register_operand")
16918 (match_operand 3 "const_int_operand")) 0)))
16919 (clobber (reg:CC FLAGS_REG))]
16921 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16922 == GET_MODE_BITSIZE (<MODE>mode)-1
16923 && ix86_pre_reload_split ()"
16926 [(set (reg:CCC FLAGS_REG)
16928 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16931 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))
16932 (set (match_dup 0) (zero_extend:SWI48 (match_dup 3)))]
16934 operands[2] = gen_lowpart (QImode, operands[2]);
16935 operands[3] = gen_reg_rtx (QImode);
16938 ;; Store-flag instructions.
16941 [(set (match_operand:QI 0 "nonimmediate_operand")
16942 (match_operator:QI 1 "add_comparison_operator"
16943 [(not:SWI (match_operand:SWI 2 "register_operand"))
16944 (match_operand:SWI 3 "nonimmediate_operand")]))]
16946 [(set (reg:CCC FLAGS_REG)
16948 (plus:SWI (match_dup 2) (match_dup 3))
16951 (match_op_dup 1 [(reg:CCC FLAGS_REG) (const_int 0)]))])
16954 [(set (match_operand:QI 0 "nonimmediate_operand")
16955 (match_operator:QI 1 "shr_comparison_operator"
16956 [(match_operand:DI 2 "register_operand")
16957 (match_operand 3 "const_int_operand")]))]
16959 && IN_RANGE (exact_log2 (UINTVAL (operands[3]) + 1), 32, 63)"
16960 [(set (reg:CCZ FLAGS_REG)
16962 (lshiftrt:DI (match_dup 2) (match_dup 4))
16965 (match_op_dup 1 [(reg:CCZ FLAGS_REG) (const_int 0)]))]
16967 enum rtx_code new_code;
16969 operands[1] = shallow_copy_rtx (operands[1]);
16970 switch (GET_CODE (operands[1]))
16972 case GTU: new_code = NE; break;
16973 case LEU: new_code = EQ; break;
16974 default: gcc_unreachable ();
16976 PUT_CODE (operands[1], new_code);
16978 operands[4] = GEN_INT (exact_log2 (UINTVAL (operands[3]) + 1));
16981 ;; For all sCOND expanders, also expand the compare or test insn that
16982 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
16984 (define_insn_and_split "*setcc_di_1"
16985 [(set (match_operand:DI 0 "register_operand" "=q")
16986 (match_operator:DI 1 "ix86_comparison_operator"
16987 [(reg FLAGS_REG) (const_int 0)]))]
16988 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
16990 "&& reload_completed"
16991 [(set (match_dup 2) (match_dup 1))
16992 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
16994 operands[1] = shallow_copy_rtx (operands[1]);
16995 PUT_MODE (operands[1], QImode);
16996 operands[2] = gen_lowpart (QImode, operands[0]);
16999 (define_insn_and_split "*setcc_<mode>_1_and"
17000 [(set (match_operand:SWI24 0 "register_operand" "=q")
17001 (match_operator:SWI24 1 "ix86_comparison_operator"
17002 [(reg FLAGS_REG) (const_int 0)]))
17003 (clobber (reg:CC FLAGS_REG))]
17004 "!TARGET_PARTIAL_REG_STALL
17005 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
17007 "&& reload_completed"
17008 [(set (match_dup 2) (match_dup 1))
17009 (parallel [(set (match_dup 0) (zero_extend:SWI24 (match_dup 2)))
17010 (clobber (reg:CC FLAGS_REG))])]
17012 operands[1] = shallow_copy_rtx (operands[1]);
17013 PUT_MODE (operands[1], QImode);
17014 operands[2] = gen_lowpart (QImode, operands[0]);
17017 (define_insn_and_split "*setcc_<mode>_1_movzbl"
17018 [(set (match_operand:SWI24 0 "register_operand" "=q")
17019 (match_operator:SWI24 1 "ix86_comparison_operator"
17020 [(reg FLAGS_REG) (const_int 0)]))]
17021 "!TARGET_PARTIAL_REG_STALL
17022 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
17024 "&& reload_completed"
17025 [(set (match_dup 2) (match_dup 1))
17026 (set (match_dup 0) (zero_extend:SWI24 (match_dup 2)))]
17028 operands[1] = shallow_copy_rtx (operands[1]);
17029 PUT_MODE (operands[1], QImode);
17030 operands[2] = gen_lowpart (QImode, operands[0]);
17033 (define_insn "*setcc_qi"
17034 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
17035 (match_operator:QI 1 "ix86_comparison_operator"
17036 [(reg FLAGS_REG) (const_int 0)]))]
17039 [(set_attr "type" "setcc")
17040 (set_attr "mode" "QI")])
17042 (define_insn "*setcc_qi_slp"
17043 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+q"))
17044 (match_operator:QI 1 "ix86_comparison_operator"
17045 [(reg FLAGS_REG) (const_int 0)]))]
17048 [(set_attr "type" "setcc")
17049 (set_attr "mode" "QI")])
17051 ;; In general it is not safe to assume too much about CCmode registers,
17052 ;; so simplify-rtx stops when it sees a second one. Under certain
17053 ;; conditions this is safe on x86, so help combine not create
17060 [(set (match_operand:QI 0 "nonimmediate_operand")
17061 (ne:QI (match_operator 1 "ix86_comparison_operator"
17062 [(reg FLAGS_REG) (const_int 0)])
17065 [(set (match_dup 0) (match_dup 1))]
17067 operands[1] = shallow_copy_rtx (operands[1]);
17068 PUT_MODE (operands[1], QImode);
17072 [(set (strict_low_part (match_operand:QI 0 "register_operand"))
17073 (ne:QI (match_operator 1 "ix86_comparison_operator"
17074 [(reg FLAGS_REG) (const_int 0)])
17077 [(set (match_dup 0) (match_dup 1))]
17079 operands[1] = shallow_copy_rtx (operands[1]);
17080 PUT_MODE (operands[1], QImode);
17084 [(set (match_operand:QI 0 "nonimmediate_operand")
17085 (eq:QI (match_operator 1 "ix86_comparison_operator"
17086 [(reg FLAGS_REG) (const_int 0)])
17089 [(set (match_dup 0) (match_dup 1))]
17091 operands[1] = shallow_copy_rtx (operands[1]);
17092 PUT_MODE (operands[1], QImode);
17093 PUT_CODE (operands[1],
17094 ix86_reverse_condition (GET_CODE (operands[1]),
17095 GET_MODE (XEXP (operands[1], 0))));
17097 /* Make sure that (a) the CCmode we have for the flags is strong
17098 enough for the reversed compare or (b) we have a valid FP compare. */
17099 if (! ix86_comparison_operator (operands[1], VOIDmode))
17104 [(set (strict_low_part (match_operand:QI 0 "register_operand"))
17105 (eq:QI (match_operator 1 "ix86_comparison_operator"
17106 [(reg FLAGS_REG) (const_int 0)])
17109 [(set (match_dup 0) (match_dup 1))]
17111 operands[1] = shallow_copy_rtx (operands[1]);
17112 PUT_MODE (operands[1], QImode);
17113 PUT_CODE (operands[1],
17114 ix86_reverse_condition (GET_CODE (operands[1]),
17115 GET_MODE (XEXP (operands[1], 0))));
17117 /* Make sure that (a) the CCmode we have for the flags is strong
17118 enough for the reversed compare or (b) we have a valid FP compare. */
17119 if (! ix86_comparison_operator (operands[1], VOIDmode))
17123 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
17124 ;; subsequent logical operations are used to imitate conditional moves.
17125 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
17128 (define_insn "setcc_<mode>_sse"
17129 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
17130 (match_operator:MODEF 3 "sse_comparison_operator"
17131 [(match_operand:MODEF 1 "register_operand" "0,x")
17132 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xjm")]))]
17133 "SSE_FLOAT_MODE_P (<MODE>mode)"
17135 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
17136 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17137 [(set_attr "isa" "noavx,avx")
17138 (set_attr "addr" "*,gpr16")
17139 (set_attr "type" "ssecmp")
17140 (set_attr "length_immediate" "1")
17141 (set_attr "prefix" "orig,vex")
17142 (set_attr "mode" "<MODE>")])
17144 (define_insn "setcc_hf_mask"
17145 [(set (match_operand:QI 0 "register_operand" "=k")
17147 [(match_operand:HF 1 "register_operand" "v")
17148 (match_operand:HF 2 "nonimmediate_operand" "vm")
17149 (match_operand:SI 3 "const_0_to_31_operand")]
17151 "TARGET_AVX512FP16"
17152 "vcmpsh\t{%3, %2, %1, %0|%0, %1, %2, %3}"
17153 [(set_attr "type" "ssecmp")
17154 (set_attr "prefix" "evex")
17155 (set_attr "mode" "HF")])
17158 ;; Basic conditional jump instructions.
17163 (match_operator 1 "add_comparison_operator"
17164 [(not:SWI (match_operand:SWI 2 "register_operand"))
17165 (match_operand:SWI 3 "nonimmediate_operand")])
17166 (label_ref (match_operand 0))
17169 [(set (reg:CCC FLAGS_REG)
17171 (plus:SWI (match_dup 2) (match_dup 3))
17174 (if_then_else (match_op_dup 1 [(reg:CCC FLAGS_REG) (const_int 0)])
17175 (label_ref (match_operand 0))
17181 (match_operator 1 "shr_comparison_operator"
17182 [(match_operand:DI 2 "register_operand")
17183 (match_operand 3 "const_int_operand")])
17184 (label_ref (match_operand 0))
17187 && IN_RANGE (exact_log2 (UINTVAL (operands[3]) + 1), 32, 63)"
17188 [(set (reg:CCZ FLAGS_REG)
17190 (lshiftrt:DI (match_dup 2) (match_dup 4))
17193 (if_then_else (match_op_dup 1 [(reg:CCZ FLAGS_REG) (const_int 0)])
17194 (label_ref (match_operand 0))
17197 enum rtx_code new_code;
17199 operands[1] = shallow_copy_rtx (operands[1]);
17200 switch (GET_CODE (operands[1]))
17202 case GTU: new_code = NE; break;
17203 case LEU: new_code = EQ; break;
17204 default: gcc_unreachable ();
17206 PUT_CODE (operands[1], new_code);
17208 operands[4] = GEN_INT (exact_log2 (UINTVAL (operands[3]) + 1));
17211 ;; We ignore the overflow flag for signed branch instructions.
17213 (define_insn "*jcc"
17215 (if_then_else (match_operator 1 "ix86_comparison_operator"
17216 [(reg FLAGS_REG) (const_int 0)])
17217 (label_ref (match_operand 0))
17221 [(set_attr "type" "ibr")
17222 (set_attr "modrm" "0")
17223 (set (attr "length")
17225 (and (ge (minus (match_dup 0) (pc))
17227 (lt (minus (match_dup 0) (pc))
17232 ;; In general it is not safe to assume too much about CCmode registers,
17233 ;; so simplify-rtx stops when it sees a second one. Under certain
17234 ;; conditions this is safe on x86, so help combine not create
17242 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
17243 [(reg FLAGS_REG) (const_int 0)])
17245 (label_ref (match_operand 1))
17249 (if_then_else (match_dup 0)
17250 (label_ref (match_dup 1))
17253 operands[0] = shallow_copy_rtx (operands[0]);
17254 PUT_MODE (operands[0], VOIDmode);
17259 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
17260 [(reg FLAGS_REG) (const_int 0)])
17262 (label_ref (match_operand 1))
17266 (if_then_else (match_dup 0)
17267 (label_ref (match_dup 1))
17270 operands[0] = shallow_copy_rtx (operands[0]);
17271 PUT_MODE (operands[0], VOIDmode);
17272 PUT_CODE (operands[0],
17273 ix86_reverse_condition (GET_CODE (operands[0]),
17274 GET_MODE (XEXP (operands[0], 0))));
17276 /* Make sure that (a) the CCmode we have for the flags is strong
17277 enough for the reversed compare or (b) we have a valid FP compare. */
17278 if (! ix86_comparison_operator (operands[0], VOIDmode))
17282 ;; Unconditional and other jump instructions
17284 (define_insn "jump"
17286 (label_ref (match_operand 0)))]
17289 [(set_attr "type" "ibr")
17290 (set_attr "modrm" "0")
17291 (set (attr "length")
17293 (and (ge (minus (match_dup 0) (pc))
17295 (lt (minus (match_dup 0) (pc))
17300 (define_expand "indirect_jump"
17301 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
17304 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
17305 operands[0] = convert_memory_address (word_mode, operands[0]);
17306 cfun->machine->has_local_indirect_jump = true;
17309 (define_insn "*indirect_jump"
17310 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
17312 "* return ix86_output_indirect_jmp (operands[0]);"
17313 [(set (attr "type")
17314 (if_then_else (match_test "(cfun->machine->indirect_branch_type
17315 != indirect_branch_keep)")
17316 (const_string "multi")
17317 (const_string "ibr")))
17318 (set_attr "length_immediate" "0")])
17320 (define_expand "tablejump"
17321 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
17322 (use (label_ref (match_operand 1)))])]
17325 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
17326 relative. Convert the relative address to an absolute address. */
17330 enum rtx_code code;
17332 /* We can't use @GOTOFF for text labels on VxWorks;
17333 see gotoff_operand. */
17334 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
17338 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
17340 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
17344 op1 = pic_offset_table_rtx;
17349 op0 = pic_offset_table_rtx;
17353 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
17357 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
17358 operands[0] = convert_memory_address (word_mode, operands[0]);
17359 cfun->machine->has_local_indirect_jump = true;
17362 (define_insn "*tablejump_1"
17363 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
17364 (use (label_ref (match_operand 1)))]
17366 "* return ix86_output_indirect_jmp (operands[0]);"
17367 [(set (attr "type")
17368 (if_then_else (match_test "(cfun->machine->indirect_branch_type
17369 != indirect_branch_keep)")
17370 (const_string "multi")
17371 (const_string "ibr")))
17372 (set_attr "length_immediate" "0")])
17374 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
17377 [(set (match_operand 4 "flags_reg_operand") (match_operand 0))
17378 (set (match_operand:QI 1 "register_operand")
17379 (match_operator:QI 2 "ix86_comparison_operator"
17380 [(reg FLAGS_REG) (const_int 0)]))
17381 (set (match_operand 3 "any_QIreg_operand")
17382 (zero_extend (match_dup 1)))]
17383 "(peep2_reg_dead_p (3, operands[1])
17384 || operands_match_p (operands[1], operands[3]))
17385 && ! reg_overlap_mentioned_p (operands[3], operands[0])
17386 && peep2_regno_dead_p (0, FLAGS_REG)"
17387 [(set (match_dup 4) (match_dup 0))
17388 (set (strict_low_part (match_dup 5))
17391 operands[5] = gen_lowpart (QImode, operands[3]);
17392 ix86_expand_clear (operands[3]);
17396 [(parallel [(set (match_operand 5 "flags_reg_operand") (match_operand 0))
17397 (match_operand 4)])
17398 (set (match_operand:QI 1 "register_operand")
17399 (match_operator:QI 2 "ix86_comparison_operator"
17400 [(reg FLAGS_REG) (const_int 0)]))
17401 (set (match_operand 3 "any_QIreg_operand")
17402 (zero_extend (match_dup 1)))]
17403 "(peep2_reg_dead_p (3, operands[1])
17404 || operands_match_p (operands[1], operands[3]))
17405 && ! reg_overlap_mentioned_p (operands[3], operands[0])
17406 && ! reg_overlap_mentioned_p (operands[3], operands[4])
17407 && ! reg_set_p (operands[3], operands[4])
17408 && peep2_regno_dead_p (0, FLAGS_REG)"
17409 [(parallel [(set (match_dup 5) (match_dup 0))
17411 (set (strict_low_part (match_dup 6))
17414 operands[6] = gen_lowpart (QImode, operands[3]);
17415 ix86_expand_clear (operands[3]);
17419 [(set (match_operand 6 "flags_reg_operand") (match_operand 0))
17420 (parallel [(set (match_operand 7 "flags_reg_operand") (match_operand 1))
17421 (match_operand 5)])
17422 (set (match_operand:QI 2 "register_operand")
17423 (match_operator:QI 3 "ix86_comparison_operator"
17424 [(reg FLAGS_REG) (const_int 0)]))
17425 (set (match_operand 4 "any_QIreg_operand")
17426 (zero_extend (match_dup 2)))]
17427 "(peep2_reg_dead_p (4, operands[2])
17428 || operands_match_p (operands[2], operands[4]))
17429 && ! reg_overlap_mentioned_p (operands[4], operands[0])
17430 && ! reg_overlap_mentioned_p (operands[4], operands[1])
17431 && ! reg_overlap_mentioned_p (operands[4], operands[5])
17432 && ! reg_set_p (operands[4], operands[5])
17433 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
17434 && peep2_regno_dead_p (0, FLAGS_REG)"
17435 [(set (match_dup 6) (match_dup 0))
17436 (parallel [(set (match_dup 7) (match_dup 1))
17438 (set (strict_low_part (match_dup 8))
17441 operands[8] = gen_lowpart (QImode, operands[4]);
17442 ix86_expand_clear (operands[4]);
17445 ;; Similar, but match zero extend with andsi3.
17448 [(set (match_operand 4 "flags_reg_operand") (match_operand 0))
17449 (set (match_operand:QI 1 "register_operand")
17450 (match_operator:QI 2 "ix86_comparison_operator"
17451 [(reg FLAGS_REG) (const_int 0)]))
17452 (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
17453 (and:SI (match_dup 3) (const_int 255)))
17454 (clobber (reg:CC FLAGS_REG))])]
17455 "REGNO (operands[1]) == REGNO (operands[3])
17456 && ! reg_overlap_mentioned_p (operands[3], operands[0])
17457 && peep2_regno_dead_p (0, FLAGS_REG)"
17458 [(set (match_dup 4) (match_dup 0))
17459 (set (strict_low_part (match_dup 5))
17462 operands[5] = gen_lowpart (QImode, operands[3]);
17463 ix86_expand_clear (operands[3]);
17467 [(parallel [(set (match_operand 5 "flags_reg_operand") (match_operand 0))
17468 (match_operand 4)])
17469 (set (match_operand:QI 1 "register_operand")
17470 (match_operator:QI 2 "ix86_comparison_operator"
17471 [(reg FLAGS_REG) (const_int 0)]))
17472 (parallel [(set (match_operand 3 "any_QIreg_operand")
17473 (zero_extend (match_dup 1)))
17474 (clobber (reg:CC FLAGS_REG))])]
17475 "(peep2_reg_dead_p (3, operands[1])
17476 || operands_match_p (operands[1], operands[3]))
17477 && ! reg_overlap_mentioned_p (operands[3], operands[0])
17478 && ! reg_overlap_mentioned_p (operands[3], operands[4])
17479 && ! reg_set_p (operands[3], operands[4])
17480 && peep2_regno_dead_p (0, FLAGS_REG)"
17481 [(parallel [(set (match_dup 5) (match_dup 0))
17483 (set (strict_low_part (match_dup 6))
17486 operands[6] = gen_lowpart (QImode, operands[3]);
17487 ix86_expand_clear (operands[3]);
17491 [(set (match_operand 6 "flags_reg_operand") (match_operand 0))
17492 (parallel [(set (match_operand 7 "flags_reg_operand") (match_operand 1))
17493 (match_operand 5)])
17494 (set (match_operand:QI 2 "register_operand")
17495 (match_operator:QI 3 "ix86_comparison_operator"
17496 [(reg FLAGS_REG) (const_int 0)]))
17497 (parallel [(set (match_operand 4 "any_QIreg_operand")
17498 (zero_extend (match_dup 2)))
17499 (clobber (reg:CC FLAGS_REG))])]
17500 "(peep2_reg_dead_p (4, operands[2])
17501 || operands_match_p (operands[2], operands[4]))
17502 && ! reg_overlap_mentioned_p (operands[4], operands[0])
17503 && ! reg_overlap_mentioned_p (operands[4], operands[1])
17504 && ! reg_overlap_mentioned_p (operands[4], operands[5])
17505 && ! reg_set_p (operands[4], operands[5])
17506 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
17507 && peep2_regno_dead_p (0, FLAGS_REG)"
17508 [(set (match_dup 6) (match_dup 0))
17509 (parallel [(set (match_dup 7) (match_dup 1))
17511 (set (strict_low_part (match_dup 8))
17514 operands[8] = gen_lowpart (QImode, operands[4]);
17515 ix86_expand_clear (operands[4]);
17518 ;; Call instructions.
17520 ;; The predicates normally associated with named expanders are not properly
17521 ;; checked for calls. This is a bug in the generic code, but it isn't that
17522 ;; easy to fix. Ignore it for now and be prepared to fix things up.
17524 ;; P6 processors will jump to the address after the decrement when %esp
17525 ;; is used as a call operand, so they will execute return address as a code.
17526 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
17528 ;; Register constraint for call instruction.
17529 (define_mode_attr c [(SI "l") (DI "r")])
17531 ;; Call subroutine returning no value.
17533 (define_expand "call"
17534 [(call (match_operand:QI 0)
17536 (use (match_operand 2))]
17539 ix86_expand_call (NULL, operands[0], operands[1],
17540 operands[2], NULL, false);
17544 (define_expand "sibcall"
17545 [(call (match_operand:QI 0)
17547 (use (match_operand 2))]
17550 ix86_expand_call (NULL, operands[0], operands[1],
17551 operands[2], NULL, true);
17555 (define_insn "*call"
17556 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
17557 (match_operand 1))]
17558 "!SIBLING_CALL_P (insn)"
17559 "* return ix86_output_call_insn (insn, operands[0]);"
17560 [(set_attr "type" "call")])
17562 ;; This covers both call and sibcall since only GOT slot is allowed.
17563 (define_insn "*call_got_x32"
17564 [(call (mem:QI (zero_extend:DI
17565 (match_operand:SI 0 "GOT_memory_operand" "Bg")))
17566 (match_operand 1))]
17569 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
17570 return ix86_output_call_insn (insn, fnaddr);
17572 [(set_attr "type" "call")])
17574 ;; Since sibcall never returns, we can only use call-clobbered register
17576 (define_insn "*sibcall_GOT_32"
17579 (match_operand:SI 0 "register_no_elim_operand" "U")
17580 (match_operand:SI 1 "GOT32_symbol_operand"))))
17581 (match_operand 2))]
17584 && !TARGET_INDIRECT_BRANCH_REGISTER
17585 && SIBLING_CALL_P (insn)"
17587 rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
17588 fnaddr = gen_const_mem (SImode, fnaddr);
17589 return ix86_output_call_insn (insn, fnaddr);
17591 [(set_attr "type" "call")])
17593 (define_insn "*sibcall"
17594 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
17595 (match_operand 1))]
17596 "SIBLING_CALL_P (insn)"
17597 "* return ix86_output_call_insn (insn, operands[0]);"
17598 [(set_attr "type" "call")])
17600 (define_insn "*sibcall_memory"
17601 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
17603 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17604 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
17605 "* return ix86_output_call_insn (insn, operands[0]);"
17606 [(set_attr "type" "call")])
17609 [(set (match_operand:W 0 "register_operand")
17610 (match_operand:W 1 "memory_operand"))
17611 (call (mem:QI (match_dup 0))
17612 (match_operand 3))]
17614 && !TARGET_INDIRECT_BRANCH_REGISTER
17615 && SIBLING_CALL_P (peep2_next_insn (1))
17616 && !reg_mentioned_p (operands[0],
17617 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17618 [(parallel [(call (mem:QI (match_dup 1))
17620 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17623 [(set (match_operand:W 0 "register_operand")
17624 (match_operand:W 1 "memory_operand"))
17625 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17626 (call (mem:QI (match_dup 0))
17627 (match_operand 3))]
17629 && !TARGET_INDIRECT_BRANCH_REGISTER
17630 && SIBLING_CALL_P (peep2_next_insn (2))
17631 && !reg_mentioned_p (operands[0],
17632 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17633 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17634 (parallel [(call (mem:QI (match_dup 1))
17636 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17638 (define_expand "call_pop"
17639 [(parallel [(call (match_operand:QI 0)
17640 (match_operand:SI 1))
17641 (set (reg:SI SP_REG)
17642 (plus:SI (reg:SI SP_REG)
17643 (match_operand:SI 3)))])]
17646 ix86_expand_call (NULL, operands[0], operands[1],
17647 operands[2], operands[3], false);
17651 (define_insn "*call_pop"
17652 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz"))
17654 (set (reg:SI SP_REG)
17655 (plus:SI (reg:SI SP_REG)
17656 (match_operand:SI 2 "immediate_operand" "i")))]
17657 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17658 "* return ix86_output_call_insn (insn, operands[0]);"
17659 [(set_attr "type" "call")])
17661 (define_insn "*sibcall_pop"
17662 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
17664 (set (reg:SI SP_REG)
17665 (plus:SI (reg:SI SP_REG)
17666 (match_operand:SI 2 "immediate_operand" "i")))]
17667 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17668 "* return ix86_output_call_insn (insn, operands[0]);"
17669 [(set_attr "type" "call")])
17671 (define_insn "*sibcall_pop_memory"
17672 [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs"))
17674 (set (reg:SI SP_REG)
17675 (plus:SI (reg:SI SP_REG)
17676 (match_operand:SI 2 "immediate_operand" "i")))
17677 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17679 "* return ix86_output_call_insn (insn, operands[0]);"
17680 [(set_attr "type" "call")])
17683 [(set (match_operand:SI 0 "register_operand")
17684 (match_operand:SI 1 "memory_operand"))
17685 (parallel [(call (mem:QI (match_dup 0))
17687 (set (reg:SI SP_REG)
17688 (plus:SI (reg:SI SP_REG)
17689 (match_operand:SI 4 "immediate_operand")))])]
17690 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
17691 && !reg_mentioned_p (operands[0],
17692 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17693 [(parallel [(call (mem:QI (match_dup 1))
17695 (set (reg:SI SP_REG)
17696 (plus:SI (reg:SI SP_REG)
17698 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17701 [(set (match_operand:SI 0 "register_operand")
17702 (match_operand:SI 1 "memory_operand"))
17703 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17704 (parallel [(call (mem:QI (match_dup 0))
17706 (set (reg:SI SP_REG)
17707 (plus:SI (reg:SI SP_REG)
17708 (match_operand:SI 4 "immediate_operand")))])]
17709 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
17710 && !reg_mentioned_p (operands[0],
17711 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17712 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17713 (parallel [(call (mem:QI (match_dup 1))
17715 (set (reg:SI SP_REG)
17716 (plus:SI (reg:SI SP_REG)
17718 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17720 ;; Combining simple memory jump instruction
17723 [(set (match_operand:W 0 "register_operand")
17724 (match_operand:W 1 "memory_operand"))
17725 (set (pc) (match_dup 0))]
17727 && !TARGET_INDIRECT_BRANCH_REGISTER
17728 && peep2_reg_dead_p (2, operands[0])"
17729 [(set (pc) (match_dup 1))])
17731 ;; Call subroutine, returning value in operand 0
17733 (define_expand "call_value"
17734 [(set (match_operand 0)
17735 (call (match_operand:QI 1)
17736 (match_operand 2)))
17737 (use (match_operand 3))]
17740 ix86_expand_call (operands[0], operands[1], operands[2],
17741 operands[3], NULL, false);
17745 (define_expand "sibcall_value"
17746 [(set (match_operand 0)
17747 (call (match_operand:QI 1)
17748 (match_operand 2)))
17749 (use (match_operand 3))]
17752 ix86_expand_call (operands[0], operands[1], operands[2],
17753 operands[3], NULL, true);
17757 (define_insn "*call_value"
17758 [(set (match_operand 0)
17759 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
17760 (match_operand 2)))]
17761 "!SIBLING_CALL_P (insn)"
17762 "* return ix86_output_call_insn (insn, operands[1]);"
17763 [(set_attr "type" "callv")])
17765 ;; This covers both call and sibcall since only GOT slot is allowed.
17766 (define_insn "*call_value_got_x32"
17767 [(set (match_operand 0)
17770 (match_operand:SI 1 "GOT_memory_operand" "Bg")))
17771 (match_operand 2)))]
17774 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
17775 return ix86_output_call_insn (insn, fnaddr);
17777 [(set_attr "type" "callv")])
17779 ;; Since sibcall never returns, we can only use call-clobbered register
17781 (define_insn "*sibcall_value_GOT_32"
17782 [(set (match_operand 0)
17785 (match_operand:SI 1 "register_no_elim_operand" "U")
17786 (match_operand:SI 2 "GOT32_symbol_operand"))))
17787 (match_operand 3)))]
17790 && !TARGET_INDIRECT_BRANCH_REGISTER
17791 && SIBLING_CALL_P (insn)"
17793 rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
17794 fnaddr = gen_const_mem (SImode, fnaddr);
17795 return ix86_output_call_insn (insn, fnaddr);
17797 [(set_attr "type" "callv")])
17799 (define_insn "*sibcall_value"
17800 [(set (match_operand 0)
17801 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
17802 (match_operand 2)))]
17803 "SIBLING_CALL_P (insn)"
17804 "* return ix86_output_call_insn (insn, operands[1]);"
17805 [(set_attr "type" "callv")])
17807 (define_insn "*sibcall_value_memory"
17808 [(set (match_operand 0)
17809 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
17810 (match_operand 2)))
17811 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17812 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
17813 "* return ix86_output_call_insn (insn, operands[1]);"
17814 [(set_attr "type" "callv")])
17817 [(set (match_operand:W 0 "register_operand")
17818 (match_operand:W 1 "memory_operand"))
17819 (set (match_operand 2)
17820 (call (mem:QI (match_dup 0))
17821 (match_operand 3)))]
17823 && !TARGET_INDIRECT_BRANCH_REGISTER
17824 && SIBLING_CALL_P (peep2_next_insn (1))
17825 && !reg_mentioned_p (operands[0],
17826 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17827 [(parallel [(set (match_dup 2)
17828 (call (mem:QI (match_dup 1))
17830 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17833 [(set (match_operand:W 0 "register_operand")
17834 (match_operand:W 1 "memory_operand"))
17835 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17836 (set (match_operand 2)
17837 (call (mem:QI (match_dup 0))
17838 (match_operand 3)))]
17840 && !TARGET_INDIRECT_BRANCH_REGISTER
17841 && SIBLING_CALL_P (peep2_next_insn (2))
17842 && !reg_mentioned_p (operands[0],
17843 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17844 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17845 (parallel [(set (match_dup 2)
17846 (call (mem:QI (match_dup 1))
17848 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17850 (define_expand "call_value_pop"
17851 [(parallel [(set (match_operand 0)
17852 (call (match_operand:QI 1)
17853 (match_operand:SI 2)))
17854 (set (reg:SI SP_REG)
17855 (plus:SI (reg:SI SP_REG)
17856 (match_operand:SI 4)))])]
17859 ix86_expand_call (operands[0], operands[1], operands[2],
17860 operands[3], operands[4], false);
17864 (define_insn "*call_value_pop"
17865 [(set (match_operand 0)
17866 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz"))
17867 (match_operand 2)))
17868 (set (reg:SI SP_REG)
17869 (plus:SI (reg:SI SP_REG)
17870 (match_operand:SI 3 "immediate_operand" "i")))]
17871 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17872 "* return ix86_output_call_insn (insn, operands[1]);"
17873 [(set_attr "type" "callv")])
17875 (define_insn "*sibcall_value_pop"
17876 [(set (match_operand 0)
17877 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
17878 (match_operand 2)))
17879 (set (reg:SI SP_REG)
17880 (plus:SI (reg:SI SP_REG)
17881 (match_operand:SI 3 "immediate_operand" "i")))]
17882 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17883 "* return ix86_output_call_insn (insn, operands[1]);"
17884 [(set_attr "type" "callv")])
17886 (define_insn "*sibcall_value_pop_memory"
17887 [(set (match_operand 0)
17888 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
17889 (match_operand 2)))
17890 (set (reg:SI SP_REG)
17891 (plus:SI (reg:SI SP_REG)
17892 (match_operand:SI 3 "immediate_operand" "i")))
17893 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17895 "* return ix86_output_call_insn (insn, operands[1]);"
17896 [(set_attr "type" "callv")])
17899 [(set (match_operand:SI 0 "register_operand")
17900 (match_operand:SI 1 "memory_operand"))
17901 (parallel [(set (match_operand 2)
17902 (call (mem:QI (match_dup 0))
17903 (match_operand 3)))
17904 (set (reg:SI SP_REG)
17905 (plus:SI (reg:SI SP_REG)
17906 (match_operand:SI 4 "immediate_operand")))])]
17907 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
17908 && !reg_mentioned_p (operands[0],
17909 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17910 [(parallel [(set (match_dup 2)
17911 (call (mem:QI (match_dup 1))
17913 (set (reg:SI SP_REG)
17914 (plus:SI (reg:SI SP_REG)
17916 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17919 [(set (match_operand:SI 0 "register_operand")
17920 (match_operand:SI 1 "memory_operand"))
17921 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17922 (parallel [(set (match_operand 2)
17923 (call (mem:QI (match_dup 0))
17924 (match_operand 3)))
17925 (set (reg:SI SP_REG)
17926 (plus:SI (reg:SI SP_REG)
17927 (match_operand:SI 4 "immediate_operand")))])]
17928 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
17929 && !reg_mentioned_p (operands[0],
17930 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17931 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17932 (parallel [(set (match_dup 2)
17933 (call (mem:QI (match_dup 1))
17935 (set (reg:SI SP_REG)
17936 (plus:SI (reg:SI SP_REG)
17938 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17940 ;; Call subroutine returning any type.
17942 (define_expand "untyped_call"
17943 [(parallel [(call (match_operand 0)
17946 (match_operand 2)])]
17951 /* In order to give reg-stack an easier job in validating two
17952 coprocessor registers as containing a possible return value,
17953 simply pretend the untyped call returns a complex long double
17956 We can't use SSE_REGPARM_MAX here since callee is unprototyped
17957 and should have the default ABI. */
17959 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
17960 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
17961 operands[0], const0_rtx,
17962 GEN_INT ((TARGET_64BIT
17963 ? (ix86_abi == SYSV_ABI
17964 ? X86_64_SSE_REGPARM_MAX
17965 : X86_64_MS_SSE_REGPARM_MAX)
17966 : X86_32_SSE_REGPARM_MAX)
17970 for (i = 0; i < XVECLEN (operands[2], 0); i++)
17972 rtx set = XVECEXP (operands[2], 0, i);
17973 emit_move_insn (SET_DEST (set), SET_SRC (set));
17976 /* The optimizer does not know that the call sets the function value
17977 registers we stored in the result block. We avoid problems by
17978 claiming that all hard registers are used and clobbered at this
17980 emit_insn (gen_blockage ());
17985 ;; Prologue and epilogue instructions
17987 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
17988 ;; all of memory. This blocks insns from being moved across this point.
17990 (define_insn "blockage"
17991 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
17994 [(set_attr "length" "0")])
17996 ;; Do not schedule instructions accessing memory across this point.
17998 (define_expand "memory_blockage"
17999 [(set (match_dup 0)
18000 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
18003 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18004 MEM_VOLATILE_P (operands[0]) = 1;
18007 (define_insn "*memory_blockage"
18008 [(set (match_operand:BLK 0)
18009 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
18012 [(set_attr "length" "0")])
18014 ;; As USE insns aren't meaningful after reload, this is used instead
18015 ;; to prevent deleting instructions setting registers for PIC code
18016 (define_insn "prologue_use"
18017 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
18020 [(set_attr "length" "0")])
18022 ;; Insn emitted into the body of a function to return from a function.
18023 ;; This is only done if the function's epilogue is known to be simple.
18024 ;; See comments for ix86_can_use_return_insn_p in i386.cc.
18026 (define_expand "return"
18028 "ix86_can_use_return_insn_p ()"
18030 if (crtl->args.pops_args)
18032 rtx popc = GEN_INT (crtl->args.pops_args);
18033 emit_jump_insn (gen_simple_return_pop_internal (popc));
18038 ;; We need to disable this for TARGET_SEH, as otherwise
18039 ;; shrink-wrapped prologue gets enabled too. This might exceed
18040 ;; the maximum size of prologue in unwind information.
18041 ;; Also disallow shrink-wrapping if using stack slot to pass the
18042 ;; static chain pointer - the first instruction has to be pushl %esi
18043 ;; and it can't be moved around, as we use alternate entry points
18045 ;; Also disallow for ms_hook_prologue functions which have frame
18046 ;; pointer set up in function label which is correctly handled in
18047 ;; ix86_expand_{prologue|epligoue}() only.
18049 (define_expand "simple_return"
18051 "!TARGET_SEH && !ix86_static_chain_on_stack && !ix86_function_ms_hook_prologue (cfun->decl)"
18053 if (crtl->args.pops_args)
18055 rtx popc = GEN_INT (crtl->args.pops_args);
18056 emit_jump_insn (gen_simple_return_pop_internal (popc));
18061 (define_insn "simple_return_internal"
18064 "* return ix86_output_function_return (false);"
18065 [(set_attr "length" "1")
18066 (set_attr "atom_unit" "jeu")
18067 (set_attr "length_immediate" "0")
18068 (set_attr "modrm" "0")])
18070 (define_insn "interrupt_return"
18072 (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
18075 return TARGET_64BIT ? (TARGET_UINTR ? "uiret" : "iretq") : "iret";
18078 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
18079 ;; instruction Athlon and K8 have.
18081 (define_insn "simple_return_internal_long"
18083 (unspec [(const_int 0)] UNSPEC_REP)]
18085 "* return ix86_output_function_return (true);"
18086 [(set_attr "length" "2")
18087 (set_attr "atom_unit" "jeu")
18088 (set_attr "length_immediate" "0")
18089 (set_attr "prefix_rep" "1")
18090 (set_attr "modrm" "0")])
18092 (define_insn_and_split "simple_return_pop_internal"
18094 (use (match_operand:SI 0 "const_int_operand"))]
18097 "&& cfun->machine->function_return_type != indirect_branch_keep"
18099 "ix86_split_simple_return_pop_internal (operands[0]); DONE;"
18100 [(set_attr "length" "3")
18101 (set_attr "atom_unit" "jeu")
18102 (set_attr "length_immediate" "2")
18103 (set_attr "modrm" "0")])
18105 (define_expand "simple_return_indirect_internal"
18108 (use (match_operand 0 "register_operand"))])])
18110 (define_insn "*simple_return_indirect_internal<mode>"
18112 (use (match_operand:W 0 "register_operand" "r"))]
18114 "* return ix86_output_indirect_function_return (operands[0]);"
18115 [(set (attr "type")
18116 (if_then_else (match_test "(cfun->machine->indirect_branch_type
18117 != indirect_branch_keep)")
18118 (const_string "multi")
18119 (const_string "ibr")))
18120 (set_attr "length_immediate" "0")])
18126 [(set_attr "length" "1")
18127 (set_attr "length_immediate" "0")
18128 (set_attr "modrm" "0")])
18130 ;; Generate nops. Operand 0 is the number of nops, up to 8.
18131 (define_insn "nops"
18132 [(unspec_volatile [(match_operand 0 "const_int_operand")]
18136 int num = INTVAL (operands[0]);
18138 gcc_assert (IN_RANGE (num, 1, 8));
18141 fputs ("\tnop\n", asm_out_file);
18145 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
18146 (set_attr "length_immediate" "0")
18147 (set_attr "modrm" "0")])
18149 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
18150 ;; branch prediction penalty for the third jump in a 16-byte
18154 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
18157 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
18158 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
18160 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
18161 The align insn is used to avoid 3 jump instructions in the row to improve
18162 branch prediction and the benefits hardly outweigh the cost of extra 8
18163 nops on the average inserted by full alignment pseudo operation. */
18167 [(set_attr "length" "16")])
18169 (define_expand "prologue"
18172 "ix86_expand_prologue (); DONE;")
18174 (define_expand "set_got"
18176 [(set (match_operand:SI 0 "register_operand")
18177 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
18178 (clobber (reg:CC FLAGS_REG))])]
18181 if (flag_pic && !TARGET_VXWORKS_RTP)
18182 ix86_pc_thunk_call_expanded = true;
18185 (define_insn "*set_got"
18186 [(set (match_operand:SI 0 "register_operand" "=r")
18187 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
18188 (clobber (reg:CC FLAGS_REG))]
18190 "* return output_set_got (operands[0], NULL_RTX);"
18191 [(set_attr "type" "multi")
18192 (set_attr "length" "12")])
18194 (define_expand "set_got_labelled"
18196 [(set (match_operand:SI 0 "register_operand")
18197 (unspec:SI [(label_ref (match_operand 1))]
18199 (clobber (reg:CC FLAGS_REG))])]
18202 if (flag_pic && !TARGET_VXWORKS_RTP)
18203 ix86_pc_thunk_call_expanded = true;
18206 (define_insn "*set_got_labelled"
18207 [(set (match_operand:SI 0 "register_operand" "=r")
18208 (unspec:SI [(label_ref (match_operand 1))]
18210 (clobber (reg:CC FLAGS_REG))]
18212 "* return output_set_got (operands[0], operands[1]);"
18213 [(set_attr "type" "multi")
18214 (set_attr "length" "12")])
18216 (define_insn "set_got_rex64"
18217 [(set (match_operand:DI 0 "register_operand" "=r")
18218 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
18220 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
18221 [(set_attr "type" "lea")
18222 (set_attr "length_address" "4")
18223 (set_attr "mode" "DI")])
18225 (define_insn "set_rip_rex64"
18226 [(set (match_operand:DI 0 "register_operand" "=r")
18227 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
18229 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
18230 [(set_attr "type" "lea")
18231 (set_attr "length_address" "4")
18232 (set_attr "mode" "DI")])
18234 (define_insn "set_got_offset_rex64"
18235 [(set (match_operand:DI 0 "register_operand" "=r")
18237 [(label_ref (match_operand 1))]
18238 UNSPEC_SET_GOT_OFFSET))]
18240 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
18241 [(set_attr "type" "imov")
18242 (set_attr "length_immediate" "0")
18243 (set_attr "length_address" "8")
18244 (set_attr "mode" "DI")])
18246 (define_expand "epilogue"
18249 "ix86_expand_epilogue (1); DONE;")
18251 (define_expand "sibcall_epilogue"
18254 "ix86_expand_epilogue (0); DONE;")
18256 (define_expand "eh_return"
18257 [(use (match_operand 0 "register_operand"))]
18260 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
18262 /* Tricky bit: we write the address of the handler to which we will
18263 be returning into someone else's stack frame, one word below the
18264 stack address we wish to restore. */
18265 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
18266 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
18267 /* Return address is always in word_mode. */
18268 tmp = gen_rtx_MEM (word_mode, tmp);
18269 if (GET_MODE (ra) != word_mode)
18270 ra = convert_to_mode (word_mode, ra, 1);
18271 emit_move_insn (tmp, ra);
18273 emit_jump_insn (gen_eh_return_internal ());
18278 (define_insn_and_split "eh_return_internal"
18282 "epilogue_completed"
18284 "ix86_expand_epilogue (2); DONE;")
18286 (define_expand "@leave_<mode>"
18288 [(set (reg:W SP_REG) (plus:W (reg:W BP_REG) (match_dup 0)))
18289 (set (reg:W BP_REG) (mem:W (reg:W BP_REG)))
18290 (clobber (mem:BLK (scratch)))])]
18292 "operands[0] = GEN_INT (<MODE_SIZE>);")
18294 (define_insn "*leave"
18295 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
18296 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
18297 (clobber (mem:BLK (scratch)))]
18300 [(set_attr "type" "leave")])
18302 (define_insn "*leave_rex64"
18303 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
18304 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
18305 (clobber (mem:BLK (scratch)))]
18308 [(set_attr "type" "leave")])
18310 ;; Handle -fsplit-stack.
18312 (define_expand "split_stack_prologue"
18316 ix86_expand_split_stack_prologue ();
18320 ;; In order to support the call/return predictor, we use a return
18321 ;; instruction which the middle-end doesn't see.
18322 (define_insn "split_stack_return"
18323 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
18324 UNSPECV_SPLIT_STACK_RETURN)]
18327 if (operands[0] == const0_rtx)
18332 [(set_attr "atom_unit" "jeu")
18333 (set_attr "modrm" "0")
18334 (set (attr "length")
18335 (if_then_else (match_operand:SI 0 "const0_operand")
18338 (set (attr "length_immediate")
18339 (if_then_else (match_operand:SI 0 "const0_operand")
18343 ;; If there are operand 0 bytes available on the stack, jump to
18346 (define_expand "split_stack_space_check"
18347 [(set (pc) (if_then_else
18348 (ltu (minus (reg SP_REG)
18349 (match_operand 0 "register_operand"))
18351 (label_ref (match_operand 1))
18355 rtx reg = gen_reg_rtx (Pmode);
18357 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, operands[0]));
18359 operands[2] = ix86_split_stack_guard ();
18360 ix86_expand_branch (GEU, reg, operands[2], operands[1]);
18365 ;; Bit manipulation instructions.
18367 (define_expand "ffs<mode>2"
18368 [(set (match_dup 2) (const_int -1))
18369 (parallel [(set (match_dup 3) (match_dup 4))
18370 (set (match_operand:SWI48 0 "register_operand")
18372 (match_operand:SWI48 1 "nonimmediate_operand")))])
18373 (set (match_dup 0) (if_then_else:SWI48
18374 (eq (match_dup 3) (const_int 0))
18377 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
18378 (clobber (reg:CC FLAGS_REG))])]
18381 machine_mode flags_mode;
18383 if (<MODE>mode == SImode && !TARGET_CMOVE)
18385 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
18389 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
18391 operands[2] = gen_reg_rtx (<MODE>mode);
18392 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
18393 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
18396 (define_insn_and_split "ffssi2_no_cmove"
18397 [(set (match_operand:SI 0 "register_operand" "=r")
18398 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
18399 (clobber (match_scratch:SI 2 "=&q"))
18400 (clobber (reg:CC FLAGS_REG))]
18403 "&& reload_completed"
18404 [(parallel [(set (match_dup 4) (match_dup 5))
18405 (set (match_dup 0) (ctz:SI (match_dup 1)))])
18406 (set (strict_low_part (match_dup 3))
18407 (eq:QI (match_dup 4) (const_int 0)))
18408 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
18409 (clobber (reg:CC FLAGS_REG))])
18410 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
18411 (clobber (reg:CC FLAGS_REG))])
18412 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
18413 (clobber (reg:CC FLAGS_REG))])]
18415 machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
18417 operands[3] = gen_lowpart (QImode, operands[2]);
18418 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
18419 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
18421 ix86_expand_clear (operands[2]);
18424 (define_insn_and_split "*tzcnt<mode>_1"
18425 [(set (reg:CCC FLAGS_REG)
18426 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18428 (set (match_operand:SWI48 0 "register_operand" "=r")
18429 (ctz:SWI48 (match_dup 1)))]
18431 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
18432 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18433 && optimize_function_for_speed_p (cfun)
18434 && !reg_mentioned_p (operands[0], operands[1])"
18436 [(set (reg:CCC FLAGS_REG)
18437 (compare:CCC (match_dup 1) (const_int 0)))
18439 (ctz:SWI48 (match_dup 1)))
18440 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
18441 "ix86_expand_clear (operands[0]);"
18442 [(set_attr "type" "alu1")
18443 (set_attr "prefix_0f" "1")
18444 (set_attr "prefix_rep" "1")
18445 (set_attr "btver2_decode" "double")
18446 (set_attr "mode" "<MODE>")])
18448 ; False dependency happens when destination is only updated by tzcnt,
18449 ; lzcnt or popcnt. There is no false dependency when destination is
18450 ; also used in source.
18451 (define_insn "*tzcnt<mode>_1_falsedep"
18452 [(set (reg:CCC FLAGS_REG)
18453 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18455 (set (match_operand:SWI48 0 "register_operand" "=r")
18456 (ctz:SWI48 (match_dup 1)))
18457 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18458 UNSPEC_INSN_FALSE_DEP)]
18460 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
18461 [(set_attr "type" "alu1")
18462 (set_attr "prefix_0f" "1")
18463 (set_attr "prefix_rep" "1")
18464 (set_attr "btver2_decode" "double")
18465 (set_attr "mode" "<MODE>")])
18467 (define_insn "*bsf<mode>_1"
18468 [(set (reg:CCZ FLAGS_REG)
18469 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18471 (set (match_operand:SWI48 0 "register_operand" "=r")
18472 (ctz:SWI48 (match_dup 1)))]
18474 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
18475 [(set_attr "type" "alu1")
18476 (set_attr "prefix_0f" "1")
18477 (set_attr "btver2_decode" "double")
18478 (set_attr "znver1_decode" "vector")
18479 (set_attr "mode" "<MODE>")])
18481 (define_insn_and_split "ctz<mode>2"
18482 [(set (match_operand:SWI48 0 "register_operand" "=r")
18484 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18485 (clobber (reg:CC FLAGS_REG))]
18489 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
18490 else if (optimize_function_for_size_p (cfun))
18492 else if (TARGET_CPU_P (GENERIC))
18493 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
18494 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
18496 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
18498 "(TARGET_BMI || TARGET_CPU_P (GENERIC))
18499 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18500 && optimize_function_for_speed_p (cfun)
18501 && !reg_mentioned_p (operands[0], operands[1])"
18503 [(set (match_dup 0)
18504 (ctz:SWI48 (match_dup 1)))
18505 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18506 (clobber (reg:CC FLAGS_REG))])]
18507 "ix86_expand_clear (operands[0]);"
18508 [(set_attr "type" "alu1")
18509 (set_attr "prefix_0f" "1")
18510 (set (attr "prefix_rep")
18512 (ior (match_test "TARGET_BMI")
18513 (and (not (match_test "optimize_function_for_size_p (cfun)"))
18514 (match_test "TARGET_CPU_P (GENERIC)")))
18516 (const_string "0")))
18517 (set_attr "mode" "<MODE>")])
18519 ; False dependency happens when destination is only updated by tzcnt,
18520 ; lzcnt or popcnt. There is no false dependency when destination is
18521 ; also used in source.
18522 (define_insn "*ctz<mode>2_falsedep"
18523 [(set (match_operand:SWI48 0 "register_operand" "=r")
18525 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18526 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18527 UNSPEC_INSN_FALSE_DEP)
18528 (clobber (reg:CC FLAGS_REG))]
18532 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
18533 else if (TARGET_CPU_P (GENERIC))
18534 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
18535 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
18537 gcc_unreachable ();
18539 [(set_attr "type" "alu1")
18540 (set_attr "prefix_0f" "1")
18541 (set_attr "prefix_rep" "1")
18542 (set_attr "mode" "<MODE>")])
18544 (define_insn_and_split "*ctzsi2_zext"
18545 [(set (match_operand:DI 0 "register_operand" "=r")
18549 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
18551 (clobber (reg:CC FLAGS_REG))]
18552 "TARGET_BMI && TARGET_64BIT"
18553 "tzcnt{l}\t{%1, %k0|%k0, %1}"
18554 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18555 && optimize_function_for_speed_p (cfun)
18556 && !reg_mentioned_p (operands[0], operands[1])"
18558 [(set (match_dup 0)
18559 (and:DI (subreg:DI (ctz:SI (match_dup 1)) 0) (const_int 63)))
18560 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18561 (clobber (reg:CC FLAGS_REG))])]
18562 "ix86_expand_clear (operands[0]);"
18563 [(set_attr "type" "alu1")
18564 (set_attr "prefix_0f" "1")
18565 (set_attr "prefix_rep" "1")
18566 (set_attr "mode" "SI")])
18568 ; False dependency happens when destination is only updated by tzcnt,
18569 ; lzcnt or popcnt. There is no false dependency when destination is
18570 ; also used in source.
18571 (define_insn "*ctzsi2_zext_falsedep"
18572 [(set (match_operand:DI 0 "register_operand" "=r")
18576 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
18578 (unspec [(match_operand:DI 2 "register_operand" "0")]
18579 UNSPEC_INSN_FALSE_DEP)
18580 (clobber (reg:CC FLAGS_REG))]
18581 "TARGET_BMI && TARGET_64BIT"
18582 "tzcnt{l}\t{%1, %k0|%k0, %1}"
18583 [(set_attr "type" "alu1")
18584 (set_attr "prefix_0f" "1")
18585 (set_attr "prefix_rep" "1")
18586 (set_attr "mode" "SI")])
18588 (define_insn_and_split "*ctzsidi2_<s>ext"
18589 [(set (match_operand:DI 0 "register_operand" "=r")
18592 (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18593 (clobber (reg:CC FLAGS_REG))]
18597 return "tzcnt{l}\t{%1, %k0|%k0, %1}";
18598 else if (TARGET_CPU_P (GENERIC)
18599 && !optimize_function_for_size_p (cfun))
18600 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
18601 return "rep%; bsf{l}\t{%1, %k0|%k0, %1}";
18602 return "bsf{l}\t{%1, %k0|%k0, %1}";
18604 "(TARGET_BMI || TARGET_CPU_P (GENERIC))
18605 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18606 && optimize_function_for_speed_p (cfun)
18607 && !reg_mentioned_p (operands[0], operands[1])"
18609 [(set (match_dup 0)
18610 (any_extend:DI (ctz:SI (match_dup 1))))
18611 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18612 (clobber (reg:CC FLAGS_REG))])]
18613 "ix86_expand_clear (operands[0]);"
18614 [(set_attr "type" "alu1")
18615 (set_attr "prefix_0f" "1")
18616 (set (attr "prefix_rep")
18618 (ior (match_test "TARGET_BMI")
18619 (and (not (match_test "optimize_function_for_size_p (cfun)"))
18620 (match_test "TARGET_CPU_P (GENERIC)")))
18622 (const_string "0")))
18623 (set_attr "mode" "SI")])
18625 (define_insn "*ctzsidi2_<s>ext_falsedep"
18626 [(set (match_operand:DI 0 "register_operand" "=r")
18629 (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18630 (unspec [(match_operand:DI 2 "register_operand" "0")]
18631 UNSPEC_INSN_FALSE_DEP)
18632 (clobber (reg:CC FLAGS_REG))]
18636 return "tzcnt{l}\t{%1, %k0|%k0, %1}";
18637 else if (TARGET_CPU_P (GENERIC))
18638 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
18639 return "rep%; bsf{l}\t{%1, %k0|%k0, %1}";
18641 gcc_unreachable ();
18643 [(set_attr "type" "alu1")
18644 (set_attr "prefix_0f" "1")
18645 (set_attr "prefix_rep" "1")
18646 (set_attr "mode" "SI")])
18648 (define_insn "bsr_rex64"
18649 [(set (reg:CCZ FLAGS_REG)
18650 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
18652 (set (match_operand:DI 0 "register_operand" "=r")
18653 (minus:DI (const_int 63)
18654 (clz:DI (match_dup 1))))]
18656 "bsr{q}\t{%1, %0|%0, %1}"
18657 [(set_attr "type" "alu1")
18658 (set_attr "prefix_0f" "1")
18659 (set_attr "znver1_decode" "vector")
18660 (set_attr "mode" "DI")])
18662 (define_insn "bsr_rex64_1"
18663 [(set (match_operand:DI 0 "register_operand" "=r")
18664 (minus:DI (const_int 63)
18665 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
18666 (clobber (reg:CC FLAGS_REG))]
18667 "!TARGET_LZCNT && TARGET_64BIT"
18668 "bsr{q}\t{%1, %0|%0, %1}"
18669 [(set_attr "type" "alu1")
18670 (set_attr "prefix_0f" "1")
18671 (set_attr "znver1_decode" "vector")
18672 (set_attr "mode" "DI")])
18674 (define_insn "bsr_rex64_1_zext"
18675 [(set (match_operand:DI 0 "register_operand" "=r")
18677 (minus:SI (const_int 63)
18679 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
18681 (clobber (reg:CC FLAGS_REG))]
18682 "!TARGET_LZCNT && TARGET_64BIT"
18683 "bsr{q}\t{%1, %0|%0, %1}"
18684 [(set_attr "type" "alu1")
18685 (set_attr "prefix_0f" "1")
18686 (set_attr "znver1_decode" "vector")
18687 (set_attr "mode" "DI")])
18690 [(set (reg:CCZ FLAGS_REG)
18691 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
18693 (set (match_operand:SI 0 "register_operand" "=r")
18694 (minus:SI (const_int 31)
18695 (clz:SI (match_dup 1))))]
18697 "bsr{l}\t{%1, %0|%0, %1}"
18698 [(set_attr "type" "alu1")
18699 (set_attr "prefix_0f" "1")
18700 (set_attr "znver1_decode" "vector")
18701 (set_attr "mode" "SI")])
18703 (define_insn "bsr_1"
18704 [(set (match_operand:SI 0 "register_operand" "=r")
18705 (minus:SI (const_int 31)
18706 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18707 (clobber (reg:CC FLAGS_REG))]
18709 "bsr{l}\t{%1, %0|%0, %1}"
18710 [(set_attr "type" "alu1")
18711 (set_attr "prefix_0f" "1")
18712 (set_attr "znver1_decode" "vector")
18713 (set_attr "mode" "SI")])
18715 (define_insn "bsr_zext_1"
18716 [(set (match_operand:DI 0 "register_operand" "=r")
18720 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))))
18721 (clobber (reg:CC FLAGS_REG))]
18722 "!TARGET_LZCNT && TARGET_64BIT"
18723 "bsr{l}\t{%1, %k0|%k0, %1}"
18724 [(set_attr "type" "alu1")
18725 (set_attr "prefix_0f" "1")
18726 (set_attr "znver1_decode" "vector")
18727 (set_attr "mode" "SI")])
18729 ; As bsr is undefined behavior on zero and for other input
18730 ; values it is in range 0 to 63, we can optimize away sign-extends.
18731 (define_insn_and_split "*bsr_rex64_2"
18732 [(set (match_operand:DI 0 "register_operand")
18737 (subreg:SI (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
18740 (clobber (reg:CC FLAGS_REG))]
18741 "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
18744 [(parallel [(set (reg:CCZ FLAGS_REG)
18745 (compare:CCZ (match_dup 1) (const_int 0)))
18747 (minus:DI (const_int 63) (clz:DI (match_dup 1))))])
18748 (parallel [(set (match_dup 0)
18749 (zero_extend:DI (xor:SI (match_dup 3) (const_int 63))))
18750 (clobber (reg:CC FLAGS_REG))])]
18752 operands[2] = gen_reg_rtx (DImode);
18753 operands[3] = lowpart_subreg (SImode, operands[2], DImode);
18756 (define_insn_and_split "*bsr_2"
18757 [(set (match_operand:DI 0 "register_operand")
18762 (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
18764 (clobber (reg:CC FLAGS_REG))]
18765 "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
18768 [(parallel [(set (reg:CCZ FLAGS_REG)
18769 (compare:CCZ (match_dup 1) (const_int 0)))
18771 (minus:SI (const_int 31) (clz:SI (match_dup 1))))])
18772 (parallel [(set (match_dup 0)
18773 (zero_extend:DI (xor:SI (match_dup 2) (const_int 31))))
18774 (clobber (reg:CC FLAGS_REG))])]
18775 "operands[2] = gen_reg_rtx (SImode);")
18777 ; Splitters to optimize 64 - __builtin_clzl (x) or 32 - __builtin_clz (x).
18778 ; Again, as for !TARGET_LZCNT CLZ is UB at zero, CLZ is guaranteed to be
18779 ; in [0, 63] or [0, 31] range.
18781 [(set (match_operand:SI 0 "register_operand")
18783 (match_operand:SI 2 "const_int_operand")
18785 (minus:SI (const_int 63)
18787 (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
18790 "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
18791 [(set (match_dup 3)
18792 (minus:DI (const_int 63) (clz:DI (match_dup 1))))
18794 (plus:SI (match_dup 5) (match_dup 4)))]
18796 operands[3] = gen_reg_rtx (DImode);
18797 operands[5] = lowpart_subreg (SImode, operands[3], DImode);
18798 if (INTVAL (operands[2]) == 63)
18800 emit_insn (gen_bsr_rex64_1_zext (operands[3], operands[1]));
18801 emit_move_insn (operands[0], operands[5]);
18804 operands[4] = gen_int_mode (UINTVAL (operands[2]) - 63, SImode);
18808 [(set (match_operand:SI 0 "register_operand")
18810 (match_operand:SI 2 "const_int_operand")
18812 (minus:SI (const_int 31)
18813 (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
18815 "!TARGET_LZCNT && ix86_pre_reload_split ()"
18816 [(set (match_dup 3)
18817 (minus:SI (const_int 31) (clz:SI (match_dup 1))))
18819 (plus:SI (match_dup 3) (match_dup 4)))]
18821 if (INTVAL (operands[2]) == 31)
18823 emit_insn (gen_bsr_1 (operands[0], operands[1]));
18826 operands[3] = gen_reg_rtx (SImode);
18827 operands[4] = gen_int_mode (UINTVAL (operands[2]) - 31, SImode);
18831 [(set (match_operand:DI 0 "register_operand")
18833 (match_operand:DI 2 "const_int_operand")
18836 (minus:SI (const_int 63)
18838 (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
18843 && ix86_pre_reload_split ()
18844 && ((unsigned HOST_WIDE_INT)
18845 trunc_int_for_mode (UINTVAL (operands[2]) - 63, SImode)
18846 == UINTVAL (operands[2]) - 63)"
18847 [(set (match_dup 3)
18848 (minus:DI (const_int 63) (clz:DI (match_dup 1))))
18850 (plus:DI (match_dup 3) (match_dup 4)))]
18852 if (INTVAL (operands[2]) == 63)
18854 emit_insn (gen_bsr_rex64_1 (operands[0], operands[1]));
18857 operands[3] = gen_reg_rtx (DImode);
18858 operands[4] = GEN_INT (UINTVAL (operands[2]) - 63);
18862 [(set (match_operand:DI 0 "register_operand")
18864 (match_operand:DI 2 "const_int_operand")
18867 (minus:SI (const_int 31)
18868 (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
18869 (const_int 31)))))]
18872 && ix86_pre_reload_split ()
18873 && ((unsigned HOST_WIDE_INT)
18874 trunc_int_for_mode (UINTVAL (operands[2]) - 31, SImode)
18875 == UINTVAL (operands[2]) - 31)"
18876 [(set (match_dup 3)
18877 (zero_extend:DI (minus:SI (const_int 31) (clz:SI (match_dup 1)))))
18879 (plus:DI (match_dup 3) (match_dup 4)))]
18881 if (INTVAL (operands[2]) == 31)
18883 emit_insn (gen_bsr_zext_1 (operands[0], operands[1]));
18886 operands[3] = gen_reg_rtx (DImode);
18887 operands[4] = GEN_INT (UINTVAL (operands[2]) - 31);
18890 (define_expand "clz<mode>2"
18892 [(set (reg:CCZ FLAGS_REG)
18893 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18895 (set (match_dup 3) (minus:SWI48
18897 (clz:SWI48 (match_dup 1))))])
18899 [(set (match_operand:SWI48 0 "register_operand")
18900 (xor:SWI48 (match_dup 3) (match_dup 2)))
18901 (clobber (reg:CC FLAGS_REG))])]
18906 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
18909 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
18910 operands[3] = gen_reg_rtx (<MODE>mode);
18913 (define_insn_and_split "clz<mode>2_lzcnt"
18914 [(set (match_operand:SWI48 0 "register_operand" "=r")
18916 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18917 (clobber (reg:CC FLAGS_REG))]
18919 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
18920 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18921 && optimize_function_for_speed_p (cfun)
18922 && !reg_mentioned_p (operands[0], operands[1])"
18924 [(set (match_dup 0)
18925 (clz:SWI48 (match_dup 1)))
18926 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18927 (clobber (reg:CC FLAGS_REG))])]
18928 "ix86_expand_clear (operands[0]);"
18929 [(set_attr "prefix_rep" "1")
18930 (set_attr "type" "bitmanip")
18931 (set_attr "mode" "<MODE>")])
18933 ; False dependency happens when destination is only updated by tzcnt,
18934 ; lzcnt or popcnt. There is no false dependency when destination is
18935 ; also used in source.
18936 (define_insn "*clz<mode>2_lzcnt_falsedep"
18937 [(set (match_operand:SWI48 0 "register_operand" "=r")
18939 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18940 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18941 UNSPEC_INSN_FALSE_DEP)
18942 (clobber (reg:CC FLAGS_REG))]
18944 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
18945 [(set_attr "prefix_rep" "1")
18946 (set_attr "type" "bitmanip")
18947 (set_attr "mode" "<MODE>")])
18949 (define_insn_and_split "*clzsi2_lzcnt_zext"
18950 [(set (match_operand:DI 0 "register_operand" "=r")
18954 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
18956 (clobber (reg:CC FLAGS_REG))]
18957 "TARGET_LZCNT && TARGET_64BIT"
18958 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18959 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18960 && optimize_function_for_speed_p (cfun)
18961 && !reg_mentioned_p (operands[0], operands[1])"
18963 [(set (match_dup 0)
18964 (and:DI (subreg:DI (clz:SI (match_dup 1)) 0) (const_int 63)))
18965 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18966 (clobber (reg:CC FLAGS_REG))])]
18967 "ix86_expand_clear (operands[0]);"
18968 [(set_attr "prefix_rep" "1")
18969 (set_attr "type" "bitmanip")
18970 (set_attr "mode" "SI")])
18972 ; False dependency happens when destination is only updated by tzcnt,
18973 ; lzcnt or popcnt. There is no false dependency when destination is
18974 ; also used in source.
18975 (define_insn "*clzsi2_lzcnt_zext_falsedep"
18976 [(set (match_operand:DI 0 "register_operand" "=r")
18980 (match_operand:SWI48 1 "nonimmediate_operand" "rm")) 0)
18982 (unspec [(match_operand:DI 2 "register_operand" "0")]
18983 UNSPEC_INSN_FALSE_DEP)
18984 (clobber (reg:CC FLAGS_REG))]
18986 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18987 [(set_attr "prefix_rep" "1")
18988 (set_attr "type" "bitmanip")
18989 (set_attr "mode" "SI")])
18991 (define_insn_and_split "*clzsi2_lzcnt_zext_2"
18992 [(set (match_operand:DI 0 "register_operand" "=r")
18994 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18995 (clobber (reg:CC FLAGS_REG))]
18996 "TARGET_LZCNT && TARGET_64BIT"
18997 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18998 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18999 && optimize_function_for_speed_p (cfun)
19000 && !reg_mentioned_p (operands[0], operands[1])"
19002 [(set (match_dup 0)
19003 (zero_extend:DI (clz:SI (match_dup 1))))
19004 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
19005 (clobber (reg:CC FLAGS_REG))])]
19006 "ix86_expand_clear (operands[0]);"
19007 [(set_attr "prefix_rep" "1")
19008 (set_attr "type" "bitmanip")
19009 (set_attr "mode" "SI")])
19011 ; False dependency happens when destination is only updated by tzcnt,
19012 ; lzcnt or popcnt. There is no false dependency when destination is
19013 ; also used in source.
19014 (define_insn "*clzsi2_lzcnt_zext_2_falsedep"
19015 [(set (match_operand:DI 0 "register_operand" "=r")
19017 (clz:SI (match_operand:SWI48 1 "nonimmediate_operand" "rm"))))
19018 (unspec [(match_operand:DI 2 "register_operand" "0")]
19019 UNSPEC_INSN_FALSE_DEP)
19020 (clobber (reg:CC FLAGS_REG))]
19022 "lzcnt{l}\t{%1, %k0|%k0, %1}"
19023 [(set_attr "prefix_rep" "1")
19024 (set_attr "type" "bitmanip")
19025 (set_attr "mode" "SI")])
19027 (define_int_iterator LT_ZCNT
19028 [(UNSPEC_TZCNT "TARGET_BMI")
19029 (UNSPEC_LZCNT "TARGET_LZCNT")])
19031 (define_int_attr lt_zcnt
19032 [(UNSPEC_TZCNT "tzcnt")
19033 (UNSPEC_LZCNT "lzcnt")])
19035 (define_int_attr lt_zcnt_type
19036 [(UNSPEC_TZCNT "alu1")
19037 (UNSPEC_LZCNT "bitmanip")])
19039 ;; Version of lzcnt/tzcnt that is expanded from intrinsics. This version
19040 ;; provides operand size as output when source operand is zero.
19042 (define_insn_and_split "<lt_zcnt>_<mode>"
19043 [(set (match_operand:SWI48 0 "register_operand" "=r")
19045 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
19046 (clobber (reg:CC FLAGS_REG))]
19048 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
19049 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
19050 && optimize_function_for_speed_p (cfun)
19051 && !reg_mentioned_p (operands[0], operands[1])"
19053 [(set (match_dup 0)
19054 (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
19055 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
19056 (clobber (reg:CC FLAGS_REG))])]
19057 "ix86_expand_clear (operands[0]);"
19058 [(set_attr "type" "<lt_zcnt_type>")
19059 (set_attr "prefix_0f" "1")
19060 (set_attr "prefix_rep" "1")
19061 (set_attr "mode" "<MODE>")])
19063 ; False dependency happens when destination is only updated by tzcnt,
19064 ; lzcnt or popcnt. There is no false dependency when destination is
19065 ; also used in source.
19066 (define_insn "*<lt_zcnt>_<mode>_falsedep"
19067 [(set (match_operand:SWI48 0 "register_operand" "=r")
19069 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
19070 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
19071 UNSPEC_INSN_FALSE_DEP)
19072 (clobber (reg:CC FLAGS_REG))]
19074 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
19075 [(set_attr "type" "<lt_zcnt_type>")
19076 (set_attr "prefix_0f" "1")
19077 (set_attr "prefix_rep" "1")
19078 (set_attr "mode" "<MODE>")])
19080 (define_insn "<lt_zcnt>_hi"
19081 [(set (match_operand:HI 0 "register_operand" "=r")
19083 [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT))
19084 (clobber (reg:CC FLAGS_REG))]
19086 "<lt_zcnt>{w}\t{%1, %0|%0, %1}"
19087 [(set_attr "type" "<lt_zcnt_type>")
19088 (set_attr "prefix_0f" "1")
19089 (set_attr "prefix_rep" "1")
19090 (set_attr "mode" "HI")])
19092 ;; BMI instructions.
19094 (define_insn "bmi_bextr_<mode>"
19095 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
19096 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
19097 (match_operand:SWI48 2 "register_operand" "r,r")]
19099 (clobber (reg:CC FLAGS_REG))]
19101 "bextr\t{%2, %1, %0|%0, %1, %2}"
19102 [(set_attr "type" "bitmanip")
19103 (set_attr "btver2_decode" "direct, double")
19104 (set_attr "mode" "<MODE>")])
19106 (define_insn "*bmi_bextr_<mode>_ccz"
19107 [(set (reg:CCZ FLAGS_REG)
19109 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
19110 (match_operand:SWI48 2 "register_operand" "r,r")]
19113 (clobber (match_scratch:SWI48 0 "=r,r"))]
19115 "bextr\t{%2, %1, %0|%0, %1, %2}"
19116 [(set_attr "type" "bitmanip")
19117 (set_attr "btver2_decode" "direct, double")
19118 (set_attr "mode" "<MODE>")])
19120 (define_insn "*bmi_blsi_<mode>"
19121 [(set (match_operand:SWI48 0 "register_operand" "=r")
19124 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
19126 (clobber (reg:CC FLAGS_REG))]
19128 "blsi\t{%1, %0|%0, %1}"
19129 [(set_attr "type" "bitmanip")
19130 (set_attr "btver2_decode" "double")
19131 (set_attr "mode" "<MODE>")])
19133 (define_insn "*bmi_blsi_<mode>_cmp"
19134 [(set (reg FLAGS_REG)
19137 (neg:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
19140 (set (match_operand:SWI48 0 "register_operand" "=r")
19141 (and:SWI48 (neg:SWI48 (match_dup 1)) (match_dup 1)))]
19142 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
19143 "blsi\t{%1, %0|%0, %1}"
19144 [(set_attr "type" "bitmanip")
19145 (set_attr "btver2_decode" "double")
19146 (set_attr "mode" "<MODE>")])
19148 (define_insn "*bmi_blsi_<mode>_ccno"
19149 [(set (reg FLAGS_REG)
19152 (neg:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
19155 (clobber (match_scratch:SWI48 0 "=r"))]
19156 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
19157 "blsi\t{%1, %0|%0, %1}"
19158 [(set_attr "type" "bitmanip")
19159 (set_attr "btver2_decode" "double")
19160 (set_attr "mode" "<MODE>")])
19162 (define_insn "*bmi_blsmsk_<mode>"
19163 [(set (match_operand:SWI48 0 "register_operand" "=r")
19166 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19169 (clobber (reg:CC FLAGS_REG))]
19171 "blsmsk\t{%1, %0|%0, %1}"
19172 [(set_attr "type" "bitmanip")
19173 (set_attr "btver2_decode" "double")
19174 (set_attr "mode" "<MODE>")])
19176 (define_insn "*bmi_blsr_<mode>"
19177 [(set (match_operand:SWI48 0 "register_operand" "=r")
19180 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19183 (clobber (reg:CC FLAGS_REG))]
19185 "blsr\t{%1, %0|%0, %1}"
19186 [(set_attr "type" "bitmanip")
19187 (set_attr "btver2_decode" "double")
19188 (set_attr "mode" "<MODE>")])
19190 (define_insn "*bmi_blsr_<mode>_cmp"
19191 [(set (reg:CCZ FLAGS_REG)
19195 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19199 (set (match_operand:SWI48 0 "register_operand" "=r")
19206 "blsr\t{%1, %0|%0, %1}"
19207 [(set_attr "type" "bitmanip")
19208 (set_attr "btver2_decode" "double")
19209 (set_attr "mode" "<MODE>")])
19211 (define_insn "*bmi_blsr_<mode>_ccz"
19212 [(set (reg:CCZ FLAGS_REG)
19216 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19220 (clobber (match_scratch:SWI48 0 "=r"))]
19222 "blsr\t{%1, %0|%0, %1}"
19223 [(set_attr "type" "bitmanip")
19224 (set_attr "btver2_decode" "double")
19225 (set_attr "mode" "<MODE>")])
19227 ;; BMI2 instructions.
19228 (define_expand "bmi2_bzhi_<mode>3"
19230 [(set (match_operand:SWI48 0 "register_operand")
19231 (if_then_else:SWI48
19232 (ne:QI (match_operand:QI 2 "register_operand")
19234 (zero_extract:SWI48
19235 (match_operand:SWI48 1 "nonimmediate_operand")
19236 (umin:QI (match_dup 2) (match_dup 3))
19239 (clobber (reg:CC FLAGS_REG))])]
19242 operands[2] = gen_lowpart (QImode, operands[2]);
19243 operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
19246 (define_insn "*bmi2_bzhi_<mode>3"
19247 [(set (match_operand:SWI48 0 "register_operand" "=r")
19248 (if_then_else:SWI48
19249 (ne:QI (match_operand:QI 2 "register_operand" "q")
19251 (zero_extract:SWI48
19252 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19253 (umin:QI (match_dup 2)
19254 (match_operand:QI 3 "const_int_operand"))
19257 (clobber (reg:CC FLAGS_REG))]
19258 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
19259 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
19260 [(set_attr "type" "bitmanip")
19261 (set_attr "prefix" "vex")
19262 (set_attr "mode" "<MODE>")])
19264 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
19265 [(set (reg:CCZ FLAGS_REG)
19267 (if_then_else:SWI48
19268 (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0))
19269 (zero_extract:SWI48
19270 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19271 (umin:QI (match_dup 2)
19272 (match_operand:QI 3 "const_int_operand"))
19276 (clobber (match_scratch:SWI48 0 "=r"))]
19277 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
19278 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
19279 [(set_attr "type" "bitmanip")
19280 (set_attr "prefix" "vex")
19281 (set_attr "mode" "<MODE>")])
19283 (define_insn "*bmi2_bzhi_<mode>3_2"
19284 [(set (match_operand:SWI48 0 "register_operand" "=r")
19287 (ashift:SWI48 (const_int 1)
19288 (match_operand:QI 2 "register_operand" "r"))
19290 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
19291 (clobber (reg:CC FLAGS_REG))]
19293 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
19294 [(set_attr "type" "bitmanip")
19295 (set_attr "prefix" "vex")
19296 (set_attr "mode" "<MODE>")])
19298 (define_insn "*bmi2_bzhi_<mode>3_3"
19299 [(set (match_operand:SWI48 0 "register_operand" "=r")
19302 (ashift:SWI48 (const_int -1)
19303 (match_operand:QI 2 "register_operand" "r")))
19304 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
19305 (clobber (reg:CC FLAGS_REG))]
19307 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
19308 [(set_attr "type" "bitmanip")
19309 (set_attr "prefix" "vex")
19310 (set_attr "mode" "<MODE>")])
19312 (define_insn "*bmi2_bzhi_zero_extendsidi_4"
19313 [(set (match_operand:DI 0 "register_operand" "=r")
19317 (ashift:SI (const_int 1)
19318 (match_operand:QI 2 "register_operand" "r"))
19320 (match_operand:SI 1 "nonimmediate_operand" "rm"))))
19321 (clobber (reg:CC FLAGS_REG))]
19322 "TARGET_64BIT && TARGET_BMI2"
19323 "bzhi\t{%q2, %q1, %q0|%q0, %q1, %q2}"
19324 [(set_attr "type" "bitmanip")
19325 (set_attr "prefix" "vex")
19326 (set_attr "mode" "DI")])
19328 (define_insn "*bmi2_bzhi_zero_extendsidi_5"
19329 [(set (match_operand:DI 0 "register_operand" "=r")
19333 (ashift:SI (const_int 1)
19334 (match_operand:QI 2 "register_operand" "r"))
19336 (match_operand:DI 1 "nonimmediate_operand" "rm")))
19337 (clobber (reg:CC FLAGS_REG))]
19338 "TARGET_64BIT && TARGET_BMI2"
19339 "bzhi\t{%q2, %q1, %q0|%q0, %q1, %q2}"
19340 [(set_attr "type" "bitmanip")
19341 (set_attr "prefix" "vex")
19342 (set_attr "mode" "DI")])
19344 (define_insn "bmi2_pdep_<mode>3"
19345 [(set (match_operand:SWI48 0 "register_operand" "=r")
19346 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
19347 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
19350 "pdep\t{%2, %1, %0|%0, %1, %2}"
19351 [(set_attr "type" "bitmanip")
19352 (set_attr "prefix" "vex")
19353 (set_attr "mode" "<MODE>")])
19355 (define_insn "bmi2_pext_<mode>3"
19356 [(set (match_operand:SWI48 0 "register_operand" "=r")
19357 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
19358 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
19361 "pext\t{%2, %1, %0|%0, %1, %2}"
19362 [(set_attr "type" "bitmanip")
19363 (set_attr "prefix" "vex")
19364 (set_attr "mode" "<MODE>")])
19366 ;; TBM instructions.
19367 (define_insn "@tbm_bextri_<mode>"
19368 [(set (match_operand:SWI48 0 "register_operand" "=r")
19369 (zero_extract:SWI48
19370 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19371 (match_operand:QI 2 "const_0_to_255_operand")
19372 (match_operand:QI 3 "const_0_to_255_operand")))
19373 (clobber (reg:CC FLAGS_REG))]
19376 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
19377 return "bextr\t{%2, %1, %0|%0, %1, %2}";
19379 [(set_attr "type" "bitmanip")
19380 (set_attr "mode" "<MODE>")])
19382 (define_insn "*tbm_blcfill_<mode>"
19383 [(set (match_operand:SWI48 0 "register_operand" "=r")
19386 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19389 (clobber (reg:CC FLAGS_REG))]
19391 "blcfill\t{%1, %0|%0, %1}"
19392 [(set_attr "type" "bitmanip")
19393 (set_attr "mode" "<MODE>")])
19395 (define_insn "*tbm_blci_<mode>"
19396 [(set (match_operand:SWI48 0 "register_operand" "=r")
19400 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19403 (clobber (reg:CC FLAGS_REG))]
19405 "blci\t{%1, %0|%0, %1}"
19406 [(set_attr "type" "bitmanip")
19407 (set_attr "mode" "<MODE>")])
19409 (define_insn "*tbm_blcic_<mode>"
19410 [(set (match_operand:SWI48 0 "register_operand" "=r")
19413 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19417 (clobber (reg:CC FLAGS_REG))]
19419 "blcic\t{%1, %0|%0, %1}"
19420 [(set_attr "type" "bitmanip")
19421 (set_attr "mode" "<MODE>")])
19423 (define_insn "*tbm_blcmsk_<mode>"
19424 [(set (match_operand:SWI48 0 "register_operand" "=r")
19427 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19430 (clobber (reg:CC FLAGS_REG))]
19432 "blcmsk\t{%1, %0|%0, %1}"
19433 [(set_attr "type" "bitmanip")
19434 (set_attr "mode" "<MODE>")])
19436 (define_insn "*tbm_blcs_<mode>"
19437 [(set (match_operand:SWI48 0 "register_operand" "=r")
19440 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19443 (clobber (reg:CC FLAGS_REG))]
19445 "blcs\t{%1, %0|%0, %1}"
19446 [(set_attr "type" "bitmanip")
19447 (set_attr "mode" "<MODE>")])
19449 (define_insn "*tbm_blsfill_<mode>"
19450 [(set (match_operand:SWI48 0 "register_operand" "=r")
19453 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19456 (clobber (reg:CC FLAGS_REG))]
19458 "blsfill\t{%1, %0|%0, %1}"
19459 [(set_attr "type" "bitmanip")
19460 (set_attr "mode" "<MODE>")])
19462 (define_insn "*tbm_blsic_<mode>"
19463 [(set (match_operand:SWI48 0 "register_operand" "=r")
19466 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19470 (clobber (reg:CC FLAGS_REG))]
19472 "blsic\t{%1, %0|%0, %1}"
19473 [(set_attr "type" "bitmanip")
19474 (set_attr "mode" "<MODE>")])
19476 (define_insn "*tbm_t1mskc_<mode>"
19477 [(set (match_operand:SWI48 0 "register_operand" "=r")
19480 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19484 (clobber (reg:CC FLAGS_REG))]
19486 "t1mskc\t{%1, %0|%0, %1}"
19487 [(set_attr "type" "bitmanip")
19488 (set_attr "mode" "<MODE>")])
19490 (define_insn "*tbm_tzmsk_<mode>"
19491 [(set (match_operand:SWI48 0 "register_operand" "=r")
19494 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19498 (clobber (reg:CC FLAGS_REG))]
19500 "tzmsk\t{%1, %0|%0, %1}"
19501 [(set_attr "type" "bitmanip")
19502 (set_attr "mode" "<MODE>")])
19504 (define_insn_and_split "popcount<mode>2"
19505 [(set (match_operand:SWI48 0 "register_operand" "=r")
19507 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
19508 (clobber (reg:CC FLAGS_REG))]
19512 return "popcnt\t{%1, %0|%0, %1}";
19514 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
19517 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
19518 && optimize_function_for_speed_p (cfun)
19519 && !reg_mentioned_p (operands[0], operands[1])"
19521 [(set (match_dup 0)
19522 (popcount:SWI48 (match_dup 1)))
19523 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
19524 (clobber (reg:CC FLAGS_REG))])]
19525 "ix86_expand_clear (operands[0]);"
19526 [(set_attr "prefix_rep" "1")
19527 (set_attr "type" "bitmanip")
19528 (set_attr "mode" "<MODE>")])
19530 ; False dependency happens when destination is only updated by tzcnt,
19531 ; lzcnt or popcnt. There is no false dependency when destination is
19532 ; also used in source.
19533 (define_insn "*popcount<mode>2_falsedep"
19534 [(set (match_operand:SWI48 0 "register_operand" "=r")
19536 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
19537 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
19538 UNSPEC_INSN_FALSE_DEP)
19539 (clobber (reg:CC FLAGS_REG))]
19543 return "popcnt\t{%1, %0|%0, %1}";
19545 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
19548 [(set_attr "prefix_rep" "1")
19549 (set_attr "type" "bitmanip")
19550 (set_attr "mode" "<MODE>")])
19552 (define_insn_and_split "*popcountsi2_zext"
19553 [(set (match_operand:DI 0 "register_operand" "=r")
19557 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
19559 (clobber (reg:CC FLAGS_REG))]
19560 "TARGET_POPCNT && TARGET_64BIT"
19563 return "popcnt\t{%1, %k0|%k0, %1}";
19565 return "popcnt{l}\t{%1, %k0|%k0, %1}";
19568 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
19569 && optimize_function_for_speed_p (cfun)
19570 && !reg_mentioned_p (operands[0], operands[1])"
19572 [(set (match_dup 0)
19573 (and:DI (subreg:DI (popcount:SI (match_dup 1)) 0) (const_int 63)))
19574 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
19575 (clobber (reg:CC FLAGS_REG))])]
19576 "ix86_expand_clear (operands[0]);"
19577 [(set_attr "prefix_rep" "1")
19578 (set_attr "type" "bitmanip")
19579 (set_attr "mode" "SI")])
19581 ; False dependency happens when destination is only updated by tzcnt,
19582 ; lzcnt or popcnt. There is no false dependency when destination is
19583 ; also used in source.
19584 (define_insn "*popcountsi2_zext_falsedep"
19585 [(set (match_operand:DI 0 "register_operand" "=r")
19589 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
19591 (unspec [(match_operand:DI 2 "register_operand" "0")]
19592 UNSPEC_INSN_FALSE_DEP)
19593 (clobber (reg:CC FLAGS_REG))]
19594 "TARGET_POPCNT && TARGET_64BIT"
19597 return "popcnt\t{%1, %k0|%k0, %1}";
19599 return "popcnt{l}\t{%1, %k0|%k0, %1}";
19602 [(set_attr "prefix_rep" "1")
19603 (set_attr "type" "bitmanip")
19604 (set_attr "mode" "SI")])
19606 (define_insn_and_split "*popcountsi2_zext_2"
19607 [(set (match_operand:DI 0 "register_operand" "=r")
19609 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
19610 (clobber (reg:CC FLAGS_REG))]
19611 "TARGET_POPCNT && TARGET_64BIT"
19614 return "popcnt\t{%1, %k0|%k0, %1}";
19616 return "popcnt{l}\t{%1, %k0|%k0, %1}";
19619 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
19620 && optimize_function_for_speed_p (cfun)
19621 && !reg_mentioned_p (operands[0], operands[1])"
19623 [(set (match_dup 0)
19624 (zero_extend:DI (popcount:SI (match_dup 1))))
19625 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
19626 (clobber (reg:CC FLAGS_REG))])]
19627 "ix86_expand_clear (operands[0]);"
19628 [(set_attr "prefix_rep" "1")
19629 (set_attr "type" "bitmanip")
19630 (set_attr "mode" "SI")])
19632 ; False dependency happens when destination is only updated by tzcnt,
19633 ; lzcnt or popcnt. There is no false dependency when destination is
19634 ; also used in source.
19635 (define_insn "*popcountsi2_zext_2_falsedep"
19636 [(set (match_operand:DI 0 "register_operand" "=r")
19638 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
19639 (unspec [(match_operand:DI 2 "register_operand" "0")]
19640 UNSPEC_INSN_FALSE_DEP)
19641 (clobber (reg:CC FLAGS_REG))]
19642 "TARGET_POPCNT && TARGET_64BIT"
19645 return "popcnt\t{%1, %k0|%k0, %1}";
19647 return "popcnt{l}\t{%1, %k0|%k0, %1}";
19650 [(set_attr "prefix_rep" "1")
19651 (set_attr "type" "bitmanip")
19652 (set_attr "mode" "SI")])
19654 (define_insn_and_split "*popcounthi2_1"
19655 [(set (match_operand:SI 0 "register_operand")
19657 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
19658 (clobber (reg:CC FLAGS_REG))]
19660 && ix86_pre_reload_split ()"
19665 rtx tmp = gen_reg_rtx (HImode);
19667 emit_insn (gen_popcounthi2 (tmp, operands[1]));
19668 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
19672 (define_insn_and_split "*popcounthi2_2"
19673 [(set (match_operand:SI 0 "register_operand")
19675 (popcount:HI (match_operand:HI 1 "nonimmediate_operand"))))
19676 (clobber (reg:CC FLAGS_REG))]
19678 && ix86_pre_reload_split ()"
19683 rtx tmp = gen_reg_rtx (HImode);
19685 emit_insn (gen_popcounthi2 (tmp, operands[1]));
19686 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
19690 (define_insn "popcounthi2"
19691 [(set (match_operand:HI 0 "register_operand" "=r")
19693 (match_operand:HI 1 "nonimmediate_operand" "rm")))
19694 (clobber (reg:CC FLAGS_REG))]
19698 return "popcnt\t{%1, %0|%0, %1}";
19700 return "popcnt{w}\t{%1, %0|%0, %1}";
19703 [(set_attr "prefix_rep" "1")
19704 (set_attr "type" "bitmanip")
19705 (set_attr "mode" "HI")])
19707 (define_expand "bswapdi2"
19708 [(set (match_operand:DI 0 "register_operand")
19709 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
19713 operands[1] = force_reg (DImode, operands[1]);
19716 (define_expand "bswapsi2"
19717 [(set (match_operand:SI 0 "register_operand")
19718 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
19723 else if (TARGET_BSWAP)
19724 operands[1] = force_reg (SImode, operands[1]);
19727 rtx x = operands[0];
19729 emit_move_insn (x, operands[1]);
19730 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
19731 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
19732 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
19737 (define_insn "*bswap<mode>2_movbe"
19738 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
19739 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
19741 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
19744 movbe{<imodesuffix>}\t{%1, %0|%0, %1}
19745 movbe{<imodesuffix>}\t{%1, %0|%0, %1}"
19746 [(set_attr "type" "bitmanip,imov,imov")
19747 (set_attr "modrm" "0,1,1")
19748 (set_attr "prefix_0f" "*,1,1")
19749 (set_attr "prefix_extra" "*,1,1")
19750 (set_attr "mode" "<MODE>")])
19752 (define_insn "*bswap<mode>2"
19753 [(set (match_operand:SWI48 0 "register_operand" "=r")
19754 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
19757 [(set_attr "type" "bitmanip")
19758 (set_attr "modrm" "0")
19759 (set_attr "mode" "<MODE>")])
19761 (define_expand "bswaphi2"
19762 [(set (match_operand:HI 0 "register_operand")
19763 (bswap:HI (match_operand:HI 1 "nonimmediate_operand")))]
19766 (define_insn "*bswaphi2_movbe"
19767 [(set (match_operand:HI 0 "nonimmediate_operand" "=Q,r,m")
19768 (bswap:HI (match_operand:HI 1 "nonimmediate_operand" "0,m,r")))]
19770 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
19772 xchg{b}\t{%h0, %b0|%b0, %h0}
19773 movbe{w}\t{%1, %0|%0, %1}
19774 movbe{w}\t{%1, %0|%0, %1}"
19775 [(set_attr "type" "imov")
19776 (set_attr "modrm" "*,1,1")
19777 (set_attr "prefix_0f" "*,1,1")
19778 (set_attr "prefix_extra" "*,1,1")
19779 (set_attr "pent_pair" "np,*,*")
19780 (set_attr "athlon_decode" "vector,*,*")
19781 (set_attr "amdfam10_decode" "double,*,*")
19782 (set_attr "bdver1_decode" "double,*,*")
19783 (set_attr "mode" "QI,HI,HI")])
19786 [(set (match_operand:HI 0 "general_reg_operand")
19787 (bswap:HI (match_dup 0)))]
19789 && !(TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))
19790 && peep2_regno_dead_p (0, FLAGS_REG)"
19791 [(parallel [(set (match_dup 0) (rotate:HI (match_dup 0) (const_int 8)))
19792 (clobber (reg:CC FLAGS_REG))])])
19794 (define_insn "bswaphi_lowpart"
19795 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
19796 (bswap:HI (match_dup 0)))
19797 (clobber (reg:CC FLAGS_REG))]
19800 xchg{b}\t{%h0, %b0|%b0, %h0}
19801 rol{w}\t{$8, %0|%0, 8}"
19802 [(set (attr "preferred_for_size")
19803 (cond [(eq_attr "alternative" "0")
19804 (symbol_ref "true")]
19805 (symbol_ref "false")))
19806 (set (attr "preferred_for_speed")
19807 (cond [(eq_attr "alternative" "0")
19808 (symbol_ref "TARGET_USE_XCHGB")]
19809 (symbol_ref "!TARGET_USE_XCHGB")))
19810 (set_attr "length" "2,4")
19811 (set_attr "mode" "QI,HI")])
19813 (define_expand "paritydi2"
19814 [(set (match_operand:DI 0 "register_operand")
19815 (parity:DI (match_operand:DI 1 "register_operand")))]
19818 rtx scratch = gen_reg_rtx (QImode);
19819 rtx hipart1 = gen_reg_rtx (SImode);
19820 rtx lopart1 = gen_reg_rtx (SImode);
19821 rtx xor1 = gen_reg_rtx (SImode);
19822 rtx shift2 = gen_reg_rtx (SImode);
19823 rtx hipart2 = gen_reg_rtx (HImode);
19824 rtx lopart2 = gen_reg_rtx (HImode);
19825 rtx xor2 = gen_reg_rtx (HImode);
19829 rtx shift1 = gen_reg_rtx (DImode);
19830 emit_insn (gen_lshrdi3 (shift1, operands[1], GEN_INT (32)));
19831 emit_move_insn (hipart1, gen_lowpart (SImode, shift1));
19834 emit_move_insn (hipart1, gen_highpart (SImode, operands[1]));
19836 emit_move_insn (lopart1, gen_lowpart (SImode, operands[1]));
19837 emit_insn (gen_xorsi3 (xor1, hipart1, lopart1));
19839 emit_insn (gen_lshrsi3 (shift2, xor1, GEN_INT (16)));
19840 emit_move_insn (hipart2, gen_lowpart (HImode, shift2));
19841 emit_move_insn (lopart2, gen_lowpart (HImode, xor1));
19842 emit_insn (gen_xorhi3 (xor2, hipart2, lopart2));
19844 emit_insn (gen_parityhi2_cmp (xor2));
19846 ix86_expand_setcc (scratch, ORDERED,
19847 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19850 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
19853 rtx tmp = gen_reg_rtx (SImode);
19855 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
19856 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
19861 (define_expand "paritysi2"
19862 [(set (match_operand:SI 0 "register_operand")
19863 (parity:SI (match_operand:SI 1 "register_operand")))]
19866 rtx scratch = gen_reg_rtx (QImode);
19867 rtx shift = gen_reg_rtx (SImode);
19868 rtx hipart = gen_reg_rtx (HImode);
19869 rtx lopart = gen_reg_rtx (HImode);
19870 rtx tmp = gen_reg_rtx (HImode);
19872 emit_insn (gen_lshrsi3 (shift, operands[1], GEN_INT (16)));
19873 emit_move_insn (hipart, gen_lowpart (HImode, shift));
19874 emit_move_insn (lopart, gen_lowpart (HImode, operands[1]));
19875 emit_insn (gen_xorhi3 (tmp, hipart, lopart));
19877 emit_insn (gen_parityhi2_cmp (tmp));
19879 ix86_expand_setcc (scratch, ORDERED,
19880 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19882 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
19886 (define_expand "parityhi2"
19887 [(set (match_operand:HI 0 "register_operand")
19888 (parity:HI (match_operand:HI 1 "register_operand")))]
19891 rtx scratch = gen_reg_rtx (QImode);
19893 emit_insn (gen_parityhi2_cmp (operands[1]));
19895 ix86_expand_setcc (scratch, ORDERED,
19896 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19898 emit_insn (gen_zero_extendqihi2 (operands[0], scratch));
19902 (define_expand "parityqi2"
19903 [(set (match_operand:QI 0 "register_operand")
19904 (parity:QI (match_operand:QI 1 "register_operand")))]
19907 emit_insn (gen_parityqi2_cmp (operands[1]));
19909 ix86_expand_setcc (operands[0], ORDERED,
19910 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19914 (define_insn "parityhi2_cmp"
19915 [(set (reg:CC FLAGS_REG)
19916 (unspec:CC [(match_operand:HI 0 "register_operand" "+Q")]
19918 (clobber (match_dup 0))]
19920 "xor{b}\t{%h0, %b0|%b0, %h0}"
19921 [(set_attr "length" "2")
19922 (set_attr "mode" "QI")])
19924 (define_insn "parityqi2_cmp"
19925 [(set (reg:CC FLAGS_REG)
19926 (unspec:CC [(match_operand:QI 0 "register_operand" "q")]
19930 [(set_attr "mode" "QI")])
19932 ;; Replace zero_extend:HI followed by parityhi2_cmp with parityqi2_cmp
19934 [(set (match_operand:HI 0 "register_operand")
19935 (zero_extend:HI (match_operand:QI 1 "general_reg_operand")))
19936 (parallel [(set (reg:CC FLAGS_REG)
19937 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
19938 (clobber (match_dup 0))])]
19940 [(set (reg:CC FLAGS_REG)
19941 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))])
19943 ;; Eliminate QImode popcount&1 using parity flag
19945 [(set (match_operand:SI 0 "register_operand")
19946 (zero_extend:SI (match_operand:QI 1 "general_reg_operand")))
19947 (parallel [(set (match_operand:SI 2 "register_operand")
19948 (popcount:SI (match_dup 0)))
19949 (clobber (reg:CC FLAGS_REG))])
19950 (set (reg:CCZ FLAGS_REG)
19951 (compare:CCZ (and:QI (match_operand:QI 3 "register_operand")
19954 (set (pc) (if_then_else (match_operator 4 "bt_comparison_operator"
19955 [(reg:CCZ FLAGS_REG)
19957 (label_ref (match_operand 5))
19959 "REGNO (operands[2]) == REGNO (operands[3])
19960 && peep2_reg_dead_p (3, operands[0])
19961 && peep2_reg_dead_p (3, operands[2])
19962 && peep2_regno_dead_p (4, FLAGS_REG)"
19963 [(set (reg:CC FLAGS_REG)
19964 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
19965 (set (pc) (if_then_else (match_op_dup 4 [(reg:CC FLAGS_REG)
19967 (label_ref (match_dup 5))
19970 operands[4] = shallow_copy_rtx (operands[4]);
19971 PUT_CODE (operands[4], GET_CODE (operands[4]) == EQ ? UNORDERED : ORDERED);
19974 ;; Eliminate HImode popcount&1 using parity flag
19976 [(match_scratch:HI 0 "Q")
19977 (parallel [(set (match_operand:HI 1 "register_operand")
19979 (match_operand:HI 2 "nonimmediate_operand")))
19980 (clobber (reg:CC FLAGS_REG))])
19981 (set (match_operand 3 "register_operand")
19982 (zero_extend (match_dup 1)))
19983 (set (reg:CCZ FLAGS_REG)
19984 (compare:CCZ (and:QI (match_operand:QI 4 "register_operand")
19987 (set (pc) (if_then_else (match_operator 5 "bt_comparison_operator"
19988 [(reg:CCZ FLAGS_REG)
19990 (label_ref (match_operand 6))
19992 "REGNO (operands[3]) == REGNO (operands[4])
19993 && peep2_reg_dead_p (3, operands[1])
19994 && peep2_reg_dead_p (3, operands[3])
19995 && peep2_regno_dead_p (4, FLAGS_REG)"
19996 [(set (match_dup 0) (match_dup 2))
19997 (parallel [(set (reg:CC FLAGS_REG)
19998 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
19999 (clobber (match_dup 0))])
20000 (set (pc) (if_then_else (match_op_dup 5 [(reg:CC FLAGS_REG)
20002 (label_ref (match_dup 6))
20005 operands[5] = shallow_copy_rtx (operands[5]);
20006 PUT_CODE (operands[5], GET_CODE (operands[5]) == EQ ? UNORDERED : ORDERED);
20009 ;; Eliminate HImode popcount&1 using parity flag (variant 2)
20011 [(match_scratch:HI 0 "Q")
20012 (parallel [(set (match_operand:HI 1 "register_operand")
20014 (match_operand:HI 2 "nonimmediate_operand")))
20015 (clobber (reg:CC FLAGS_REG))])
20016 (set (reg:CCZ FLAGS_REG)
20017 (compare:CCZ (and:QI (match_operand:QI 3 "register_operand")
20020 (set (pc) (if_then_else (match_operator 4 "bt_comparison_operator"
20021 [(reg:CCZ FLAGS_REG)
20023 (label_ref (match_operand 5))
20025 "REGNO (operands[1]) == REGNO (operands[3])
20026 && peep2_reg_dead_p (2, operands[1])
20027 && peep2_reg_dead_p (2, operands[3])
20028 && peep2_regno_dead_p (3, FLAGS_REG)"
20029 [(set (match_dup 0) (match_dup 2))
20030 (parallel [(set (reg:CC FLAGS_REG)
20031 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
20032 (clobber (match_dup 0))])
20033 (set (pc) (if_then_else (match_op_dup 4 [(reg:CC FLAGS_REG)
20035 (label_ref (match_dup 5))
20038 operands[4] = shallow_copy_rtx (operands[4]);
20039 PUT_CODE (operands[4], GET_CODE (operands[4]) == EQ ? UNORDERED : ORDERED);
20043 ;; Thread-local storage patterns for ELF.
20045 ;; Note that these code sequences must appear exactly as shown
20046 ;; in order to allow linker relaxation.
20048 (define_insn "*tls_global_dynamic_32_gnu"
20049 [(set (match_operand:SI 0 "register_operand" "=a")
20051 [(match_operand:SI 1 "register_operand" "Yb")
20052 (match_operand 2 "tls_symbolic_operand")
20053 (match_operand 3 "constant_call_address_operand" "Bz")
20056 (clobber (match_scratch:SI 4 "=d"))
20057 (clobber (match_scratch:SI 5 "=c"))
20058 (clobber (reg:CC FLAGS_REG))]
20059 "!TARGET_64BIT && TARGET_GNU_TLS"
20061 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
20063 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
20066 ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
20067 if (TARGET_SUN_TLS)
20068 #ifdef HAVE_AS_IX86_TLSGDPLT
20069 return "call\t%a2@tlsgdplt";
20071 return "call\t%p3@plt";
20073 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
20074 return "call\t%P3";
20075 return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
20077 [(set_attr "type" "multi")
20078 (set_attr "length" "12")])
20080 (define_expand "tls_global_dynamic_32"
20082 [(set (match_operand:SI 0 "register_operand")
20083 (unspec:SI [(match_operand:SI 2 "register_operand")
20084 (match_operand 1 "tls_symbolic_operand")
20085 (match_operand 3 "constant_call_address_operand")
20088 (clobber (scratch:SI))
20089 (clobber (scratch:SI))
20090 (clobber (reg:CC FLAGS_REG))])]
20092 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
20094 (define_insn "*tls_global_dynamic_64_<mode>"
20095 [(set (match_operand:P 0 "register_operand" "=a")
20097 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
20098 (match_operand 3)))
20099 (unspec:P [(match_operand 1 "tls_symbolic_operand")
20105 /* The .loc directive has effect for 'the immediately following assembly
20106 instruction'. So for a sequence:
20110 the 'immediately following assembly instruction' is insn1.
20111 We want to emit an insn prefix here, but if we use .byte (as shown in
20112 'ELF Handling For Thread-Local Storage'), a preceding .loc will point
20113 inside the insn sequence, rather than to the start. After relaxation
20114 of the sequence by the linker, the .loc might point inside an insn.
20115 Use data16 prefix instead, which doesn't have this problem. */
20116 fputs ("\tdata16", asm_out_file);
20118 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
20119 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
20120 fputs (ASM_SHORT "0x6666\n", asm_out_file);
20122 fputs (ASM_BYTE "0x66\n", asm_out_file);
20123 fputs ("\trex64\n", asm_out_file);
20124 if (TARGET_SUN_TLS)
20125 return "call\t%p2@plt";
20126 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
20127 return "call\t%P2";
20128 return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
20130 [(set_attr "type" "multi")
20131 (set (attr "length")
20132 (symbol_ref "TARGET_X32 ? 15 : 16"))])
20134 (define_insn "*tls_global_dynamic_64_largepic"
20135 [(set (match_operand:DI 0 "register_operand" "=a")
20137 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
20138 (match_operand:DI 3 "immediate_operand" "i")))
20139 (match_operand 4)))
20140 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
20143 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
20144 && GET_CODE (operands[3]) == CONST
20145 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
20146 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
20149 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
20150 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
20151 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
20152 return "call\t{*%%rax|rax}";
20154 [(set_attr "type" "multi")
20155 (set_attr "length" "22")])
20157 (define_expand "@tls_global_dynamic_64_<mode>"
20159 [(set (match_operand:P 0 "register_operand")
20161 (mem:QI (match_operand 2))
20163 (unspec:P [(match_operand 1 "tls_symbolic_operand")
20167 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
20169 (define_insn "*tls_local_dynamic_base_32_gnu"
20170 [(set (match_operand:SI 0 "register_operand" "=a")
20172 [(match_operand:SI 1 "register_operand" "Yb")
20173 (match_operand 2 "constant_call_address_operand" "Bz")
20175 UNSPEC_TLS_LD_BASE))
20176 (clobber (match_scratch:SI 3 "=d"))
20177 (clobber (match_scratch:SI 4 "=c"))
20178 (clobber (reg:CC FLAGS_REG))]
20179 "!TARGET_64BIT && TARGET_GNU_TLS"
20182 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
20183 if (TARGET_SUN_TLS)
20185 if (HAVE_AS_IX86_TLSLDMPLT)
20186 return "call\t%&@tlsldmplt";
20188 return "call\t%p2@plt";
20190 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
20191 return "call\t%P2";
20192 return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
20194 [(set_attr "type" "multi")
20195 (set_attr "length" "11")])
20197 (define_expand "tls_local_dynamic_base_32"
20199 [(set (match_operand:SI 0 "register_operand")
20201 [(match_operand:SI 1 "register_operand")
20202 (match_operand 2 "constant_call_address_operand")
20204 UNSPEC_TLS_LD_BASE))
20205 (clobber (scratch:SI))
20206 (clobber (scratch:SI))
20207 (clobber (reg:CC FLAGS_REG))])]
20209 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
20211 (define_insn "*tls_local_dynamic_base_64_<mode>"
20212 [(set (match_operand:P 0 "register_operand" "=a")
20214 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
20215 (match_operand 2)))
20216 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
20220 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
20221 if (TARGET_SUN_TLS)
20222 return "call\t%p1@plt";
20223 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
20224 return "call\t%P1";
20225 return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
20227 [(set_attr "type" "multi")
20228 (set_attr "length" "12")])
20230 (define_insn "*tls_local_dynamic_base_64_largepic"
20231 [(set (match_operand:DI 0 "register_operand" "=a")
20233 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
20234 (match_operand:DI 2 "immediate_operand" "i")))
20235 (match_operand 3)))
20236 (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
20237 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
20238 && GET_CODE (operands[2]) == CONST
20239 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
20240 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
20243 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
20244 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
20245 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
20246 return "call\t{*%%rax|rax}";
20248 [(set_attr "type" "multi")
20249 (set_attr "length" "22")])
20251 (define_expand "@tls_local_dynamic_base_64_<mode>"
20253 [(set (match_operand:P 0 "register_operand")
20255 (mem:QI (match_operand 1))
20257 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
20259 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
20261 ;; Local dynamic of a single variable is a lose. Show combine how
20262 ;; to convert that back to global dynamic.
20264 (define_insn_and_split "*tls_local_dynamic_32_once"
20265 [(set (match_operand:SI 0 "register_operand" "=a")
20267 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
20268 (match_operand 2 "constant_call_address_operand" "Bz")
20270 UNSPEC_TLS_LD_BASE)
20271 (const:SI (unspec:SI
20272 [(match_operand 3 "tls_symbolic_operand")]
20274 (clobber (match_scratch:SI 4 "=d"))
20275 (clobber (match_scratch:SI 5 "=c"))
20276 (clobber (reg:CC FLAGS_REG))]
20281 [(set (match_dup 0)
20282 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
20285 (clobber (match_dup 4))
20286 (clobber (match_dup 5))
20287 (clobber (reg:CC FLAGS_REG))])])
20289 ;; Load and add the thread base pointer from %<tp_seg>:0.
20290 (define_expand "get_thread_pointer<mode>"
20291 [(set (match_operand:PTR 0 "register_operand")
20292 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
20295 /* targetm is not visible in the scope of the condition. */
20296 if (!targetm.have_tls)
20297 error ("%<__builtin_thread_pointer%> is not supported on this target");
20300 (define_insn_and_split "*load_tp_<mode>"
20301 [(set (match_operand:PTR 0 "register_operand" "=r")
20302 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
20306 [(set (match_dup 0)
20309 addr_space_t as = DEFAULT_TLS_SEG_REG;
20311 operands[1] = gen_const_mem (<MODE>mode, const0_rtx);
20312 set_mem_addr_space (operands[1], as);
20315 (define_insn_and_split "*load_tp_x32_zext"
20316 [(set (match_operand:DI 0 "register_operand" "=r")
20318 (unspec:SI [(const_int 0)] UNSPEC_TP)))]
20322 [(set (match_dup 0)
20323 (zero_extend:DI (match_dup 1)))]
20325 addr_space_t as = DEFAULT_TLS_SEG_REG;
20327 operands[1] = gen_const_mem (SImode, const0_rtx);
20328 set_mem_addr_space (operands[1], as);
20331 (define_insn_and_split "*add_tp_<mode>"
20332 [(set (match_operand:PTR 0 "register_operand" "=r")
20334 (unspec:PTR [(const_int 0)] UNSPEC_TP)
20335 (match_operand:PTR 1 "register_operand" "0")))
20336 (clobber (reg:CC FLAGS_REG))]
20341 [(set (match_dup 0)
20342 (plus:PTR (match_dup 1) (match_dup 2)))
20343 (clobber (reg:CC FLAGS_REG))])]
20345 addr_space_t as = DEFAULT_TLS_SEG_REG;
20347 operands[2] = gen_const_mem (<MODE>mode, const0_rtx);
20348 set_mem_addr_space (operands[2], as);
20351 (define_insn_and_split "*add_tp_x32_zext"
20352 [(set (match_operand:DI 0 "register_operand" "=r")
20354 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
20355 (match_operand:SI 1 "register_operand" "0"))))
20356 (clobber (reg:CC FLAGS_REG))]
20361 [(set (match_dup 0)
20363 (plus:SI (match_dup 1) (match_dup 2))))
20364 (clobber (reg:CC FLAGS_REG))])]
20366 addr_space_t as = DEFAULT_TLS_SEG_REG;
20368 operands[2] = gen_const_mem (SImode, const0_rtx);
20369 set_mem_addr_space (operands[2], as);
20372 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
20373 ;; %rax as destination of the initial executable code sequence.
20374 (define_insn "tls_initial_exec_64_sun"
20375 [(set (match_operand:DI 0 "register_operand" "=a")
20377 [(match_operand 1 "tls_symbolic_operand")]
20378 UNSPEC_TLS_IE_SUN))
20379 (clobber (reg:CC FLAGS_REG))]
20380 "TARGET_64BIT && TARGET_SUN_TLS"
20383 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
20384 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
20386 [(set_attr "type" "multi")])
20388 ;; GNU2 TLS patterns can be split.
20390 (define_expand "tls_dynamic_gnu2_32"
20391 [(set (match_dup 3)
20392 (plus:SI (match_operand:SI 2 "register_operand")
20394 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
20397 [(set (match_operand:SI 0 "register_operand")
20398 (unspec:SI [(match_dup 1) (match_dup 3)
20399 (match_dup 2) (reg:SI SP_REG)]
20401 (clobber (reg:CC FLAGS_REG))])]
20402 "!TARGET_64BIT && TARGET_GNU2_TLS"
20404 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
20405 ix86_tls_descriptor_calls_expanded_in_cfun = true;
20408 (define_insn "*tls_dynamic_gnu2_lea_32"
20409 [(set (match_operand:SI 0 "register_operand" "=r")
20410 (plus:SI (match_operand:SI 1 "register_operand" "b")
20412 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
20413 UNSPEC_TLSDESC))))]
20414 "!TARGET_64BIT && TARGET_GNU2_TLS"
20415 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
20416 [(set_attr "type" "lea")
20417 (set_attr "mode" "SI")
20418 (set_attr "length" "6")
20419 (set_attr "length_address" "4")])
20421 (define_insn "*tls_dynamic_gnu2_call_32"
20422 [(set (match_operand:SI 0 "register_operand" "=a")
20423 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
20424 (match_operand:SI 2 "register_operand" "0")
20425 ;; we have to make sure %ebx still points to the GOT
20426 (match_operand:SI 3 "register_operand" "b")
20429 (clobber (reg:CC FLAGS_REG))]
20430 "!TARGET_64BIT && TARGET_GNU2_TLS"
20431 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
20432 [(set_attr "type" "call")
20433 (set_attr "length" "2")
20434 (set_attr "length_address" "0")])
20436 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
20437 [(set (match_operand:SI 0 "register_operand" "=&a")
20439 (unspec:SI [(match_operand 3 "tls_modbase_operand")
20440 (match_operand:SI 4)
20441 (match_operand:SI 2 "register_operand" "b")
20444 (const:SI (unspec:SI
20445 [(match_operand 1 "tls_symbolic_operand")]
20447 (clobber (reg:CC FLAGS_REG))]
20448 "!TARGET_64BIT && TARGET_GNU2_TLS"
20451 [(set (match_dup 0) (match_dup 5))]
20453 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
20454 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
20457 (define_expand "@tls_dynamic_gnu2_64_<mode>"
20458 [(set (match_dup 2)
20459 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")]
20462 [(set (match_operand:PTR 0 "register_operand")
20463 (unspec:PTR [(match_dup 1) (match_dup 2) (reg:PTR SP_REG)]
20465 (clobber (reg:CC FLAGS_REG))])]
20466 "TARGET_64BIT && TARGET_GNU2_TLS"
20468 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (ptr_mode) : operands[0];
20469 ix86_tls_descriptor_calls_expanded_in_cfun = true;
20472 (define_insn "*tls_dynamic_gnu2_lea_64_<mode>"
20473 [(set (match_operand:PTR 0 "register_operand" "=r")
20474 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")]
20476 "TARGET_64BIT && TARGET_GNU2_TLS"
20477 "lea%z0\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
20478 [(set_attr "type" "lea")
20479 (set_attr "mode" "<MODE>")
20480 (set_attr "length" "7")
20481 (set_attr "length_address" "4")])
20483 (define_insn "*tls_dynamic_gnu2_call_64_<mode>"
20484 [(set (match_operand:PTR 0 "register_operand" "=a")
20485 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")
20486 (match_operand:PTR 2 "register_operand" "0")
20489 (clobber (reg:CC FLAGS_REG))]
20490 "TARGET_64BIT && TARGET_GNU2_TLS"
20491 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
20492 [(set_attr "type" "call")
20493 (set_attr "length" "2")
20494 (set_attr "length_address" "0")])
20496 (define_insn_and_split "*tls_dynamic_gnu2_combine_64_<mode>"
20497 [(set (match_operand:PTR 0 "register_operand" "=&a")
20499 (unspec:PTR [(match_operand 2 "tls_modbase_operand")
20500 (match_operand:PTR 3)
20503 (const:PTR (unspec:PTR
20504 [(match_operand 1 "tls_symbolic_operand")]
20506 (clobber (reg:CC FLAGS_REG))]
20507 "TARGET_64BIT && TARGET_GNU2_TLS"
20510 [(set (match_dup 0) (match_dup 4))]
20512 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (ptr_mode) : operands[0];
20513 emit_insn (gen_tls_dynamic_gnu2_64 (ptr_mode, operands[4], operands[1]));
20517 [(match_operand 0 "tls_address_pattern")]
20518 "TARGET_TLS_DIRECT_SEG_REFS"
20520 "operands[0] = ix86_rewrite_tls_address (operands[0]);")
20523 ;; These patterns match the binary 387 instructions for addM3, subM3,
20524 ;; mulM3 and divM3. There are three patterns for each of DFmode and
20525 ;; SFmode. The first is the normal insn, the second the same insn but
20526 ;; with one operand a conversion, and the third the same insn but with
20527 ;; the other operand a conversion. The conversion may be SFmode or
20528 ;; SImode if the target mode DFmode, but only SImode if the target mode
20531 ;; Gcc is slightly more smart about handling normal two address instructions
20532 ;; so use special patterns for add and mull.
20534 (define_insn "*fop_xf_comm_i387"
20535 [(set (match_operand:XF 0 "register_operand" "=f")
20536 (match_operator:XF 3 "binary_fp_operator"
20537 [(match_operand:XF 1 "register_operand" "%0")
20538 (match_operand:XF 2 "register_operand" "f")]))]
20540 && COMMUTATIVE_ARITH_P (operands[3])"
20541 "* return output_387_binary_op (insn, operands);"
20542 [(set (attr "type")
20543 (if_then_else (match_operand:XF 3 "mult_operator")
20544 (const_string "fmul")
20545 (const_string "fop")))
20546 (set_attr "mode" "XF")])
20548 (define_insn "*fop_<mode>_comm"
20549 [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
20550 (match_operator:MODEF 3 "binary_fp_operator"
20551 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
20552 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
20553 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20554 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
20555 && COMMUTATIVE_ARITH_P (operands[3])
20556 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
20557 "* return output_387_binary_op (insn, operands);"
20558 [(set (attr "type")
20559 (if_then_else (eq_attr "alternative" "1,2")
20560 (if_then_else (match_operand:MODEF 3 "mult_operator")
20561 (const_string "ssemul")
20562 (const_string "sseadd"))
20563 (if_then_else (match_operand:MODEF 3 "mult_operator")
20564 (const_string "fmul")
20565 (const_string "fop"))))
20566 (set_attr "isa" "*,noavx,avx")
20567 (set_attr "prefix" "orig,orig,vex")
20568 (set_attr "mode" "<MODE>")
20569 (set (attr "enabled")
20571 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
20573 (eq_attr "alternative" "0")
20574 (symbol_ref "TARGET_MIX_SSE_I387
20575 && X87_ENABLE_ARITH (<MODE>mode)")
20576 (const_string "*"))
20578 (eq_attr "alternative" "0")
20579 (symbol_ref "true")
20580 (symbol_ref "false"))))])
20582 (define_insn "*<insn>hf"
20583 [(set (match_operand:HF 0 "register_operand" "=v")
20584 (plusminusmultdiv:HF
20585 (match_operand:HF 1 "nonimmediate_operand" "<comm>v")
20586 (match_operand:HF 2 "nonimmediate_operand" "vm")))]
20588 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
20589 "v<insn>sh\t{%2, %1, %0|%0, %1, %2}"
20590 [(set_attr "prefix" "evex")
20591 (set_attr "mode" "HF")])
20593 (define_insn "*rcpsf2_sse"
20594 [(set (match_operand:SF 0 "register_operand" "=x,x,x,x")
20595 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m,ja")]
20597 "TARGET_SSE && TARGET_SSE_MATH"
20599 %vrcpss\t{%d1, %0|%0, %d1}
20600 %vrcpss\t{%d1, %0|%0, %d1}
20601 rcpss\t{%1, %d0|%d0, %1}
20602 vrcpss\t{%1, %d0|%d0, %1}"
20603 [(set_attr "isa" "*,*,noavx,avx")
20604 (set_attr "addr" "*,*,*,gpr16")
20605 (set_attr "type" "sse")
20606 (set_attr "atom_sse_attr" "rcp")
20607 (set_attr "btver2_sse_attr" "rcp")
20608 (set_attr "prefix" "maybe_vex")
20609 (set_attr "mode" "SF")
20610 (set_attr "avx_partial_xmm_update" "false,false,true,true")
20611 (set (attr "preferred_for_speed")
20612 (cond [(match_test "TARGET_AVX")
20613 (symbol_ref "true")
20614 (eq_attr "alternative" "1,2,3")
20615 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
20617 (symbol_ref "true")))])
20619 (define_insn "rcphf2"
20620 [(set (match_operand:HF 0 "register_operand" "=v,v")
20621 (unspec:HF [(match_operand:HF 1 "nonimmediate_operand" "v,m")]
20623 "TARGET_AVX512FP16"
20625 vrcpsh\t{%d1, %0|%0, %d1}
20626 vrcpsh\t{%1, %d0|%d0, %1}"
20627 [(set_attr "type" "sse")
20628 (set_attr "prefix" "evex")
20629 (set_attr "mode" "HF")
20630 (set_attr "avx_partial_xmm_update" "false,true")])
20632 (define_insn "*fop_xf_1_i387"
20633 [(set (match_operand:XF 0 "register_operand" "=f,f")
20634 (match_operator:XF 3 "binary_fp_operator"
20635 [(match_operand:XF 1 "register_operand" "0,f")
20636 (match_operand:XF 2 "register_operand" "f,0")]))]
20638 && !COMMUTATIVE_ARITH_P (operands[3])"
20639 "* return output_387_binary_op (insn, operands);"
20640 [(set (attr "type")
20641 (if_then_else (match_operand:XF 3 "div_operator")
20642 (const_string "fdiv")
20643 (const_string "fop")))
20644 (set_attr "mode" "XF")])
20646 (define_insn "*fop_<mode>_1"
20647 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
20648 (match_operator:MODEF 3 "binary_fp_operator"
20649 [(match_operand:MODEF 1
20650 "x87nonimm_ssenomem_operand" "0,fm,0,v")
20651 (match_operand:MODEF 2
20652 "nonimmediate_operand" "fm,0,xm,vm")]))]
20653 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20654 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
20655 && !COMMUTATIVE_ARITH_P (operands[3])
20656 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
20657 "* return output_387_binary_op (insn, operands);"
20658 [(set (attr "type")
20659 (if_then_else (eq_attr "alternative" "2,3")
20660 (if_then_else (match_operand:MODEF 3 "div_operator")
20661 (const_string "ssediv")
20662 (const_string "sseadd"))
20663 (if_then_else (match_operand:MODEF 3 "div_operator")
20664 (const_string "fdiv")
20665 (const_string "fop"))))
20666 (set_attr "isa" "*,*,noavx,avx")
20667 (set_attr "prefix" "orig,orig,orig,vex")
20668 (set_attr "mode" "<MODE>")
20669 (set (attr "enabled")
20671 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
20673 (eq_attr "alternative" "0,1")
20674 (symbol_ref "TARGET_MIX_SSE_I387
20675 && X87_ENABLE_ARITH (<MODE>mode)")
20676 (const_string "*"))
20678 (eq_attr "alternative" "0,1")
20679 (symbol_ref "true")
20680 (symbol_ref "false"))))])
20682 (define_insn "*fop_<X87MODEF:mode>_2_i387"
20683 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
20684 (match_operator:X87MODEF 3 "binary_fp_operator"
20686 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
20687 (match_operand:X87MODEF 2 "register_operand" "0")]))]
20688 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
20689 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
20690 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
20691 || optimize_function_for_size_p (cfun))"
20692 "* return output_387_binary_op (insn, operands);"
20693 [(set (attr "type")
20694 (cond [(match_operand:X87MODEF 3 "mult_operator")
20695 (const_string "fmul")
20696 (match_operand:X87MODEF 3 "div_operator")
20697 (const_string "fdiv")
20699 (const_string "fop")))
20700 (set_attr "fp_int_src" "true")
20701 (set_attr "mode" "<SWI24:MODE>")])
20703 (define_insn "*fop_<X87MODEF:mode>_3_i387"
20704 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
20705 (match_operator:X87MODEF 3 "binary_fp_operator"
20706 [(match_operand:X87MODEF 1 "register_operand" "0")
20708 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
20709 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
20710 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
20711 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
20712 || optimize_function_for_size_p (cfun))"
20713 "* return output_387_binary_op (insn, operands);"
20714 [(set (attr "type")
20715 (cond [(match_operand:X87MODEF 3 "mult_operator")
20716 (const_string "fmul")
20717 (match_operand:X87MODEF 3 "div_operator")
20718 (const_string "fdiv")
20720 (const_string "fop")))
20721 (set_attr "fp_int_src" "true")
20722 (set_attr "mode" "<SWI24:MODE>")])
20724 (define_insn "*fop_xf_4_i387"
20725 [(set (match_operand:XF 0 "register_operand" "=f,f")
20726 (match_operator:XF 3 "binary_fp_operator"
20728 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
20729 (match_operand:XF 2 "register_operand" "0,f")]))]
20731 "* return output_387_binary_op (insn, operands);"
20732 [(set (attr "type")
20733 (cond [(match_operand:XF 3 "mult_operator")
20734 (const_string "fmul")
20735 (match_operand:XF 3 "div_operator")
20736 (const_string "fdiv")
20738 (const_string "fop")))
20739 (set_attr "mode" "<MODE>")])
20741 (define_insn "*fop_df_4_i387"
20742 [(set (match_operand:DF 0 "register_operand" "=f,f")
20743 (match_operator:DF 3 "binary_fp_operator"
20745 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
20746 (match_operand:DF 2 "register_operand" "0,f")]))]
20747 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
20748 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
20749 "* return output_387_binary_op (insn, operands);"
20750 [(set (attr "type")
20751 (cond [(match_operand:DF 3 "mult_operator")
20752 (const_string "fmul")
20753 (match_operand:DF 3 "div_operator")
20754 (const_string "fdiv")
20756 (const_string "fop")))
20757 (set_attr "mode" "SF")])
20759 (define_insn "*fop_xf_5_i387"
20760 [(set (match_operand:XF 0 "register_operand" "=f,f")
20761 (match_operator:XF 3 "binary_fp_operator"
20762 [(match_operand:XF 1 "register_operand" "0,f")
20764 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
20766 "* return output_387_binary_op (insn, operands);"
20767 [(set (attr "type")
20768 (cond [(match_operand:XF 3 "mult_operator")
20769 (const_string "fmul")
20770 (match_operand:XF 3 "div_operator")
20771 (const_string "fdiv")
20773 (const_string "fop")))
20774 (set_attr "mode" "<MODE>")])
20776 (define_insn "*fop_df_5_i387"
20777 [(set (match_operand:DF 0 "register_operand" "=f,f")
20778 (match_operator:DF 3 "binary_fp_operator"
20779 [(match_operand:DF 1 "register_operand" "0,f")
20781 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
20782 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
20783 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
20784 "* return output_387_binary_op (insn, operands);"
20785 [(set (attr "type")
20786 (cond [(match_operand:DF 3 "mult_operator")
20787 (const_string "fmul")
20788 (match_operand:DF 3 "div_operator")
20789 (const_string "fdiv")
20791 (const_string "fop")))
20792 (set_attr "mode" "SF")])
20794 (define_insn "*fop_xf_6_i387"
20795 [(set (match_operand:XF 0 "register_operand" "=f,f")
20796 (match_operator:XF 3 "binary_fp_operator"
20798 (match_operand:MODEF 1 "register_operand" "0,f"))
20800 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
20802 "* return output_387_binary_op (insn, operands);"
20803 [(set (attr "type")
20804 (cond [(match_operand:XF 3 "mult_operator")
20805 (const_string "fmul")
20806 (match_operand:XF 3 "div_operator")
20807 (const_string "fdiv")
20809 (const_string "fop")))
20810 (set_attr "mode" "<MODE>")])
20812 (define_insn "*fop_df_6_i387"
20813 [(set (match_operand:DF 0 "register_operand" "=f,f")
20814 (match_operator:DF 3 "binary_fp_operator"
20816 (match_operand:SF 1 "register_operand" "0,f"))
20818 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
20819 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
20820 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
20821 "* return output_387_binary_op (insn, operands);"
20822 [(set (attr "type")
20823 (cond [(match_operand:DF 3 "mult_operator")
20824 (const_string "fmul")
20825 (match_operand:DF 3 "div_operator")
20826 (const_string "fdiv")
20828 (const_string "fop")))
20829 (set_attr "mode" "SF")])
20831 ;; FPU special functions.
20833 ;; This pattern implements a no-op XFmode truncation for
20834 ;; all fancy i386 XFmode math functions.
20836 (define_insn "truncxf<mode>2_i387_noop_unspec"
20837 [(set (match_operand:MODEF 0 "nonimmediate_operand" "=mf")
20838 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
20839 UNSPEC_TRUNC_NOOP))]
20840 "TARGET_USE_FANCY_MATH_387"
20841 "* return output_387_reg_move (insn, operands);"
20842 [(set_attr "type" "fmov")
20843 (set_attr "mode" "<MODE>")])
20845 (define_insn "sqrtxf2"
20846 [(set (match_operand:XF 0 "register_operand" "=f")
20847 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
20848 "TARGET_USE_FANCY_MATH_387"
20850 [(set_attr "type" "fpspc")
20851 (set_attr "mode" "XF")
20852 (set_attr "athlon_decode" "direct")
20853 (set_attr "amdfam10_decode" "direct")
20854 (set_attr "bdver1_decode" "direct")])
20856 (define_insn "*rsqrtsf2_sse"
20857 [(set (match_operand:SF 0 "register_operand" "=x,x,x,x")
20858 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m,ja")]
20860 "TARGET_SSE && TARGET_SSE_MATH"
20862 %vrsqrtss\t{%d1, %0|%0, %d1}
20863 %vrsqrtss\t{%d1, %0|%0, %d1}
20864 rsqrtss\t{%1, %d0|%d0, %1}
20865 vrsqrtss\t{%1, %d0|%d0, %1}"
20866 [(set_attr "isa" "*,*,noavx,avx")
20867 (set_attr "addr" "*,*,*,gpr16")
20868 (set_attr "type" "sse")
20869 (set_attr "atom_sse_attr" "rcp")
20870 (set_attr "btver2_sse_attr" "rcp")
20871 (set_attr "prefix" "maybe_vex")
20872 (set_attr "mode" "SF")
20873 (set_attr "avx_partial_xmm_update" "false,false,true,true")
20874 (set (attr "preferred_for_speed")
20875 (cond [(match_test "TARGET_AVX")
20876 (symbol_ref "true")
20877 (eq_attr "alternative" "1,2,3")
20878 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
20880 (symbol_ref "true")))])
20882 (define_expand "rsqrtsf2"
20883 [(set (match_operand:SF 0 "register_operand")
20884 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
20886 "TARGET_SSE && TARGET_SSE_MATH"
20888 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
20892 (define_insn "rsqrthf2"
20893 [(set (match_operand:HF 0 "register_operand" "=v,v")
20894 (unspec:HF [(match_operand:HF 1 "nonimmediate_operand" "v,m")]
20896 "TARGET_AVX512FP16"
20898 vrsqrtsh\t{%d1, %0|%0, %d1}
20899 vrsqrtsh\t{%1, %d0|%d0, %1}"
20900 [(set_attr "type" "sse")
20901 (set_attr "prefix" "evex")
20902 (set_attr "avx_partial_xmm_update" "false,true")
20903 (set_attr "mode" "HF")])
20905 (define_insn "sqrthf2"
20906 [(set (match_operand:HF 0 "register_operand" "=v,v")
20908 (match_operand:HF 1 "nonimmediate_operand" "v,m")))]
20909 "TARGET_AVX512FP16"
20911 vsqrtsh\t{%d1, %0|%0, %d1}
20912 vsqrtsh\t{%1, %d0|%d0, %1}"
20913 [(set_attr "type" "sse")
20914 (set_attr "prefix" "evex")
20915 (set_attr "avx_partial_xmm_update" "false,true")
20916 (set_attr "mode" "HF")])
20918 (define_insn "*sqrt<mode>2_sse"
20919 [(set (match_operand:MODEF 0 "register_operand" "=v,v,v")
20921 (match_operand:MODEF 1 "nonimmediate_operand" "0,v,m")))]
20922 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20924 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
20925 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
20926 %vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
20927 [(set_attr "type" "sse")
20928 (set_attr "atom_sse_attr" "sqrt")
20929 (set_attr "btver2_sse_attr" "sqrt")
20930 (set_attr "prefix" "maybe_vex")
20931 (set_attr "avx_partial_xmm_update" "false,false,true")
20932 (set_attr "mode" "<MODE>")
20933 (set (attr "preferred_for_speed")
20934 (cond [(match_test "TARGET_AVX")
20935 (symbol_ref "true")
20936 (eq_attr "alternative" "1,2")
20937 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
20939 (symbol_ref "true")))])
20941 (define_expand "sqrt<mode>2"
20942 [(set (match_operand:MODEF 0 "register_operand")
20944 (match_operand:MODEF 1 "nonimmediate_operand")))]
20945 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
20946 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
20948 if (<MODE>mode == SFmode
20949 && TARGET_SSE && TARGET_SSE_MATH
20950 && TARGET_RECIP_SQRT
20951 && !optimize_function_for_size_p (cfun)
20952 && flag_finite_math_only && !flag_trapping_math
20953 && flag_unsafe_math_optimizations)
20955 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
20959 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
20961 rtx op0 = gen_reg_rtx (XFmode);
20962 rtx op1 = gen_reg_rtx (XFmode);
20964 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20965 emit_insn (gen_sqrtxf2 (op0, op1));
20966 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
20971 (define_expand "hypot<mode>3"
20972 [(use (match_operand:MODEF 0 "register_operand"))
20973 (use (match_operand:MODEF 1 "general_operand"))
20974 (use (match_operand:MODEF 2 "general_operand"))]
20975 "TARGET_USE_FANCY_MATH_387
20976 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20977 || TARGET_MIX_SSE_I387)
20978 && flag_finite_math_only
20979 && flag_unsafe_math_optimizations"
20981 rtx op0 = gen_reg_rtx (XFmode);
20982 rtx op1 = gen_reg_rtx (XFmode);
20983 rtx op2 = gen_reg_rtx (XFmode);
20985 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20986 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20988 emit_insn (gen_mulxf3 (op1, op1, op1));
20989 emit_insn (gen_mulxf3 (op2, op2, op2));
20990 emit_insn (gen_addxf3 (op0, op2, op1));
20991 emit_insn (gen_sqrtxf2 (op0, op0));
20993 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20997 (define_insn "x86_fnstsw_1"
20998 [(set (match_operand:HI 0 "register_operand" "=a")
20999 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
21002 [(set_attr "length" "2")
21003 (set_attr "mode" "SI")
21004 (set_attr "unit" "i387")])
21006 (define_insn "fpremxf4_i387"
21007 [(set (match_operand:XF 0 "register_operand" "=f")
21008 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
21009 (match_operand:XF 3 "register_operand" "1")]
21011 (set (match_operand:XF 1 "register_operand" "=f")
21012 (unspec:XF [(match_dup 2) (match_dup 3)]
21014 (set (reg:CCFP FPSR_REG)
21015 (unspec:CCFP [(match_dup 2) (match_dup 3)]
21017 "TARGET_USE_FANCY_MATH_387"
21019 [(set_attr "type" "fpspc")
21020 (set_attr "znver1_decode" "vector")
21021 (set_attr "mode" "XF")])
21023 (define_expand "fmodxf3"
21024 [(use (match_operand:XF 0 "register_operand"))
21025 (use (match_operand:XF 1 "general_operand"))
21026 (use (match_operand:XF 2 "general_operand"))]
21027 "TARGET_USE_FANCY_MATH_387"
21029 rtx_code_label *label = gen_label_rtx ();
21031 rtx op1 = gen_reg_rtx (XFmode);
21032 rtx op2 = gen_reg_rtx (XFmode);
21034 emit_move_insn (op2, operands[2]);
21035 emit_move_insn (op1, operands[1]);
21037 emit_label (label);
21038 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
21039 ix86_emit_fp_unordered_jump (label);
21040 LABEL_NUSES (label) = 1;
21042 emit_move_insn (operands[0], op1);
21046 (define_expand "fmod<mode>3"
21047 [(use (match_operand:MODEF 0 "register_operand"))
21048 (use (match_operand:MODEF 1 "general_operand"))
21049 (use (match_operand:MODEF 2 "general_operand"))]
21050 "TARGET_USE_FANCY_MATH_387"
21052 rtx (*gen_truncxf) (rtx, rtx);
21054 rtx_code_label *label = gen_label_rtx ();
21056 rtx op1 = gen_reg_rtx (XFmode);
21057 rtx op2 = gen_reg_rtx (XFmode);
21059 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
21060 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21062 emit_label (label);
21063 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
21064 ix86_emit_fp_unordered_jump (label);
21065 LABEL_NUSES (label) = 1;
21067 /* Truncate the result properly for strict SSE math. */
21068 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
21069 && !TARGET_MIX_SSE_I387)
21070 gen_truncxf = gen_truncxf<mode>2;
21072 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
21074 emit_insn (gen_truncxf (operands[0], op1));
21078 (define_insn "fprem1xf4_i387"
21079 [(set (match_operand:XF 0 "register_operand" "=f")
21080 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
21081 (match_operand:XF 3 "register_operand" "1")]
21083 (set (match_operand:XF 1 "register_operand" "=f")
21084 (unspec:XF [(match_dup 2) (match_dup 3)]
21086 (set (reg:CCFP FPSR_REG)
21087 (unspec:CCFP [(match_dup 2) (match_dup 3)]
21089 "TARGET_USE_FANCY_MATH_387"
21091 [(set_attr "type" "fpspc")
21092 (set_attr "znver1_decode" "vector")
21093 (set_attr "mode" "XF")])
21095 (define_expand "remainderxf3"
21096 [(use (match_operand:XF 0 "register_operand"))
21097 (use (match_operand:XF 1 "general_operand"))
21098 (use (match_operand:XF 2 "general_operand"))]
21099 "TARGET_USE_FANCY_MATH_387"
21101 rtx_code_label *label = gen_label_rtx ();
21103 rtx op1 = gen_reg_rtx (XFmode);
21104 rtx op2 = gen_reg_rtx (XFmode);
21106 emit_move_insn (op2, operands[2]);
21107 emit_move_insn (op1, operands[1]);
21109 emit_label (label);
21110 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
21111 ix86_emit_fp_unordered_jump (label);
21112 LABEL_NUSES (label) = 1;
21114 emit_move_insn (operands[0], op1);
21118 (define_expand "remainder<mode>3"
21119 [(use (match_operand:MODEF 0 "register_operand"))
21120 (use (match_operand:MODEF 1 "general_operand"))
21121 (use (match_operand:MODEF 2 "general_operand"))]
21122 "TARGET_USE_FANCY_MATH_387"
21124 rtx (*gen_truncxf) (rtx, rtx);
21126 rtx_code_label *label = gen_label_rtx ();
21128 rtx op1 = gen_reg_rtx (XFmode);
21129 rtx op2 = gen_reg_rtx (XFmode);
21131 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
21132 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21134 emit_label (label);
21136 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
21137 ix86_emit_fp_unordered_jump (label);
21138 LABEL_NUSES (label) = 1;
21140 /* Truncate the result properly for strict SSE math. */
21141 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
21142 && !TARGET_MIX_SSE_I387)
21143 gen_truncxf = gen_truncxf<mode>2;
21145 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
21147 emit_insn (gen_truncxf (operands[0], op1));
21151 (define_int_iterator SINCOS
21155 (define_int_attr sincos
21156 [(UNSPEC_SIN "sin")
21157 (UNSPEC_COS "cos")])
21159 (define_insn "<sincos>xf2"
21160 [(set (match_operand:XF 0 "register_operand" "=f")
21161 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
21163 "TARGET_USE_FANCY_MATH_387
21164 && flag_unsafe_math_optimizations"
21166 [(set_attr "type" "fpspc")
21167 (set_attr "znver1_decode" "vector")
21168 (set_attr "mode" "XF")])
21170 (define_expand "<sincos><mode>2"
21171 [(set (match_operand:MODEF 0 "register_operand")
21172 (unspec:MODEF [(match_operand:MODEF 1 "general_operand")]
21174 "TARGET_USE_FANCY_MATH_387
21175 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21176 || TARGET_MIX_SSE_I387)
21177 && flag_unsafe_math_optimizations"
21179 rtx op0 = gen_reg_rtx (XFmode);
21180 rtx op1 = gen_reg_rtx (XFmode);
21182 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21183 emit_insn (gen_<sincos>xf2 (op0, op1));
21184 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21188 (define_insn "sincosxf3"
21189 [(set (match_operand:XF 0 "register_operand" "=f")
21190 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
21191 UNSPEC_SINCOS_COS))
21192 (set (match_operand:XF 1 "register_operand" "=f")
21193 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
21194 "TARGET_USE_FANCY_MATH_387
21195 && flag_unsafe_math_optimizations"
21197 [(set_attr "type" "fpspc")
21198 (set_attr "znver1_decode" "vector")
21199 (set_attr "mode" "XF")])
21201 (define_expand "sincos<mode>3"
21202 [(use (match_operand:MODEF 0 "register_operand"))
21203 (use (match_operand:MODEF 1 "register_operand"))
21204 (use (match_operand:MODEF 2 "general_operand"))]
21205 "TARGET_USE_FANCY_MATH_387
21206 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21207 || TARGET_MIX_SSE_I387)
21208 && flag_unsafe_math_optimizations"
21210 rtx op0 = gen_reg_rtx (XFmode);
21211 rtx op1 = gen_reg_rtx (XFmode);
21212 rtx op2 = gen_reg_rtx (XFmode);
21214 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
21215 emit_insn (gen_sincosxf3 (op0, op1, op2));
21216 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21217 emit_insn (gen_truncxf<mode>2 (operands[1], op1));
21221 (define_insn "fptanxf4_i387"
21222 [(set (match_operand:SF 0 "register_operand" "=f")
21223 (match_operand:SF 3 "const1_operand"))
21224 (set (match_operand:XF 1 "register_operand" "=f")
21225 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
21227 "TARGET_USE_FANCY_MATH_387
21228 && flag_unsafe_math_optimizations"
21230 [(set_attr "type" "fpspc")
21231 (set_attr "znver1_decode" "vector")
21232 (set_attr "mode" "XF")])
21234 (define_expand "tanxf2"
21235 [(use (match_operand:XF 0 "register_operand"))
21236 (use (match_operand:XF 1 "register_operand"))]
21237 "TARGET_USE_FANCY_MATH_387
21238 && flag_unsafe_math_optimizations"
21240 rtx one = gen_reg_rtx (SFmode);
21241 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1],
21242 CONST1_RTX (SFmode)));
21246 (define_expand "tan<mode>2"
21247 [(use (match_operand:MODEF 0 "register_operand"))
21248 (use (match_operand:MODEF 1 "general_operand"))]
21249 "TARGET_USE_FANCY_MATH_387
21250 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21251 || TARGET_MIX_SSE_I387)
21252 && flag_unsafe_math_optimizations"
21254 rtx op0 = gen_reg_rtx (XFmode);
21255 rtx op1 = gen_reg_rtx (XFmode);
21257 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21258 emit_insn (gen_tanxf2 (op0, op1));
21259 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21263 (define_insn "atan2xf3"
21264 [(set (match_operand:XF 0 "register_operand" "=f")
21265 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
21266 (match_operand:XF 1 "register_operand" "f")]
21268 (clobber (match_scratch:XF 3 "=1"))]
21269 "TARGET_USE_FANCY_MATH_387
21270 && flag_unsafe_math_optimizations"
21272 [(set_attr "type" "fpspc")
21273 (set_attr "znver1_decode" "vector")
21274 (set_attr "mode" "XF")])
21276 (define_expand "atan2<mode>3"
21277 [(use (match_operand:MODEF 0 "register_operand"))
21278 (use (match_operand:MODEF 1 "general_operand"))
21279 (use (match_operand:MODEF 2 "general_operand"))]
21280 "TARGET_USE_FANCY_MATH_387
21281 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21282 || TARGET_MIX_SSE_I387)
21283 && flag_unsafe_math_optimizations"
21285 rtx op0 = gen_reg_rtx (XFmode);
21286 rtx op1 = gen_reg_rtx (XFmode);
21287 rtx op2 = gen_reg_rtx (XFmode);
21289 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
21290 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21292 emit_insn (gen_atan2xf3 (op0, op1, op2));
21293 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21297 (define_expand "atanxf2"
21298 [(parallel [(set (match_operand:XF 0 "register_operand")
21299 (unspec:XF [(match_dup 2)
21300 (match_operand:XF 1 "register_operand")]
21302 (clobber (scratch:XF))])]
21303 "TARGET_USE_FANCY_MATH_387
21304 && flag_unsafe_math_optimizations"
21305 "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
21307 (define_expand "atan<mode>2"
21308 [(use (match_operand:MODEF 0 "register_operand"))
21309 (use (match_operand:MODEF 1 "general_operand"))]
21310 "TARGET_USE_FANCY_MATH_387
21311 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21312 || TARGET_MIX_SSE_I387)
21313 && flag_unsafe_math_optimizations"
21315 rtx op0 = gen_reg_rtx (XFmode);
21316 rtx op1 = gen_reg_rtx (XFmode);
21318 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21319 emit_insn (gen_atanxf2 (op0, op1));
21320 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21324 (define_expand "asinxf2"
21325 [(set (match_dup 2)
21326 (mult:XF (match_operand:XF 1 "register_operand")
21328 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
21329 (set (match_dup 5) (sqrt:XF (match_dup 4)))
21330 (parallel [(set (match_operand:XF 0 "register_operand")
21331 (unspec:XF [(match_dup 5) (match_dup 1)]
21333 (clobber (scratch:XF))])]
21334 "TARGET_USE_FANCY_MATH_387
21335 && flag_unsafe_math_optimizations"
21339 for (i = 2; i < 6; i++)
21340 operands[i] = gen_reg_rtx (XFmode);
21342 emit_move_insn (operands[3], CONST1_RTX (XFmode));
21345 (define_expand "asin<mode>2"
21346 [(use (match_operand:MODEF 0 "register_operand"))
21347 (use (match_operand:MODEF 1 "general_operand"))]
21348 "TARGET_USE_FANCY_MATH_387
21349 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21350 || TARGET_MIX_SSE_I387)
21351 && flag_unsafe_math_optimizations"
21353 rtx op0 = gen_reg_rtx (XFmode);
21354 rtx op1 = gen_reg_rtx (XFmode);
21356 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21357 emit_insn (gen_asinxf2 (op0, op1));
21358 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21362 (define_expand "acosxf2"
21363 [(set (match_dup 2)
21364 (mult:XF (match_operand:XF 1 "register_operand")
21366 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
21367 (set (match_dup 5) (sqrt:XF (match_dup 4)))
21368 (parallel [(set (match_operand:XF 0 "register_operand")
21369 (unspec:XF [(match_dup 1) (match_dup 5)]
21371 (clobber (scratch:XF))])]
21372 "TARGET_USE_FANCY_MATH_387
21373 && flag_unsafe_math_optimizations"
21377 for (i = 2; i < 6; i++)
21378 operands[i] = gen_reg_rtx (XFmode);
21380 emit_move_insn (operands[3], CONST1_RTX (XFmode));
21383 (define_expand "acos<mode>2"
21384 [(use (match_operand:MODEF 0 "register_operand"))
21385 (use (match_operand:MODEF 1 "general_operand"))]
21386 "TARGET_USE_FANCY_MATH_387
21387 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21388 || TARGET_MIX_SSE_I387)
21389 && flag_unsafe_math_optimizations"
21391 rtx op0 = gen_reg_rtx (XFmode);
21392 rtx op1 = gen_reg_rtx (XFmode);
21394 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21395 emit_insn (gen_acosxf2 (op0, op1));
21396 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21400 (define_expand "sinhxf2"
21401 [(use (match_operand:XF 0 "register_operand"))
21402 (use (match_operand:XF 1 "register_operand"))]
21403 "TARGET_USE_FANCY_MATH_387
21404 && flag_finite_math_only
21405 && flag_unsafe_math_optimizations"
21407 ix86_emit_i387_sinh (operands[0], operands[1]);
21411 (define_expand "sinh<mode>2"
21412 [(use (match_operand:MODEF 0 "register_operand"))
21413 (use (match_operand:MODEF 1 "general_operand"))]
21414 "TARGET_USE_FANCY_MATH_387
21415 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21416 || TARGET_MIX_SSE_I387)
21417 && flag_finite_math_only
21418 && flag_unsafe_math_optimizations"
21420 rtx op0 = gen_reg_rtx (XFmode);
21421 rtx op1 = gen_reg_rtx (XFmode);
21423 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21424 emit_insn (gen_sinhxf2 (op0, op1));
21425 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21429 (define_expand "coshxf2"
21430 [(use (match_operand:XF 0 "register_operand"))
21431 (use (match_operand:XF 1 "register_operand"))]
21432 "TARGET_USE_FANCY_MATH_387
21433 && flag_unsafe_math_optimizations"
21435 ix86_emit_i387_cosh (operands[0], operands[1]);
21439 (define_expand "cosh<mode>2"
21440 [(use (match_operand:MODEF 0 "register_operand"))
21441 (use (match_operand:MODEF 1 "general_operand"))]
21442 "TARGET_USE_FANCY_MATH_387
21443 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21444 || TARGET_MIX_SSE_I387)
21445 && flag_unsafe_math_optimizations"
21447 rtx op0 = gen_reg_rtx (XFmode);
21448 rtx op1 = gen_reg_rtx (XFmode);
21450 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21451 emit_insn (gen_coshxf2 (op0, op1));
21452 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21456 (define_expand "tanhxf2"
21457 [(use (match_operand:XF 0 "register_operand"))
21458 (use (match_operand:XF 1 "register_operand"))]
21459 "TARGET_USE_FANCY_MATH_387
21460 && flag_unsafe_math_optimizations"
21462 ix86_emit_i387_tanh (operands[0], operands[1]);
21466 (define_expand "tanh<mode>2"
21467 [(use (match_operand:MODEF 0 "register_operand"))
21468 (use (match_operand:MODEF 1 "general_operand"))]
21469 "TARGET_USE_FANCY_MATH_387
21470 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21471 || TARGET_MIX_SSE_I387)
21472 && flag_unsafe_math_optimizations"
21474 rtx op0 = gen_reg_rtx (XFmode);
21475 rtx op1 = gen_reg_rtx (XFmode);
21477 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21478 emit_insn (gen_tanhxf2 (op0, op1));
21479 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21483 (define_expand "asinhxf2"
21484 [(use (match_operand:XF 0 "register_operand"))
21485 (use (match_operand:XF 1 "register_operand"))]
21486 "TARGET_USE_FANCY_MATH_387
21487 && flag_finite_math_only
21488 && flag_unsafe_math_optimizations"
21490 ix86_emit_i387_asinh (operands[0], operands[1]);
21494 (define_expand "asinh<mode>2"
21495 [(use (match_operand:MODEF 0 "register_operand"))
21496 (use (match_operand:MODEF 1 "general_operand"))]
21497 "TARGET_USE_FANCY_MATH_387
21498 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21499 || TARGET_MIX_SSE_I387)
21500 && flag_finite_math_only
21501 && flag_unsafe_math_optimizations"
21503 rtx op0 = gen_reg_rtx (XFmode);
21504 rtx op1 = gen_reg_rtx (XFmode);
21506 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21507 emit_insn (gen_asinhxf2 (op0, op1));
21508 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21512 (define_expand "acoshxf2"
21513 [(use (match_operand:XF 0 "register_operand"))
21514 (use (match_operand:XF 1 "register_operand"))]
21515 "TARGET_USE_FANCY_MATH_387
21516 && flag_unsafe_math_optimizations"
21518 ix86_emit_i387_acosh (operands[0], operands[1]);
21522 (define_expand "acosh<mode>2"
21523 [(use (match_operand:MODEF 0 "register_operand"))
21524 (use (match_operand:MODEF 1 "general_operand"))]
21525 "TARGET_USE_FANCY_MATH_387
21526 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21527 || TARGET_MIX_SSE_I387)
21528 && flag_unsafe_math_optimizations"
21530 rtx op0 = gen_reg_rtx (XFmode);
21531 rtx op1 = gen_reg_rtx (XFmode);
21533 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21534 emit_insn (gen_acoshxf2 (op0, op1));
21535 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21539 (define_expand "atanhxf2"
21540 [(use (match_operand:XF 0 "register_operand"))
21541 (use (match_operand:XF 1 "register_operand"))]
21542 "TARGET_USE_FANCY_MATH_387
21543 && flag_unsafe_math_optimizations"
21545 ix86_emit_i387_atanh (operands[0], operands[1]);
21549 (define_expand "atanh<mode>2"
21550 [(use (match_operand:MODEF 0 "register_operand"))
21551 (use (match_operand:MODEF 1 "general_operand"))]
21552 "TARGET_USE_FANCY_MATH_387
21553 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21554 || TARGET_MIX_SSE_I387)
21555 && flag_unsafe_math_optimizations"
21557 rtx op0 = gen_reg_rtx (XFmode);
21558 rtx op1 = gen_reg_rtx (XFmode);
21560 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21561 emit_insn (gen_atanhxf2 (op0, op1));
21562 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21566 (define_insn "fyl2xxf3_i387"
21567 [(set (match_operand:XF 0 "register_operand" "=f")
21568 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
21569 (match_operand:XF 2 "register_operand" "f")]
21571 (clobber (match_scratch:XF 3 "=2"))]
21572 "TARGET_USE_FANCY_MATH_387
21573 && flag_unsafe_math_optimizations"
21575 [(set_attr "type" "fpspc")
21576 (set_attr "znver1_decode" "vector")
21577 (set_attr "mode" "XF")])
21579 (define_expand "logxf2"
21580 [(parallel [(set (match_operand:XF 0 "register_operand")
21581 (unspec:XF [(match_operand:XF 1 "register_operand")
21582 (match_dup 2)] UNSPEC_FYL2X))
21583 (clobber (scratch:XF))])]
21584 "TARGET_USE_FANCY_MATH_387
21585 && flag_unsafe_math_optimizations"
21588 = force_reg (XFmode, standard_80387_constant_rtx (4)); /* fldln2 */
21591 (define_expand "log<mode>2"
21592 [(use (match_operand:MODEF 0 "register_operand"))
21593 (use (match_operand:MODEF 1 "general_operand"))]
21594 "TARGET_USE_FANCY_MATH_387
21595 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21596 || TARGET_MIX_SSE_I387)
21597 && flag_unsafe_math_optimizations"
21599 rtx op0 = gen_reg_rtx (XFmode);
21600 rtx op1 = gen_reg_rtx (XFmode);
21602 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21603 emit_insn (gen_logxf2 (op0, op1));
21604 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21608 (define_expand "log10xf2"
21609 [(parallel [(set (match_operand:XF 0 "register_operand")
21610 (unspec:XF [(match_operand:XF 1 "register_operand")
21611 (match_dup 2)] UNSPEC_FYL2X))
21612 (clobber (scratch:XF))])]
21613 "TARGET_USE_FANCY_MATH_387
21614 && flag_unsafe_math_optimizations"
21617 = force_reg (XFmode, standard_80387_constant_rtx (3)); /* fldlg2 */
21620 (define_expand "log10<mode>2"
21621 [(use (match_operand:MODEF 0 "register_operand"))
21622 (use (match_operand:MODEF 1 "general_operand"))]
21623 "TARGET_USE_FANCY_MATH_387
21624 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21625 || TARGET_MIX_SSE_I387)
21626 && flag_unsafe_math_optimizations"
21628 rtx op0 = gen_reg_rtx (XFmode);
21629 rtx op1 = gen_reg_rtx (XFmode);
21631 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21632 emit_insn (gen_log10xf2 (op0, op1));
21633 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21637 (define_expand "log2xf2"
21638 [(parallel [(set (match_operand:XF 0 "register_operand")
21639 (unspec:XF [(match_operand:XF 1 "register_operand")
21640 (match_dup 2)] UNSPEC_FYL2X))
21641 (clobber (scratch:XF))])]
21642 "TARGET_USE_FANCY_MATH_387
21643 && flag_unsafe_math_optimizations"
21644 "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
21646 (define_expand "log2<mode>2"
21647 [(use (match_operand:MODEF 0 "register_operand"))
21648 (use (match_operand:MODEF 1 "general_operand"))]
21649 "TARGET_USE_FANCY_MATH_387
21650 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21651 || TARGET_MIX_SSE_I387)
21652 && flag_unsafe_math_optimizations"
21654 rtx op0 = gen_reg_rtx (XFmode);
21655 rtx op1 = gen_reg_rtx (XFmode);
21657 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21658 emit_insn (gen_log2xf2 (op0, op1));
21659 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21663 (define_insn "fyl2xp1xf3_i387"
21664 [(set (match_operand:XF 0 "register_operand" "=f")
21665 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
21666 (match_operand:XF 2 "register_operand" "f")]
21668 (clobber (match_scratch:XF 3 "=2"))]
21669 "TARGET_USE_FANCY_MATH_387
21670 && flag_unsafe_math_optimizations"
21672 [(set_attr "type" "fpspc")
21673 (set_attr "znver1_decode" "vector")
21674 (set_attr "mode" "XF")])
21676 (define_expand "log1pxf2"
21677 [(use (match_operand:XF 0 "register_operand"))
21678 (use (match_operand:XF 1 "register_operand"))]
21679 "TARGET_USE_FANCY_MATH_387
21680 && flag_unsafe_math_optimizations"
21682 ix86_emit_i387_log1p (operands[0], operands[1]);
21686 (define_expand "log1p<mode>2"
21687 [(use (match_operand:MODEF 0 "register_operand"))
21688 (use (match_operand:MODEF 1 "general_operand"))]
21689 "TARGET_USE_FANCY_MATH_387
21690 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21691 || TARGET_MIX_SSE_I387)
21692 && flag_unsafe_math_optimizations"
21694 rtx op0 = gen_reg_rtx (XFmode);
21695 rtx op1 = gen_reg_rtx (XFmode);
21697 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21698 emit_insn (gen_log1pxf2 (op0, op1));
21699 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21703 (define_insn "fxtractxf3_i387"
21704 [(set (match_operand:XF 0 "register_operand" "=f")
21705 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
21706 UNSPEC_XTRACT_FRACT))
21707 (set (match_operand:XF 1 "register_operand" "=f")
21708 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
21709 "TARGET_USE_FANCY_MATH_387
21710 && flag_unsafe_math_optimizations"
21712 [(set_attr "type" "fpspc")
21713 (set_attr "znver1_decode" "vector")
21714 (set_attr "mode" "XF")])
21716 (define_expand "logbxf2"
21717 [(parallel [(set (match_dup 2)
21718 (unspec:XF [(match_operand:XF 1 "register_operand")]
21719 UNSPEC_XTRACT_FRACT))
21720 (set (match_operand:XF 0 "register_operand")
21721 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
21722 "TARGET_USE_FANCY_MATH_387
21723 && flag_unsafe_math_optimizations"
21724 "operands[2] = gen_reg_rtx (XFmode);")
21726 (define_expand "logb<mode>2"
21727 [(use (match_operand:MODEF 0 "register_operand"))
21728 (use (match_operand:MODEF 1 "general_operand"))]
21729 "TARGET_USE_FANCY_MATH_387
21730 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21731 || TARGET_MIX_SSE_I387)
21732 && flag_unsafe_math_optimizations"
21734 rtx op0 = gen_reg_rtx (XFmode);
21735 rtx op1 = gen_reg_rtx (XFmode);
21737 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21738 emit_insn (gen_logbxf2 (op0, op1));
21739 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
21743 (define_expand "ilogbxf2"
21744 [(use (match_operand:SI 0 "register_operand"))
21745 (use (match_operand:XF 1 "register_operand"))]
21746 "TARGET_USE_FANCY_MATH_387
21747 && flag_unsafe_math_optimizations"
21751 if (optimize_insn_for_size_p ())
21754 op0 = gen_reg_rtx (XFmode);
21755 op1 = gen_reg_rtx (XFmode);
21757 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
21758 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
21762 (define_expand "ilogb<mode>2"
21763 [(use (match_operand:SI 0 "register_operand"))
21764 (use (match_operand:MODEF 1 "general_operand"))]
21765 "TARGET_USE_FANCY_MATH_387
21766 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21767 || TARGET_MIX_SSE_I387)
21768 && flag_unsafe_math_optimizations"
21772 if (optimize_insn_for_size_p ())
21775 op0 = gen_reg_rtx (XFmode);
21776 op1 = gen_reg_rtx (XFmode);
21777 op2 = gen_reg_rtx (XFmode);
21779 emit_insn (gen_extend<mode>xf2 (op2, operands[1]));
21780 emit_insn (gen_fxtractxf3_i387 (op0, op1, op2));
21781 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
21785 (define_insn "*f2xm1xf2_i387"
21786 [(set (match_operand:XF 0 "register_operand" "=f")
21787 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
21789 "TARGET_USE_FANCY_MATH_387
21790 && flag_unsafe_math_optimizations"
21792 [(set_attr "type" "fpspc")
21793 (set_attr "znver1_decode" "vector")
21794 (set_attr "mode" "XF")])
21796 (define_insn "fscalexf4_i387"
21797 [(set (match_operand:XF 0 "register_operand" "=f")
21798 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
21799 (match_operand:XF 3 "register_operand" "1")]
21800 UNSPEC_FSCALE_FRACT))
21801 (set (match_operand:XF 1 "register_operand" "=f")
21802 (unspec:XF [(match_dup 2) (match_dup 3)]
21803 UNSPEC_FSCALE_EXP))]
21804 "TARGET_USE_FANCY_MATH_387
21805 && flag_unsafe_math_optimizations"
21807 [(set_attr "type" "fpspc")
21808 (set_attr "znver1_decode" "vector")
21809 (set_attr "mode" "XF")])
21811 (define_expand "expNcorexf3"
21812 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
21813 (match_operand:XF 2 "register_operand")))
21814 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
21815 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
21816 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
21817 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
21818 (parallel [(set (match_operand:XF 0 "register_operand")
21819 (unspec:XF [(match_dup 8) (match_dup 4)]
21820 UNSPEC_FSCALE_FRACT))
21822 (unspec:XF [(match_dup 8) (match_dup 4)]
21823 UNSPEC_FSCALE_EXP))])]
21824 "TARGET_USE_FANCY_MATH_387
21825 && flag_unsafe_math_optimizations"
21829 for (i = 3; i < 10; i++)
21830 operands[i] = gen_reg_rtx (XFmode);
21832 emit_move_insn (operands[7], CONST1_RTX (XFmode));
21835 (define_expand "expxf2"
21836 [(use (match_operand:XF 0 "register_operand"))
21837 (use (match_operand:XF 1 "register_operand"))]
21838 "TARGET_USE_FANCY_MATH_387
21839 && flag_unsafe_math_optimizations"
21841 rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (5)); /* fldl2e */
21843 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
21847 (define_expand "exp<mode>2"
21848 [(use (match_operand:MODEF 0 "register_operand"))
21849 (use (match_operand:MODEF 1 "general_operand"))]
21850 "TARGET_USE_FANCY_MATH_387
21851 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21852 || TARGET_MIX_SSE_I387)
21853 && flag_unsafe_math_optimizations"
21855 rtx op0 = gen_reg_rtx (XFmode);
21856 rtx op1 = gen_reg_rtx (XFmode);
21858 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21859 emit_insn (gen_expxf2 (op0, op1));
21860 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21864 (define_expand "exp10xf2"
21865 [(use (match_operand:XF 0 "register_operand"))
21866 (use (match_operand:XF 1 "register_operand"))]
21867 "TARGET_USE_FANCY_MATH_387
21868 && flag_unsafe_math_optimizations"
21870 rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (6)); /* fldl2t */
21872 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
21876 (define_expand "exp10<mode>2"
21877 [(use (match_operand:MODEF 0 "register_operand"))
21878 (use (match_operand:MODEF 1 "general_operand"))]
21879 "TARGET_USE_FANCY_MATH_387
21880 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21881 || TARGET_MIX_SSE_I387)
21882 && flag_unsafe_math_optimizations"
21884 rtx op0 = gen_reg_rtx (XFmode);
21885 rtx op1 = gen_reg_rtx (XFmode);
21887 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21888 emit_insn (gen_exp10xf2 (op0, op1));
21889 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21893 (define_expand "exp2xf2"
21894 [(use (match_operand:XF 0 "register_operand"))
21895 (use (match_operand:XF 1 "register_operand"))]
21896 "TARGET_USE_FANCY_MATH_387
21897 && flag_unsafe_math_optimizations"
21899 rtx op2 = force_reg (XFmode, CONST1_RTX (XFmode));
21901 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
21905 (define_expand "exp2<mode>2"
21906 [(use (match_operand:MODEF 0 "register_operand"))
21907 (use (match_operand:MODEF 1 "general_operand"))]
21908 "TARGET_USE_FANCY_MATH_387
21909 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21910 || TARGET_MIX_SSE_I387)
21911 && flag_unsafe_math_optimizations"
21913 rtx op0 = gen_reg_rtx (XFmode);
21914 rtx op1 = gen_reg_rtx (XFmode);
21916 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21917 emit_insn (gen_exp2xf2 (op0, op1));
21918 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21922 (define_expand "expm1xf2"
21923 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
21925 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
21926 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
21927 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
21928 (parallel [(set (match_dup 7)
21929 (unspec:XF [(match_dup 6) (match_dup 4)]
21930 UNSPEC_FSCALE_FRACT))
21932 (unspec:XF [(match_dup 6) (match_dup 4)]
21933 UNSPEC_FSCALE_EXP))])
21934 (parallel [(set (match_dup 10)
21935 (unspec:XF [(match_dup 9) (match_dup 8)]
21936 UNSPEC_FSCALE_FRACT))
21937 (set (match_dup 11)
21938 (unspec:XF [(match_dup 9) (match_dup 8)]
21939 UNSPEC_FSCALE_EXP))])
21940 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
21941 (set (match_operand:XF 0 "register_operand")
21942 (plus:XF (match_dup 12) (match_dup 7)))]
21943 "TARGET_USE_FANCY_MATH_387
21944 && flag_unsafe_math_optimizations"
21948 for (i = 2; i < 13; i++)
21949 operands[i] = gen_reg_rtx (XFmode);
21951 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
21952 emit_move_insn (operands[9], CONST1_RTX (XFmode));
21955 (define_expand "expm1<mode>2"
21956 [(use (match_operand:MODEF 0 "register_operand"))
21957 (use (match_operand:MODEF 1 "general_operand"))]
21958 "TARGET_USE_FANCY_MATH_387
21959 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21960 || TARGET_MIX_SSE_I387)
21961 && flag_unsafe_math_optimizations"
21963 rtx op0 = gen_reg_rtx (XFmode);
21964 rtx op1 = gen_reg_rtx (XFmode);
21966 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21967 emit_insn (gen_expm1xf2 (op0, op1));
21968 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21972 (define_insn "avx512f_scalef<mode>2"
21973 [(set (match_operand:MODEF 0 "register_operand" "=v")
21975 [(match_operand:MODEF 1 "register_operand" "v")
21976 (match_operand:MODEF 2 "nonimmediate_operand" "vm")]
21979 "vscalef<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
21980 [(set_attr "prefix" "evex")
21981 (set_attr "mode" "<MODE>")])
21983 (define_expand "ldexpxf3"
21984 [(match_operand:XF 0 "register_operand")
21985 (match_operand:XF 1 "register_operand")
21986 (match_operand:SI 2 "register_operand")]
21987 "TARGET_USE_FANCY_MATH_387
21988 && flag_unsafe_math_optimizations"
21990 rtx tmp1 = gen_reg_rtx (XFmode);
21991 rtx tmp2 = gen_reg_rtx (XFmode);
21993 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
21994 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
21995 operands[1], tmp1));
21999 (define_expand "ldexp<mode>3"
22000 [(use (match_operand:MODEF 0 "register_operand"))
22001 (use (match_operand:MODEF 1 "general_operand"))
22002 (use (match_operand:SI 2 "register_operand"))]
22003 "((TARGET_USE_FANCY_MATH_387
22004 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22005 || TARGET_MIX_SSE_I387))
22006 || (TARGET_AVX512F && TARGET_SSE_MATH))
22007 && flag_unsafe_math_optimizations"
22009 /* Prefer avx512f version. */
22010 if (TARGET_AVX512F && TARGET_SSE_MATH)
22012 rtx op2 = gen_reg_rtx (<MODE>mode);
22013 operands[1] = force_reg (<MODE>mode, operands[1]);
22015 emit_insn (gen_floatsi<mode>2 (op2, operands[2]));
22016 emit_insn (gen_avx512f_scalef<mode>2 (operands[0], operands[1], op2));
22020 rtx op0 = gen_reg_rtx (XFmode);
22021 rtx op1 = gen_reg_rtx (XFmode);
22023 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22024 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
22025 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
22030 (define_expand "scalbxf3"
22031 [(parallel [(set (match_operand:XF 0 " register_operand")
22032 (unspec:XF [(match_operand:XF 1 "register_operand")
22033 (match_operand:XF 2 "register_operand")]
22034 UNSPEC_FSCALE_FRACT))
22036 (unspec:XF [(match_dup 1) (match_dup 2)]
22037 UNSPEC_FSCALE_EXP))])]
22038 "TARGET_USE_FANCY_MATH_387
22039 && flag_unsafe_math_optimizations"
22040 "operands[3] = gen_reg_rtx (XFmode);")
22042 (define_expand "scalb<mode>3"
22043 [(use (match_operand:MODEF 0 "register_operand"))
22044 (use (match_operand:MODEF 1 "general_operand"))
22045 (use (match_operand:MODEF 2 "general_operand"))]
22046 "TARGET_USE_FANCY_MATH_387
22047 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22048 || TARGET_MIX_SSE_I387)
22049 && flag_unsafe_math_optimizations"
22051 rtx op0 = gen_reg_rtx (XFmode);
22052 rtx op1 = gen_reg_rtx (XFmode);
22053 rtx op2 = gen_reg_rtx (XFmode);
22055 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22056 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
22057 emit_insn (gen_scalbxf3 (op0, op1, op2));
22058 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
22062 (define_expand "significandxf2"
22063 [(parallel [(set (match_operand:XF 0 "register_operand")
22064 (unspec:XF [(match_operand:XF 1 "register_operand")]
22065 UNSPEC_XTRACT_FRACT))
22067 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
22068 "TARGET_USE_FANCY_MATH_387
22069 && flag_unsafe_math_optimizations"
22070 "operands[2] = gen_reg_rtx (XFmode);")
22072 (define_expand "significand<mode>2"
22073 [(use (match_operand:MODEF 0 "register_operand"))
22074 (use (match_operand:MODEF 1 "general_operand"))]
22075 "TARGET_USE_FANCY_MATH_387
22076 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22077 || TARGET_MIX_SSE_I387)
22078 && flag_unsafe_math_optimizations"
22080 rtx op0 = gen_reg_rtx (XFmode);
22081 rtx op1 = gen_reg_rtx (XFmode);
22083 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22084 emit_insn (gen_significandxf2 (op0, op1));
22085 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
22090 (define_insn "sse4_1_round<mode>2"
22091 [(set (match_operand:MODEFH 0 "register_operand" "=x,x,x,v,v")
22093 [(match_operand:MODEFH 1 "nonimmediate_operand" "0,x,jm,v,m")
22094 (match_operand:SI 2 "const_0_to_15_operand")]
22098 %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
22099 %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
22100 %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
22101 vrndscale<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
22102 vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
22103 [(set_attr "type" "ssecvt")
22104 (set_attr "prefix_extra" "1,1,1,*,*")
22105 (set_attr "length_immediate" "1")
22106 (set_attr "addr" "*,*,gpr16,*,*")
22107 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,evex,evex")
22108 (set_attr "isa" "noavx512f,noavx512f,noavx512f,avx512f,avx512f")
22109 (set_attr "avx_partial_xmm_update" "false,false,true,false,true")
22110 (set_attr "mode" "<MODE>")
22111 (set (attr "preferred_for_speed")
22112 (cond [(match_test "TARGET_AVX")
22113 (symbol_ref "true")
22114 (eq_attr "alternative" "1,2")
22115 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
22117 (symbol_ref "true")))])
22119 (define_insn "rintxf2"
22120 [(set (match_operand:XF 0 "register_operand" "=f")
22121 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
22123 "TARGET_USE_FANCY_MATH_387"
22125 [(set_attr "type" "fpspc")
22126 (set_attr "znver1_decode" "vector")
22127 (set_attr "mode" "XF")])
22129 (define_expand "rinthf2"
22130 [(match_operand:HF 0 "register_operand")
22131 (match_operand:HF 1 "nonimmediate_operand")]
22132 "TARGET_AVX512FP16"
22134 emit_insn (gen_sse4_1_roundhf2 (operands[0],
22136 GEN_INT (ROUND_MXCSR)));
22140 (define_expand "rint<mode>2"
22141 [(use (match_operand:MODEF 0 "register_operand"))
22142 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
22143 "TARGET_USE_FANCY_MATH_387
22144 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
22146 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22149 emit_insn (gen_sse4_1_round<mode>2
22150 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
22152 ix86_expand_rint (operands[0], operands[1]);
22156 rtx op0 = gen_reg_rtx (XFmode);
22157 rtx op1 = gen_reg_rtx (XFmode);
22159 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22160 emit_insn (gen_rintxf2 (op0, op1));
22161 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
22166 (define_expand "nearbyintxf2"
22167 [(set (match_operand:XF 0 "register_operand")
22168 (unspec:XF [(match_operand:XF 1 "register_operand")]
22170 "TARGET_USE_FANCY_MATH_387
22171 && !flag_trapping_math")
22173 (define_expand "nearbyinthf2"
22174 [(match_operand:HF 0 "register_operand")
22175 (match_operand:HF 1 "nonimmediate_operand")]
22176 "TARGET_AVX512FP16"
22178 emit_insn (gen_sse4_1_roundhf2 (operands[0],
22180 GEN_INT (ROUND_MXCSR | ROUND_NO_EXC)));
22184 (define_expand "nearbyint<mode>2"
22185 [(use (match_operand:MODEF 0 "register_operand"))
22186 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
22187 "(TARGET_USE_FANCY_MATH_387
22188 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22189 || TARGET_MIX_SSE_I387)
22190 && !flag_trapping_math)
22191 || (TARGET_SSE4_1 && TARGET_SSE_MATH)"
22193 if (TARGET_SSE4_1 && TARGET_SSE_MATH)
22194 emit_insn (gen_sse4_1_round<mode>2
22195 (operands[0], operands[1], GEN_INT (ROUND_MXCSR
22199 rtx op0 = gen_reg_rtx (XFmode);
22200 rtx op1 = gen_reg_rtx (XFmode);
22202 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22203 emit_insn (gen_nearbyintxf2 (op0, op1));
22204 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
22209 (define_expand "roundhf2"
22210 [(match_operand:HF 0 "register_operand")
22211 (match_operand:HF 1 "register_operand")]
22212 "TARGET_AVX512FP16 && !flag_trapping_math && !flag_rounding_math"
22214 ix86_expand_round_sse4 (operands[0], operands[1]);
22218 (define_expand "round<mode>2"
22219 [(match_operand:X87MODEF 0 "register_operand")
22220 (match_operand:X87MODEF 1 "nonimmediate_operand")]
22221 "(TARGET_USE_FANCY_MATH_387
22222 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22223 || TARGET_MIX_SSE_I387)
22224 && flag_unsafe_math_optimizations
22225 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
22226 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
22227 && !flag_trapping_math && !flag_rounding_math)"
22229 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
22230 && !flag_trapping_math && !flag_rounding_math)
22234 operands[1] = force_reg (<MODE>mode, operands[1]);
22235 ix86_expand_round_sse4 (operands[0], operands[1]);
22237 else if (TARGET_64BIT || (<MODE>mode != DFmode))
22238 ix86_expand_round (operands[0], operands[1]);
22240 ix86_expand_rounddf_32 (operands[0], operands[1]);
22244 operands[1] = force_reg (<MODE>mode, operands[1]);
22245 ix86_emit_i387_round (operands[0], operands[1]);
22250 (define_insn "lrintxfdi2"
22251 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
22252 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
22254 (clobber (match_scratch:XF 2 "=&f"))]
22255 "TARGET_USE_FANCY_MATH_387"
22256 "* return output_fix_trunc (insn, operands, false);"
22257 [(set_attr "type" "fpspc")
22258 (set_attr "mode" "DI")])
22260 (define_insn "lrintxf<mode>2"
22261 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
22262 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
22264 "TARGET_USE_FANCY_MATH_387"
22265 "* return output_fix_trunc (insn, operands, false);"
22266 [(set_attr "type" "fpspc")
22267 (set_attr "mode" "<MODE>")])
22269 (define_expand "lroundhf<mode>2"
22270 [(set (match_operand:SWI248 0 "register_operand")
22271 (unspec:SWI248 [(match_operand:HF 1 "nonimmediate_operand")]
22272 UNSPEC_FIX_NOTRUNC))]
22273 "TARGET_AVX512FP16 && !flag_trapping_math && !flag_rounding_math"
22275 ix86_expand_lround (operands[0], operands[1]);
22279 (define_expand "lrinthf<mode>2"
22280 [(set (match_operand:SWI48 0 "register_operand")
22281 (unspec:SWI48 [(match_operand:HF 1 "nonimmediate_operand")]
22282 UNSPEC_FIX_NOTRUNC))]
22283 "TARGET_AVX512FP16")
22285 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
22286 [(set (match_operand:SWI48 0 "register_operand")
22287 (unspec:SWI48 [(match_operand:MODEF 1 "nonimmediate_operand")]
22288 UNSPEC_FIX_NOTRUNC))]
22289 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
22291 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
22292 [(match_operand:SWI248x 0 "nonimmediate_operand")
22293 (match_operand:X87MODEF 1 "register_operand")]
22294 "(TARGET_USE_FANCY_MATH_387
22295 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
22296 || TARGET_MIX_SSE_I387)
22297 && flag_unsafe_math_optimizations)
22298 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
22299 && <SWI248x:MODE>mode != HImode
22300 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
22301 && !flag_trapping_math && !flag_rounding_math)"
22303 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
22304 && <SWI248x:MODE>mode != HImode
22305 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
22306 && !flag_trapping_math && !flag_rounding_math)
22307 ix86_expand_lround (operands[0], operands[1]);
22309 ix86_emit_i387_round (operands[0], operands[1]);
22313 (define_int_iterator FRNDINT_ROUNDING
22314 [UNSPEC_FRNDINT_ROUNDEVEN
22315 UNSPEC_FRNDINT_FLOOR
22316 UNSPEC_FRNDINT_CEIL
22317 UNSPEC_FRNDINT_TRUNC])
22319 (define_int_iterator FIST_ROUNDING
22323 ;; Base name for define_insn
22324 (define_int_attr rounding_insn
22325 [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven")
22326 (UNSPEC_FRNDINT_FLOOR "floor")
22327 (UNSPEC_FRNDINT_CEIL "ceil")
22328 (UNSPEC_FRNDINT_TRUNC "btrunc")
22329 (UNSPEC_FIST_FLOOR "floor")
22330 (UNSPEC_FIST_CEIL "ceil")])
22332 (define_int_attr rounding
22333 [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven")
22334 (UNSPEC_FRNDINT_FLOOR "floor")
22335 (UNSPEC_FRNDINT_CEIL "ceil")
22336 (UNSPEC_FRNDINT_TRUNC "trunc")
22337 (UNSPEC_FIST_FLOOR "floor")
22338 (UNSPEC_FIST_CEIL "ceil")])
22340 (define_int_attr ROUNDING
22341 [(UNSPEC_FRNDINT_ROUNDEVEN "ROUNDEVEN")
22342 (UNSPEC_FRNDINT_FLOOR "FLOOR")
22343 (UNSPEC_FRNDINT_CEIL "CEIL")
22344 (UNSPEC_FRNDINT_TRUNC "TRUNC")
22345 (UNSPEC_FIST_FLOOR "FLOOR")
22346 (UNSPEC_FIST_CEIL "CEIL")])
22348 ;; Rounding mode control word calculation could clobber FLAGS_REG.
22349 (define_insn_and_split "frndintxf2_<rounding>"
22350 [(set (match_operand:XF 0 "register_operand")
22351 (unspec:XF [(match_operand:XF 1 "register_operand")]
22353 (clobber (reg:CC FLAGS_REG))]
22354 "TARGET_USE_FANCY_MATH_387
22355 && (flag_fp_int_builtin_inexact || !flag_trapping_math)
22356 && ix86_pre_reload_split ()"
22361 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
22363 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
22364 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
22366 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
22367 operands[2], operands[3]));
22370 [(set_attr "type" "frndint")
22371 (set_attr "i387_cw" "<rounding>")
22372 (set_attr "mode" "XF")])
22374 (define_insn "frndintxf2_<rounding>_i387"
22375 [(set (match_operand:XF 0 "register_operand" "=f")
22376 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
22378 (use (match_operand:HI 2 "memory_operand" "m"))
22379 (use (match_operand:HI 3 "memory_operand" "m"))]
22380 "TARGET_USE_FANCY_MATH_387
22381 && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
22382 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
22383 [(set_attr "type" "frndint")
22384 (set_attr "i387_cw" "<rounding>")
22385 (set_attr "mode" "XF")])
22387 (define_expand "<rounding_insn>xf2"
22388 [(parallel [(set (match_operand:XF 0 "register_operand")
22389 (unspec:XF [(match_operand:XF 1 "register_operand")]
22391 (clobber (reg:CC FLAGS_REG))])]
22392 "TARGET_USE_FANCY_MATH_387
22393 && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
22395 (define_expand "<rounding_insn>hf2"
22396 [(parallel [(set (match_operand:HF 0 "register_operand")
22397 (unspec:HF [(match_operand:HF 1 "register_operand")]
22399 (clobber (reg:CC FLAGS_REG))])]
22400 "TARGET_AVX512FP16"
22402 emit_insn (gen_sse4_1_roundhf2 (operands[0], operands[1],
22403 GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
22407 (define_expand "<rounding_insn><mode>2"
22408 [(parallel [(set (match_operand:MODEF 0 "register_operand")
22409 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
22411 (clobber (reg:CC FLAGS_REG))])]
22412 "(TARGET_USE_FANCY_MATH_387
22413 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22414 || TARGET_MIX_SSE_I387)
22415 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
22416 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
22418 || (ROUND_<ROUNDING> != ROUND_ROUNDEVEN
22419 && (flag_fp_int_builtin_inexact || !flag_trapping_math))))"
22421 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
22423 || (ROUND_<ROUNDING> != ROUND_ROUNDEVEN
22424 && (flag_fp_int_builtin_inexact || !flag_trapping_math))))
22427 emit_insn (gen_sse4_1_round<mode>2
22428 (operands[0], operands[1],
22429 GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
22430 else if (TARGET_64BIT || (<MODE>mode != DFmode))
22432 if (ROUND_<ROUNDING> == ROUND_FLOOR)
22433 ix86_expand_floorceil (operands[0], operands[1], true);
22434 else if (ROUND_<ROUNDING> == ROUND_CEIL)
22435 ix86_expand_floorceil (operands[0], operands[1], false);
22436 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
22437 ix86_expand_trunc (operands[0], operands[1]);
22439 gcc_unreachable ();
22443 if (ROUND_<ROUNDING> == ROUND_FLOOR)
22444 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
22445 else if (ROUND_<ROUNDING> == ROUND_CEIL)
22446 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
22447 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
22448 ix86_expand_truncdf_32 (operands[0], operands[1]);
22450 gcc_unreachable ();
22455 rtx op0 = gen_reg_rtx (XFmode);
22456 rtx op1 = gen_reg_rtx (XFmode);
22458 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22459 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
22460 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
22465 ;; Rounding mode control word calculation could clobber FLAGS_REG.
22466 (define_insn_and_split "*fist<mode>2_<rounding>_1"
22467 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
22468 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
22470 (clobber (reg:CC FLAGS_REG))]
22471 "TARGET_USE_FANCY_MATH_387
22472 && flag_unsafe_math_optimizations
22473 && ix86_pre_reload_split ()"
22478 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
22480 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
22481 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
22483 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
22484 operands[2], operands[3]));
22487 [(set_attr "type" "fistp")
22488 (set_attr "i387_cw" "<rounding>")
22489 (set_attr "mode" "<MODE>")])
22491 (define_insn "fistdi2_<rounding>"
22492 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
22493 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
22495 (use (match_operand:HI 2 "memory_operand" "m"))
22496 (use (match_operand:HI 3 "memory_operand" "m"))
22497 (clobber (match_scratch:XF 4 "=&f"))]
22498 "TARGET_USE_FANCY_MATH_387
22499 && flag_unsafe_math_optimizations"
22500 "* return output_fix_trunc (insn, operands, false);"
22501 [(set_attr "type" "fistp")
22502 (set_attr "i387_cw" "<rounding>")
22503 (set_attr "mode" "DI")])
22505 (define_insn "fist<mode>2_<rounding>"
22506 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
22507 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
22509 (use (match_operand:HI 2 "memory_operand" "m"))
22510 (use (match_operand:HI 3 "memory_operand" "m"))]
22511 "TARGET_USE_FANCY_MATH_387
22512 && flag_unsafe_math_optimizations"
22513 "* return output_fix_trunc (insn, operands, false);"
22514 [(set_attr "type" "fistp")
22515 (set_attr "i387_cw" "<rounding>")
22516 (set_attr "mode" "<MODE>")])
22518 (define_expand "l<rounding_insn>xf<mode>2"
22519 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
22520 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
22522 (clobber (reg:CC FLAGS_REG))])]
22523 "TARGET_USE_FANCY_MATH_387
22524 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
22525 && flag_unsafe_math_optimizations")
22527 (define_expand "l<rounding_insn>hf<mode>2"
22528 [(set (match_operand:SWI48 0 "nonimmediate_operand")
22529 (unspec:SWI48 [(match_operand:HF 1 "register_operand")]
22531 "TARGET_AVX512FP16"
22533 rtx tmp = gen_reg_rtx (HFmode);
22534 emit_insn (gen_sse4_1_roundhf2 (tmp, operands[1],
22535 GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
22536 emit_insn (gen_fix_trunchf<mode>2 (operands[0], tmp));
22540 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
22541 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
22542 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
22544 (clobber (reg:CC FLAGS_REG))])]
22545 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
22546 && (TARGET_SSE4_1 || !flag_trapping_math)"
22550 rtx tmp = gen_reg_rtx (<MODEF:MODE>mode);
22552 emit_insn (gen_sse4_1_round<MODEF:mode>2
22553 (tmp, operands[1], GEN_INT (ROUND_<ROUNDING>
22555 emit_insn (gen_fix_trunc<MODEF:mode><SWI48:mode>2
22556 (operands[0], tmp));
22558 else if (ROUND_<ROUNDING> == ROUND_FLOOR)
22559 ix86_expand_lfloorceil (operands[0], operands[1], true);
22560 else if (ROUND_<ROUNDING> == ROUND_CEIL)
22561 ix86_expand_lfloorceil (operands[0], operands[1], false);
22563 gcc_unreachable ();
22568 (define_insn "fxam<mode>2_i387"
22569 [(set (match_operand:HI 0 "register_operand" "=a")
22571 [(match_operand:X87MODEF 1 "register_operand" "f")]
22573 "TARGET_USE_FANCY_MATH_387"
22574 "fxam\n\tfnstsw\t%0"
22575 [(set_attr "type" "multi")
22576 (set_attr "length" "4")
22577 (set_attr "unit" "i387")
22578 (set_attr "mode" "<MODE>")])
22580 (define_expand "signbittf2"
22581 [(use (match_operand:SI 0 "register_operand"))
22582 (use (match_operand:TF 1 "register_operand"))]
22587 rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
22588 rtx scratch = gen_reg_rtx (QImode);
22590 emit_insn (gen_ptesttf2 (operands[1], mask));
22591 ix86_expand_setcc (scratch, NE,
22592 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
22594 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
22598 emit_insn (gen_sse_movmskps (operands[0],
22599 gen_lowpart (V4SFmode, operands[1])));
22600 emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8)));
22605 (define_expand "signbitxf2"
22606 [(use (match_operand:SI 0 "register_operand"))
22607 (use (match_operand:XF 1 "register_operand"))]
22608 "TARGET_USE_FANCY_MATH_387"
22610 rtx scratch = gen_reg_rtx (HImode);
22612 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
22613 emit_insn (gen_andsi3 (operands[0],
22614 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
22618 (define_insn "movmsk_df"
22619 [(set (match_operand:SI 0 "register_operand" "=r,jr")
22621 [(match_operand:DF 1 "register_operand" "x,x")]
22623 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
22624 "%vmovmskpd\t{%1, %0|%0, %1}"
22625 [(set_attr "isa" "noavx,avx")
22626 (set_attr "type" "ssemov")
22627 (set_attr "prefix" "maybe_evex")
22628 (set_attr "mode" "DF")])
22630 ;; Use movmskpd in SSE mode to avoid store forwarding stall
22631 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
22632 (define_expand "signbitdf2"
22633 [(use (match_operand:SI 0 "register_operand"))
22634 (use (match_operand:DF 1 "register_operand"))]
22635 "TARGET_USE_FANCY_MATH_387
22636 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
22638 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
22640 emit_insn (gen_movmsk_df (operands[0], operands[1]));
22641 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
22645 rtx scratch = gen_reg_rtx (HImode);
22647 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
22648 emit_insn (gen_andsi3 (operands[0],
22649 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
22654 (define_expand "signbitsf2"
22655 [(use (match_operand:SI 0 "register_operand"))
22656 (use (match_operand:SF 1 "register_operand"))]
22657 "TARGET_USE_FANCY_MATH_387
22658 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
22660 rtx scratch = gen_reg_rtx (HImode);
22662 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
22663 emit_insn (gen_andsi3 (operands[0],
22664 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
22668 ;; Block operation instructions
22671 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
22674 [(set_attr "length" "1")
22675 (set_attr "length_immediate" "0")
22676 (set_attr "modrm" "0")])
22678 (define_expand "cpymem<mode>"
22679 [(use (match_operand:BLK 0 "memory_operand"))
22680 (use (match_operand:BLK 1 "memory_operand"))
22681 (use (match_operand:SWI48 2 "nonmemory_operand"))
22682 (use (match_operand:SWI48 3 "const_int_operand"))
22683 (use (match_operand:SI 4 "const_int_operand"))
22684 (use (match_operand:SI 5 "const_int_operand"))
22685 (use (match_operand:SI 6 ""))
22686 (use (match_operand:SI 7 ""))
22687 (use (match_operand:SI 8 ""))]
22690 if (ix86_expand_set_or_cpymem (operands[0], operands[1],
22691 operands[2], NULL, operands[3],
22692 operands[4], operands[5],
22693 operands[6], operands[7],
22694 operands[8], false))
22700 ;; Most CPUs don't like single string operations
22701 ;; Handle this case here to simplify previous expander.
22703 (define_expand "strmov"
22704 [(set (match_dup 4) (match_operand 3 "memory_operand"))
22705 (set (match_operand 1 "memory_operand") (match_dup 4))
22706 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
22707 (clobber (reg:CC FLAGS_REG))])
22708 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
22709 (clobber (reg:CC FLAGS_REG))])]
22712 /* Can't use this for non-default address spaces. */
22713 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
22716 int piece_size = GET_MODE_SIZE (GET_MODE (operands[1]));
22718 /* If .md ever supports :P for Pmode, these can be directly
22719 in the pattern above. */
22720 operands[5] = plus_constant (Pmode, operands[0], piece_size);
22721 operands[6] = plus_constant (Pmode, operands[2], piece_size);
22723 /* Can't use this if the user has appropriated esi or edi. */
22724 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
22725 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
22727 emit_insn (gen_strmov_singleop (operands[0], operands[1],
22728 operands[2], operands[3],
22729 operands[5], operands[6]));
22733 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
22736 (define_expand "strmov_singleop"
22737 [(parallel [(set (match_operand 1 "memory_operand")
22738 (match_operand 3 "memory_operand"))
22739 (set (match_operand 0 "register_operand")
22741 (set (match_operand 2 "register_operand")
22742 (match_operand 5))])]
22746 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22749 (define_insn "*strmovdi_rex_1"
22750 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
22751 (mem:DI (match_operand:P 3 "register_operand" "1")))
22752 (set (match_operand:P 0 "register_operand" "=D")
22753 (plus:P (match_dup 2)
22755 (set (match_operand:P 1 "register_operand" "=S")
22756 (plus:P (match_dup 3)
22759 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22760 && ix86_check_no_addr_space (insn)"
22762 [(set_attr "type" "str")
22763 (set_attr "memory" "both")
22764 (set_attr "mode" "DI")])
22766 (define_insn "*strmovsi_1"
22767 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
22768 (mem:SI (match_operand:P 3 "register_operand" "1")))
22769 (set (match_operand:P 0 "register_operand" "=D")
22770 (plus:P (match_dup 2)
22772 (set (match_operand:P 1 "register_operand" "=S")
22773 (plus:P (match_dup 3)
22775 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22776 && ix86_check_no_addr_space (insn)"
22778 [(set_attr "type" "str")
22779 (set_attr "memory" "both")
22780 (set_attr "mode" "SI")])
22782 (define_insn "*strmovhi_1"
22783 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
22784 (mem:HI (match_operand:P 3 "register_operand" "1")))
22785 (set (match_operand:P 0 "register_operand" "=D")
22786 (plus:P (match_dup 2)
22788 (set (match_operand:P 1 "register_operand" "=S")
22789 (plus:P (match_dup 3)
22791 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22792 && ix86_check_no_addr_space (insn)"
22794 [(set_attr "type" "str")
22795 (set_attr "memory" "both")
22796 (set_attr "mode" "HI")])
22798 (define_insn "*strmovqi_1"
22799 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
22800 (mem:QI (match_operand:P 3 "register_operand" "1")))
22801 (set (match_operand:P 0 "register_operand" "=D")
22802 (plus:P (match_dup 2)
22804 (set (match_operand:P 1 "register_operand" "=S")
22805 (plus:P (match_dup 3)
22807 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22808 && ix86_check_no_addr_space (insn)"
22810 [(set_attr "type" "str")
22811 (set_attr "memory" "both")
22812 (set (attr "prefix_rex")
22814 (match_test "<P:MODE>mode == DImode")
22816 (const_string "*")))
22817 (set_attr "mode" "QI")])
22819 (define_expand "rep_mov"
22820 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
22821 (set (match_operand 0 "register_operand")
22823 (set (match_operand 2 "register_operand")
22825 (set (match_operand 1 "memory_operand")
22826 (match_operand 3 "memory_operand"))
22827 (use (match_dup 4))])]
22831 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22834 (define_insn "*rep_movdi_rex64"
22835 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
22836 (set (match_operand:P 0 "register_operand" "=D")
22837 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
22839 (match_operand:P 3 "register_operand" "0")))
22840 (set (match_operand:P 1 "register_operand" "=S")
22841 (plus:P (ashift:P (match_dup 5) (const_int 3))
22842 (match_operand:P 4 "register_operand" "1")))
22843 (set (mem:BLK (match_dup 3))
22844 (mem:BLK (match_dup 4)))
22845 (use (match_dup 5))]
22847 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22848 && ix86_check_no_addr_space (insn)"
22850 [(set_attr "type" "str")
22851 (set_attr "prefix_rep" "1")
22852 (set_attr "memory" "both")
22853 (set_attr "mode" "DI")])
22855 (define_insn "*rep_movsi"
22856 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
22857 (set (match_operand:P 0 "register_operand" "=D")
22858 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
22860 (match_operand:P 3 "register_operand" "0")))
22861 (set (match_operand:P 1 "register_operand" "=S")
22862 (plus:P (ashift:P (match_dup 5) (const_int 2))
22863 (match_operand:P 4 "register_operand" "1")))
22864 (set (mem:BLK (match_dup 3))
22865 (mem:BLK (match_dup 4)))
22866 (use (match_dup 5))]
22867 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22868 && ix86_check_no_addr_space (insn)"
22869 "%^rep{%;} movs{l|d}"
22870 [(set_attr "type" "str")
22871 (set_attr "prefix_rep" "1")
22872 (set_attr "memory" "both")
22873 (set_attr "mode" "SI")])
22875 (define_insn "*rep_movqi"
22876 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
22877 (set (match_operand:P 0 "register_operand" "=D")
22878 (plus:P (match_operand:P 3 "register_operand" "0")
22879 (match_operand:P 5 "register_operand" "2")))
22880 (set (match_operand:P 1 "register_operand" "=S")
22881 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
22882 (set (mem:BLK (match_dup 3))
22883 (mem:BLK (match_dup 4)))
22884 (use (match_dup 5))]
22885 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22886 && ix86_check_no_addr_space (insn)"
22888 [(set_attr "type" "str")
22889 (set_attr "prefix_rep" "1")
22890 (set_attr "memory" "both")
22891 (set_attr "mode" "QI")])
22893 (define_expand "setmem<mode>"
22894 [(use (match_operand:BLK 0 "memory_operand"))
22895 (use (match_operand:SWI48 1 "nonmemory_operand"))
22896 (use (match_operand:QI 2 "nonmemory_operand"))
22897 (use (match_operand 3 "const_int_operand"))
22898 (use (match_operand:SI 4 "const_int_operand"))
22899 (use (match_operand:SI 5 "const_int_operand"))
22900 (use (match_operand:SI 6 ""))
22901 (use (match_operand:SI 7 ""))
22902 (use (match_operand:SI 8 ""))]
22905 if (ix86_expand_set_or_cpymem (operands[0], NULL,
22906 operands[1], operands[2],
22907 operands[3], operands[4],
22908 operands[5], operands[6],
22909 operands[7], operands[8], true))
22915 ;; Most CPUs don't like single string operations
22916 ;; Handle this case here to simplify previous expander.
22918 (define_expand "strset"
22919 [(set (match_operand 1 "memory_operand")
22920 (match_operand 2 "register_operand"))
22921 (parallel [(set (match_operand 0 "register_operand")
22923 (clobber (reg:CC FLAGS_REG))])]
22926 /* Can't use this for non-default address spaces. */
22927 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
22930 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
22931 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
22933 /* If .md ever supports :P for Pmode, this can be directly
22934 in the pattern above. */
22935 operands[3] = plus_constant (Pmode, operands[0],
22936 GET_MODE_SIZE (GET_MODE (operands[2])));
22938 /* Can't use this if the user has appropriated eax or edi. */
22939 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
22940 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
22942 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
22948 (define_expand "strset_singleop"
22949 [(parallel [(set (match_operand 1 "memory_operand")
22950 (match_operand 2 "register_operand"))
22951 (set (match_operand 0 "register_operand")
22953 (unspec [(const_int 0)] UNSPEC_STOS)])]
22957 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22960 (define_insn "*strsetdi_rex_1"
22961 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
22962 (match_operand:DI 2 "register_operand" "a"))
22963 (set (match_operand:P 0 "register_operand" "=D")
22964 (plus:P (match_dup 1)
22966 (unspec [(const_int 0)] UNSPEC_STOS)]
22968 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22969 && ix86_check_no_addr_space (insn)"
22971 [(set_attr "type" "str")
22972 (set_attr "memory" "store")
22973 (set_attr "mode" "DI")])
22975 (define_insn "*strsetsi_1"
22976 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
22977 (match_operand:SI 2 "register_operand" "a"))
22978 (set (match_operand:P 0 "register_operand" "=D")
22979 (plus:P (match_dup 1)
22981 (unspec [(const_int 0)] UNSPEC_STOS)]
22982 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22983 && ix86_check_no_addr_space (insn)"
22985 [(set_attr "type" "str")
22986 (set_attr "memory" "store")
22987 (set_attr "mode" "SI")])
22989 (define_insn "*strsethi_1"
22990 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
22991 (match_operand:HI 2 "register_operand" "a"))
22992 (set (match_operand:P 0 "register_operand" "=D")
22993 (plus:P (match_dup 1)
22995 (unspec [(const_int 0)] UNSPEC_STOS)]
22996 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22997 && ix86_check_no_addr_space (insn)"
22999 [(set_attr "type" "str")
23000 (set_attr "memory" "store")
23001 (set_attr "mode" "HI")])
23003 (define_insn "*strsetqi_1"
23004 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
23005 (match_operand:QI 2 "register_operand" "a"))
23006 (set (match_operand:P 0 "register_operand" "=D")
23007 (plus:P (match_dup 1)
23009 (unspec [(const_int 0)] UNSPEC_STOS)]
23010 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
23011 && ix86_check_no_addr_space (insn)"
23013 [(set_attr "type" "str")
23014 (set_attr "memory" "store")
23015 (set (attr "prefix_rex")
23017 (match_test "<P:MODE>mode == DImode")
23019 (const_string "*")))
23020 (set_attr "mode" "QI")])
23022 (define_expand "rep_stos"
23023 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
23024 (set (match_operand 0 "register_operand")
23026 (set (match_operand 2 "memory_operand") (const_int 0))
23027 (use (match_operand 3 "register_operand"))
23028 (use (match_dup 1))])]
23032 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
23035 (define_insn "*rep_stosdi_rex64"
23036 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
23037 (set (match_operand:P 0 "register_operand" "=D")
23038 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
23040 (match_operand:P 3 "register_operand" "0")))
23041 (set (mem:BLK (match_dup 3))
23043 (use (match_operand:DI 2 "register_operand" "a"))
23044 (use (match_dup 4))]
23046 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
23047 && ix86_check_no_addr_space (insn)"
23049 [(set_attr "type" "str")
23050 (set_attr "prefix_rep" "1")
23051 (set_attr "memory" "store")
23052 (set_attr "mode" "DI")])
23054 (define_insn "*rep_stossi"
23055 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
23056 (set (match_operand:P 0 "register_operand" "=D")
23057 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
23059 (match_operand:P 3 "register_operand" "0")))
23060 (set (mem:BLK (match_dup 3))
23062 (use (match_operand:SI 2 "register_operand" "a"))
23063 (use (match_dup 4))]
23064 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
23065 && ix86_check_no_addr_space (insn)"
23066 "%^rep{%;} stos{l|d}"
23067 [(set_attr "type" "str")
23068 (set_attr "prefix_rep" "1")
23069 (set_attr "memory" "store")
23070 (set_attr "mode" "SI")])
23072 (define_insn "*rep_stosqi"
23073 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
23074 (set (match_operand:P 0 "register_operand" "=D")
23075 (plus:P (match_operand:P 3 "register_operand" "0")
23076 (match_operand:P 4 "register_operand" "1")))
23077 (set (mem:BLK (match_dup 3))
23079 (use (match_operand:QI 2 "register_operand" "a"))
23080 (use (match_dup 4))]
23081 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
23082 && ix86_check_no_addr_space (insn)"
23084 [(set_attr "type" "str")
23085 (set_attr "prefix_rep" "1")
23086 (set_attr "memory" "store")
23087 (set (attr "prefix_rex")
23089 (match_test "<P:MODE>mode == DImode")
23091 (const_string "*")))
23092 (set_attr "mode" "QI")])
23094 (define_expand "cmpmemsi"
23095 [(set (match_operand:SI 0 "register_operand" "")
23096 (compare:SI (match_operand:BLK 1 "memory_operand" "")
23097 (match_operand:BLK 2 "memory_operand" "") ) )
23098 (use (match_operand 3 "general_operand"))
23099 (use (match_operand 4 "immediate_operand"))]
23102 if (ix86_expand_cmpstrn_or_cmpmem (operands[0], operands[1],
23103 operands[2], operands[3],
23104 operands[4], false))
23110 (define_expand "cmpstrnsi"
23111 [(set (match_operand:SI 0 "register_operand")
23112 (compare:SI (match_operand:BLK 1 "general_operand")
23113 (match_operand:BLK 2 "general_operand")))
23114 (use (match_operand 3 "general_operand"))
23115 (use (match_operand 4 "immediate_operand"))]
23118 if (ix86_expand_cmpstrn_or_cmpmem (operands[0], operands[1],
23119 operands[2], operands[3],
23120 operands[4], true))
23126 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
23128 (define_expand "cmpintqi"
23129 [(set (match_dup 1)
23130 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
23132 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
23133 (parallel [(set (match_operand:QI 0 "register_operand")
23134 (minus:QI (match_dup 1)
23136 (clobber (reg:CC FLAGS_REG))])]
23139 operands[1] = gen_reg_rtx (QImode);
23140 operands[2] = gen_reg_rtx (QImode);
23143 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
23144 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
23146 (define_expand "cmpstrnqi_nz_1"
23147 [(parallel [(set (reg:CC FLAGS_REG)
23148 (compare:CC (match_operand 4 "memory_operand")
23149 (match_operand 5 "memory_operand")))
23150 (use (match_operand 2 "register_operand"))
23151 (use (match_operand:SI 3 "immediate_operand"))
23152 (clobber (match_operand 0 "register_operand"))
23153 (clobber (match_operand 1 "register_operand"))
23154 (clobber (match_dup 2))])]
23158 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
23161 (define_insn "*cmpstrnqi_nz_1"
23162 [(set (reg:CC FLAGS_REG)
23163 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
23164 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
23165 (use (match_operand:P 6 "register_operand" "2"))
23166 (use (match_operand:SI 3 "immediate_operand" "i"))
23167 (clobber (match_operand:P 0 "register_operand" "=S"))
23168 (clobber (match_operand:P 1 "register_operand" "=D"))
23169 (clobber (match_operand:P 2 "register_operand" "=c"))]
23170 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
23171 && ix86_check_no_addr_space (insn)"
23173 [(set_attr "type" "str")
23174 (set_attr "mode" "QI")
23175 (set (attr "prefix_rex")
23177 (match_test "<P:MODE>mode == DImode")
23179 (const_string "*")))
23180 (set_attr "prefix_rep" "1")])
23182 ;; The same, but the count is not known to not be zero.
23184 (define_expand "cmpstrnqi_1"
23185 [(parallel [(set (reg:CC FLAGS_REG)
23186 (if_then_else:CC (ne (match_operand 2 "register_operand")
23188 (compare:CC (match_operand 4 "memory_operand")
23189 (match_operand 5 "memory_operand"))
23191 (use (match_operand:SI 3 "immediate_operand"))
23192 (use (reg:CC FLAGS_REG))
23193 (clobber (match_operand 0 "register_operand"))
23194 (clobber (match_operand 1 "register_operand"))
23195 (clobber (match_dup 2))])]
23199 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
23202 (define_insn "*cmpstrnqi_1"
23203 [(set (reg:CC FLAGS_REG)
23204 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
23206 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
23207 (mem:BLK (match_operand:P 5 "register_operand" "1")))
23209 (use (match_operand:SI 3 "immediate_operand" "i"))
23210 (use (reg:CC FLAGS_REG))
23211 (clobber (match_operand:P 0 "register_operand" "=S"))
23212 (clobber (match_operand:P 1 "register_operand" "=D"))
23213 (clobber (match_operand:P 2 "register_operand" "=c"))]
23214 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
23215 && ix86_check_no_addr_space (insn)"
23217 [(set_attr "type" "str")
23218 (set_attr "mode" "QI")
23219 (set (attr "prefix_rex")
23221 (match_test "<P:MODE>mode == DImode")
23223 (const_string "*")))
23224 (set_attr "prefix_rep" "1")])
23226 (define_expand "strlen<mode>"
23227 [(set (match_operand:P 0 "register_operand")
23228 (unspec:P [(match_operand:BLK 1 "general_operand")
23229 (match_operand:QI 2 "immediate_operand")
23230 (match_operand 3 "immediate_operand")]
23234 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
23240 (define_expand "strlenqi_1"
23241 [(parallel [(set (match_operand 0 "register_operand")
23243 (clobber (match_operand 1 "register_operand"))
23244 (clobber (reg:CC FLAGS_REG))])]
23248 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
23251 (define_insn "*strlenqi_1"
23252 [(set (match_operand:P 0 "register_operand" "=&c")
23253 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
23254 (match_operand:QI 2 "register_operand" "a")
23255 (match_operand:P 3 "immediate_operand" "i")
23256 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
23257 (clobber (match_operand:P 1 "register_operand" "=D"))
23258 (clobber (reg:CC FLAGS_REG))]
23259 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
23260 && ix86_check_no_addr_space (insn)"
23261 "%^repnz{%;} scasb"
23262 [(set_attr "type" "str")
23263 (set_attr "mode" "QI")
23264 (set (attr "prefix_rex")
23266 (match_test "<P:MODE>mode == DImode")
23268 (const_string "*")))
23269 (set_attr "prefix_rep" "1")])
23271 ;; Peephole optimizations to clean up after cmpstrn*. This should be
23272 ;; handled in combine, but it is not currently up to the task.
23273 ;; When used for their truth value, the cmpstrn* expanders generate
23282 ;; The intermediate three instructions are unnecessary.
23284 ;; This one handles cmpstrn*_nz_1...
23287 (set (reg:CC FLAGS_REG)
23288 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
23289 (mem:BLK (match_operand 5 "register_operand"))))
23290 (use (match_operand 6 "register_operand"))
23291 (use (match_operand:SI 3 "immediate_operand"))
23292 (clobber (match_operand 0 "register_operand"))
23293 (clobber (match_operand 1 "register_operand"))
23294 (clobber (match_operand 2 "register_operand"))])
23295 (set (match_operand:QI 7 "register_operand")
23296 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
23297 (set (match_operand:QI 8 "register_operand")
23298 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
23299 (set (reg FLAGS_REG)
23300 (compare (match_dup 7) (match_dup 8)))
23302 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
23304 (set (reg:CC FLAGS_REG)
23305 (compare:CC (mem:BLK (match_dup 4))
23306 (mem:BLK (match_dup 5))))
23307 (use (match_dup 6))
23308 (use (match_dup 3))
23309 (clobber (match_dup 0))
23310 (clobber (match_dup 1))
23311 (clobber (match_dup 2))])])
23313 ;; ...and this one handles cmpstrn*_1.
23316 (set (reg:CC FLAGS_REG)
23317 (if_then_else:CC (ne (match_operand 6 "register_operand")
23319 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
23320 (mem:BLK (match_operand 5 "register_operand")))
23322 (use (match_operand:SI 3 "immediate_operand"))
23323 (use (reg:CC FLAGS_REG))
23324 (clobber (match_operand 0 "register_operand"))
23325 (clobber (match_operand 1 "register_operand"))
23326 (clobber (match_operand 2 "register_operand"))])
23327 (set (match_operand:QI 7 "register_operand")
23328 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
23329 (set (match_operand:QI 8 "register_operand")
23330 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
23331 (set (reg FLAGS_REG)
23332 (compare (match_dup 7) (match_dup 8)))
23334 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
23336 (set (reg:CC FLAGS_REG)
23337 (if_then_else:CC (ne (match_dup 6)
23339 (compare:CC (mem:BLK (match_dup 4))
23340 (mem:BLK (match_dup 5)))
23342 (use (match_dup 3))
23343 (use (reg:CC FLAGS_REG))
23344 (clobber (match_dup 0))
23345 (clobber (match_dup 1))
23346 (clobber (match_dup 2))])])
23348 ;; Conditional move instructions.
23350 (define_expand "mov<mode>cc"
23351 [(set (match_operand:SWIM 0 "register_operand")
23352 (if_then_else:SWIM (match_operand 1 "comparison_operator")
23353 (match_operand:SWIM 2 "<general_operand>")
23354 (match_operand:SWIM 3 "<general_operand>")))]
23356 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
23358 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
23359 ;; the register first winds up with `sbbl $0,reg', which is also weird.
23360 ;; So just document what we're doing explicitly.
23362 (define_expand "x86_mov<mode>cc_0_m1"
23364 [(set (match_operand:SWI48 0 "register_operand")
23365 (if_then_else:SWI48
23366 (match_operator:SWI48 2 "ix86_carry_flag_operator"
23367 [(match_operand 1 "flags_reg_operand")
23371 (clobber (reg:CC FLAGS_REG))])])
23373 (define_insn "*x86_mov<mode>cc_0_m1"
23374 [(set (match_operand:SWI48 0 "register_operand" "=r")
23375 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
23376 [(reg FLAGS_REG) (const_int 0)])
23379 (clobber (reg:CC FLAGS_REG))]
23381 "sbb{<imodesuffix>}\t%0, %0"
23382 [(set_attr "type" "alu1")
23383 (set_attr "use_carry" "1")
23384 (set_attr "pent_pair" "pu")
23385 (set_attr "mode" "<MODE>")
23386 (set_attr "length_immediate" "0")])
23388 (define_insn "*x86_mov<mode>cc_0_m1_se"
23389 [(set (match_operand:SWI48 0 "register_operand" "=r")
23390 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
23391 [(reg FLAGS_REG) (const_int 0)])
23394 (clobber (reg:CC FLAGS_REG))]
23396 "sbb{<imodesuffix>}\t%0, %0"
23397 [(set_attr "type" "alu1")
23398 (set_attr "use_carry" "1")
23399 (set_attr "pent_pair" "pu")
23400 (set_attr "mode" "<MODE>")
23401 (set_attr "length_immediate" "0")])
23403 (define_insn "*x86_mov<mode>cc_0_m1_neg"
23404 [(set (match_operand:SWI 0 "register_operand" "=<r>")
23405 (neg:SWI (match_operator 1 "ix86_carry_flag_operator"
23406 [(reg FLAGS_REG) (const_int 0)])))
23407 (clobber (reg:CC FLAGS_REG))]
23409 "sbb{<imodesuffix>}\t%0, %0"
23410 [(set_attr "type" "alu1")
23411 (set_attr "use_carry" "1")
23412 (set_attr "pent_pair" "pu")
23413 (set_attr "mode" "<MODE>")
23414 (set_attr "length_immediate" "0")])
23416 (define_expand "x86_mov<mode>cc_0_m1_neg"
23418 [(set (match_operand:SWI48 0 "register_operand")
23419 (neg:SWI48 (ltu:SWI48 (reg:CCC FLAGS_REG) (const_int 0))))
23420 (clobber (reg:CC FLAGS_REG))])])
23423 [(set (match_operand:SWI48 0 "register_operand")
23426 (match_operand 1 "int_nonimmediate_operand")
23427 (match_operand 2 "const_int_operand"))))]
23428 "x86_64_immediate_operand (operands[2], VOIDmode)
23429 && INTVAL (operands[2]) != -1
23430 && INTVAL (operands[2]) != 2147483647"
23431 [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
23433 (neg:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))))]
23434 "operands[2] = GEN_INT (INTVAL (operands[2]) + 1);")
23437 [(set (match_operand:SWI 0 "register_operand")
23440 (match_operand 1 "int_nonimmediate_operand")
23443 [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (const_int 1)))
23445 (neg:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))))])
23448 [(set (match_operand:SWI 0 "register_operand")
23451 (match_operand 1 "int_nonimmediate_operand")
23454 [(set (reg:CCC FLAGS_REG)
23455 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
23457 (neg:SWI (ltu:SWI (reg:CCC FLAGS_REG) (const_int 0))))])
23459 (define_insn "*mov<mode>cc_noc"
23460 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
23461 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
23462 [(reg FLAGS_REG) (const_int 0)])
23463 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
23464 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
23465 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23467 cmov%O2%C1\t{%2, %0|%0, %2}
23468 cmov%O2%c1\t{%3, %0|%0, %3}"
23469 [(set_attr "type" "icmov")
23470 (set_attr "mode" "<MODE>")])
23472 (define_insn "*movsicc_noc_zext"
23473 [(set (match_operand:DI 0 "register_operand" "=r,r")
23474 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
23475 [(reg FLAGS_REG) (const_int 0)])
23477 (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
23479 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
23481 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23483 cmov%O2%C1\t{%2, %k0|%k0, %2}
23484 cmov%O2%c1\t{%3, %k0|%k0, %3}"
23485 [(set_attr "type" "icmov")
23486 (set_attr "mode" "SI")])
23488 (define_insn "*movsicc_noc_zext_1"
23489 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r")
23491 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
23492 [(reg FLAGS_REG) (const_int 0)])
23493 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
23494 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
23496 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23498 cmov%O2%C1\t{%2, %k0|%k0, %2}
23499 cmov%O2%c1\t{%3, %k0|%k0, %3}"
23500 [(set_attr "type" "icmov")
23501 (set_attr "mode" "SI")])
23504 ;; Don't do conditional moves with memory inputs. This splitter helps
23505 ;; register starved x86_32 by forcing inputs into registers before reload.
23507 [(set (match_operand:SWI248 0 "register_operand")
23508 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
23509 [(reg FLAGS_REG) (const_int 0)])
23510 (match_operand:SWI248 2 "nonimmediate_operand")
23511 (match_operand:SWI248 3 "nonimmediate_operand")))]
23512 "!TARGET_64BIT && TARGET_CMOVE
23513 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23514 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23515 && can_create_pseudo_p ()
23516 && optimize_insn_for_speed_p ()"
23517 [(set (match_dup 0)
23518 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
23520 operands[2] = force_reg (<MODE>mode, operands[2]);
23521 operands[3] = force_reg (<MODE>mode, operands[3]);
23524 (define_insn "*movqicc_noc"
23525 [(set (match_operand:QI 0 "register_operand" "=r,r")
23526 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
23527 [(reg FLAGS_REG) (const_int 0)])
23528 (match_operand:QI 2 "register_operand" "r,0")
23529 (match_operand:QI 3 "register_operand" "0,r")))]
23530 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
23532 [(set_attr "type" "icmov")
23533 (set_attr "mode" "QI")])
23536 [(set (match_operand:SWI12 0 "register_operand")
23537 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
23538 [(reg FLAGS_REG) (const_int 0)])
23539 (match_operand:SWI12 2 "register_operand")
23540 (match_operand:SWI12 3 "register_operand")))]
23541 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
23542 && reload_completed"
23543 [(set (match_dup 0)
23544 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
23546 operands[0] = gen_lowpart (SImode, operands[0]);
23547 operands[2] = gen_lowpart (SImode, operands[2]);
23548 operands[3] = gen_lowpart (SImode, operands[3]);
23551 ;; Don't do conditional moves with memory inputs
23553 [(match_scratch:SWI248 4 "r")
23554 (set (match_operand:SWI248 0 "register_operand")
23555 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
23556 [(reg FLAGS_REG) (const_int 0)])
23557 (match_operand:SWI248 2 "nonimmediate_operand")
23558 (match_operand:SWI248 3 "nonimmediate_operand")))]
23559 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23560 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23561 && optimize_insn_for_speed_p ()"
23562 [(set (match_dup 4) (match_dup 5))
23564 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
23566 if (MEM_P (operands[2]))
23568 operands[5] = operands[2];
23569 operands[2] = operands[4];
23571 else if (MEM_P (operands[3]))
23573 operands[5] = operands[3];
23574 operands[3] = operands[4];
23577 gcc_unreachable ();
23581 [(match_scratch:SI 4 "r")
23582 (set (match_operand:DI 0 "register_operand")
23583 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
23584 [(reg FLAGS_REG) (const_int 0)])
23586 (match_operand:SI 2 "nonimmediate_operand"))
23588 (match_operand:SI 3 "nonimmediate_operand"))))]
23590 && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23591 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23592 && optimize_insn_for_speed_p ()"
23593 [(set (match_dup 4) (match_dup 5))
23595 (if_then_else:DI (match_dup 1)
23596 (zero_extend:DI (match_dup 2))
23597 (zero_extend:DI (match_dup 3))))]
23599 if (MEM_P (operands[2]))
23601 operands[5] = operands[2];
23602 operands[2] = operands[4];
23604 else if (MEM_P (operands[3]))
23606 operands[5] = operands[3];
23607 operands[3] = operands[4];
23610 gcc_unreachable ();
23613 ;; Eliminate a reg-reg mov by inverting the condition of a cmov (#1).
23614 ;; mov r0,r1; dec r0; mov r2,r3; cmov r0,r2 -> dec r1; mov r0,r3; cmov r0, r1
23616 [(set (match_operand:SWI248 0 "general_reg_operand")
23617 (match_operand:SWI248 1 "general_reg_operand"))
23618 (parallel [(set (reg FLAGS_REG) (match_operand 5))
23619 (set (match_dup 0) (match_operand:SWI248 6))])
23620 (set (match_operand:SWI248 2 "general_reg_operand")
23621 (match_operand:SWI248 3 "general_gr_operand"))
23623 (if_then_else:SWI248 (match_operator 4 "ix86_comparison_operator"
23624 [(reg FLAGS_REG) (const_int 0)])
23628 && REGNO (operands[2]) != REGNO (operands[0])
23629 && REGNO (operands[2]) != REGNO (operands[1])
23630 && peep2_reg_dead_p (1, operands[1])
23631 && peep2_reg_dead_p (4, operands[2])
23632 && !reg_overlap_mentioned_p (operands[0], operands[3])"
23633 [(parallel [(set (match_dup 7) (match_dup 8))
23634 (set (match_dup 1) (match_dup 9))])
23635 (set (match_dup 0) (match_dup 3))
23636 (set (match_dup 0) (if_then_else:SWI248 (match_dup 4)
23640 operands[7] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
23642 = ix86_replace_reg_with_reg (operands[5], operands[0], operands[1]);
23644 = ix86_replace_reg_with_reg (operands[6], operands[0], operands[1]);
23647 ;; Eliminate a reg-reg mov by inverting the condition of a cmov (#2).
23648 ;; mov r2,r3; mov r0,r1; dec r0; cmov r0,r2 -> dec r1; mov r0,r3; cmov r0, r1
23650 [(set (match_operand:SWI248 2 "general_reg_operand")
23651 (match_operand:SWI248 3 "general_gr_operand"))
23652 (set (match_operand:SWI248 0 "general_reg_operand")
23653 (match_operand:SWI248 1 "general_reg_operand"))
23654 (parallel [(set (reg FLAGS_REG) (match_operand 5))
23655 (set (match_dup 0) (match_operand:SWI248 6))])
23657 (if_then_else:SWI248 (match_operator 4 "ix86_comparison_operator"
23658 [(reg FLAGS_REG) (const_int 0)])
23662 && REGNO (operands[2]) != REGNO (operands[0])
23663 && REGNO (operands[2]) != REGNO (operands[1])
23664 && peep2_reg_dead_p (2, operands[1])
23665 && peep2_reg_dead_p (4, operands[2])
23666 && !reg_overlap_mentioned_p (operands[0], operands[3])
23667 && !reg_mentioned_p (operands[2], operands[6])"
23668 [(parallel [(set (match_dup 7) (match_dup 8))
23669 (set (match_dup 1) (match_dup 9))])
23670 (set (match_dup 0) (match_dup 3))
23671 (set (match_dup 0) (if_then_else:SWI248 (match_dup 4)
23675 operands[7] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (2)), 0, 0));
23677 = ix86_replace_reg_with_reg (operands[5], operands[0], operands[1]);
23679 = ix86_replace_reg_with_reg (operands[6], operands[0], operands[1]);
23682 (define_insn "movhf_mask"
23683 [(set (match_operand:HF 0 "nonimmediate_operand" "=v,m,v")
23685 [(match_operand:HF 1 "nonimmediate_operand" "m,v,v")
23686 (match_operand:HF 2 "nonimm_or_0_operand" "0C,0C,0C")
23687 (match_operand:QI 3 "register_operand" "Yk,Yk,Yk")]
23688 UNSPEC_MOVCC_MASK))]
23689 "TARGET_AVX512FP16"
23691 vmovsh\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}
23692 vmovsh\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}
23693 vmovsh\t{%d1, %0%{%3%}%N2|%0%{%3%}%N2, %d1}"
23694 [(set_attr "type" "ssemov")
23695 (set_attr "prefix" "evex")
23696 (set_attr "mode" "HF")])
23698 (define_expand "movhfcc"
23699 [(set (match_operand:HF 0 "register_operand")
23701 (match_operand 1 "comparison_operator")
23702 (match_operand:HF 2 "register_operand")
23703 (match_operand:HF 3 "register_operand")))]
23704 "TARGET_AVX512FP16"
23705 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
23707 (define_expand "mov<mode>cc"
23708 [(set (match_operand:X87MODEF 0 "register_operand")
23709 (if_then_else:X87MODEF
23710 (match_operand 1 "comparison_operator")
23711 (match_operand:X87MODEF 2 "register_operand")
23712 (match_operand:X87MODEF 3 "register_operand")))]
23713 "(TARGET_80387 && TARGET_CMOVE)
23714 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
23715 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
23717 (define_insn "*movxfcc_1"
23718 [(set (match_operand:XF 0 "register_operand" "=f,f")
23719 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
23720 [(reg FLAGS_REG) (const_int 0)])
23721 (match_operand:XF 2 "register_operand" "f,0")
23722 (match_operand:XF 3 "register_operand" "0,f")))]
23723 "TARGET_80387 && TARGET_CMOVE"
23725 fcmov%F1\t{%2, %0|%0, %2}
23726 fcmov%f1\t{%3, %0|%0, %3}"
23727 [(set_attr "type" "fcmov")
23728 (set_attr "mode" "XF")])
23730 (define_insn "*movdfcc_1"
23731 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
23732 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
23733 [(reg FLAGS_REG) (const_int 0)])
23734 (match_operand:DF 2 "nonimmediate_operand"
23736 (match_operand:DF 3 "nonimmediate_operand"
23737 "0 ,f,0 ,rm,0, rm")))]
23738 "TARGET_80387 && TARGET_CMOVE
23739 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23741 fcmov%F1\t{%2, %0|%0, %2}
23742 fcmov%f1\t{%3, %0|%0, %3}
23745 cmov%O2%C1\t{%2, %0|%0, %2}
23746 cmov%O2%c1\t{%3, %0|%0, %3}"
23747 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
23748 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
23749 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
23752 [(set (match_operand:DF 0 "general_reg_operand")
23753 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
23754 [(reg FLAGS_REG) (const_int 0)])
23755 (match_operand:DF 2 "nonimmediate_operand")
23756 (match_operand:DF 3 "nonimmediate_operand")))]
23757 "!TARGET_64BIT && reload_completed"
23758 [(set (match_dup 2)
23759 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
23761 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
23763 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
23764 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
23767 (define_insn "*movsfcc_1_387"
23768 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
23769 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
23770 [(reg FLAGS_REG) (const_int 0)])
23771 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
23772 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
23773 "TARGET_80387 && TARGET_CMOVE
23774 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23776 fcmov%F1\t{%2, %0|%0, %2}
23777 fcmov%f1\t{%3, %0|%0, %3}
23778 cmov%O2%C1\t{%2, %0|%0, %2}
23779 cmov%O2%c1\t{%3, %0|%0, %3}"
23780 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
23781 (set_attr "mode" "SF,SF,SI,SI")])
23783 ;; Don't do conditional moves with memory inputs. This splitter helps
23784 ;; register starved x86_32 by forcing inputs into registers before reload.
23786 [(set (match_operand:MODEF 0 "register_operand")
23787 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
23788 [(reg FLAGS_REG) (const_int 0)])
23789 (match_operand:MODEF 2 "nonimmediate_operand")
23790 (match_operand:MODEF 3 "nonimmediate_operand")))]
23791 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
23792 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23793 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23794 && can_create_pseudo_p ()
23795 && optimize_insn_for_speed_p ()"
23796 [(set (match_dup 0)
23797 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
23799 operands[2] = force_reg (<MODE>mode, operands[2]);
23800 operands[3] = force_reg (<MODE>mode, operands[3]);
23803 ;; Don't do conditional moves with memory inputs
23805 [(match_scratch:MODEF 4 "r")
23806 (set (match_operand:MODEF 0 "general_reg_operand")
23807 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
23808 [(reg FLAGS_REG) (const_int 0)])
23809 (match_operand:MODEF 2 "nonimmediate_operand")
23810 (match_operand:MODEF 3 "nonimmediate_operand")))]
23811 "(<MODE>mode != DFmode || TARGET_64BIT)
23812 && TARGET_80387 && TARGET_CMOVE
23813 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23814 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23815 && optimize_insn_for_speed_p ()"
23816 [(set (match_dup 4) (match_dup 5))
23818 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
23820 if (MEM_P (operands[2]))
23822 operands[5] = operands[2];
23823 operands[2] = operands[4];
23825 else if (MEM_P (operands[3]))
23827 operands[5] = operands[3];
23828 operands[3] = operands[4];
23831 gcc_unreachable ();
23834 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
23835 ;; the scalar versions to have only XMM registers as operands.
23837 ;; XOP conditional move
23838 (define_insn "*xop_pcmov_<mode>"
23839 [(set (match_operand:MODEF 0 "register_operand" "=x")
23840 (if_then_else:MODEF
23841 (match_operand:MODEF 1 "register_operand" "x")
23842 (match_operand:MODEF 2 "register_operand" "x")
23843 (match_operand:MODEF 3 "register_operand" "x")))]
23845 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
23846 [(set_attr "type" "sse4arg")
23847 (set_attr "mode" "TI")])
23849 ;; These versions of the min/max patterns are intentionally ignorant of
23850 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
23851 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
23852 ;; are undefined in this condition, we're certain this is correct.
23854 (define_insn "<code><mode>3"
23855 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
23857 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
23858 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
23859 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
23861 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
23862 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
23863 [(set_attr "isa" "noavx,avx")
23864 (set_attr "prefix" "orig,vex")
23865 (set_attr "type" "sseadd")
23866 (set_attr "mode" "<MODE>")])
23868 (define_insn "<code>hf3"
23869 [(set (match_operand:HF 0 "register_operand" "=v")
23871 (match_operand:HF 1 "nonimmediate_operand" "%v")
23872 (match_operand:HF 2 "nonimmediate_operand" "vm")))]
23873 "TARGET_AVX512FP16"
23874 "v<maxmin_float>sh\t{%2, %1, %0|%0, %1, %2}"
23875 [(set_attr "prefix" "evex")
23876 (set_attr "type" "sseadd")
23877 (set_attr "mode" "HF")])
23879 ;; These versions of the min/max patterns implement exactly the operations
23880 ;; min = (op1 < op2 ? op1 : op2)
23881 ;; max = (!(op1 < op2) ? op1 : op2)
23882 ;; Their operands are not commutative, and thus they may be used in the
23883 ;; presence of -0.0 and NaN.
23885 (define_insn "*ieee_s<ieee_maxmin>hf3"
23886 [(set (match_operand:HF 0 "register_operand" "=v")
23888 [(match_operand:HF 1 "register_operand" "v")
23889 (match_operand:HF 2 "nonimmediate_operand" "vm")]
23891 "TARGET_AVX512FP16"
23892 "v<ieee_maxmin>sh\t{%2, %1, %0|%0, %1, %2}"
23893 [(set_attr "prefix" "evex")
23894 (set_attr "type" "sseadd")
23895 (set_attr "mode" "HF")])
23897 (define_insn "*ieee_s<ieee_maxmin><mode>3"
23898 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
23900 [(match_operand:MODEF 1 "register_operand" "0,v")
23901 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
23903 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
23905 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
23906 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
23907 [(set_attr "isa" "noavx,avx")
23908 (set_attr "prefix" "orig,maybe_evex")
23909 (set_attr "type" "sseadd")
23910 (set_attr "mode" "<MODE>")])
23912 ;; Operands order in min/max instruction matters for signed zero and NANs.
23913 (define_insn_and_split "*ieee_max<mode>3_1"
23914 [(set (match_operand:MODEF 0 "register_operand")
23916 [(match_operand:MODEF 1 "register_operand")
23917 (match_operand:MODEF 2 "register_operand")
23919 (match_operand:MODEF 3 "register_operand")
23920 (match_operand:MODEF 4 "register_operand"))]
23922 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
23923 && (rtx_equal_p (operands[1], operands[3])
23924 && rtx_equal_p (operands[2], operands[4]))
23925 && ix86_pre_reload_split ()"
23928 [(set (match_dup 0)
23932 UNSPEC_IEEE_MAX))])
23934 (define_insn_and_split "*ieee_min<mode>3_1"
23935 [(set (match_operand:MODEF 0 "register_operand")
23937 [(match_operand:MODEF 1 "register_operand")
23938 (match_operand:MODEF 2 "register_operand")
23940 (match_operand:MODEF 3 "register_operand")
23941 (match_operand:MODEF 4 "register_operand"))]
23943 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
23944 && (rtx_equal_p (operands[1], operands[4])
23945 && rtx_equal_p (operands[2], operands[3]))
23946 && ix86_pre_reload_split ()"
23949 [(set (match_dup 0)
23953 UNSPEC_IEEE_MIN))])
23955 ;; Make two stack loads independent:
23957 ;; fld %st(0) -> fld bb
23958 ;; fmul bb fmul %st(1), %st
23960 ;; Actually we only match the last two instructions for simplicity.
23963 [(set (match_operand 0 "fp_register_operand")
23964 (match_operand 1 "fp_register_operand"))
23966 (match_operator 2 "binary_fp_operator"
23968 (match_operand 3 "memory_operand")]))]
23969 "REGNO (operands[0]) != REGNO (operands[1])"
23970 [(set (match_dup 0) (match_dup 3))
23973 [(match_dup 5) (match_dup 4)]))]
23975 operands[4] = operands[0];
23976 operands[5] = operands[1];
23978 /* The % modifier is not operational anymore in peephole2's, so we have to
23979 swap the operands manually in the case of addition and multiplication. */
23980 if (COMMUTATIVE_ARITH_P (operands[2]))
23981 std::swap (operands[4], operands[5]);
23985 [(set (match_operand 0 "fp_register_operand")
23986 (match_operand 1 "fp_register_operand"))
23988 (match_operator 2 "binary_fp_operator"
23989 [(match_operand 3 "memory_operand")
23991 "REGNO (operands[0]) != REGNO (operands[1])"
23992 [(set (match_dup 0) (match_dup 3))
23995 [(match_dup 4) (match_dup 5)]))]
23997 operands[4] = operands[0];
23998 operands[5] = operands[1];
24000 /* The % modifier is not operational anymore in peephole2's, so we have to
24001 swap the operands manually in the case of addition and multiplication. */
24002 if (COMMUTATIVE_ARITH_P (operands[2]))
24003 std::swap (operands[4], operands[5]);
24006 ;; Conditional addition patterns
24007 (define_expand "add<mode>cc"
24008 [(match_operand:SWI 0 "register_operand")
24009 (match_operand 1 "ordered_comparison_operator")
24010 (match_operand:SWI 2 "register_operand")
24011 (match_operand:SWI 3 "const_int_operand")]
24013 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
24015 ;; min/max patterns
24017 (define_code_attr maxmin_rel
24018 [(smax "GE") (smin "LE") (umax "GEU") (umin "LEU")])
24020 (define_expand "<code><mode>3"
24022 [(set (match_operand:SDWIM 0 "register_operand")
24024 (match_operand:SDWIM 1 "register_operand")
24025 (match_operand:SDWIM 2 "general_operand")))
24026 (clobber (reg:CC FLAGS_REG))])]
24028 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)")
24030 (define_insn_and_split "*<code><dwi>3_doubleword"
24031 [(set (match_operand:<DWI> 0 "register_operand")
24033 (match_operand:<DWI> 1 "register_operand")
24034 (match_operand:<DWI> 2 "general_operand")))
24035 (clobber (reg:CC FLAGS_REG))]
24037 && ix86_pre_reload_split ()"
24040 [(set (match_dup 0)
24041 (if_then_else:DWIH (match_dup 6)
24045 (if_then_else:DWIH (match_dup 6)
24049 operands[2] = force_reg (<DWI>mode, operands[2]);
24051 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
24053 rtx cmplo[2] = { operands[1], operands[2] };
24054 rtx cmphi[2] = { operands[4], operands[5] };
24056 enum rtx_code code = <maxmin_rel>;
24061 std::swap (cmplo[0], cmplo[1]);
24062 std::swap (cmphi[0], cmphi[1]);
24063 code = swap_condition (code);
24068 bool uns = (code == GEU);
24069 rtx (*sbb_insn) (machine_mode, rtx, rtx, rtx)
24070 = uns ? gen_sub3_carry_ccc : gen_sub3_carry_ccgz;
24072 emit_insn (gen_cmp_1 (<MODE>mode, cmplo[0], cmplo[1]));
24074 rtx tmp = gen_rtx_SCRATCH (<MODE>mode);
24075 emit_insn (sbb_insn (<MODE>mode, tmp, cmphi[0], cmphi[1]));
24077 rtx flags = gen_rtx_REG (uns ? CCCmode : CCGZmode, FLAGS_REG);
24078 operands[6] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
24084 gcc_unreachable ();
24088 (define_insn_and_split "*<code><mode>3_1"
24089 [(set (match_operand:SWI 0 "register_operand")
24091 (match_operand:SWI 1 "register_operand")
24092 (match_operand:SWI 2 "general_operand")))
24093 (clobber (reg:CC FLAGS_REG))]
24095 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
24096 && ix86_pre_reload_split ()"
24099 [(set (match_dup 0)
24100 (if_then_else:SWI (match_dup 3)
24104 machine_mode mode = <MODE>mode;
24105 rtx cmp_op = operands[2];
24107 operands[2] = force_reg (mode, cmp_op);
24109 enum rtx_code code = <maxmin_rel>;
24111 if (cmp_op == const1_rtx)
24113 /* Convert smax (x, 1) into (x > 0 ? x : 1).
24114 Convert umax (x, 1) into (x != 0 ? x : 1).
24115 Convert ?min (x, 1) into (x <= 0 ? x : 1). */
24116 cmp_op = const0_rtx;
24119 else if (code == GEU)
24122 /* Convert smin (x, -1) into (x < 0 ? x : -1). */
24123 else if (cmp_op == constm1_rtx && code == LE)
24125 cmp_op = const0_rtx;
24128 /* Convert smax (x, -1) into (x >= 0 ? x : -1). */
24129 else if (cmp_op == constm1_rtx && code == GE)
24130 cmp_op = const0_rtx;
24131 else if (cmp_op != const0_rtx)
24132 cmp_op = operands[2];
24134 machine_mode cmpmode = SELECT_CC_MODE (code, operands[1], cmp_op);
24135 rtx flags = gen_rtx_REG (cmpmode, FLAGS_REG);
24137 rtx tmp = gen_rtx_COMPARE (cmpmode, operands[1], cmp_op);
24138 emit_insn (gen_rtx_SET (flags, tmp));
24140 operands[3] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
24143 ;; Avoid clearing a register between a flags setting comparison and its use,
24144 ;; i.e. prefer "xorl %eax,%eax; test/cmp" over "test/cmp; movl $0, %eax".
24146 [(set (reg FLAGS_REG) (match_operand 0))
24147 (set (match_operand:SWI 1 "general_reg_operand") (const_int 0))]
24148 "peep2_regno_dead_p (0, FLAGS_REG)
24149 && !reg_overlap_mentioned_p (operands[1], operands[0])"
24150 [(set (match_dup 2) (match_dup 0))]
24152 operands[2] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
24153 ix86_expand_clear (operands[1]);
24156 ;; When optimizing for size, zeroing memory should use a register.
24158 [(match_scratch:SWI48 0 "r")
24159 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
24160 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))
24161 (set (match_operand:SWI48 3 "memory_operand") (const_int 0))
24162 (set (match_operand:SWI48 4 "memory_operand") (const_int 0))]
24163 "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
24166 ix86_expand_clear (operands[0]);
24167 emit_move_insn (operands[1], operands[0]);
24168 emit_move_insn (operands[2], operands[0]);
24169 emit_move_insn (operands[3], operands[0]);
24170 ix86_last_zero_store_uid
24171 = INSN_UID (emit_move_insn (operands[4], operands[0]));
24176 [(match_scratch:SWI48 0 "r")
24177 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
24178 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))]
24179 "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
24182 ix86_expand_clear (operands[0]);
24183 emit_move_insn (operands[1], operands[0]);
24184 ix86_last_zero_store_uid
24185 = INSN_UID (emit_move_insn (operands[2], operands[0]));
24190 [(match_scratch:SWI48 0 "r")
24191 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))]
24192 "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
24195 ix86_expand_clear (operands[0]);
24196 ix86_last_zero_store_uid
24197 = INSN_UID (emit_move_insn (operands[1], operands[0]));
24202 [(set (match_operand:SWI48 5 "memory_operand")
24203 (match_operand:SWI48 0 "general_reg_operand"))
24204 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
24205 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))
24206 (set (match_operand:SWI48 3 "memory_operand") (const_int 0))
24207 (set (match_operand:SWI48 4 "memory_operand") (const_int 0))]
24208 "optimize_insn_for_size_p ()
24209 && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
24212 emit_move_insn (operands[5], operands[0]);
24213 emit_move_insn (operands[1], operands[0]);
24214 emit_move_insn (operands[2], operands[0]);
24215 emit_move_insn (operands[3], operands[0]);
24216 ix86_last_zero_store_uid
24217 = INSN_UID (emit_move_insn (operands[4], operands[0]));
24222 [(set (match_operand:SWI48 3 "memory_operand")
24223 (match_operand:SWI48 0 "general_reg_operand"))
24224 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
24225 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))]
24226 "optimize_insn_for_size_p ()
24227 && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
24230 emit_move_insn (operands[3], operands[0]);
24231 emit_move_insn (operands[1], operands[0]);
24232 ix86_last_zero_store_uid
24233 = INSN_UID (emit_move_insn (operands[2], operands[0]));
24238 [(set (match_operand:SWI48 2 "memory_operand")
24239 (match_operand:SWI48 0 "general_reg_operand"))
24240 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))]
24241 "optimize_insn_for_size_p ()
24242 && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
24245 emit_move_insn (operands[2], operands[0]);
24246 ix86_last_zero_store_uid
24247 = INSN_UID (emit_move_insn (operands[1], operands[0]));
24251 ;; Reload dislikes loading constants directly into class_likely_spilled
24252 ;; hard registers. Try to tidy things up here.
24254 [(set (match_operand:SWI 0 "general_reg_operand")
24255 (match_operand:SWI 1 "x86_64_general_operand"))
24256 (set (match_operand:SWI 2 "general_reg_operand")
24258 "peep2_reg_dead_p (2, operands[0])"
24259 [(set (match_dup 2) (match_dup 1))])
24261 ;; Misc patterns (?)
24263 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
24264 ;; Otherwise there will be nothing to keep
24266 ;; [(set (reg ebp) (reg esp))]
24267 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
24268 ;; (clobber (eflags)]
24269 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
24271 ;; in proper program order.
24273 (define_insn "@pro_epilogue_adjust_stack_add_<mode>"
24274 [(set (match_operand:P 0 "register_operand" "=r,r")
24275 (plus:P (match_operand:P 1 "register_operand" "0,r")
24276 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
24277 (clobber (reg:CC FLAGS_REG))
24278 (clobber (mem:BLK (scratch)))]
24281 switch (get_attr_type (insn))
24284 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
24287 gcc_assert (rtx_equal_p (operands[0], operands[1]));
24288 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
24289 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
24291 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
24294 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
24295 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
24298 [(set (attr "type")
24299 (cond [(and (eq_attr "alternative" "0")
24300 (not (match_test "TARGET_OPT_AGU")))
24301 (const_string "alu")
24302 (match_operand:<MODE> 2 "const0_operand")
24303 (const_string "imov")
24305 (const_string "lea")))
24306 (set (attr "length_immediate")
24307 (cond [(eq_attr "type" "imov")
24309 (and (eq_attr "type" "alu")
24310 (match_operand 2 "const128_operand"))
24313 (const_string "*")))
24314 (set_attr "mode" "<MODE>")])
24316 (define_insn "@pro_epilogue_adjust_stack_sub_<mode>"
24317 [(set (match_operand:P 0 "register_operand" "=r")
24318 (minus:P (match_operand:P 1 "register_operand" "0")
24319 (match_operand:P 2 "register_operand" "r")))
24320 (clobber (reg:CC FLAGS_REG))
24321 (clobber (mem:BLK (scratch)))]
24323 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
24324 [(set_attr "type" "alu")
24325 (set_attr "mode" "<MODE>")])
24327 (define_insn "@allocate_stack_worker_probe_<mode>"
24328 [(set (match_operand:P 0 "register_operand" "=a")
24329 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
24330 UNSPECV_STACK_PROBE))
24331 (clobber (reg:CC FLAGS_REG))]
24332 "ix86_target_stack_probe ()"
24333 "call\t___chkstk_ms"
24334 [(set_attr "type" "multi")
24335 (set_attr "length" "5")])
24337 (define_expand "allocate_stack"
24338 [(match_operand 0 "register_operand")
24339 (match_operand 1 "general_operand")]
24340 "ix86_target_stack_probe ()"
24344 #ifndef CHECK_STACK_LIMIT
24345 #define CHECK_STACK_LIMIT 0
24348 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
24349 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
24353 x = copy_to_mode_reg (Pmode, operands[1]);
24355 emit_insn (gen_allocate_stack_worker_probe (Pmode, x, x));
24358 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
24359 stack_pointer_rtx, 0, OPTAB_DIRECT);
24361 if (x != stack_pointer_rtx)
24362 emit_move_insn (stack_pointer_rtx, x);
24364 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
24368 (define_expand "probe_stack"
24369 [(match_operand 0 "memory_operand")]
24372 emit_insn (gen_probe_stack_1
24373 (word_mode, operands[0], const0_rtx));
24377 ;; Use OR for stack probes, this is shorter.
24378 (define_insn "@probe_stack_1_<mode>"
24379 [(set (match_operand:W 0 "memory_operand" "=m")
24380 (unspec:W [(match_operand:W 1 "const0_operand")]
24381 UNSPEC_PROBE_STACK))
24382 (clobber (reg:CC FLAGS_REG))]
24384 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
24385 [(set_attr "type" "alu1")
24386 (set_attr "mode" "<MODE>")
24387 (set_attr "length_immediate" "1")])
24389 (define_insn "@adjust_stack_and_probe_<mode>"
24390 [(set (match_operand:P 0 "register_operand" "=r")
24391 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
24392 UNSPECV_PROBE_STACK_RANGE))
24393 (set (reg:P SP_REG)
24394 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand")))
24395 (clobber (reg:CC FLAGS_REG))
24396 (clobber (mem:BLK (scratch)))]
24398 "* return output_adjust_stack_and_probe (operands[0]);"
24399 [(set_attr "type" "multi")])
24401 (define_insn "@probe_stack_range_<mode>"
24402 [(set (match_operand:P 0 "register_operand" "=r")
24403 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
24404 (match_operand:P 2 "const_int_operand")]
24405 UNSPECV_PROBE_STACK_RANGE))
24406 (clobber (reg:CC FLAGS_REG))]
24408 "* return output_probe_stack_range (operands[0], operands[2]);"
24409 [(set_attr "type" "multi")])
24411 (define_expand "builtin_setjmp_receiver"
24412 [(label_ref (match_operand 0))]
24413 "!TARGET_64BIT && flag_pic"
24419 rtx_code_label *label_rtx = gen_label_rtx ();
24420 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
24421 xops[0] = xops[1] = pic_offset_table_rtx;
24422 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
24423 ix86_expand_binary_operator (MINUS, SImode, xops);
24427 emit_insn (gen_set_got (pic_offset_table_rtx));
24431 (define_expand "save_stack_nonlocal"
24432 [(set (match_operand 0 "memory_operand")
24433 (match_operand 1 "register_operand"))]
24438 if (flag_cf_protection & CF_RETURN)
24440 /* Copy shadow stack pointer to the first slot
24441 and stack pointer to the second slot. */
24442 rtx ssp_slot = adjust_address (operands[0], word_mode, 0);
24443 stack_slot = adjust_address (operands[0], Pmode, UNITS_PER_WORD);
24445 rtx reg_ssp = force_reg (word_mode, const0_rtx);
24446 emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
24447 emit_move_insn (ssp_slot, reg_ssp);
24450 stack_slot = adjust_address (operands[0], Pmode, 0);
24451 emit_move_insn (stack_slot, operands[1]);
24455 (define_expand "restore_stack_nonlocal"
24456 [(set (match_operand 0 "register_operand" "")
24457 (match_operand 1 "memory_operand" ""))]
24462 if (flag_cf_protection & CF_RETURN)
24464 /* Restore shadow stack pointer from the first slot
24465 and stack pointer from the second slot. */
24466 rtx ssp_slot = adjust_address (operands[1], word_mode, 0);
24467 stack_slot = adjust_address (operands[1], Pmode, UNITS_PER_WORD);
24469 /* Get the current shadow stack pointer. The code below will check if
24470 SHSTK feature is enabled. If it is not enabled the RDSSP instruction
24472 rtx reg_ssp = force_reg (word_mode, const0_rtx);
24473 emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
24475 /* Compare through subtraction the saved and the current ssp
24476 to decide if ssp has to be adjusted. */
24477 reg_ssp = expand_simple_binop (word_mode, MINUS,
24479 reg_ssp, 1, OPTAB_DIRECT);
24481 /* Compare and jump over adjustment code. */
24482 rtx noadj_label = gen_label_rtx ();
24483 emit_cmp_and_jump_insns (reg_ssp, const0_rtx, EQ, NULL_RTX,
24484 word_mode, 1, noadj_label);
24486 /* Compute the number of frames to adjust. */
24487 rtx reg_adj = gen_lowpart (ptr_mode, reg_ssp);
24488 rtx reg_adj_neg = expand_simple_unop (ptr_mode, NEG, reg_adj,
24491 reg_adj = expand_simple_binop (ptr_mode, LSHIFTRT, reg_adj_neg,
24492 GEN_INT (exact_log2 (UNITS_PER_WORD)),
24493 reg_adj, 1, OPTAB_DIRECT);
24495 /* Check if number of frames <= 255 so no loop is needed. */
24496 rtx inc_label = gen_label_rtx ();
24497 emit_cmp_and_jump_insns (reg_adj, GEN_INT (255), LEU, NULL_RTX,
24498 ptr_mode, 1, inc_label);
24500 /* Adjust the ssp in a loop. */
24501 rtx loop_label = gen_label_rtx ();
24502 emit_label (loop_label);
24503 LABEL_NUSES (loop_label) = 1;
24505 rtx reg_255 = force_reg (word_mode, GEN_INT (255));
24506 emit_insn (gen_incssp (word_mode, reg_255));
24508 reg_adj = expand_simple_binop (ptr_mode, MINUS,
24509 reg_adj, GEN_INT (255),
24510 reg_adj, 1, OPTAB_DIRECT);
24512 /* Compare and jump to the loop label. */
24513 emit_cmp_and_jump_insns (reg_adj, GEN_INT (255), GTU, NULL_RTX,
24514 ptr_mode, 1, loop_label);
24516 emit_label (inc_label);
24517 LABEL_NUSES (inc_label) = 1;
24519 emit_insn (gen_incssp (word_mode, reg_ssp));
24521 emit_label (noadj_label);
24522 LABEL_NUSES (noadj_label) = 1;
24525 stack_slot = adjust_address (operands[1], Pmode, 0);
24526 emit_move_insn (operands[0], stack_slot);
24530 (define_expand "stack_protect_set"
24531 [(match_operand 0 "memory_operand")
24532 (match_operand 1 "memory_operand")]
24535 rtx scratch = gen_reg_rtx (word_mode);
24537 emit_insn (gen_stack_protect_set_1
24538 (ptr_mode, word_mode, operands[0], operands[1], scratch));
24542 (define_insn "@stack_protect_set_1_<PTR:mode>_<W:mode>"
24543 [(set (match_operand:PTR 0 "memory_operand" "=m")
24544 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
24546 (set (match_operand:W 2 "register_operand" "=&r") (const_int 0))
24547 (clobber (reg:CC FLAGS_REG))]
24550 output_asm_insn ("mov{<PTR:imodesuffix>}\t{%1, %<PTR:k>2|%<PTR:k>2, %1}",
24552 output_asm_insn ("mov{<PTR:imodesuffix>}\t{%<PTR:k>2, %0|%0, %<PTR:k>2}",
24554 if (!TARGET_USE_MOV0 || optimize_insn_for_size_p ())
24555 return "xor{l}\t%k2, %k2";
24557 return "mov{l}\t{$0, %k2|%k2, 0}";
24559 [(set_attr "type" "multi")])
24561 ;; Patterns and peephole2s to optimize stack_protect_set_1_<mode>
24562 ;; immediately followed by *mov{s,d}i_internal, where we can avoid
24563 ;; the xor{l} above. We don't split this, so that scheduling or
24564 ;; anything else doesn't separate the *stack_protect_set* pattern from
24565 ;; the set of the register that overwrites the register with a new value.
24568 [(parallel [(set (match_operand:PTR 0 "memory_operand")
24569 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
24571 (set (match_operand 2 "general_reg_operand") (const_int 0))
24572 (clobber (reg:CC FLAGS_REG))])
24573 (set (match_operand 3 "general_reg_operand")
24574 (match_operand 4 "const0_operand"))]
24575 "GET_MODE (operands[2]) == word_mode
24576 && GET_MODE_SIZE (GET_MODE (operands[3])) <= UNITS_PER_WORD
24577 && peep2_reg_dead_p (0, operands[3])
24578 && peep2_reg_dead_p (1, operands[2])"
24579 [(parallel [(set (match_dup 0)
24580 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
24581 (set (match_dup 3) (const_int 0))
24582 (clobber (reg:CC FLAGS_REG))])]
24583 "operands[3] = gen_lowpart (word_mode, operands[3]);")
24585 (define_insn "*stack_protect_set_2_<mode>_si"
24586 [(set (match_operand:PTR 0 "memory_operand" "=m")
24587 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
24589 (set (match_operand:SI 1 "register_operand" "=&r")
24590 (match_operand:SI 2 "general_operand" "g"))]
24593 output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
24594 output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
24595 if (pic_32bit_operand (operands[2], SImode)
24596 || ix86_use_lea_for_mov (insn, operands + 1))
24597 return "lea{l}\t{%E2, %1|%1, %E2}";
24599 return "mov{l}\t{%2, %1|%1, %2}";
24601 [(set_attr "type" "multi")
24602 (set_attr "length" "24")])
24604 (define_insn "*stack_protect_set_2_<mode>_di"
24605 [(set (match_operand:PTR 0 "memory_operand" "=m,m,m")
24606 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m,m,m")]
24608 (set (match_operand:DI 1 "register_operand" "=&r,&r,&r")
24609 (match_operand:DI 2 "general_operand" "Z,rem,i"))]
24610 "TARGET_64BIT && reload_completed"
24612 output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
24613 output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
24614 if (pic_32bit_operand (operands[2], DImode))
24615 return "lea{q}\t{%E2, %1|%1, %E2}";
24616 else if (which_alternative == 0)
24617 return "mov{l}\t{%k2, %k1|%k1, %k2}";
24618 else if (which_alternative == 2)
24619 return "movabs{q}\t{%2, %1|%1, %2}";
24620 else if (ix86_use_lea_for_mov (insn, operands + 1))
24621 return "lea{q}\t{%E2, %1|%1, %E2}";
24623 return "mov{q}\t{%2, %1|%1, %2}";
24625 [(set_attr "type" "multi")
24626 (set_attr "length" "24")])
24629 [(parallel [(set (match_operand:PTR 0 "memory_operand")
24630 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
24632 (set (match_operand 2 "general_reg_operand") (const_int 0))
24633 (clobber (reg:CC FLAGS_REG))])
24634 (set (match_operand:SWI48 3 "general_reg_operand")
24635 (match_operand:SWI48 4 "general_gr_operand"))]
24636 "GET_MODE (operands[2]) == word_mode
24637 && peep2_reg_dead_p (0, operands[3])
24638 && peep2_reg_dead_p (1, operands[2])"
24639 [(parallel [(set (match_dup 0)
24640 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
24641 (set (match_dup 3) (match_dup 4))])])
24644 [(set (match_operand:SWI48 3 "general_reg_operand")
24645 (match_operand:SWI48 4 "general_gr_operand"))
24646 (parallel [(set (match_operand:PTR 0 "memory_operand")
24647 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
24649 (set (match_operand 2 "general_reg_operand") (const_int 0))
24650 (clobber (reg:CC FLAGS_REG))])]
24651 "GET_MODE (operands[2]) == word_mode
24652 && peep2_reg_dead_p (0, operands[3])
24653 && peep2_reg_dead_p (2, operands[2])
24654 && !reg_mentioned_p (operands[3], operands[0])
24655 && !reg_mentioned_p (operands[3], operands[1])"
24656 [(parallel [(set (match_dup 0)
24657 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
24658 (set (match_dup 3) (match_dup 4))])])
24660 (define_insn "*stack_protect_set_3_<PTR:mode>_<SWI48:mode>"
24661 [(set (match_operand:PTR 0 "memory_operand" "=m")
24662 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
24664 (set (match_operand:SWI48 1 "register_operand" "=&r")
24665 (match_operand:SWI48 2 "address_no_seg_operand" "Ts"))]
24668 output_asm_insn ("mov{<PTR:imodesuffix>}\t{%3, %<PTR:k>1|%<PTR:k>1, %3}",
24670 output_asm_insn ("mov{<PTR:imodesuffix>}\t{%<PTR:k>1, %0|%0, %<PTR:k>1}",
24672 if (SImode_address_operand (operands[2], VOIDmode))
24674 gcc_assert (TARGET_64BIT);
24675 return "lea{l}\t{%E2, %k1|%k1, %E2}";
24678 return "lea{<SWI48:imodesuffix>}\t{%E2, %1|%1, %E2}";
24680 [(set_attr "type" "multi")
24681 (set_attr "length" "24")])
24684 [(parallel [(set (match_operand:PTR 0 "memory_operand")
24685 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
24687 (set (match_operand 2 "general_reg_operand") (const_int 0))
24688 (clobber (reg:CC FLAGS_REG))])
24689 (set (match_operand:SWI48 3 "general_reg_operand")
24690 (match_operand:SWI48 4 "address_no_seg_operand"))]
24691 "GET_MODE (operands[2]) == word_mode
24692 && peep2_reg_dead_p (0, operands[3])
24693 && peep2_reg_dead_p (1, operands[2])"
24694 [(parallel [(set (match_dup 0)
24695 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
24696 (set (match_dup 3) (match_dup 4))])])
24698 (define_insn "*stack_protect_set_4z_<mode>_di"
24699 [(set (match_operand:PTR 0 "memory_operand" "=m")
24700 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
24702 (set (match_operand:DI 1 "register_operand" "=&r")
24703 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))]
24704 "TARGET_64BIT && reload_completed"
24706 output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
24707 output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
24708 if (ix86_use_lea_for_mov (insn, operands + 1))
24709 return "lea{l}\t{%E2, %k1|%k1, %E2}";
24711 return "mov{l}\t{%2, %k1|%k1, %2}";
24713 [(set_attr "type" "multi")
24714 (set_attr "length" "24")])
24716 (define_insn "*stack_protect_set_4s_<mode>_di"
24717 [(set (match_operand:PTR 0 "memory_operand" "=m")
24718 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
24720 (set (match_operand:DI 1 "register_operand" "=&r")
24721 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))]
24722 "TARGET_64BIT && reload_completed"
24724 output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
24725 output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
24726 return "movs{lq|x}\t{%2, %1|%1, %2}";
24728 [(set_attr "type" "multi")
24729 (set_attr "length" "24")])
24732 [(parallel [(set (match_operand:PTR 0 "memory_operand")
24733 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
24735 (set (match_operand 2 "general_reg_operand") (const_int 0))
24736 (clobber (reg:CC FLAGS_REG))])
24737 (set (match_operand:DI 3 "general_reg_operand")
24739 (match_operand:SI 4 "nonimmediate_gr_operand")))]
24741 && GET_MODE (operands[2]) == word_mode
24742 && peep2_reg_dead_p (0, operands[3])
24743 && peep2_reg_dead_p (1, operands[2])"
24744 [(parallel [(set (match_dup 0)
24745 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
24747 (any_extend:DI (match_dup 4)))])])
24749 (define_expand "stack_protect_test"
24750 [(match_operand 0 "memory_operand")
24751 (match_operand 1 "memory_operand")
24755 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
24757 emit_insn (gen_stack_protect_test_1
24758 (ptr_mode, flags, operands[0], operands[1]));
24760 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
24761 flags, const0_rtx, operands[2]));
24765 (define_insn "@stack_protect_test_1_<mode>"
24766 [(set (match_operand:CCZ 0 "flags_reg_operand")
24767 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
24768 (match_operand:PTR 2 "memory_operand" "m")]
24770 (clobber (match_scratch:PTR 3 "=&r"))]
24773 output_asm_insn ("mov{<imodesuffix>}\t{%1, %3|%3, %1}", operands);
24774 return "sub{<imodesuffix>}\t{%2, %3|%3, %2}";
24776 [(set_attr "type" "multi")])
24778 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
24779 ;; Do not split instructions with mask registers.
24781 [(set (match_operand 0 "general_reg_operand")
24782 (match_operator 3 "promotable_binary_operator"
24783 [(match_operand 1 "general_reg_operand")
24784 (match_operand 2 "aligned_operand")]))
24785 (clobber (reg:CC FLAGS_REG))]
24786 "! TARGET_PARTIAL_REG_STALL && reload_completed
24787 && ((GET_MODE (operands[0]) == HImode
24788 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
24789 /* ??? next two lines just !satisfies_constraint_K (...) */
24790 || !CONST_INT_P (operands[2])
24791 || satisfies_constraint_K (operands[2])))
24792 || (GET_MODE (operands[0]) == QImode
24793 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
24794 [(parallel [(set (match_dup 0)
24795 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
24796 (clobber (reg:CC FLAGS_REG))])]
24798 operands[0] = gen_lowpart (SImode, operands[0]);
24799 operands[1] = gen_lowpart (SImode, operands[1]);
24800 if (GET_CODE (operands[3]) != ASHIFT)
24801 operands[2] = gen_lowpart (SImode, operands[2]);
24802 operands[3] = shallow_copy_rtx (operands[3]);
24803 PUT_MODE (operands[3], SImode);
24806 ; Promote the QImode tests, as i386 has encoding of the AND
24807 ; instruction with 32-bit sign-extended immediate and thus the
24808 ; instruction size is unchanged, except in the %eax case for
24809 ; which it is increased by one byte, hence the ! optimize_size.
24811 [(set (match_operand 0 "flags_reg_operand")
24812 (match_operator 2 "compare_operator"
24813 [(and (match_operand 3 "aligned_operand")
24814 (match_operand 4 "const_int_operand"))
24816 (set (match_operand 1 "register_operand")
24817 (and (match_dup 3) (match_dup 4)))]
24818 "! TARGET_PARTIAL_REG_STALL && reload_completed
24819 && optimize_insn_for_speed_p ()
24820 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
24821 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
24822 /* Ensure that the operand will remain sign-extended immediate. */
24823 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
24824 [(parallel [(set (match_dup 0)
24825 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
24828 (and:SI (match_dup 3) (match_dup 4)))])]
24831 = gen_int_mode (INTVAL (operands[4])
24832 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
24833 operands[1] = gen_lowpart (SImode, operands[1]);
24834 operands[3] = gen_lowpart (SImode, operands[3]);
24837 ; Don't promote the QImode tests, as i386 doesn't have encoding of
24838 ; the TEST instruction with 32-bit sign-extended immediate and thus
24839 ; the instruction size would at least double, which is not what we
24840 ; want even with ! optimize_size.
24842 [(set (match_operand 0 "flags_reg_operand")
24843 (match_operator 1 "compare_operator"
24844 [(and (match_operand:HI 2 "aligned_operand")
24845 (match_operand:HI 3 "const_int_operand"))
24847 "! TARGET_PARTIAL_REG_STALL && reload_completed
24848 && ! TARGET_FAST_PREFIX
24849 && optimize_insn_for_speed_p ()
24850 /* Ensure that the operand will remain sign-extended immediate. */
24851 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
24852 [(set (match_dup 0)
24853 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
24857 = gen_int_mode (INTVAL (operands[3])
24858 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
24859 operands[2] = gen_lowpart (SImode, operands[2]);
24863 [(set (match_operand 0 "register_operand")
24864 (neg (match_operand 1 "register_operand")))
24865 (clobber (reg:CC FLAGS_REG))]
24866 "! TARGET_PARTIAL_REG_STALL && reload_completed
24867 && (GET_MODE (operands[0]) == HImode
24868 || (GET_MODE (operands[0]) == QImode
24869 && (TARGET_PROMOTE_QImode
24870 || optimize_insn_for_size_p ())))"
24871 [(parallel [(set (match_dup 0)
24872 (neg:SI (match_dup 1)))
24873 (clobber (reg:CC FLAGS_REG))])]
24875 operands[0] = gen_lowpart (SImode, operands[0]);
24876 operands[1] = gen_lowpart (SImode, operands[1]);
24879 ;; Do not split instructions with mask regs.
24881 [(set (match_operand 0 "general_reg_operand")
24882 (not (match_operand 1 "general_reg_operand")))]
24883 "! TARGET_PARTIAL_REG_STALL && reload_completed
24884 && (GET_MODE (operands[0]) == HImode
24885 || (GET_MODE (operands[0]) == QImode
24886 && (TARGET_PROMOTE_QImode
24887 || optimize_insn_for_size_p ())))"
24888 [(set (match_dup 0)
24889 (not:SI (match_dup 1)))]
24891 operands[0] = gen_lowpart (SImode, operands[0]);
24892 operands[1] = gen_lowpart (SImode, operands[1]);
24895 ;; RTL Peephole optimizations, run before sched2. These primarily look to
24896 ;; transform a complex memory operation into two memory to register operations.
24898 ;; Don't push memory operands
24900 [(set (match_operand:SWI 0 "push_operand")
24901 (match_operand:SWI 1 "memory_operand"))
24902 (match_scratch:SWI 2 "<r>")]
24903 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
24904 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
24905 [(set (match_dup 2) (match_dup 1))
24906 (set (match_dup 0) (match_dup 2))])
24908 ;; We need to handle SFmode only, because DFmode and XFmode are split to
24911 [(set (match_operand:SF 0 "push_operand")
24912 (match_operand:SF 1 "memory_operand"))
24913 (match_scratch:SF 2 "r")]
24914 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
24915 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
24916 [(set (match_dup 2) (match_dup 1))
24917 (set (match_dup 0) (match_dup 2))])
24919 ;; Don't move an immediate directly to memory when the instruction
24920 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
24922 [(match_scratch:SWI124 1 "<r>")
24923 (set (match_operand:SWI124 0 "memory_operand")
24925 "optimize_insn_for_speed_p ()
24926 && ((<MODE>mode == HImode
24927 && TARGET_LCP_STALL)
24928 || (!TARGET_USE_MOV0
24929 && TARGET_SPLIT_LONG_MOVES
24930 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
24931 && peep2_regno_dead_p (0, FLAGS_REG)"
24932 [(parallel [(set (match_dup 2) (const_int 0))
24933 (clobber (reg:CC FLAGS_REG))])
24934 (set (match_dup 0) (match_dup 1))]
24935 "operands[2] = gen_lowpart (SImode, operands[1]);")
24938 [(match_scratch:SWI124 2 "<r>")
24939 (set (match_operand:SWI124 0 "memory_operand")
24940 (match_operand:SWI124 1 "immediate_operand"))]
24941 "optimize_insn_for_speed_p ()
24942 && ((<MODE>mode == HImode
24943 && TARGET_LCP_STALL)
24944 || (TARGET_SPLIT_LONG_MOVES
24945 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
24946 [(set (match_dup 2) (match_dup 1))
24947 (set (match_dup 0) (match_dup 2))])
24949 ;; Don't compare memory with zero, load and use a test instead.
24951 [(set (match_operand 0 "flags_reg_operand")
24952 (match_operator 1 "compare_operator"
24953 [(match_operand:SI 2 "memory_operand")
24955 (match_scratch:SI 3 "r")]
24956 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
24957 [(set (match_dup 3) (match_dup 2))
24958 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
24960 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
24961 ;; Don't split NOTs with a displacement operand, because resulting XOR
24962 ;; will not be pairable anyway.
24964 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
24965 ;; represented using a modRM byte. The XOR replacement is long decoded,
24966 ;; so this split helps here as well.
24968 ;; Note: Can't do this as a regular split because we can't get proper
24969 ;; lifetime information then.
24972 [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
24973 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
24974 "optimize_insn_for_speed_p ()
24975 && ((TARGET_NOT_UNPAIRABLE
24976 && (!MEM_P (operands[0])
24977 || !memory_displacement_operand (operands[0], <MODE>mode)))
24978 || (TARGET_NOT_VECTORMODE
24979 && long_memory_operand (operands[0], <MODE>mode)))
24980 && peep2_regno_dead_p (0, FLAGS_REG)"
24981 [(parallel [(set (match_dup 0)
24982 (xor:SWI124 (match_dup 1) (const_int -1)))
24983 (clobber (reg:CC FLAGS_REG))])])
24985 ;; Non pairable "test imm, reg" instructions can be translated to
24986 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
24987 ;; byte opcode instead of two, have a short form for byte operands),
24988 ;; so do it for other CPUs as well. Given that the value was dead,
24989 ;; this should not create any new dependencies. Pass on the sub-word
24990 ;; versions if we're concerned about partial register stalls.
24993 [(set (match_operand 0 "flags_reg_operand")
24994 (match_operator 1 "compare_operator"
24995 [(and:SI (match_operand:SI 2 "register_operand")
24996 (match_operand:SI 3 "immediate_operand"))
24998 "ix86_match_ccmode (insn, CCNOmode)
24999 && (REGNO (operands[2]) != AX_REG
25000 || satisfies_constraint_K (operands[3]))
25001 && peep2_reg_dead_p (1, operands[2])"
25003 [(set (match_dup 0)
25004 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
25007 (and:SI (match_dup 2) (match_dup 3)))])])
25009 ;; We don't need to handle HImode case, because it will be promoted to SImode
25010 ;; on ! TARGET_PARTIAL_REG_STALL
25013 [(set (match_operand 0 "flags_reg_operand")
25014 (match_operator 1 "compare_operator"
25015 [(and:QI (match_operand:QI 2 "register_operand")
25016 (match_operand:QI 3 "immediate_operand"))
25018 "! TARGET_PARTIAL_REG_STALL
25019 && ix86_match_ccmode (insn, CCNOmode)
25020 && REGNO (operands[2]) != AX_REG
25021 && peep2_reg_dead_p (1, operands[2])"
25023 [(set (match_dup 0)
25024 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
25027 (and:QI (match_dup 2) (match_dup 3)))])])
25030 [(set (match_operand 0 "flags_reg_operand")
25031 (match_operator 1 "compare_operator"
25034 (match_operator:SWI248 4 "extract_operator"
25035 [(match_operand 2 "int248_register_operand")
25038 (match_operand 3 "const_int_operand"))
25040 "! TARGET_PARTIAL_REG_STALL
25041 && ix86_match_ccmode (insn, CCNOmode)
25042 && REGNO (operands[2]) != AX_REG
25043 && peep2_reg_dead_p (1, operands[2])"
25045 [(set (match_dup 0)
25049 (match_op_dup 4 [(match_dup 2)
25054 (set (zero_extract:SWI248 (match_dup 2)
25060 (match_op_dup 4 [(match_dup 2)
25063 (match_dup 3)) 0))])])
25065 ;; Don't do logical operations with memory inputs.
25067 [(match_scratch:SWI 2 "<r>")
25068 (parallel [(set (match_operand:SWI 0 "register_operand")
25069 (match_operator:SWI 3 "arith_or_logical_operator"
25071 (match_operand:SWI 1 "memory_operand")]))
25072 (clobber (reg:CC FLAGS_REG))])]
25073 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
25074 [(set (match_dup 2) (match_dup 1))
25075 (parallel [(set (match_dup 0)
25076 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
25077 (clobber (reg:CC FLAGS_REG))])])
25080 [(match_scratch:SWI 2 "<r>")
25081 (parallel [(set (match_operand:SWI 0 "register_operand")
25082 (match_operator:SWI 3 "arith_or_logical_operator"
25083 [(match_operand:SWI 1 "memory_operand")
25085 (clobber (reg:CC FLAGS_REG))])]
25086 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
25087 [(set (match_dup 2) (match_dup 1))
25088 (parallel [(set (match_dup 0)
25089 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
25090 (clobber (reg:CC FLAGS_REG))])])
25092 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when
25093 ;; the memory address refers to the destination of the load!
25096 [(set (match_operand:SWI 0 "general_reg_operand")
25097 (match_operand:SWI 1 "general_reg_operand"))
25098 (parallel [(set (match_dup 0)
25099 (match_operator:SWI 3 "commutative_operator"
25101 (match_operand:SWI 2 "memory_operand")]))
25102 (clobber (reg:CC FLAGS_REG))])]
25103 "REGNO (operands[0]) != REGNO (operands[1])
25104 && (<MODE>mode != QImode
25105 || any_QIreg_operand (operands[1], QImode))"
25106 [(set (match_dup 0) (match_dup 4))
25107 (parallel [(set (match_dup 0)
25108 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
25109 (clobber (reg:CC FLAGS_REG))])]
25112 = ix86_replace_reg_with_reg (operands[2], operands[0], operands[1]);
25116 [(set (match_operand 0 "mmx_reg_operand")
25117 (match_operand 1 "mmx_reg_operand"))
25119 (match_operator 3 "commutative_operator"
25121 (match_operand 2 "memory_operand")]))]
25122 "REGNO (operands[0]) != REGNO (operands[1])"
25123 [(set (match_dup 0) (match_dup 2))
25125 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
25128 [(set (match_operand 0 "sse_reg_operand")
25129 (match_operand 1 "sse_reg_operand"))
25131 (match_operator 3 "commutative_operator"
25133 (match_operand 2 "memory_operand")]))]
25134 "REGNO (operands[0]) != REGNO (operands[1])
25135 /* Punt if operands[1] is %[xy]mm16+ and AVX512BW is not enabled,
25136 as EVEX encoded vpadd[bw], vpmullw, vpmin[su][bw] and vpmax[su][bw]
25137 instructions require AVX512BW and AVX512VL, but with the original
25138 instructions it might require just AVX512VL.
25139 AVX512VL is implied from TARGET_HARD_REGNO_MODE_OK. */
25140 && (!EXT_REX_SSE_REGNO_P (REGNO (operands[1]))
25142 || GET_MODE_SIZE (GET_MODE_INNER (GET_MODE (operands[0]))) > 2
25143 || logic_operator (operands[3], VOIDmode))"
25144 [(set (match_dup 0) (match_dup 2))
25146 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
25148 ; Don't do logical operations with memory outputs
25150 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
25151 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
25152 ; the same decoder scheduling characteristics as the original.
25155 [(match_scratch:SWI 2 "<r>")
25156 (parallel [(set (match_operand:SWI 0 "memory_operand")
25157 (match_operator:SWI 3 "arith_or_logical_operator"
25159 (match_operand:SWI 1 "<nonmemory_operand>")]))
25160 (clobber (reg:CC FLAGS_REG))])]
25161 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
25162 [(set (match_dup 2) (match_dup 0))
25163 (parallel [(set (match_dup 2)
25164 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
25165 (clobber (reg:CC FLAGS_REG))])
25166 (set (match_dup 0) (match_dup 2))])
25169 [(match_scratch:SWI 2 "<r>")
25170 (parallel [(set (match_operand:SWI 0 "memory_operand")
25171 (match_operator:SWI 3 "arith_or_logical_operator"
25172 [(match_operand:SWI 1 "<nonmemory_operand>")
25174 (clobber (reg:CC FLAGS_REG))])]
25175 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
25176 [(set (match_dup 2) (match_dup 0))
25177 (parallel [(set (match_dup 2)
25178 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
25179 (clobber (reg:CC FLAGS_REG))])
25180 (set (match_dup 0) (match_dup 2))])
25182 ;; Attempt to use arith or logical operations with memory outputs with
25183 ;; setting of flags.
25185 [(set (match_operand:SWI 0 "register_operand")
25186 (match_operand:SWI 1 "memory_operand"))
25187 (parallel [(set (match_dup 0)
25188 (match_operator:SWI 3 "plusminuslogic_operator"
25190 (match_operand:SWI 2 "<nonmemory_operand>")]))
25191 (clobber (reg:CC FLAGS_REG))])
25192 (set (match_dup 1) (match_dup 0))
25193 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
25194 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25195 && peep2_reg_dead_p (4, operands[0])
25196 && !reg_overlap_mentioned_p (operands[0], operands[1])
25197 && !reg_overlap_mentioned_p (operands[0], operands[2])
25198 && (<MODE>mode != QImode
25199 || immediate_operand (operands[2], QImode)
25200 || any_QIreg_operand (operands[2], QImode))
25201 && ix86_match_ccmode (peep2_next_insn (3),
25202 (GET_CODE (operands[3]) == PLUS
25203 || GET_CODE (operands[3]) == MINUS)
25204 ? CCGOCmode : CCNOmode)"
25205 [(parallel [(set (match_dup 4) (match_dup 6))
25206 (set (match_dup 1) (match_dup 5))])]
25208 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
25210 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
25211 copy_rtx (operands[1]),
25214 = gen_rtx_COMPARE (GET_MODE (operands[4]),
25215 copy_rtx (operands[5]),
25219 ;; Likewise for cmpelim optimized pattern.
25221 [(set (match_operand:SWI 0 "register_operand")
25222 (match_operand:SWI 1 "memory_operand"))
25223 (parallel [(set (reg FLAGS_REG)
25224 (compare (match_operator:SWI 3 "plusminuslogic_operator"
25226 (match_operand:SWI 2 "<nonmemory_operand>")])
25228 (set (match_dup 0) (match_dup 3))])
25229 (set (match_dup 1) (match_dup 0))]
25230 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25231 && peep2_reg_dead_p (3, operands[0])
25232 && !reg_overlap_mentioned_p (operands[0], operands[1])
25233 && !reg_overlap_mentioned_p (operands[0], operands[2])
25234 && ix86_match_ccmode (peep2_next_insn (1),
25235 (GET_CODE (operands[3]) == PLUS
25236 || GET_CODE (operands[3]) == MINUS)
25237 ? CCGOCmode : CCNOmode)"
25238 [(parallel [(set (match_dup 4) (match_dup 6))
25239 (set (match_dup 1) (match_dup 5))])]
25241 operands[4] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
25243 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
25244 copy_rtx (operands[1]), operands[2]);
25246 = gen_rtx_COMPARE (GET_MODE (operands[4]), copy_rtx (operands[5]),
25250 ;; Likewise for instances where we have a lea pattern.
25252 [(set (match_operand:SWI 0 "register_operand")
25253 (match_operand:SWI 1 "memory_operand"))
25254 (set (match_operand:<LEAMODE> 3 "register_operand")
25255 (plus:<LEAMODE> (match_operand:<LEAMODE> 4 "register_operand")
25256 (match_operand:<LEAMODE> 2 "<nonmemory_operand>")))
25257 (set (match_dup 1) (match_operand:SWI 5 "register_operand"))
25258 (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
25259 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25260 && REGNO (operands[4]) == REGNO (operands[0])
25261 && REGNO (operands[5]) == REGNO (operands[3])
25262 && peep2_reg_dead_p (4, operands[3])
25263 && ((REGNO (operands[0]) == REGNO (operands[3]))
25264 || peep2_reg_dead_p (2, operands[0]))
25265 && !reg_overlap_mentioned_p (operands[0], operands[1])
25266 && !reg_overlap_mentioned_p (operands[3], operands[1])
25267 && !reg_overlap_mentioned_p (operands[0], operands[2])
25268 && (<MODE>mode != QImode
25269 || immediate_operand (operands[2], QImode)
25270 || any_QIreg_operand (operands[2], QImode))
25271 && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
25272 [(parallel [(set (match_dup 6) (match_dup 8))
25273 (set (match_dup 1) (match_dup 7))])]
25275 operands[6] = SET_DEST (PATTERN (peep2_next_insn (3)));
25277 = gen_rtx_PLUS (<MODE>mode,
25278 copy_rtx (operands[1]),
25279 gen_lowpart (<MODE>mode, operands[2]));
25281 = gen_rtx_COMPARE (GET_MODE (operands[6]),
25282 copy_rtx (operands[7]),
25287 [(parallel [(set (match_operand:SWI 0 "register_operand")
25288 (match_operator:SWI 2 "plusminuslogic_operator"
25290 (match_operand:SWI 1 "memory_operand")]))
25291 (clobber (reg:CC FLAGS_REG))])
25292 (set (match_dup 1) (match_dup 0))
25293 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
25294 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25295 && COMMUTATIVE_ARITH_P (operands[2])
25296 && peep2_reg_dead_p (3, operands[0])
25297 && !reg_overlap_mentioned_p (operands[0], operands[1])
25298 && ix86_match_ccmode (peep2_next_insn (2),
25299 GET_CODE (operands[2]) == PLUS
25300 ? CCGOCmode : CCNOmode)"
25301 [(parallel [(set (match_dup 3) (match_dup 5))
25302 (set (match_dup 1) (match_dup 4))])]
25304 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
25306 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
25307 copy_rtx (operands[1]),
25310 = gen_rtx_COMPARE (GET_MODE (operands[3]),
25311 copy_rtx (operands[4]),
25315 ;; Likewise for cmpelim optimized pattern.
25317 [(parallel [(set (reg FLAGS_REG)
25318 (compare (match_operator:SWI 2 "plusminuslogic_operator"
25319 [(match_operand:SWI 0 "register_operand")
25320 (match_operand:SWI 1 "memory_operand")])
25322 (set (match_dup 0) (match_dup 2))])
25323 (set (match_dup 1) (match_dup 0))]
25324 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25325 && COMMUTATIVE_ARITH_P (operands[2])
25326 && peep2_reg_dead_p (2, operands[0])
25327 && !reg_overlap_mentioned_p (operands[0], operands[1])
25328 && ix86_match_ccmode (peep2_next_insn (0),
25329 GET_CODE (operands[2]) == PLUS
25330 ? CCGOCmode : CCNOmode)"
25331 [(parallel [(set (match_dup 3) (match_dup 5))
25332 (set (match_dup 1) (match_dup 4))])]
25334 operands[3] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (0)), 0, 0));
25336 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
25337 copy_rtx (operands[1]), operands[0]);
25339 = gen_rtx_COMPARE (GET_MODE (operands[3]), copy_rtx (operands[4]),
25344 [(set (match_operand:SWI12 0 "register_operand")
25345 (match_operand:SWI12 1 "memory_operand"))
25346 (parallel [(set (match_operand:SI 4 "register_operand")
25347 (match_operator:SI 3 "plusminuslogic_operator"
25349 (match_operand:SI 2 "nonmemory_operand")]))
25350 (clobber (reg:CC FLAGS_REG))])
25351 (set (match_dup 1) (match_dup 0))
25352 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
25353 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25354 && REGNO (operands[0]) == REGNO (operands[4])
25355 && peep2_reg_dead_p (4, operands[0])
25356 && (<MODE>mode != QImode
25357 || immediate_operand (operands[2], SImode)
25358 || any_QIreg_operand (operands[2], SImode))
25359 && !reg_overlap_mentioned_p (operands[0], operands[1])
25360 && !reg_overlap_mentioned_p (operands[0], operands[2])
25361 && ix86_match_ccmode (peep2_next_insn (3),
25362 (GET_CODE (operands[3]) == PLUS
25363 || GET_CODE (operands[3]) == MINUS)
25364 ? CCGOCmode : CCNOmode)"
25365 [(parallel [(set (match_dup 5) (match_dup 7))
25366 (set (match_dup 1) (match_dup 6))])]
25368 operands[5] = SET_DEST (PATTERN (peep2_next_insn (3)));
25370 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
25371 copy_rtx (operands[1]),
25372 gen_lowpart (<MODE>mode, operands[2]));
25374 = gen_rtx_COMPARE (GET_MODE (operands[5]),
25375 copy_rtx (operands[6]),
25379 ;; peephole2 comes before regcprop, so deal also with a case that
25380 ;; would be cleaned up by regcprop.
25382 [(set (match_operand:SWI 0 "register_operand")
25383 (match_operand:SWI 1 "memory_operand"))
25384 (parallel [(set (match_dup 0)
25385 (match_operator:SWI 3 "plusminuslogic_operator"
25387 (match_operand:SWI 2 "<nonmemory_operand>")]))
25388 (clobber (reg:CC FLAGS_REG))])
25389 (set (match_operand:SWI 4 "register_operand") (match_dup 0))
25390 (set (match_dup 1) (match_dup 4))
25391 (set (reg FLAGS_REG) (compare (match_dup 4) (const_int 0)))]
25392 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25393 && peep2_reg_dead_p (3, operands[0])
25394 && peep2_reg_dead_p (5, operands[4])
25395 && !reg_overlap_mentioned_p (operands[0], operands[1])
25396 && !reg_overlap_mentioned_p (operands[0], operands[2])
25397 && !reg_overlap_mentioned_p (operands[4], operands[1])
25398 && (<MODE>mode != QImode
25399 || immediate_operand (operands[2], QImode)
25400 || any_QIreg_operand (operands[2], QImode))
25401 && ix86_match_ccmode (peep2_next_insn (4),
25402 (GET_CODE (operands[3]) == PLUS
25403 || GET_CODE (operands[3]) == MINUS)
25404 ? CCGOCmode : CCNOmode)"
25405 [(parallel [(set (match_dup 5) (match_dup 7))
25406 (set (match_dup 1) (match_dup 6))])]
25408 operands[5] = SET_DEST (PATTERN (peep2_next_insn (4)));
25410 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
25411 copy_rtx (operands[1]),
25414 = gen_rtx_COMPARE (GET_MODE (operands[5]),
25415 copy_rtx (operands[6]),
25420 [(set (match_operand:SWI12 0 "register_operand")
25421 (match_operand:SWI12 1 "memory_operand"))
25422 (parallel [(set (match_operand:SI 4 "register_operand")
25423 (match_operator:SI 3 "plusminuslogic_operator"
25425 (match_operand:SI 2 "nonmemory_operand")]))
25426 (clobber (reg:CC FLAGS_REG))])
25427 (set (match_operand:SWI12 5 "register_operand") (match_dup 0))
25428 (set (match_dup 1) (match_dup 5))
25429 (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
25430 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25431 && REGNO (operands[0]) == REGNO (operands[4])
25432 && peep2_reg_dead_p (3, operands[0])
25433 && peep2_reg_dead_p (5, operands[5])
25434 && (<MODE>mode != QImode
25435 || immediate_operand (operands[2], SImode)
25436 || any_QIreg_operand (operands[2], SImode))
25437 && !reg_overlap_mentioned_p (operands[0], operands[1])
25438 && !reg_overlap_mentioned_p (operands[0], operands[2])
25439 && !reg_overlap_mentioned_p (operands[5], operands[1])
25440 && ix86_match_ccmode (peep2_next_insn (4),
25441 (GET_CODE (operands[3]) == PLUS
25442 || GET_CODE (operands[3]) == MINUS)
25443 ? CCGOCmode : CCNOmode)"
25444 [(parallel [(set (match_dup 6) (match_dup 8))
25445 (set (match_dup 1) (match_dup 7))])]
25447 operands[6] = SET_DEST (PATTERN (peep2_next_insn (4)));
25449 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
25450 copy_rtx (operands[1]),
25451 gen_lowpart (<MODE>mode, operands[2]));
25453 = gen_rtx_COMPARE (GET_MODE (operands[6]),
25454 copy_rtx (operands[7]),
25458 ;; Likewise for cmpelim optimized pattern.
25460 [(set (match_operand:SWI 0 "register_operand")
25461 (match_operand:SWI 1 "memory_operand"))
25462 (parallel [(set (reg FLAGS_REG)
25463 (compare (match_operator:SWI 3 "plusminuslogic_operator"
25465 (match_operand:SWI 2 "<nonmemory_operand>")])
25467 (set (match_dup 0) (match_dup 3))])
25468 (set (match_operand:SWI 4 "register_operand") (match_dup 0))
25469 (set (match_dup 1) (match_dup 4))]
25470 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25471 && peep2_reg_dead_p (3, operands[0])
25472 && peep2_reg_dead_p (4, operands[4])
25473 && !reg_overlap_mentioned_p (operands[0], operands[1])
25474 && !reg_overlap_mentioned_p (operands[0], operands[2])
25475 && !reg_overlap_mentioned_p (operands[4], operands[1])
25476 && ix86_match_ccmode (peep2_next_insn (1),
25477 (GET_CODE (operands[3]) == PLUS
25478 || GET_CODE (operands[3]) == MINUS)
25479 ? CCGOCmode : CCNOmode)"
25480 [(parallel [(set (match_dup 5) (match_dup 7))
25481 (set (match_dup 1) (match_dup 6))])]
25483 operands[5] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
25485 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
25486 copy_rtx (operands[1]), operands[2]);
25488 = gen_rtx_COMPARE (GET_MODE (operands[5]), copy_rtx (operands[6]),
25492 ;; Special cases for xor, where (x ^= y) != 0 is (misoptimized)
25493 ;; into x = z; x ^= y; x != z
25495 [(set (match_operand:SWI 0 "register_operand")
25496 (match_operand:SWI 1 "memory_operand"))
25497 (set (match_operand:SWI 3 "register_operand") (match_dup 0))
25498 (parallel [(set (match_operand:SWI 4 "register_operand")
25499 (xor:SWI (match_dup 4)
25500 (match_operand:SWI 2 "<nonmemory_operand>")))
25501 (clobber (reg:CC FLAGS_REG))])
25502 (set (match_dup 1) (match_dup 4))
25503 (set (reg:CCZ FLAGS_REG)
25504 (compare:CCZ (match_operand:SWI 5 "register_operand")
25505 (match_operand:SWI 6 "<nonmemory_operand>")))]
25506 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25507 && (REGNO (operands[4]) == REGNO (operands[0])
25508 || REGNO (operands[4]) == REGNO (operands[3]))
25509 && (rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
25510 ? 3 : 0], operands[5])
25511 ? rtx_equal_p (operands[2], operands[6])
25512 : rtx_equal_p (operands[2], operands[5])
25513 && rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
25514 ? 3 : 0], operands[6]))
25515 && peep2_reg_dead_p (4, operands[4])
25516 && peep2_reg_dead_p (5, operands[REGNO (operands[4]) == REGNO (operands[0])
25518 && !reg_overlap_mentioned_p (operands[0], operands[1])
25519 && !reg_overlap_mentioned_p (operands[0], operands[2])
25520 && !reg_overlap_mentioned_p (operands[3], operands[0])
25521 && !reg_overlap_mentioned_p (operands[3], operands[1])
25522 && !reg_overlap_mentioned_p (operands[3], operands[2])
25523 && (<MODE>mode != QImode
25524 || immediate_operand (operands[2], QImode)
25525 || any_QIreg_operand (operands[2], QImode))"
25526 [(parallel [(set (match_dup 7) (match_dup 9))
25527 (set (match_dup 1) (match_dup 8))])]
25529 operands[7] = SET_DEST (PATTERN (peep2_next_insn (4)));
25530 operands[8] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
25533 = gen_rtx_COMPARE (GET_MODE (operands[7]),
25534 copy_rtx (operands[8]),
25539 [(set (match_operand:SWI12 0 "register_operand")
25540 (match_operand:SWI12 1 "memory_operand"))
25541 (set (match_operand:SWI12 3 "register_operand") (match_dup 0))
25542 (parallel [(set (match_operand:SI 4 "register_operand")
25543 (xor:SI (match_dup 4)
25544 (match_operand:SI 2 "<nonmemory_operand>")))
25545 (clobber (reg:CC FLAGS_REG))])
25546 (set (match_dup 1) (match_operand:SWI12 5 "register_operand"))
25547 (set (reg:CCZ FLAGS_REG)
25548 (compare:CCZ (match_operand:SWI12 6 "register_operand")
25549 (match_operand:SWI12 7 "<nonmemory_operand>")))]
25550 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25551 && (REGNO (operands[5]) == REGNO (operands[0])
25552 || REGNO (operands[5]) == REGNO (operands[3]))
25553 && REGNO (operands[5]) == REGNO (operands[4])
25554 && (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
25555 ? 3 : 0], operands[6])
25556 ? (REG_P (operands[2])
25557 ? REG_P (operands[7]) && REGNO (operands[2]) == REGNO (operands[7])
25558 : rtx_equal_p (operands[2], operands[7]))
25559 : (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
25560 ? 3 : 0], operands[7])
25561 && REG_P (operands[2])
25562 && REGNO (operands[2]) == REGNO (operands[6])))
25563 && peep2_reg_dead_p (4, operands[5])
25564 && peep2_reg_dead_p (5, operands[REGNO (operands[5]) == REGNO (operands[0])
25566 && !reg_overlap_mentioned_p (operands[0], operands[1])
25567 && !reg_overlap_mentioned_p (operands[0], operands[2])
25568 && !reg_overlap_mentioned_p (operands[3], operands[0])
25569 && !reg_overlap_mentioned_p (operands[3], operands[1])
25570 && !reg_overlap_mentioned_p (operands[3], operands[2])
25571 && (<MODE>mode != QImode
25572 || immediate_operand (operands[2], SImode)
25573 || any_QIreg_operand (operands[2], SImode))"
25574 [(parallel [(set (match_dup 8) (match_dup 10))
25575 (set (match_dup 1) (match_dup 9))])]
25577 operands[8] = SET_DEST (PATTERN (peep2_next_insn (4)));
25578 operands[9] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
25579 gen_lowpart (<MODE>mode, operands[2]));
25581 = gen_rtx_COMPARE (GET_MODE (operands[8]),
25582 copy_rtx (operands[9]),
25586 ;; Attempt to optimize away memory stores of values the memory already
25587 ;; has. See PR79593.
25589 [(set (match_operand 0 "register_operand")
25590 (match_operand 1 "memory_operand"))
25591 (set (match_operand 2 "memory_operand") (match_dup 0))]
25592 "!MEM_VOLATILE_P (operands[1])
25593 && !MEM_VOLATILE_P (operands[2])
25594 && rtx_equal_p (operands[1], operands[2])
25595 && !reg_overlap_mentioned_p (operands[0], operands[2])"
25596 [(set (match_dup 0) (match_dup 1))])
25598 ;; Attempt to always use XOR for zeroing registers (including FP modes).
25600 [(set (match_operand 0 "general_reg_operand")
25601 (match_operand 1 "const0_operand"))]
25602 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
25603 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
25604 && peep2_regno_dead_p (0, FLAGS_REG)"
25605 [(parallel [(set (match_dup 0) (const_int 0))
25606 (clobber (reg:CC FLAGS_REG))])]
25607 "operands[0] = gen_lowpart (word_mode, operands[0]);")
25610 [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
25612 "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
25613 && peep2_regno_dead_p (0, FLAGS_REG)"
25614 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
25615 (clobber (reg:CC FLAGS_REG))])])
25617 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
25619 [(set (match_operand:SWI248 0 "general_reg_operand")
25621 "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
25622 && peep2_regno_dead_p (0, FLAGS_REG)"
25623 [(parallel [(set (match_dup 0) (const_int -1))
25624 (clobber (reg:CC FLAGS_REG))])]
25626 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
25627 operands[0] = gen_lowpart (SImode, operands[0]);
25630 ;; Attempt to convert simple lea to add/shift.
25631 ;; These can be created by move expanders.
25632 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
25633 ;; relevant lea instructions were already split.
25636 [(set (match_operand:SWI48 0 "register_operand")
25637 (plus:SWI48 (match_dup 0)
25638 (match_operand:SWI48 1 "<nonmemory_operand>")))]
25640 && peep2_regno_dead_p (0, FLAGS_REG)"
25641 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
25642 (clobber (reg:CC FLAGS_REG))])])
25645 [(set (match_operand:SWI48 0 "register_operand")
25646 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
25649 && peep2_regno_dead_p (0, FLAGS_REG)"
25650 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
25651 (clobber (reg:CC FLAGS_REG))])])
25654 [(set (match_operand:DI 0 "register_operand")
25656 (plus:SI (match_operand:SI 1 "register_operand")
25657 (match_operand:SI 2 "nonmemory_operand"))))]
25658 "TARGET_64BIT && !TARGET_OPT_AGU
25659 && REGNO (operands[0]) == REGNO (operands[1])
25660 && peep2_regno_dead_p (0, FLAGS_REG)"
25661 [(parallel [(set (match_dup 0)
25662 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
25663 (clobber (reg:CC FLAGS_REG))])])
25666 [(set (match_operand:DI 0 "register_operand")
25668 (plus:SI (match_operand:SI 1 "nonmemory_operand")
25669 (match_operand:SI 2 "register_operand"))))]
25670 "TARGET_64BIT && !TARGET_OPT_AGU
25671 && REGNO (operands[0]) == REGNO (operands[2])
25672 && peep2_regno_dead_p (0, FLAGS_REG)"
25673 [(parallel [(set (match_dup 0)
25674 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
25675 (clobber (reg:CC FLAGS_REG))])])
25678 [(set (match_operand:SWI48 0 "register_operand")
25679 (mult:SWI48 (match_dup 0)
25680 (match_operand:SWI48 1 "const_int_operand")))]
25681 "pow2p_hwi (INTVAL (operands[1]))
25682 && peep2_regno_dead_p (0, FLAGS_REG)"
25683 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
25684 (clobber (reg:CC FLAGS_REG))])]
25685 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
25688 [(set (match_operand:DI 0 "register_operand")
25690 (mult:SI (match_operand:SI 1 "register_operand")
25691 (match_operand:SI 2 "const_int_operand"))))]
25693 && pow2p_hwi (INTVAL (operands[2]))
25694 && REGNO (operands[0]) == REGNO (operands[1])
25695 && peep2_regno_dead_p (0, FLAGS_REG)"
25696 [(parallel [(set (match_dup 0)
25697 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
25698 (clobber (reg:CC FLAGS_REG))])]
25699 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
25701 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
25702 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
25703 ;; On many CPUs it is also faster, since special hardware to avoid esp
25704 ;; dependencies is present.
25706 ;; While some of these conversions may be done using splitters, we use
25707 ;; peepholes in order to allow combine_stack_adjustments pass to see
25708 ;; nonobfuscated RTL.
25710 ;; Convert prologue esp subtractions to push.
25711 ;; We need register to push. In order to keep verify_flow_info happy we have
25713 ;; - use scratch and clobber it in order to avoid dependencies
25714 ;; - use already live register
25715 ;; We can't use the second way right now, since there is no reliable way how to
25716 ;; verify that given register is live. First choice will also most likely in
25717 ;; fewer dependencies. On the place of esp adjustments it is very likely that
25718 ;; call clobbered registers are dead. We may want to use base pointer as an
25719 ;; alternative when no register is available later.
25722 [(match_scratch:W 1 "r")
25723 (parallel [(set (reg:P SP_REG)
25724 (plus:P (reg:P SP_REG)
25725 (match_operand:P 0 "const_int_operand")))
25726 (clobber (reg:CC FLAGS_REG))
25727 (clobber (mem:BLK (scratch)))])]
25728 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
25729 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
25730 && !ix86_red_zone_used"
25731 [(clobber (match_dup 1))
25732 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
25733 (clobber (mem:BLK (scratch)))])])
25736 [(match_scratch:W 1 "r")
25737 (parallel [(set (reg:P SP_REG)
25738 (plus:P (reg:P SP_REG)
25739 (match_operand:P 0 "const_int_operand")))
25740 (clobber (reg:CC FLAGS_REG))
25741 (clobber (mem:BLK (scratch)))])]
25742 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
25743 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
25744 && !ix86_red_zone_used"
25745 [(clobber (match_dup 1))
25746 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
25747 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
25748 (clobber (mem:BLK (scratch)))])])
25750 ;; Convert esp subtractions to push.
25752 [(match_scratch:W 1 "r")
25753 (parallel [(set (reg:P SP_REG)
25754 (plus:P (reg:P SP_REG)
25755 (match_operand:P 0 "const_int_operand")))
25756 (clobber (reg:CC FLAGS_REG))])]
25757 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
25758 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
25759 && !ix86_red_zone_used"
25760 [(clobber (match_dup 1))
25761 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
25764 [(match_scratch:W 1 "r")
25765 (parallel [(set (reg:P SP_REG)
25766 (plus:P (reg:P SP_REG)
25767 (match_operand:P 0 "const_int_operand")))
25768 (clobber (reg:CC FLAGS_REG))])]
25769 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
25770 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
25771 && !ix86_red_zone_used"
25772 [(clobber (match_dup 1))
25773 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
25774 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
25776 ;; Convert epilogue deallocator to pop.
25778 [(match_scratch:W 1 "r")
25779 (parallel [(set (reg:P SP_REG)
25780 (plus:P (reg:P SP_REG)
25781 (match_operand:P 0 "const_int_operand")))
25782 (clobber (reg:CC FLAGS_REG))
25783 (clobber (mem:BLK (scratch)))])]
25784 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
25785 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
25786 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25787 (clobber (mem:BLK (scratch)))])])
25789 ;; Two pops case is tricky, since pop causes dependency
25790 ;; on destination register. We use two registers if available.
25792 [(match_scratch:W 1 "r")
25793 (match_scratch:W 2 "r")
25794 (parallel [(set (reg:P SP_REG)
25795 (plus:P (reg:P SP_REG)
25796 (match_operand:P 0 "const_int_operand")))
25797 (clobber (reg:CC FLAGS_REG))
25798 (clobber (mem:BLK (scratch)))])]
25799 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
25800 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
25801 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25802 (clobber (mem:BLK (scratch)))])
25803 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
25806 [(match_scratch:W 1 "r")
25807 (parallel [(set (reg:P SP_REG)
25808 (plus:P (reg:P SP_REG)
25809 (match_operand:P 0 "const_int_operand")))
25810 (clobber (reg:CC FLAGS_REG))
25811 (clobber (mem:BLK (scratch)))])]
25812 "optimize_insn_for_size_p ()
25813 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
25814 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25815 (clobber (mem:BLK (scratch)))])
25816 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
25818 ;; Convert esp additions to pop.
25820 [(match_scratch:W 1 "r")
25821 (parallel [(set (reg:P SP_REG)
25822 (plus:P (reg:P SP_REG)
25823 (match_operand:P 0 "const_int_operand")))
25824 (clobber (reg:CC FLAGS_REG))])]
25825 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
25826 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
25828 ;; Two pops case is tricky, since pop causes dependency
25829 ;; on destination register. We use two registers if available.
25831 [(match_scratch:W 1 "r")
25832 (match_scratch:W 2 "r")
25833 (parallel [(set (reg:P SP_REG)
25834 (plus:P (reg:P SP_REG)
25835 (match_operand:P 0 "const_int_operand")))
25836 (clobber (reg:CC FLAGS_REG))])]
25837 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
25838 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25839 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
25842 [(match_scratch:W 1 "r")
25843 (parallel [(set (reg:P SP_REG)
25844 (plus:P (reg:P SP_REG)
25845 (match_operand:P 0 "const_int_operand")))
25846 (clobber (reg:CC FLAGS_REG))])]
25847 "optimize_insn_for_size_p ()
25848 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
25849 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25850 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
25852 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
25853 ;; required and register dies. Similarly for 128 to -128.
25855 [(set (match_operand 0 "flags_reg_operand")
25856 (match_operator 1 "compare_operator"
25857 [(match_operand 2 "register_operand")
25858 (match_operand 3 "const_int_operand")]))]
25859 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
25860 && incdec_operand (operands[3], GET_MODE (operands[3])))
25861 || (!TARGET_FUSE_CMP_AND_BRANCH
25862 && INTVAL (operands[3]) == 128))
25863 && ix86_match_ccmode (insn, CCGCmode)
25864 && peep2_reg_dead_p (1, operands[2])"
25865 [(parallel [(set (match_dup 0)
25866 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
25867 (clobber (match_dup 2))])])
25869 ;; Convert imul by three, five and nine into lea
25872 [(set (match_operand:SWI48 0 "register_operand")
25873 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
25874 (match_operand:SWI48 2 "const359_operand")))
25875 (clobber (reg:CC FLAGS_REG))])]
25876 "!TARGET_PARTIAL_REG_STALL
25877 || <MODE>mode == SImode
25878 || optimize_function_for_size_p (cfun)"
25879 [(set (match_dup 0)
25880 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
25882 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
25886 [(set (match_operand:SWI48 0 "register_operand")
25887 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
25888 (match_operand:SWI48 2 "const359_operand")))
25889 (clobber (reg:CC FLAGS_REG))])]
25890 "optimize_insn_for_speed_p ()
25891 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
25892 [(set (match_dup 0) (match_dup 1))
25894 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
25896 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
25898 ;; imul $32bit_imm, mem, reg is vector decoded, while
25899 ;; imul $32bit_imm, reg, reg is direct decoded.
25901 [(match_scratch:SWI48 3 "r")
25902 (parallel [(set (match_operand:SWI48 0 "register_operand")
25903 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
25904 (match_operand:SWI48 2 "immediate_operand")))
25905 (clobber (reg:CC FLAGS_REG))])]
25906 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
25907 && !satisfies_constraint_K (operands[2])"
25908 [(set (match_dup 3) (match_dup 1))
25909 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
25910 (clobber (reg:CC FLAGS_REG))])])
25913 [(match_scratch:SI 3 "r")
25914 (parallel [(set (match_operand:DI 0 "register_operand")
25916 (mult:SI (match_operand:SI 1 "memory_operand")
25917 (match_operand:SI 2 "immediate_operand"))))
25918 (clobber (reg:CC FLAGS_REG))])]
25920 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
25921 && !satisfies_constraint_K (operands[2])"
25922 [(set (match_dup 3) (match_dup 1))
25923 (parallel [(set (match_dup 0)
25924 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
25925 (clobber (reg:CC FLAGS_REG))])])
25927 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
25928 ;; Convert it into imul reg, reg
25929 ;; It would be better to force assembler to encode instruction using long
25930 ;; immediate, but there is apparently no way to do so.
25932 [(parallel [(set (match_operand:SWI248 0 "register_operand")
25934 (match_operand:SWI248 1 "nonimmediate_operand")
25935 (match_operand:SWI248 2 "const_int_operand")))
25936 (clobber (reg:CC FLAGS_REG))])
25937 (match_scratch:SWI248 3 "r")]
25938 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
25939 && satisfies_constraint_K (operands[2])"
25940 [(set (match_dup 3) (match_dup 2))
25941 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
25942 (clobber (reg:CC FLAGS_REG))])]
25944 if (!rtx_equal_p (operands[0], operands[1]))
25945 emit_move_insn (operands[0], operands[1]);
25948 ;; After splitting up read-modify operations, array accesses with memory
25949 ;; operands might end up in form:
25951 ;; movl 4(%esp), %edx
25953 ;; instead of pre-splitting:
25955 ;; addl 4(%esp), %eax
25957 ;; movl 4(%esp), %edx
25958 ;; leal (%edx,%eax,4), %eax
25961 [(match_scratch:W 5 "r")
25962 (parallel [(set (match_operand 0 "register_operand")
25963 (ashift (match_operand 1 "register_operand")
25964 (match_operand 2 "const_int_operand")))
25965 (clobber (reg:CC FLAGS_REG))])
25966 (parallel [(set (match_operand 3 "register_operand")
25967 (plus (match_dup 0)
25968 (match_operand 4 "x86_64_general_operand")))
25969 (clobber (reg:CC FLAGS_REG))])]
25970 "IN_RANGE (INTVAL (operands[2]), 1, 3)
25971 /* Validate MODE for lea. */
25972 && ((!TARGET_PARTIAL_REG_STALL
25973 && (GET_MODE (operands[0]) == QImode
25974 || GET_MODE (operands[0]) == HImode))
25975 || GET_MODE (operands[0]) == SImode
25976 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
25977 && (rtx_equal_p (operands[0], operands[3])
25978 || peep2_reg_dead_p (2, operands[0]))
25979 /* We reorder load and the shift. */
25980 && !reg_overlap_mentioned_p (operands[0], operands[4])"
25981 [(set (match_dup 5) (match_dup 4))
25982 (set (match_dup 0) (match_dup 1))]
25984 machine_mode op1mode = GET_MODE (operands[1]);
25985 machine_mode mode = op1mode == DImode ? DImode : SImode;
25986 int scale = 1 << INTVAL (operands[2]);
25987 rtx index = gen_lowpart (word_mode, operands[1]);
25988 rtx base = gen_lowpart (word_mode, operands[5]);
25989 rtx dest = gen_lowpart (mode, operands[3]);
25991 operands[1] = gen_rtx_PLUS (word_mode, base,
25992 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
25993 if (mode != word_mode)
25994 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
25996 operands[5] = base;
25997 if (op1mode != word_mode)
25998 operands[5] = gen_lowpart (op1mode, operands[5]);
26000 operands[0] = dest;
26003 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
26004 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
26005 ;; caught for use by garbage collectors and the like. Using an insn that
26006 ;; maps to SIGILL makes it more likely the program will rightfully die.
26007 ;; Keeping with tradition, "6" is in honor of #UD.
26008 (define_insn "trap"
26009 [(trap_if (const_int 1) (const_int 6))]
26012 #ifdef HAVE_AS_IX86_UD2
26015 return ASM_SHORT "0x0b0f";
26018 [(set_attr "length" "2")])
26021 [(unspec_volatile [(const_int 0)] UNSPECV_UD2)]
26024 #ifdef HAVE_AS_IX86_UD2
26027 return ASM_SHORT "0x0b0f";
26030 [(set_attr "length" "2")])
26032 (define_expand "prefetch"
26033 [(prefetch (match_operand 0 "address_operand")
26034 (match_operand:SI 1 "const_int_operand")
26035 (match_operand:SI 2 "const_int_operand"))]
26036 "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
26038 bool write = operands[1] != const0_rtx;
26039 int locality = INTVAL (operands[2]);
26041 gcc_assert (IN_RANGE (locality, 0, 3));
26043 /* Use 3dNOW prefetch in case we are asking for write prefetch not
26044 supported by SSE counterpart (non-SSE2 athlon machines) or the
26045 SSE prefetch is not available (K6 machines). Otherwise use SSE
26046 prefetch as it allows specifying of locality. */
26050 if (TARGET_PREFETCHWT1)
26051 operands[2] = GEN_INT (MAX (locality, 2));
26052 else if (TARGET_PRFCHW)
26053 operands[2] = GEN_INT (3);
26054 else if (TARGET_3DNOW && !TARGET_SSE2)
26055 operands[2] = GEN_INT (3);
26056 else if (TARGET_PREFETCH_SSE)
26057 operands[1] = const0_rtx;
26060 gcc_assert (TARGET_3DNOW);
26061 operands[2] = GEN_INT (3);
26066 if (TARGET_PREFETCH_SSE)
26070 gcc_assert (TARGET_3DNOW);
26071 operands[2] = GEN_INT (3);
26076 (define_insn "*prefetch_sse"
26077 [(prefetch (match_operand 0 "address_operand" "p")
26079 (match_operand:SI 1 "const_int_operand"))]
26080 "TARGET_PREFETCH_SSE"
26082 static const char * const patterns[4] = {
26083 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
26086 int locality = INTVAL (operands[1]);
26087 gcc_assert (IN_RANGE (locality, 0, 3));
26089 return patterns[locality];
26091 [(set_attr "type" "sse")
26092 (set_attr "atom_sse_attr" "prefetch")
26093 (set (attr "length_address")
26094 (symbol_ref "memory_address_length (operands[0], false)"))
26095 (set_attr "memory" "none")])
26097 (define_insn "*prefetch_3dnow"
26098 [(prefetch (match_operand 0 "address_operand" "p")
26099 (match_operand:SI 1 "const_int_operand")
26101 "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1"
26103 if (operands[1] == const0_rtx)
26104 return "prefetch\t%a0";
26106 return "prefetchw\t%a0";
26108 [(set_attr "type" "mmx")
26109 (set (attr "length_address")
26110 (symbol_ref "memory_address_length (operands[0], false)"))
26111 (set_attr "memory" "none")])
26113 (define_insn "*prefetch_prefetchwt1"
26114 [(prefetch (match_operand 0 "address_operand" "p")
26117 "TARGET_PREFETCHWT1"
26118 "prefetchwt1\t%a0";
26119 [(set_attr "type" "sse")
26120 (set (attr "length_address")
26121 (symbol_ref "memory_address_length (operands[0], false)"))
26122 (set_attr "memory" "none")])
26124 (define_insn "prefetchi"
26125 [(unspec_volatile [(match_operand 0 "local_func_symbolic_operand" "p")
26126 (match_operand:SI 1 "const_int_operand")]
26127 UNSPECV_PREFETCHI)]
26128 "TARGET_PREFETCHI && TARGET_64BIT"
26130 static const char * const patterns[2] = {
26131 "prefetchit1\t%0", "prefetchit0\t%0"
26134 int locality = INTVAL (operands[1]);
26135 gcc_assert (IN_RANGE (locality, 2, 3));
26137 return patterns[locality - 2];
26139 [(set_attr "type" "sse")
26140 (set (attr "length_address")
26141 (symbol_ref "memory_address_length (operands[0], false)"))
26142 (set_attr "memory" "none")])
26144 (define_insn "sse4_2_crc32<mode>"
26145 [(set (match_operand:SI 0 "register_operand" "=r")
26147 [(match_operand:SI 1 "register_operand" "0")
26148 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
26151 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
26152 [(set_attr "type" "sselog1")
26153 (set_attr "prefix_rep" "1")
26154 (set_attr "prefix_extra" "1")
26155 (set (attr "prefix_data16")
26156 (if_then_else (match_operand:HI 2)
26158 (const_string "*")))
26159 (set (attr "prefix_rex")
26160 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
26162 (const_string "*")))
26163 (set_attr "mode" "SI")])
26165 (define_insn "sse4_2_crc32di"
26166 [(set (match_operand:DI 0 "register_operand" "=r")
26169 [(match_operand:SI 1 "register_operand" "0")
26170 (match_operand:DI 2 "nonimmediate_operand" "rm")]
26172 "TARGET_64BIT && TARGET_CRC32"
26173 "crc32{q}\t{%2, %0|%0, %2}"
26174 [(set_attr "type" "sselog1")
26175 (set_attr "prefix_rep" "1")
26176 (set_attr "prefix_extra" "1")
26177 (set_attr "mode" "DI")])
26179 (define_insn "rdpmc"
26180 [(set (match_operand:DI 0 "register_operand" "=A")
26181 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
26185 [(set_attr "type" "other")
26186 (set_attr "length" "2")])
26188 (define_insn "rdpmc_rex64"
26189 [(set (match_operand:DI 0 "register_operand" "=a")
26190 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
26192 (set (match_operand:DI 1 "register_operand" "=d")
26193 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
26196 [(set_attr "type" "other")
26197 (set_attr "length" "2")])
26199 (define_insn "rdtsc"
26200 [(set (match_operand:DI 0 "register_operand" "=A")
26201 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
26204 [(set_attr "type" "other")
26205 (set_attr "length" "2")])
26207 (define_insn "rdtsc_rex64"
26208 [(set (match_operand:DI 0 "register_operand" "=a")
26209 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
26210 (set (match_operand:DI 1 "register_operand" "=d")
26211 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
26214 [(set_attr "type" "other")
26215 (set_attr "length" "2")])
26217 (define_insn "rdtscp"
26218 [(set (match_operand:DI 0 "register_operand" "=A")
26219 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
26220 (set (match_operand:SI 1 "register_operand" "=c")
26221 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
26224 [(set_attr "type" "other")
26225 (set_attr "length" "3")])
26227 (define_insn "rdtscp_rex64"
26228 [(set (match_operand:DI 0 "register_operand" "=a")
26229 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
26230 (set (match_operand:DI 1 "register_operand" "=d")
26231 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
26232 (set (match_operand:SI 2 "register_operand" "=c")
26233 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
26236 [(set_attr "type" "other")
26237 (set_attr "length" "3")])
26239 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26241 ;; FXSR, XSAVE and XSAVEOPT instructions
26243 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26245 (define_insn "fxsave"
26246 [(set (match_operand:BLK 0 "memory_operand" "=m")
26247 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
26250 [(set_attr "type" "other")
26251 (set_attr "memory" "store")
26252 (set (attr "length")
26253 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
26255 (define_insn "fxsave64"
26256 [(set (match_operand:BLK 0 "memory_operand" "=jm")
26257 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
26258 "TARGET_64BIT && TARGET_FXSR"
26260 [(set_attr "type" "other")
26261 (set_attr "addr" "gpr16")
26262 (set_attr "memory" "store")
26263 (set (attr "length")
26264 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
26266 (define_insn "fxrstor"
26267 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
26271 [(set_attr "type" "other")
26272 (set_attr "memory" "load")
26273 (set (attr "length")
26274 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
26276 (define_insn "fxrstor64"
26277 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "jm")]
26278 UNSPECV_FXRSTOR64)]
26279 "TARGET_64BIT && TARGET_FXSR"
26281 [(set_attr "type" "other")
26282 (set_attr "addr" "gpr16")
26283 (set_attr "memory" "load")
26284 (set (attr "length")
26285 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
26287 (define_int_iterator ANY_XSAVE
26289 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
26290 (UNSPECV_XSAVEC "TARGET_XSAVEC")
26291 (UNSPECV_XSAVES "TARGET_XSAVES")])
26293 (define_int_iterator ANY_XSAVE64
26295 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
26296 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
26297 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
26299 (define_int_attr xsave
26300 [(UNSPECV_XSAVE "xsave")
26301 (UNSPECV_XSAVE64 "xsave64")
26302 (UNSPECV_XSAVEOPT "xsaveopt")
26303 (UNSPECV_XSAVEOPT64 "xsaveopt64")
26304 (UNSPECV_XSAVEC "xsavec")
26305 (UNSPECV_XSAVEC64 "xsavec64")
26306 (UNSPECV_XSAVES "xsaves")
26307 (UNSPECV_XSAVES64 "xsaves64")])
26309 (define_int_iterator ANY_XRSTOR
26311 (UNSPECV_XRSTORS "TARGET_XSAVES")])
26313 (define_int_iterator ANY_XRSTOR64
26315 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
26317 (define_int_attr xrstor
26318 [(UNSPECV_XRSTOR "xrstor")
26319 (UNSPECV_XRSTOR64 "xrstor")
26320 (UNSPECV_XRSTORS "xrstors")
26321 (UNSPECV_XRSTORS64 "xrstors")])
26323 (define_insn "<xsave>"
26324 [(set (match_operand:BLK 0 "memory_operand" "=m")
26325 (unspec_volatile:BLK
26326 [(match_operand:DI 1 "register_operand" "A")]
26328 "!TARGET_64BIT && TARGET_XSAVE"
26330 [(set_attr "type" "other")
26331 (set_attr "memory" "store")
26332 (set (attr "length")
26333 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
26335 (define_insn "<xsave>_rex64"
26336 [(set (match_operand:BLK 0 "memory_operand" "=jm")
26337 (unspec_volatile:BLK
26338 [(match_operand:SI 1 "register_operand" "a")
26339 (match_operand:SI 2 "register_operand" "d")]
26341 "TARGET_64BIT && TARGET_XSAVE"
26343 [(set_attr "type" "other")
26344 (set_attr "memory" "store")
26345 (set_attr "addr" "gpr16")
26346 (set (attr "length")
26347 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
26349 (define_insn "<xsave>"
26350 [(set (match_operand:BLK 0 "memory_operand" "=jm")
26351 (unspec_volatile:BLK
26352 [(match_operand:SI 1 "register_operand" "a")
26353 (match_operand:SI 2 "register_operand" "d")]
26355 "TARGET_64BIT && TARGET_XSAVE"
26357 [(set_attr "type" "other")
26358 (set_attr "memory" "store")
26359 (set_attr "addr" "gpr16")
26360 (set (attr "length")
26361 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
26363 (define_insn "<xrstor>"
26364 [(unspec_volatile:BLK
26365 [(match_operand:BLK 0 "memory_operand" "m")
26366 (match_operand:DI 1 "register_operand" "A")]
26368 "!TARGET_64BIT && TARGET_XSAVE"
26370 [(set_attr "type" "other")
26371 (set_attr "memory" "load")
26372 (set (attr "length")
26373 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
26375 (define_insn "<xrstor>_rex64"
26376 [(unspec_volatile:BLK
26377 [(match_operand:BLK 0 "memory_operand" "jm")
26378 (match_operand:SI 1 "register_operand" "a")
26379 (match_operand:SI 2 "register_operand" "d")]
26381 "TARGET_64BIT && TARGET_XSAVE"
26383 [(set_attr "type" "other")
26384 (set_attr "memory" "load")
26385 (set_attr "addr" "gpr16")
26386 (set (attr "length")
26387 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
26389 (define_insn "<xrstor>64"
26390 [(unspec_volatile:BLK
26391 [(match_operand:BLK 0 "memory_operand" "jm")
26392 (match_operand:SI 1 "register_operand" "a")
26393 (match_operand:SI 2 "register_operand" "d")]
26395 "TARGET_64BIT && TARGET_XSAVE"
26397 [(set_attr "type" "other")
26398 (set_attr "memory" "load")
26399 (set_attr "addr" "gpr16")
26400 (set (attr "length")
26401 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
26403 (define_insn "xsetbv"
26404 [(unspec_volatile:SI
26405 [(match_operand:SI 0 "register_operand" "c")
26406 (match_operand:DI 1 "register_operand" "A")]
26408 "!TARGET_64BIT && TARGET_XSAVE"
26410 [(set_attr "type" "other")])
26412 (define_insn "xsetbv_rex64"
26413 [(unspec_volatile:SI
26414 [(match_operand:SI 0 "register_operand" "c")
26415 (match_operand:SI 1 "register_operand" "a")
26416 (match_operand:SI 2 "register_operand" "d")]
26418 "TARGET_64BIT && TARGET_XSAVE"
26420 [(set_attr "type" "other")])
26422 (define_insn "xgetbv"
26423 [(set (match_operand:DI 0 "register_operand" "=A")
26424 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
26426 "!TARGET_64BIT && TARGET_XSAVE"
26428 [(set_attr "type" "other")])
26430 (define_insn "xgetbv_rex64"
26431 [(set (match_operand:DI 0 "register_operand" "=a")
26432 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
26434 (set (match_operand:DI 1 "register_operand" "=d")
26435 (unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))]
26436 "TARGET_64BIT && TARGET_XSAVE"
26438 [(set_attr "type" "other")])
26440 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26442 ;; Floating-point instructions for atomic compound assignments
26444 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26446 ; Clobber all floating-point registers on environment save and restore
26447 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
26448 (define_insn "fnstenv"
26449 [(set (match_operand:BLK 0 "memory_operand" "=m")
26450 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
26451 (clobber (reg:XF ST0_REG))
26452 (clobber (reg:XF ST1_REG))
26453 (clobber (reg:XF ST2_REG))
26454 (clobber (reg:XF ST3_REG))
26455 (clobber (reg:XF ST4_REG))
26456 (clobber (reg:XF ST5_REG))
26457 (clobber (reg:XF ST6_REG))
26458 (clobber (reg:XF ST7_REG))]
26461 [(set_attr "type" "other")
26462 (set_attr "memory" "store")
26463 (set (attr "length")
26464 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
26466 (define_insn "fldenv"
26467 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
26469 (clobber (reg:XF ST0_REG))
26470 (clobber (reg:XF ST1_REG))
26471 (clobber (reg:XF ST2_REG))
26472 (clobber (reg:XF ST3_REG))
26473 (clobber (reg:XF ST4_REG))
26474 (clobber (reg:XF ST5_REG))
26475 (clobber (reg:XF ST6_REG))
26476 (clobber (reg:XF ST7_REG))]
26479 [(set_attr "type" "other")
26480 (set_attr "memory" "load")
26481 (set (attr "length")
26482 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
26484 (define_insn "fnstsw"
26485 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
26486 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
26489 [(set_attr "type" "other,other")
26490 (set_attr "memory" "none,store")
26491 (set (attr "length")
26492 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
26494 (define_insn "fnclex"
26495 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
26498 [(set_attr "type" "other")
26499 (set_attr "memory" "none")
26500 (set_attr "length" "2")])
26502 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26504 ;; LWP instructions
26506 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26508 (define_insn "@lwp_llwpcb<mode>"
26509 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
26510 UNSPECV_LLWP_INTRINSIC)]
26513 [(set_attr "type" "lwp")
26514 (set_attr "mode" "<MODE>")
26515 (set_attr "length" "5")])
26517 (define_insn "@lwp_slwpcb<mode>"
26518 [(set (match_operand:P 0 "register_operand" "=r")
26519 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
26522 [(set_attr "type" "lwp")
26523 (set_attr "mode" "<MODE>")
26524 (set_attr "length" "5")])
26526 (define_insn "@lwp_lwpval<mode>"
26527 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
26528 (match_operand:SI 1 "nonimmediate_operand" "rm")
26529 (match_operand:SI 2 "const_int_operand")]
26530 UNSPECV_LWPVAL_INTRINSIC)]
26532 "lwpval\t{%2, %1, %0|%0, %1, %2}"
26533 [(set_attr "type" "lwp")
26534 (set_attr "mode" "<MODE>")
26535 (set (attr "length")
26536 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
26538 (define_insn "@lwp_lwpins<mode>"
26539 [(set (reg:CCC FLAGS_REG)
26540 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
26541 (match_operand:SI 1 "nonimmediate_operand" "rm")
26542 (match_operand:SI 2 "const_int_operand")]
26543 UNSPECV_LWPINS_INTRINSIC))]
26545 "lwpins\t{%2, %1, %0|%0, %1, %2}"
26546 [(set_attr "type" "lwp")
26547 (set_attr "mode" "<MODE>")
26548 (set (attr "length")
26549 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
26551 (define_int_iterator RDFSGSBASE
26555 (define_int_iterator WRFSGSBASE
26559 (define_int_attr fsgs
26560 [(UNSPECV_RDFSBASE "fs")
26561 (UNSPECV_RDGSBASE "gs")
26562 (UNSPECV_WRFSBASE "fs")
26563 (UNSPECV_WRGSBASE "gs")])
26565 (define_insn "rd<fsgs>base<mode>"
26566 [(set (match_operand:SWI48 0 "register_operand" "=r")
26567 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
26568 "TARGET_64BIT && TARGET_FSGSBASE"
26570 [(set_attr "type" "other")
26571 (set_attr "prefix_0f" "1")
26572 (set_attr "prefix_rep" "1")])
26574 (define_insn "wr<fsgs>base<mode>"
26575 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
26577 "TARGET_64BIT && TARGET_FSGSBASE"
26579 [(set_attr "type" "other")
26580 (set_attr "prefix_0f" "1")
26581 (set_attr "prefix_rep" "1")])
26583 (define_insn "ptwrite<mode>"
26584 [(unspec_volatile [(match_operand:SWI48 0 "nonimmediate_operand" "rm")]
26588 [(set_attr "type" "other")
26589 (set_attr "prefix_0f" "1")
26590 (set_attr "prefix_rep" "1")])
26592 (define_insn "@rdrand<mode>"
26593 [(set (match_operand:SWI248 0 "register_operand" "=r")
26594 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
26595 (set (reg:CCC FLAGS_REG)
26596 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
26599 [(set_attr "type" "other")
26600 (set_attr "prefix_0f" "1")])
26602 (define_insn "@rdseed<mode>"
26603 [(set (match_operand:SWI248 0 "register_operand" "=r")
26604 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
26605 (set (reg:CCC FLAGS_REG)
26606 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
26609 [(set_attr "type" "other")
26610 (set_attr "prefix_0f" "1")])
26612 (define_expand "pause"
26613 [(set (match_dup 0)
26614 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
26617 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
26618 MEM_VOLATILE_P (operands[0]) = 1;
26621 ;; Use "rep; nop", instead of "pause", to support older assemblers.
26622 ;; They have the same encoding.
26623 (define_insn "*pause"
26624 [(set (match_operand:BLK 0)
26625 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
26628 [(set_attr "length" "2")
26629 (set_attr "memory" "unknown")])
26631 ;; CET instructions
26632 (define_insn "@rdssp<mode>"
26633 [(set (match_operand:SWI48 0 "register_operand" "=r")
26634 (unspec_volatile:SWI48 [(match_operand:SWI48 1 "register_operand" "0")]
26635 UNSPECV_NOP_RDSSP))]
26636 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
26637 "rdssp<mskmodesuffix>\t%0"
26638 [(set_attr "length" "6")
26639 (set_attr "type" "other")])
26641 (define_insn "@incssp<mode>"
26642 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
26644 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
26645 "incssp<mskmodesuffix>\t%0"
26646 [(set_attr "length" "4")
26647 (set_attr "type" "other")])
26649 (define_insn "saveprevssp"
26650 [(unspec_volatile [(const_int 0)] UNSPECV_SAVEPREVSSP)]
26653 [(set_attr "length" "5")
26654 (set_attr "type" "other")])
26656 (define_insn "rstorssp"
26657 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")]
26661 [(set_attr "length" "5")
26662 (set_attr "type" "other")])
26664 (define_insn "@wrss<mode>"
26665 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
26666 (match_operand:SWI48 1 "memory_operand" "m")]
26669 "wrss<mskmodesuffix>\t%0, %1"
26670 [(set_attr "length" "3")
26671 (set_attr "type" "other")])
26673 (define_insn "@wruss<mode>"
26674 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
26675 (match_operand:SWI48 1 "memory_operand" "m")]
26678 "wruss<mskmodesuffix>\t%0, %1"
26679 [(set_attr "length" "4")
26680 (set_attr "type" "other")])
26682 (define_insn "setssbsy"
26683 [(unspec_volatile [(const_int 0)] UNSPECV_SETSSBSY)]
26686 [(set_attr "length" "4")
26687 (set_attr "type" "other")])
26689 (define_insn "clrssbsy"
26690 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")]
26694 [(set_attr "length" "4")
26695 (set_attr "type" "other")])
26697 (define_insn "nop_endbr"
26698 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]
26699 "(flag_cf_protection & CF_BRANCH)"
26701 return TARGET_64BIT ? "endbr64" : "endbr32";
26703 [(set_attr "length" "4")
26704 (set_attr "length_immediate" "0")
26705 (set_attr "modrm" "0")])
26708 (define_expand "xbegin"
26709 [(set (match_operand:SI 0 "register_operand")
26710 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
26713 rtx_code_label *label = gen_label_rtx ();
26715 /* xbegin is emitted as jump_insn, so reload won't be able
26716 to reload its operand. Force the value into AX hard register. */
26717 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
26718 emit_move_insn (ax_reg, constm1_rtx);
26720 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
26722 emit_label (label);
26723 LABEL_NUSES (label) = 1;
26725 emit_move_insn (operands[0], ax_reg);
26730 (define_insn "xbegin_1"
26732 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
26734 (label_ref (match_operand 1))
26736 (set (match_operand:SI 0 "register_operand" "+a")
26737 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
26740 [(set_attr "type" "other")
26741 (set_attr "length" "6")])
26743 (define_insn "xend"
26744 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
26747 [(set_attr "type" "other")
26748 (set_attr "length" "3")])
26750 (define_insn "xabort"
26751 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand")]
26755 [(set_attr "type" "other")
26756 (set_attr "length" "3")])
26758 (define_expand "xtest"
26759 [(set (match_operand:QI 0 "register_operand")
26760 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
26763 emit_insn (gen_xtest_1 ());
26765 ix86_expand_setcc (operands[0], NE,
26766 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
26770 (define_insn "xtest_1"
26771 [(set (reg:CCZ FLAGS_REG)
26772 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
26775 [(set_attr "type" "other")
26776 (set_attr "length" "3")])
26778 (define_insn "clwb"
26779 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
26783 [(set_attr "type" "sse")
26784 (set_attr "atom_sse_attr" "fence")
26785 (set_attr "memory" "unknown")])
26787 (define_insn "clflushopt"
26788 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
26789 UNSPECV_CLFLUSHOPT)]
26790 "TARGET_CLFLUSHOPT"
26792 [(set_attr "type" "sse")
26793 (set_attr "atom_sse_attr" "fence")
26794 (set_attr "memory" "unknown")])
26796 ;; MONITORX and MWAITX
26797 (define_insn "mwaitx"
26798 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
26799 (match_operand:SI 1 "register_operand" "a")
26800 (match_operand:SI 2 "register_operand" "b")]
26803 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
26804 ;; Since 32bit register operands are implicitly zero extended to 64bit,
26805 ;; we only need to set up 32bit registers.
26807 [(set_attr "length" "3")])
26809 (define_insn "@monitorx_<mode>"
26810 [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
26811 (match_operand:SI 1 "register_operand" "c")
26812 (match_operand:SI 2 "register_operand" "d")]
26815 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
26816 ;; RCX and RDX are used. Since 32bit register operands are implicitly
26817 ;; zero extended to 64bit, we only need to set up 32bit registers.
26819 [(set (attr "length")
26820 (symbol_ref ("(Pmode != word_mode) + 3")))])
26823 (define_insn "@clzero_<mode>"
26824 [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
26828 [(set_attr "length" "3")
26829 (set_attr "memory" "unknown")])
26831 ;; RDPKRU and WRPKRU
26833 (define_expand "rdpkru"
26835 [(set (match_operand:SI 0 "register_operand")
26836 (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
26837 (set (match_dup 2) (const_int 0))])]
26840 operands[1] = force_reg (SImode, const0_rtx);
26841 operands[2] = gen_reg_rtx (SImode);
26844 (define_insn "*rdpkru"
26845 [(set (match_operand:SI 0 "register_operand" "=a")
26846 (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
26848 (set (match_operand:SI 1 "register_operand" "=d")
26852 [(set_attr "type" "other")])
26854 (define_expand "wrpkru"
26855 [(unspec_volatile:SI
26856 [(match_operand:SI 0 "register_operand")
26857 (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
26860 operands[1] = force_reg (SImode, const0_rtx);
26861 operands[2] = force_reg (SImode, const0_rtx);
26864 (define_insn "*wrpkru"
26865 [(unspec_volatile:SI
26866 [(match_operand:SI 0 "register_operand" "a")
26867 (match_operand:SI 1 "register_operand" "d")
26868 (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
26871 [(set_attr "type" "other")])
26873 (define_insn "rdpid"
26874 [(set (match_operand:SI 0 "register_operand" "=r")
26875 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDPID))]
26876 "!TARGET_64BIT && TARGET_RDPID"
26878 [(set_attr "type" "other")])
26880 (define_insn "rdpid_rex64"
26881 [(set (match_operand:DI 0 "register_operand" "=r")
26882 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPID))]
26883 "TARGET_64BIT && TARGET_RDPID"
26885 [(set_attr "type" "other")])
26887 ;; Intirinsics for > i486
26889 (define_insn "wbinvd"
26890 [(unspec_volatile [(const_int 0)] UNSPECV_WBINVD)]
26893 [(set_attr "type" "other")])
26895 (define_insn "wbnoinvd"
26896 [(unspec_volatile [(const_int 0)] UNSPECV_WBNOINVD)]
26899 [(set_attr "type" "other")])
26901 ;; MOVDIRI and MOVDIR64B
26903 (define_insn "movdiri<mode>"
26904 [(set (match_operand:SWI48 0 "memory_operand" "=m")
26905 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")]
26908 "movdiri\t{%1, %0|%0, %1}"
26909 [(set_attr "type" "other")])
26911 (define_insn "@movdir64b_<mode>"
26912 [(set (mem:XI (match_operand:P 0 "register_operand" "r"))
26913 (unspec:XI [(match_operand:XI 1 "memory_operand" "m")]
26914 UNSPEC_MOVDIR64B))]
26916 "movdir64b\t{%1, %0|%0, %1}"
26917 [(set_attr "type" "other")])
26920 (define_int_iterator TSXLDTRK [UNSPECV_XSUSLDTRK UNSPECV_XRESLDTRK])
26921 (define_int_attr tsxldtrk [(UNSPECV_XSUSLDTRK "xsusldtrk")
26922 (UNSPECV_XRESLDTRK "xresldtrk")])
26923 (define_insn "<tsxldtrk>"
26924 [(unspec_volatile [(const_int 0)] TSXLDTRK)]
26927 [(set_attr "type" "other")
26928 (set_attr "length" "4")])
26930 ;; ENQCMD and ENQCMDS
26932 (define_int_iterator ENQCMD [UNSPECV_ENQCMD UNSPECV_ENQCMDS])
26933 (define_int_attr enqcmd_sfx [(UNSPECV_ENQCMD "") (UNSPECV_ENQCMDS "s")])
26935 (define_insn "@enqcmd<enqcmd_sfx>_<mode>"
26936 [(set (reg:CCZ FLAGS_REG)
26937 (unspec_volatile:CCZ [(match_operand:P 0 "register_operand" "r")
26938 (match_operand:XI 1 "memory_operand" "m")]
26941 "enqcmd<enqcmd_sfx>\t{%1, %0|%0, %1}"
26942 [(set_attr "type" "other")])
26945 (define_int_iterator UINTR [UNSPECV_CLUI UNSPECV_STUI])
26946 (define_int_attr uintr [(UNSPECV_CLUI "clui") (UNSPECV_STUI "stui")])
26948 (define_insn "<uintr>"
26949 [(unspec_volatile [(const_int 0)] UINTR)]
26950 "TARGET_UINTR && TARGET_64BIT"
26952 [(set_attr "type" "other")
26953 (set_attr "length" "4")])
26955 (define_insn "testui"
26956 [(set (reg:CCC FLAGS_REG)
26957 (unspec_volatile:CCC [(const_int 0)] UNSPECV_TESTUI))]
26958 "TARGET_UINTR && TARGET_64BIT"
26960 [(set_attr "type" "other")
26961 (set_attr "length" "4")])
26963 (define_insn "senduipi"
26965 [(match_operand:DI 0 "register_operand" "r")]
26967 "TARGET_UINTR && TARGET_64BIT"
26969 [(set_attr "type" "other")
26970 (set_attr "length" "4")])
26974 (define_insn "umwait"
26975 [(set (reg:CCC FLAGS_REG)
26976 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26977 (match_operand:DI 1 "register_operand" "A")]
26979 "!TARGET_64BIT && TARGET_WAITPKG"
26981 [(set_attr "length" "3")])
26983 (define_insn "umwait_rex64"
26984 [(set (reg:CCC FLAGS_REG)
26985 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26986 (match_operand:SI 1 "register_operand" "a")
26987 (match_operand:SI 2 "register_operand" "d")]
26989 "TARGET_64BIT && TARGET_WAITPKG"
26991 [(set_attr "length" "3")])
26993 (define_insn "@umonitor_<mode>"
26994 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
26998 [(set (attr "length")
26999 (symbol_ref ("(Pmode != word_mode) + 3")))])
27001 (define_insn "tpause"
27002 [(set (reg:CCC FLAGS_REG)
27003 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
27004 (match_operand:DI 1 "register_operand" "A")]
27006 "!TARGET_64BIT && TARGET_WAITPKG"
27008 [(set_attr "length" "3")])
27010 (define_insn "tpause_rex64"
27011 [(set (reg:CCC FLAGS_REG)
27012 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
27013 (match_operand:SI 1 "register_operand" "a")
27014 (match_operand:SI 2 "register_operand" "d")]
27016 "TARGET_64BIT && TARGET_WAITPKG"
27018 [(set_attr "length" "3")])
27020 (define_insn "cldemote"
27021 [(unspec_volatile[(match_operand 0 "address_operand" "p")]
27025 [(set_attr "type" "other")
27026 (set_attr "memory" "unknown")])
27028 (define_insn "speculation_barrier"
27029 [(unspec_volatile [(const_int 0)] UNSPECV_SPECULATION_BARRIER)]
27032 [(set_attr "type" "other")
27033 (set_attr "length" "3")])
27035 (define_insn "serialize"
27036 [(unspec_volatile [(const_int 0)] UNSPECV_SERIALIZE)]
27039 [(set_attr "type" "other")
27040 (set_attr "length" "3")])
27042 (define_insn "patchable_area"
27043 [(unspec_volatile [(match_operand 0 "const_int_operand")
27044 (match_operand 1 "const_int_operand")]
27045 UNSPECV_PATCHABLE_AREA)]
27048 ix86_output_patchable_area (INTVAL (operands[0]),
27049 INTVAL (operands[1]) != 0);
27052 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
27053 (set_attr "length_immediate" "0")
27054 (set_attr "modrm" "0")])
27056 (define_insn "hreset"
27057 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")]
27061 [(set_attr "type" "other")
27062 (set_attr "length" "4")])
27064 ;; Spaceship optimization
27065 (define_expand "spaceship<mode>3"
27066 [(match_operand:SI 0 "register_operand")
27067 (match_operand:MODEF 1 "cmp_fp_expander_operand")
27068 (match_operand:MODEF 2 "cmp_fp_expander_operand")]
27069 "(TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
27070 && (TARGET_CMOVE || (TARGET_SAHF && TARGET_USE_SAHF))"
27072 ix86_expand_fp_spaceship (operands[0], operands[1], operands[2]);
27076 (define_expand "spaceshipxf3"
27077 [(match_operand:SI 0 "register_operand")
27078 (match_operand:XF 1 "nonmemory_operand")
27079 (match_operand:XF 2 "nonmemory_operand")]
27080 "TARGET_80387 && (TARGET_CMOVE || (TARGET_SAHF && TARGET_USE_SAHF))"
27082 ix86_expand_fp_spaceship (operands[0], operands[1], operands[2]);
27086 ;; Defined because the generic expand_builtin_issignaling for XFmode
27087 ;; only tests for sNaNs, but i387 treats also pseudo numbers as always
27089 (define_expand "issignalingxf2"
27090 [(match_operand:SI 0 "register_operand")
27091 (match_operand:XF 1 "general_operand")]
27094 rtx temp = operands[1];
27097 rtx mem = assign_stack_temp (XFmode, GET_MODE_SIZE (XFmode));
27098 emit_move_insn (mem, temp);
27101 rtx ex = adjust_address (temp, HImode, 8);
27102 rtx hi = adjust_address (temp, SImode, 4);
27103 rtx lo = adjust_address (temp, SImode, 0);
27104 rtx val = GEN_INT (HOST_WIDE_INT_M1U << 30);
27105 rtx mask = GEN_INT (0x7fff);
27106 rtx bit = GEN_INT (HOST_WIDE_INT_1U << 30);
27108 ((ex & mask) && (int) hi >= 0)
27109 || ((ex & mask) == mask && ((hi ^ bit) | ((lo | -lo) >> 31)) > val). */
27110 rtx nlo = expand_unop (SImode, neg_optab, lo, NULL_RTX, 0);
27111 lo = expand_binop (SImode, ior_optab, lo, nlo,
27112 NULL_RTX, 1, OPTAB_LIB_WIDEN);
27113 lo = expand_shift (RSHIFT_EXPR, SImode, lo, 31, NULL_RTX, 1);
27114 temp = expand_binop (SImode, xor_optab, hi, bit,
27115 NULL_RTX, 1, OPTAB_LIB_WIDEN);
27116 temp = expand_binop (SImode, ior_optab, temp, lo,
27117 NULL_RTX, 1, OPTAB_LIB_WIDEN);
27118 temp = emit_store_flag_force (gen_reg_rtx (SImode), GTU, temp, val,
27120 ex = expand_binop (HImode, and_optab, ex, mask,
27121 NULL_RTX, 1, OPTAB_LIB_WIDEN);
27122 rtx temp2 = emit_store_flag_force (gen_reg_rtx (SImode), NE,
27123 ex, const0_rtx, SImode, 1, 1);
27124 ex = emit_store_flag_force (gen_reg_rtx (SImode), EQ,
27125 ex, mask, HImode, 1, 1);
27126 temp = expand_binop (SImode, and_optab, temp, ex,
27127 NULL_RTX, 1, OPTAB_LIB_WIDEN);
27128 rtx temp3 = emit_store_flag_force (gen_reg_rtx (SImode), GE,
27129 hi, const0_rtx, SImode, 0, 1);
27130 temp2 = expand_binop (SImode, and_optab, temp2, temp3,
27131 NULL_RTX, 1, OPTAB_LIB_WIDEN);
27132 temp = expand_binop (SImode, ior_optab, temp, temp2,
27133 NULL_RTX, 1, OPTAB_LIB_WIDEN);
27134 emit_move_insn (operands[0], temp);
27138 (define_insn "urdmsr"
27139 [(set (match_operand:DI 0 "register_operand" "=r")
27140 (unspec_volatile:DI
27141 [(match_operand:DI 1 "x86_64_szext_nonmemory_operand" "reZ")]
27143 "TARGET_USER_MSR && TARGET_64BIT"
27144 "urdmsr\t{%1, %0|%0, %1}"
27145 [(set_attr "prefix" "vex")
27146 (set_attr "type" "other")])
27148 (define_insn "uwrmsr"
27150 [(match_operand:DI 0 "x86_64_szext_nonmemory_operand" "reZ")
27151 (match_operand:DI 1 "register_operand" "r")]
27153 "TARGET_USER_MSR && TARGET_64BIT"
27154 "uwrmsr\t{%1, %0|%0, %1}"
27155 [(set_attr "prefix" "vex")
27156 (set_attr "type" "other")])
27160 (include "sync.md")