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_expand "extv<mode>"
3339 [(set (match_operand:SWI24 0 "register_operand")
3340 (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
3341 (match_operand:QI 2 "const_int_operand")
3342 (match_operand:QI 3 "const_int_operand")))]
3345 /* Handle extractions from %ah et al. */
3346 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
3349 unsigned int regno = reg_or_subregno (operands[1]);
3351 /* Be careful to expand only with registers having upper parts. */
3352 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3353 operands[1] = copy_to_reg (operands[1]);
3356 (define_insn "*extv<mode>"
3357 [(set (match_operand:SWI24 0 "register_operand" "=R")
3358 (sign_extract:SWI24 (match_operand 1 "int248_register_operand" "Q")
3362 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
3363 [(set_attr "type" "imovx")
3364 (set_attr "mode" "SI")])
3366 ;; Split sign-extension of single least significant bit as and x,$1;neg x
3367 (define_insn_and_split "*extv<mode>_1_0"
3368 [(set (match_operand:SWI48 0 "register_operand" "=r")
3369 (sign_extract:SWI48 (match_operand:SWI48 1 "register_operand" "0")
3372 (clobber (reg:CC FLAGS_REG))]
3376 [(parallel [(set (match_dup 0) (and:SWI48 (match_dup 1) (const_int 1)))
3377 (clobber (reg:CC FLAGS_REG))])
3378 (parallel [(set (match_dup 0) (neg:SWI48 (match_dup 0)))
3379 (clobber (reg:CC FLAGS_REG))])])
3381 (define_expand "extzv<mode>"
3382 [(set (match_operand:SWI248 0 "register_operand")
3383 (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
3384 (match_operand:QI 2 "const_int_operand")
3385 (match_operand:QI 3 "const_int_operand")))]
3388 if (ix86_expand_pextr (operands))
3391 /* Handle extractions from %ah et al. */
3392 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
3395 unsigned int regno = reg_or_subregno (operands[1]);
3397 /* Be careful to expand only with registers having upper parts. */
3398 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3399 operands[1] = copy_to_reg (operands[1]);
3402 (define_insn "*extzv<mode>"
3403 [(set (match_operand:SWI248 0 "register_operand" "=R")
3404 (zero_extract:SWI248 (match_operand 1 "int248_register_operand" "Q")
3408 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
3409 [(set_attr "type" "imovx")
3410 (set_attr "mode" "SI")])
3412 (define_insn "*extzvqi"
3413 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn,?R")
3415 (match_operator:SWI248 2 "extract_operator"
3416 [(match_operand 1 "int248_register_operand" "Q,Q")
3418 (const_int 8)]) 0))]
3421 switch (get_attr_type (insn))
3424 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
3426 return "mov{b}\t{%h1, %0|%0, %h1}";
3429 [(set_attr "addr" "gpr8,*")
3431 (if_then_else (and (match_operand:QI 0 "register_operand")
3432 (ior (not (match_operand:QI 0 "QIreg_operand"))
3433 (match_test "TARGET_MOVX")))
3434 (const_string "imovx")
3435 (const_string "imov")))
3437 (if_then_else (eq_attr "type" "imovx")
3439 (const_string "QI")))])
3441 (define_expand "insv<mode>"
3442 [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
3443 (match_operand:QI 1 "const_int_operand")
3444 (match_operand:QI 2 "const_int_operand"))
3445 (match_operand:SWI248 3 "register_operand"))]
3450 if (ix86_expand_pinsr (operands))
3453 /* Handle insertions to %ah et al. */
3454 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
3457 unsigned int regno = reg_or_subregno (operands[0]);
3459 /* Be careful to expand only with registers having upper parts. */
3460 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3461 dst = copy_to_reg (operands[0]);
3465 emit_insn (gen_insv_1 (<MODE>mode, dst, operands[3]));
3467 /* Fix up the destination if needed. */
3468 if (dst != operands[0])
3469 emit_move_insn (operands[0], dst);
3474 (define_insn "@insv<mode>_1"
3475 [(set (zero_extract:SWI248
3476 (match_operand 0 "int248_register_operand" "+Q")
3479 (match_operand:SWI248 1 "general_operand" "QnBn"))]
3482 if (CONST_INT_P (operands[1]))
3483 operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
3484 return "mov{b}\t{%b1, %h0|%h0, %b1}";
3486 [(set_attr "addr" "gpr8")
3487 (set_attr "type" "imov")
3488 (set_attr "mode" "QI")])
3490 (define_insn "*insvqi_1"
3491 [(set (zero_extract:SWI248
3492 (match_operand 0 "int248_register_operand" "+Q")
3496 (match_operand:QI 1 "general_operand" "QnBn") 0))]
3498 "mov{b}\t{%1, %h0|%h0, %1}"
3499 [(set_attr "addr" "gpr8")
3500 (set_attr "type" "imov")
3501 (set_attr "mode" "QI")])
3503 ;; Eliminate redundant insv, e.g. xorl %eax,%eax; movb $0, %ah
3505 [(parallel [(set (match_operand:SWI48 0 "general_reg_operand")
3507 (clobber (reg:CC FLAGS_REG))])
3508 (set (zero_extract:SWI248 (match_operand 1 "int248_register_operand")
3512 "REGNO (operands[0]) == REGNO (operands[1])"
3513 [(parallel [(set (match_operand:SWI48 0 "general_reg_operand")
3515 (clobber (reg:CC FLAGS_REG))])])
3517 ;; Combine movl followed by movb.
3519 [(set (match_operand:SWI48 0 "general_reg_operand")
3520 (match_operand:SWI48 1 "const_int_operand"))
3521 (set (zero_extract:SWI248 (match_operand 2 "int248_register_operand")
3524 (match_operand:SWI248 3 "const_int_operand"))]
3525 "REGNO (operands[0]) == REGNO (operands[2])"
3526 [(set (match_operand:SWI48 0 "general_reg_operand")
3529 HOST_WIDE_INT tmp = INTVAL (operands[1]) & ~(HOST_WIDE_INT)0xff00;
3530 tmp |= (INTVAL (operands[3]) & 0xff) << 8;
3531 operands[4] = gen_int_mode (tmp, <SWI48:MODE>mode);
3534 (define_insn "*insvqi_2"
3535 [(set (zero_extract:SWI248
3536 (match_operand 0 "int248_register_operand" "+Q")
3539 (match_operator:SWI248 2 "extract_operator"
3540 [(match_operand 1 "int248_register_operand" "Q")
3544 "mov{b}\t{%h1, %h0|%h0, %h1}"
3545 [(set_attr "type" "imov")
3546 (set_attr "mode" "QI")])
3548 (define_insn "*insvqi_3"
3549 [(set (zero_extract:SWI248
3550 (match_operand 0 "int248_register_operand" "+Q")
3554 (match_operand:SWI248 1 "register_operand" "Q")
3557 "mov{b}\t{%h1, %h0|%h0, %h1}"
3558 [(set_attr "type" "imov")
3559 (set_attr "mode" "QI")])
3561 (define_code_iterator any_or_plus [plus ior xor])
3563 (define_insn_and_split "*insvti_highpart_1"
3564 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro,r,r,&r")
3567 (match_operand:TI 1 "nonimmediate_operand" "r,m,r,m")
3568 (match_operand:TI 3 "const_scalar_int_operand" "n,n,n,n"))
3571 (match_operand:DI 2 "nonimmediate_operand" "r,r,m,m"))
3574 && CONST_WIDE_INT_P (operands[3])
3575 && CONST_WIDE_INT_NUNITS (operands[3]) == 2
3576 && CONST_WIDE_INT_ELT (operands[3], 0) == -1
3577 && CONST_WIDE_INT_ELT (operands[3], 1) == 0"
3579 "&& reload_completed"
3582 operands[4] = gen_lowpart (DImode, operands[1]);
3583 split_double_concat (TImode, operands[0], operands[4], operands[2]);
3587 (define_insn_and_split "*insvti_lowpart_1"
3588 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro,r,r,&r")
3591 (match_operand:TI 1 "nonimmediate_operand" "r,m,r,m")
3592 (match_operand:TI 3 "const_scalar_int_operand" "n,n,n,n"))
3594 (match_operand:DI 2 "nonimmediate_operand" "r,r,m,m"))))]
3596 && CONST_WIDE_INT_P (operands[3])
3597 && CONST_WIDE_INT_NUNITS (operands[3]) == 2
3598 && CONST_WIDE_INT_ELT (operands[3], 0) == 0
3599 && CONST_WIDE_INT_ELT (operands[3], 1) == -1"
3601 "&& reload_completed"
3604 operands[4] = gen_highpart (DImode, operands[1]);
3605 split_double_concat (TImode, operands[0], operands[2], operands[4]);
3609 (define_insn_and_split "*insvdi_lowpart_1"
3610 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro,r,r,&r")
3613 (match_operand:DI 1 "nonimmediate_operand" "r,m,r,m")
3614 (match_operand:DI 3 "const_int_operand" "n,n,n,n"))
3616 (match_operand:SI 2 "nonimmediate_operand" "r,r,m,m"))))]
3618 && CONST_INT_P (operands[3])
3619 && UINTVAL (operands[3]) == 0xffffffff00000000ll"
3621 "&& reload_completed"
3624 operands[4] = gen_highpart (SImode, operands[1]);
3625 split_double_concat (DImode, operands[0], operands[2], operands[4]);
3629 ;; Floating point push instructions.
3631 (define_insn "*pushtf"
3632 [(set (match_operand:TF 0 "push_operand" "=<,<")
3633 (match_operand:TF 1 "general_no_elim_operand" "v,*roC"))]
3634 "TARGET_64BIT || TARGET_SSE"
3636 /* This insn should be already split before reg-stack. */
3639 [(set_attr "isa" "*,x64")
3640 (set_attr "type" "multi")
3641 (set_attr "unit" "sse,*")
3642 (set_attr "mode" "TF,DI")])
3644 ;; %%% Kill this when call knows how to work this out.
3646 [(set (match_operand:TF 0 "push_operand")
3647 (match_operand:TF 1 "sse_reg_operand"))]
3648 "TARGET_SSE && reload_completed"
3649 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3650 (set (match_dup 0) (match_dup 1))]
3652 /* Preserve memory attributes. */
3653 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3656 (define_insn "*pushxf"
3657 [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<")
3658 (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF,oC"))]
3661 /* This insn should be already split before reg-stack. */
3664 [(set_attr "isa" "*,*,*,nox64,x64")
3665 (set_attr "type" "multi")
3666 (set_attr "unit" "i387,*,*,*,*")
3668 (cond [(eq_attr "alternative" "1,2,3,4")
3669 (if_then_else (match_test "TARGET_64BIT")
3671 (const_string "SI"))
3673 (const_string "XF")))
3674 (set (attr "preferred_for_size")
3675 (cond [(eq_attr "alternative" "1")
3676 (symbol_ref "false")]
3677 (symbol_ref "true")))])
3679 ;; %%% Kill this when call knows how to work this out.
3681 [(set (match_operand:XF 0 "push_operand")
3682 (match_operand:XF 1 "fp_register_operand"))]
3684 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3685 (set (match_dup 0) (match_dup 1))]
3687 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (XFmode)));
3688 /* Preserve memory attributes. */
3689 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3692 (define_insn "*pushdf"
3693 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
3694 (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmC,v"))]
3697 /* This insn should be already split before reg-stack. */
3700 [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
3701 (set_attr "type" "multi")
3702 (set_attr "unit" "i387,*,*,*,*,sse")
3703 (set_attr "mode" "DF,SI,SI,SI,DI,DF")
3704 (set (attr "preferred_for_size")
3705 (cond [(eq_attr "alternative" "1")
3706 (symbol_ref "false")]
3707 (symbol_ref "true")))
3708 (set (attr "preferred_for_speed")
3709 (cond [(eq_attr "alternative" "1")
3710 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3711 (symbol_ref "true")))])
3713 ;; %%% Kill this when call knows how to work this out.
3715 [(set (match_operand:DF 0 "push_operand")
3716 (match_operand:DF 1 "any_fp_register_operand"))]
3718 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3719 (set (match_dup 0) (match_dup 1))]
3721 /* Preserve memory attributes. */
3722 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3725 (define_mode_iterator HFBF [HF BF])
3727 (define_insn "*push<mode>_rex64"
3728 [(set (match_operand:HFBF 0 "push_operand" "=X,X")
3729 (match_operand:HFBF 1 "nonmemory_no_elim_operand" "r,x"))]
3732 /* Anything else should be already split before reg-stack. */
3733 gcc_assert (which_alternative == 0);
3734 return "push{q}\t%q1";
3736 [(set_attr "isa" "*,sse4")
3737 (set_attr "type" "push,multi")
3738 (set_attr "mode" "DI,TI")])
3740 (define_insn "*push<mode>"
3741 [(set (match_operand:HFBF 0 "push_operand" "=X,X")
3742 (match_operand:HFBF 1 "general_no_elim_operand" "rmF,x"))]
3745 /* Anything else should be already split before reg-stack. */
3746 gcc_assert (which_alternative == 0);
3747 return "push{l}\t%k1";
3749 [(set_attr "isa" "*,sse4")
3750 (set_attr "type" "push,multi")
3751 (set_attr "mode" "SI,TI")])
3753 (define_insn "push2_di"
3754 [(set (match_operand:TI 0 "push_operand" "=<")
3755 (unspec:TI [(match_operand:DI 1 "register_operand" "r")
3756 (match_operand:DI 2 "register_operand" "r")]
3758 "TARGET_APX_PUSH2POP2"
3760 [(set_attr "mode" "TI")
3761 (set_attr "type" "multi")
3762 (set_attr "prefix" "evex")])
3764 (define_insn "pop2_di"
3765 [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
3766 (unspec:DI [(match_operand:TI 1 "pop_operand" ">")]
3767 UNSPEC_APXPOP2_LOW))
3768 (set (match_operand:DI 2 "register_operand" "=r")
3769 (unspec:DI [(const_int 0)] UNSPEC_APXPOP2_HIGH))])]
3770 "TARGET_APX_PUSH2POP2"
3772 [(set_attr "mode" "TI")
3773 (set_attr "prefix" "evex")])
3775 (define_insn "*pushsf_rex64"
3776 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3777 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,v"))]
3780 /* Anything else should be already split before reg-stack. */
3781 if (which_alternative != 1)
3783 return "push{q}\t%q1";
3785 [(set_attr "type" "multi,push,multi")
3786 (set_attr "unit" "i387,*,*")
3787 (set_attr "mode" "SF,DI,SF")])
3789 (define_insn "*pushsf"
3790 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3791 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,v"))]
3794 /* Anything else should be already split before reg-stack. */
3795 if (which_alternative != 1)
3797 return "push{l}\t%1";
3799 [(set_attr "type" "multi,push,multi")
3800 (set_attr "unit" "i387,*,*")
3801 (set_attr "mode" "SF,SI,SF")])
3803 (define_mode_iterator MODESH [SF HF BF])
3804 ;; %%% Kill this when call knows how to work this out.
3806 [(set (match_operand:MODESH 0 "push_operand")
3807 (match_operand:MODESH 1 "any_fp_register_operand"))]
3809 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3810 (set (match_dup 0) (match_dup 1))]
3812 rtx op = XEXP (operands[0], 0);
3813 if (GET_CODE (op) == PRE_DEC)
3815 gcc_assert (!TARGET_64BIT);
3820 op = XEXP (XEXP (op, 1), 1);
3821 gcc_assert (CONST_INT_P (op));
3824 /* Preserve memory attributes. */
3825 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3829 [(set (match_operand:SF 0 "push_operand")
3830 (match_operand:SF 1 "memory_operand"))]
3832 && find_constant_src (insn)"
3833 [(set (match_dup 0) (match_dup 2))]
3834 "operands[2] = find_constant_src (curr_insn);")
3837 [(set (match_operand 0 "push_operand")
3838 (match_operand 1 "general_gr_operand"))]
3840 && (GET_MODE (operands[0]) == TFmode
3841 || GET_MODE (operands[0]) == XFmode
3842 || GET_MODE (operands[0]) == DFmode)"
3844 "ix86_split_long_move (operands); DONE;")
3846 ;; Floating point move instructions.
3848 (define_expand "movtf"
3849 [(set (match_operand:TF 0 "nonimmediate_operand")
3850 (match_operand:TF 1 "nonimmediate_operand"))]
3851 "TARGET_64BIT || TARGET_SSE"
3852 "ix86_expand_move (TFmode, operands); DONE;")
3854 (define_expand "mov<mode>"
3855 [(set (match_operand:X87MODEFH 0 "nonimmediate_operand")
3856 (match_operand:X87MODEFH 1 "general_operand"))]
3858 "ix86_expand_move (<MODE>mode, operands); DONE;")
3860 (define_insn "*movtf_internal"
3861 [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o")
3862 (match_operand:TF 1 "general_operand" "C ,vm,v,*roF,*rC"))]
3863 "(TARGET_64BIT || TARGET_SSE)
3864 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3865 && (lra_in_progress || reload_completed
3866 || !CONST_DOUBLE_P (operands[1])
3867 || (standard_sse_constant_p (operands[1], TFmode) == 1
3868 && !memory_operand (operands[0], TFmode))
3869 || (!TARGET_MEMORY_MISMATCH_STALL
3870 && memory_operand (operands[0], TFmode)))"
3872 switch (get_attr_type (insn))
3875 return standard_sse_constant_opcode (insn, operands);
3878 return ix86_output_ssemov (insn, operands);
3887 [(set_attr "isa" "*,*,*,x64,x64")
3888 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3889 (set (attr "prefix")
3890 (if_then_else (eq_attr "type" "sselog1,ssemov")
3891 (const_string "maybe_vex")
3892 (const_string "orig")))
3894 (cond [(eq_attr "alternative" "3,4")
3896 (match_test "TARGET_AVX")
3898 (ior (not (match_test "TARGET_SSE2"))
3899 (match_test "optimize_function_for_size_p (cfun)"))
3900 (const_string "V4SF")
3901 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3902 (const_string "V4SF")
3903 (and (eq_attr "alternative" "2")
3904 (match_test "TARGET_SSE_TYPELESS_STORES"))
3905 (const_string "V4SF")
3907 (const_string "TI")))])
3910 [(set (match_operand:TF 0 "nonimmediate_gr_operand")
3911 (match_operand:TF 1 "general_gr_operand"))]
3914 "ix86_split_long_move (operands); DONE;")
3916 ;; Possible store forwarding (partial memory) stall
3917 ;; in alternatives 4, 6, 7 and 8.
3918 (define_insn "*movxf_internal"
3919 [(set (match_operand:XF 0 "nonimmediate_operand"
3920 "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r ,o ,o")
3921 (match_operand:XF 1 "general_operand"
3922 "fm,f,G,roF,r ,*roF,*r,F ,C ,roF,rF,rC"))]
3923 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3924 && (lra_in_progress || reload_completed
3925 || !CONST_DOUBLE_P (operands[1])
3926 || ((optimize_function_for_size_p (cfun)
3927 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3928 && standard_80387_constant_p (operands[1]) > 0
3929 && !memory_operand (operands[0], XFmode))
3930 || (!TARGET_MEMORY_MISMATCH_STALL
3931 && memory_operand (operands[0], XFmode))
3932 || !TARGET_HARD_XF_REGS)"
3934 switch (get_attr_type (insn))
3937 if (which_alternative == 2)
3938 return standard_80387_constant_opcode (operands[1]);
3939 return output_387_reg_move (insn, operands);
3949 (cond [(eq_attr "alternative" "7,10")
3950 (const_string "nox64")
3951 (eq_attr "alternative" "8,11")
3952 (const_string "x64")
3954 (const_string "*")))
3956 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3957 (const_string "multi")
3959 (const_string "fmov")))
3961 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3962 (if_then_else (match_test "TARGET_64BIT")
3964 (const_string "SI"))
3966 (const_string "XF")))
3967 (set (attr "preferred_for_size")
3968 (cond [(eq_attr "alternative" "3,4")
3969 (symbol_ref "false")]
3970 (symbol_ref "true")))
3971 (set (attr "enabled")
3972 (cond [(eq_attr "alternative" "9,10,11")
3974 (match_test "TARGET_HARD_XF_REGS")
3975 (symbol_ref "false")
3977 (not (match_test "TARGET_HARD_XF_REGS"))
3978 (symbol_ref "false")
3980 (const_string "*")))])
3983 [(set (match_operand:XF 0 "nonimmediate_gr_operand")
3984 (match_operand:XF 1 "general_gr_operand"))]
3987 "ix86_split_long_move (operands); DONE;")
3989 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3990 (define_insn "*movdf_internal"
3991 [(set (match_operand:DF 0 "nonimmediate_operand"
3992 "=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")
3993 (match_operand:DF 1 "general_operand"
3994 "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"))]
3995 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3996 && (lra_in_progress || reload_completed
3997 || !CONST_DOUBLE_P (operands[1])
3998 || ((optimize_function_for_size_p (cfun)
3999 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
4000 && IS_STACK_MODE (DFmode)
4001 && standard_80387_constant_p (operands[1]) > 0
4002 && !memory_operand (operands[0], DFmode))
4003 || (TARGET_SSE2 && TARGET_SSE_MATH
4004 && standard_sse_constant_p (operands[1], DFmode) == 1
4005 && !memory_operand (operands[0], DFmode))
4006 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
4007 && memory_operand (operands[0], DFmode))
4008 || !TARGET_HARD_DF_REGS)"
4010 switch (get_attr_type (insn))
4013 if (which_alternative == 2)
4014 return standard_80387_constant_opcode (operands[1]);
4015 return output_387_reg_move (insn, operands);
4021 if (get_attr_mode (insn) == MODE_SI)
4022 return "mov{l}\t{%1, %k0|%k0, %1}";
4023 else if (which_alternative == 11)
4024 return "movabs{q}\t{%1, %0|%0, %1}";
4026 return "mov{q}\t{%1, %0|%0, %1}";
4029 return standard_sse_constant_opcode (insn, operands);
4032 return ix86_output_ssemov (insn, operands);
4039 (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
4040 (const_string "nox64")
4041 (eq_attr "alternative" "8,9,10,11,24,25")
4042 (const_string "x64")
4043 (eq_attr "alternative" "12,13,14,15")
4044 (const_string "sse2")
4045 (eq_attr "alternative" "20,21")
4046 (const_string "x64_sse2")
4048 (const_string "*")))
4050 (cond [(eq_attr "alternative" "0,1,2")
4051 (const_string "fmov")
4052 (eq_attr "alternative" "3,4,5,6,7,22,23")
4053 (const_string "multi")
4054 (eq_attr "alternative" "8,9,10,11,24,25")
4055 (const_string "imov")
4056 (eq_attr "alternative" "12,16")
4057 (const_string "sselog1")
4059 (const_string "ssemov")))
4061 (if_then_else (eq_attr "alternative" "11")
4063 (const_string "*")))
4064 (set (attr "length_immediate")
4065 (if_then_else (eq_attr "alternative" "11")
4067 (const_string "*")))
4068 (set (attr "prefix")
4069 (if_then_else (eq_attr "type" "sselog1,ssemov")
4070 (const_string "maybe_vex")
4071 (const_string "orig")))
4072 (set (attr "prefix_data16")
4074 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
4075 (eq_attr "mode" "V1DF"))
4077 (const_string "*")))
4079 (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
4081 (eq_attr "alternative" "8,9,11,20,21,24,25")
4084 /* xorps is one byte shorter for non-AVX targets. */
4085 (eq_attr "alternative" "12,16")
4086 (cond [(match_test "TARGET_AVX")
4087 (const_string "V2DF")
4088 (ior (not (match_test "TARGET_SSE2"))
4089 (match_test "optimize_function_for_size_p (cfun)"))
4090 (const_string "V4SF")
4091 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
4094 (const_string "V2DF"))
4096 /* For architectures resolving dependencies on
4097 whole SSE registers use movapd to break dependency
4098 chains, otherwise use short move to avoid extra work. */
4100 /* movaps is one byte shorter for non-AVX targets. */
4101 (eq_attr "alternative" "13,17")
4102 (cond [(match_test "TARGET_AVX512VL")
4103 (const_string "V2DF")
4104 (match_test "TARGET_AVX512F")
4106 (match_test "TARGET_AVX")
4107 (const_string "V2DF")
4108 (ior (not (match_test "TARGET_SSE2"))
4109 (match_test "optimize_function_for_size_p (cfun)"))
4110 (const_string "V4SF")
4111 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
4112 (const_string "V4SF")
4113 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
4114 (const_string "V2DF")
4116 (const_string "DF"))
4118 /* For architectures resolving dependencies on register
4119 parts we may avoid extra work to zero out upper part
4121 (eq_attr "alternative" "14,18")
4122 (cond [(not (match_test "TARGET_SSE2"))
4123 (const_string "V2SF")
4124 (match_test "TARGET_AVX")
4126 (match_test "TARGET_SSE_SPLIT_REGS")
4127 (const_string "V1DF")
4129 (const_string "DF"))
4131 (and (eq_attr "alternative" "15,19")
4132 (not (match_test "TARGET_SSE2")))
4133 (const_string "V2SF")
4135 (const_string "DF")))
4136 (set (attr "preferred_for_size")
4137 (cond [(eq_attr "alternative" "3,4")
4138 (symbol_ref "false")]
4139 (symbol_ref "true")))
4140 (set (attr "preferred_for_speed")
4141 (cond [(eq_attr "alternative" "3,4")
4142 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")
4143 (eq_attr "alternative" "20")
4144 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4145 (eq_attr "alternative" "21")
4146 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4148 (symbol_ref "true")))
4149 (set (attr "enabled")
4150 (cond [(eq_attr "alternative" "22,23,24,25")
4152 (match_test "TARGET_HARD_DF_REGS")
4153 (symbol_ref "false")
4155 (not (match_test "TARGET_HARD_DF_REGS"))
4156 (symbol_ref "false")
4158 (const_string "*")))])
4161 [(set (match_operand:DF 0 "nonimmediate_gr_operand")
4162 (match_operand:DF 1 "general_gr_operand"))]
4163 "!TARGET_64BIT && reload_completed"
4165 "ix86_split_long_move (operands); DONE;")
4167 (define_insn "*movsf_internal"
4168 [(set (match_operand:SF 0 "nonimmediate_operand"
4169 "=Yf*f,m ,Yf*f,?r ,?m,Yv,v,v,m,?r,?v,!*y,!*y,!m,!r,!*y,r ,m")
4170 (match_operand:SF 1 "general_operand"
4171 "Yf*fm,Yf*f,G ,rmF,rF,C ,v,m,v,v ,r ,*y ,m ,*y,*y,r ,rmF,rF"))]
4172 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
4173 && (lra_in_progress || reload_completed
4174 || !CONST_DOUBLE_P (operands[1])
4175 || ((optimize_function_for_size_p (cfun)
4176 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
4177 && IS_STACK_MODE (SFmode)
4178 && standard_80387_constant_p (operands[1]) > 0)
4179 || (TARGET_SSE && TARGET_SSE_MATH
4180 && standard_sse_constant_p (operands[1], SFmode) == 1)
4181 || memory_operand (operands[0], SFmode)
4182 || !TARGET_HARD_SF_REGS)"
4184 switch (get_attr_type (insn))
4187 if (which_alternative == 2)
4188 return standard_80387_constant_opcode (operands[1]);
4189 return output_387_reg_move (insn, operands);
4192 return "mov{l}\t{%1, %0|%0, %1}";
4195 return standard_sse_constant_opcode (insn, operands);
4198 return ix86_output_ssemov (insn, operands);
4201 switch (get_attr_mode (insn))
4204 return "movq\t{%1, %0|%0, %1}";
4206 return "movd\t{%1, %0|%0, %1}";
4217 (cond [(eq_attr "alternative" "9,10")
4218 (const_string "sse2")
4220 (const_string "*")))
4222 (cond [(eq_attr "alternative" "0,1,2")
4223 (const_string "fmov")
4224 (eq_attr "alternative" "3,4,16,17")
4225 (const_string "imov")
4226 (eq_attr "alternative" "5")
4227 (const_string "sselog1")
4228 (eq_attr "alternative" "11,12,13,14,15")
4229 (const_string "mmxmov")
4231 (const_string "ssemov")))
4232 (set (attr "prefix")
4233 (if_then_else (eq_attr "type" "sselog1,ssemov")
4234 (const_string "maybe_vex")
4235 (const_string "orig")))
4236 (set (attr "prefix_data16")
4237 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
4239 (const_string "*")))
4241 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
4243 (eq_attr "alternative" "11")
4245 (eq_attr "alternative" "5")
4246 (cond [(and (match_test "TARGET_AVX512F && TARGET_EVEX512")
4247 (not (match_test "TARGET_PREFER_AVX256")))
4248 (const_string "V16SF")
4249 (match_test "TARGET_AVX")
4250 (const_string "V4SF")
4251 (ior (not (match_test "TARGET_SSE2"))
4252 (match_test "optimize_function_for_size_p (cfun)"))
4253 (const_string "V4SF")
4254 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
4257 (const_string "V4SF"))
4259 /* For architectures resolving dependencies on
4260 whole SSE registers use APS move to break dependency
4261 chains, otherwise use short move to avoid extra work.
4263 Do the same for architectures resolving dependencies on
4264 the parts. While in DF mode it is better to always handle
4265 just register parts, the SF mode is different due to lack
4266 of instructions to load just part of the register. It is
4267 better to maintain the whole registers in single format
4268 to avoid problems on using packed logical operations. */
4269 (eq_attr "alternative" "6")
4270 (cond [(match_test "TARGET_AVX512VL")
4271 (const_string "V4SF")
4272 (match_test "TARGET_AVX512F")
4274 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
4275 (match_test "TARGET_SSE_SPLIT_REGS"))
4276 (const_string "V4SF")
4278 (const_string "SF"))
4280 (const_string "SF")))
4281 (set (attr "preferred_for_speed")
4282 (cond [(eq_attr "alternative" "9,14")
4283 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4284 (eq_attr "alternative" "10,15")
4285 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4287 (symbol_ref "true")))
4288 (set (attr "enabled")
4289 (cond [(eq_attr "alternative" "16,17")
4291 (match_test "TARGET_HARD_SF_REGS")
4292 (symbol_ref "false")
4294 (not (match_test "TARGET_HARD_SF_REGS"))
4295 (symbol_ref "false")
4297 (const_string "*")))])
4299 (define_mode_attr hfbfconstf
4302 (define_insn "*mov<mode>_internal"
4303 [(set (match_operand:HFBF 0 "nonimmediate_operand"
4304 "=?r,?r,?r,?m ,Yv,v,?r,jm,m,?v,v")
4305 (match_operand:HFBF 1 "general_operand"
4306 "r ,F ,m ,r<hfbfconstf>,C ,v, v,v ,v,r ,m"))]
4307 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
4310 || !CONST_DOUBLE_P (operands[1])
4312 && standard_sse_constant_p (operands[1], <MODE>mode) == 1)
4313 || memory_operand (operands[0], <MODE>mode))"
4315 switch (get_attr_type (insn))
4318 /* movzwl is faster than movw on p2 due to partial word stalls,
4319 though not as fast as an aligned movl. */
4320 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
4323 return ix86_output_ssemov (insn, operands);
4326 if (satisfies_constraint_C (operands[1]))
4327 return standard_sse_constant_opcode (insn, operands);
4329 if (SSE_REG_P (operands[0]))
4330 return "%vpinsrw\t{$0, %1, %d0|%d0, %1, 0}";
4332 return "%vpextrw\t{$0, %1, %0|%0, %1, 0}";
4335 if (get_attr_mode (insn) == MODE_SI)
4336 return "mov{l}\t{%k1, %k0|%k0, %k1}";
4338 return "mov{w}\t{%1, %0|%0, %1}";
4342 (cond [(eq_attr "alternative" "4,5,6,9,10")
4343 (const_string "sse2")
4344 (eq_attr "alternative" "7")
4345 (const_string "sse4_noavx")
4346 (eq_attr "alternative" "8")
4347 (const_string "avx")
4349 (const_string "*")))
4351 (if_then_else (eq_attr "alternative" "7")
4352 (const_string "gpr16")
4353 (const_string "*")))
4355 (cond [(eq_attr "alternative" "4")
4356 (const_string "sselog1")
4357 (eq_attr "alternative" "5,6,9")
4358 (const_string "ssemov")
4359 (eq_attr "alternative" "7,8,10")
4361 (match_test ("TARGET_AVX512FP16"))
4362 (const_string "ssemov")
4363 (const_string "sselog1"))
4364 (match_test "optimize_function_for_size_p (cfun)")
4365 (const_string "imov")
4366 (and (eq_attr "alternative" "0")
4367 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
4368 (not (match_test "TARGET_HIMODE_MATH"))))
4369 (const_string "imov")
4370 (and (eq_attr "alternative" "1,2")
4371 (match_operand:HI 1 "aligned_operand"))
4372 (const_string "imov")
4373 (and (match_test "TARGET_MOVX")
4374 (eq_attr "alternative" "0,2"))
4375 (const_string "imovx")
4377 (const_string "imov")))
4378 (set (attr "prefix")
4379 (cond [(eq_attr "alternative" "4,5,6,7,8,9,10")
4380 (const_string "maybe_vex")
4382 (const_string "orig")))
4384 (cond [(eq_attr "alternative" "4")
4385 (const_string "V4SF")
4386 (eq_attr "alternative" "6,9")
4388 (match_test "TARGET_AVX512FP16")
4390 (const_string "SI"))
4391 (eq_attr "alternative" "7,8,10")
4393 (match_test "TARGET_AVX512FP16")
4395 (const_string "TI"))
4396 (eq_attr "alternative" "5")
4397 (cond [(match_test "TARGET_AVX512VL")
4398 (const_string "V4SF")
4399 (match_test "TARGET_AVX512FP16")
4401 (match_test "TARGET_AVX512F")
4403 (match_test "TARGET_AVX")
4404 (const_string "V4SF")
4405 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
4406 (match_test "TARGET_SSE_SPLIT_REGS"))
4407 (const_string "V4SF")
4409 (const_string "SF"))
4410 (eq_attr "type" "imovx")
4412 (and (eq_attr "alternative" "1,2")
4413 (match_operand:HI 1 "aligned_operand"))
4415 (and (eq_attr "alternative" "0")
4416 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
4417 (not (match_test "TARGET_HIMODE_MATH"))))
4420 (const_string "HI")))
4421 (set (attr "enabled")
4422 (cond [(and (match_test "<MODE>mode == BFmode")
4423 (eq_attr "alternative" "1"))
4424 (symbol_ref "false")
4426 (const_string "*")))])
4429 [(set (match_operand 0 "any_fp_register_operand")
4430 (match_operand 1 "memory_operand"))]
4432 && (GET_MODE (operands[0]) == TFmode
4433 || GET_MODE (operands[0]) == XFmode
4434 || GET_MODE (operands[0]) == DFmode
4435 || GET_MODE (operands[0]) == SFmode)
4436 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
4437 [(set (match_dup 0) (match_dup 2))]
4438 "operands[2] = find_constant_src (curr_insn);")
4441 [(set (match_operand 0 "any_fp_register_operand")
4442 (float_extend (match_operand 1 "memory_operand")))]
4444 && (GET_MODE (operands[0]) == TFmode
4445 || GET_MODE (operands[0]) == XFmode
4446 || GET_MODE (operands[0]) == DFmode)
4447 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
4448 [(set (match_dup 0) (match_dup 2))]
4449 "operands[2] = find_constant_src (curr_insn);")
4451 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
4453 [(set (match_operand:X87MODEF 0 "fp_register_operand")
4454 (match_operand:X87MODEF 1 "immediate_operand"))]
4456 && (standard_80387_constant_p (operands[1]) == 8
4457 || standard_80387_constant_p (operands[1]) == 9)"
4458 [(set (match_dup 0)(match_dup 1))
4460 (neg:X87MODEF (match_dup 0)))]
4462 if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
4463 operands[1] = CONST0_RTX (<MODE>mode);
4465 operands[1] = CONST1_RTX (<MODE>mode);
4468 (define_insn "*swapxf"
4469 [(set (match_operand:XF 0 "register_operand" "+f")
4470 (match_operand:XF 1 "register_operand" "+f"))
4475 if (STACK_TOP_P (operands[0]))
4480 [(set_attr "type" "fxch")
4481 (set_attr "mode" "XF")])
4484 ;; Zero extension instructions
4486 (define_insn_and_split "zero_extendditi2"
4487 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4488 (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "rm,r")))]
4491 "&& reload_completed"
4492 [(set (match_dup 3) (match_dup 1))
4493 (set (match_dup 4) (const_int 0))]
4494 "split_double_mode (TImode, &operands[0], 1, &operands[3], &operands[4]);")
4496 (define_expand "zero_extendsidi2"
4497 [(set (match_operand:DI 0 "nonimmediate_operand")
4498 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
4500 (define_insn "*zero_extendsidi2"
4501 [(set (match_operand:DI 0 "nonimmediate_operand"
4502 "=r,?r,?o,r ,o,?*y,?!*y,$r,$v,$x,*x,*v,*r,*k")
4504 (match_operand:SI 1 "x86_64_zext_operand"
4505 "0 ,rm,r ,rmWz,0,r ,m ,v ,r ,m ,*x,*v,*k,*km")))]
4508 switch (get_attr_type (insn))
4511 if (ix86_use_lea_for_mov (insn, operands))
4512 return "lea{l}\t{%E1, %k0|%k0, %E1}";
4514 return "mov{l}\t{%1, %k0|%k0, %1}";
4520 return "movd\t{%1, %0|%0, %1}";
4523 if (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1]))
4525 if (EXT_REX_SSE_REG_P (operands[0])
4526 || EXT_REX_SSE_REG_P (operands[1]))
4527 return "vpmovzxdq\t{%t1, %g0|%g0, %t1}";
4529 return "%vpmovzxdq\t{%1, %0|%0, %1}";
4532 if (GENERAL_REG_P (operands[0]))
4533 return "%vmovd\t{%1, %k0|%k0, %1}";
4535 return "%vmovd\t{%1, %0|%0, %1}";
4538 return "kmovd\t{%1, %k0|%k0, %1}";
4545 (cond [(eq_attr "alternative" "0,1,2")
4546 (const_string "nox64")
4547 (eq_attr "alternative" "3")
4548 (const_string "x64")
4549 (eq_attr "alternative" "7,8,9")
4550 (const_string "sse2")
4551 (eq_attr "alternative" "10")
4552 (const_string "sse4")
4553 (eq_attr "alternative" "11")
4554 (const_string "avx512f")
4555 (eq_attr "alternative" "12")
4556 (const_string "x64_avx512bw")
4557 (eq_attr "alternative" "13")
4558 (const_string "avx512bw_512")
4560 (const_string "*")))
4561 (set (attr "mmx_isa")
4562 (if_then_else (eq_attr "alternative" "5,6")
4563 (const_string "native")
4564 (const_string "*")))
4566 (cond [(eq_attr "alternative" "0,1,2,4")
4567 (const_string "multi")
4568 (eq_attr "alternative" "5,6")
4569 (const_string "mmxmov")
4570 (eq_attr "alternative" "7")
4571 (if_then_else (match_test "TARGET_64BIT")
4572 (const_string "ssemov")
4573 (const_string "multi"))
4574 (eq_attr "alternative" "8,9,10,11")
4575 (const_string "ssemov")
4576 (eq_attr "alternative" "12,13")
4577 (const_string "mskmov")
4579 (const_string "imovx")))
4580 (set (attr "prefix_extra")
4581 (if_then_else (eq_attr "alternative" "10,11")
4583 (const_string "*")))
4584 (set (attr "prefix")
4585 (if_then_else (eq_attr "type" "ssemov")
4586 (const_string "maybe_vex")
4587 (const_string "orig")))
4588 (set (attr "prefix_0f")
4589 (if_then_else (eq_attr "type" "imovx")
4591 (const_string "*")))
4593 (cond [(eq_attr "alternative" "5,6")
4595 (and (eq_attr "alternative" "7")
4596 (match_test "TARGET_64BIT"))
4598 (eq_attr "alternative" "8,10,11")
4601 (const_string "SI")))
4602 (set (attr "preferred_for_speed")
4603 (cond [(eq_attr "alternative" "7")
4604 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4605 (eq_attr "alternative" "5,8")
4606 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4608 (symbol_ref "true")))])
4611 [(set (match_operand:DI 0 "memory_operand")
4612 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
4614 [(set (match_dup 4) (const_int 0))]
4615 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4618 [(set (match_operand:DI 0 "general_reg_operand")
4619 (zero_extend:DI (match_operand:SI 1 "general_reg_operand")))]
4620 "!TARGET_64BIT && reload_completed
4621 && REGNO (operands[0]) == REGNO (operands[1])"
4622 [(set (match_dup 4) (const_int 0))]
4623 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4626 [(set (match_operand:DI 0 "nonimmediate_gr_operand")
4627 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
4628 "!TARGET_64BIT && reload_completed
4629 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
4630 [(set (match_dup 3) (match_dup 1))
4631 (set (match_dup 4) (const_int 0))]
4632 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4634 (define_mode_attr kmov_isa
4635 [(QI "avx512dq") (HI "avx512f") (SI "avx512bw") (DI "avx512bw_512")])
4637 (define_insn "zero_extend<mode>di2"
4638 [(set (match_operand:DI 0 "register_operand" "=r,*r,*k")
4640 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k,*km")))]
4643 movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}
4644 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}
4645 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}"
4646 [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
4647 (set_attr "type" "imovx,mskmov,mskmov")
4648 (set_attr "mode" "SI,<MODE>,<MODE>")])
4650 (define_expand "zero_extend<mode>si2"
4651 [(set (match_operand:SI 0 "register_operand")
4652 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
4655 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4657 operands[1] = force_reg (<MODE>mode, operands[1]);
4658 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
4663 (define_insn_and_split "zero_extend<mode>si2_and"
4664 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
4666 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
4667 (clobber (reg:CC FLAGS_REG))]
4668 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4670 "&& reload_completed"
4671 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
4672 (clobber (reg:CC FLAGS_REG))])]
4674 if (!REG_P (operands[1])
4675 || REGNO (operands[0]) != REGNO (operands[1]))
4677 ix86_expand_clear (operands[0]);
4679 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4680 emit_insn (gen_rtx_SET
4681 (gen_rtx_STRICT_LOW_PART
4682 (VOIDmode, gen_lowpart (<MODE>mode, operands[0])),
4687 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
4689 [(set_attr "type" "alu1")
4690 (set_attr "mode" "SI")])
4692 (define_insn "*zero_extend<mode>si2"
4693 [(set (match_operand:SI 0 "register_operand" "=r,*r,*k")
4695 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k,*km")))]
4696 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4698 movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}
4699 kmov<mskmodesuffix>\t{%1, %0|%0, %1}
4700 kmov<mskmodesuffix>\t{%1, %0|%0, %1}"
4701 [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
4702 (set_attr "type" "imovx,mskmov,mskmov")
4703 (set_attr "mode" "SI,<MODE>,<MODE>")])
4705 (define_expand "zero_extendqihi2"
4706 [(set (match_operand:HI 0 "register_operand")
4707 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
4710 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4712 operands[1] = force_reg (QImode, operands[1]);
4713 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
4718 (define_insn_and_split "zero_extendqihi2_and"
4719 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
4720 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4721 (clobber (reg:CC FLAGS_REG))]
4722 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4724 "&& reload_completed"
4725 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4726 (clobber (reg:CC FLAGS_REG))])]
4728 if (!REG_P (operands[1])
4729 || REGNO (operands[0]) != REGNO (operands[1]))
4731 ix86_expand_clear (operands[0]);
4733 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4734 emit_insn (gen_rtx_SET
4735 (gen_rtx_STRICT_LOW_PART
4736 (VOIDmode, gen_lowpart (QImode, operands[0])),
4741 operands[0] = gen_lowpart (SImode, operands[0]);
4743 [(set_attr "type" "alu1")
4744 (set_attr "mode" "SI")])
4746 ; zero extend to SImode to avoid partial register stalls
4747 (define_insn "*zero_extendqihi2"
4748 [(set (match_operand:HI 0 "register_operand" "=r,*r,*k")
4749 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,*k,*km")))]
4750 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4752 movz{bl|x}\t{%1, %k0|%k0, %1}
4753 kmovb\t{%1, %k0|%k0, %1}
4754 kmovb\t{%1, %0|%0, %1}"
4755 [(set_attr "isa" "*,avx512dq,avx512dq")
4756 (set_attr "type" "imovx,mskmov,mskmov")
4757 (set_attr "mode" "SI,QI,QI")])
4759 ;; Transform xorl; mov[bw] (set strict_low_part) into movz[bw]l.
4761 [(parallel [(set (match_operand:SWI48 0 "general_reg_operand")
4763 (clobber (reg:CC FLAGS_REG))])
4764 (set (strict_low_part (match_operand:SWI12 1 "general_reg_operand"))
4765 (match_operand:SWI12 2 "nonimmediate_operand"))]
4766 "REGNO (operands[0]) == REGNO (operands[1])
4767 && (<SWI48:MODE>mode != SImode
4768 || !TARGET_ZERO_EXTEND_WITH_AND
4769 || !optimize_function_for_speed_p (cfun))"
4770 [(set (match_dup 0) (zero_extend:SWI48 (match_dup 2)))])
4772 ;; Likewise, but preserving FLAGS_REG.
4774 [(set (match_operand:SWI48 0 "general_reg_operand") (const_int 0))
4775 (set (strict_low_part (match_operand:SWI12 1 "general_reg_operand"))
4776 (match_operand:SWI12 2 "nonimmediate_operand"))]
4777 "REGNO (operands[0]) == REGNO (operands[1])
4778 && (<SWI48:MODE>mode != SImode
4779 || !TARGET_ZERO_EXTEND_WITH_AND
4780 || !optimize_function_for_speed_p (cfun))"
4781 [(set (match_dup 0) (zero_extend:SWI48 (match_dup 2)))])
4783 ;; Sign extension instructions
4785 (define_expand "extendsidi2"
4786 [(set (match_operand:DI 0 "register_operand")
4787 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
4792 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
4797 (define_insn "*extendsidi2_rex64"
4798 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4799 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4803 movs{lq|x}\t{%1, %0|%0, %1}"
4804 [(set_attr "type" "imovx")
4805 (set_attr "mode" "DI")
4806 (set_attr "prefix_0f" "0")
4807 (set_attr "modrm" "0,1")])
4809 (define_insn "extendsidi2_1"
4810 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4811 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4812 (clobber (reg:CC FLAGS_REG))
4813 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4817 (define_insn "extendditi2"
4818 [(set (match_operand:TI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4819 (sign_extend:TI (match_operand:DI 1 "register_operand" "0,0,r,r")))
4820 (clobber (reg:CC FLAGS_REG))
4821 (clobber (match_scratch:DI 2 "=X,X,X,&r"))]
4825 ;; Split the memory case. If the source register doesn't die, it will stay
4826 ;; this way, if it does die, following peephole2s take care of it.
4828 [(set (match_operand:<DWI> 0 "memory_operand")
4829 (sign_extend:<DWI> (match_operand:DWIH 1 "register_operand")))
4830 (clobber (reg:CC FLAGS_REG))
4831 (clobber (match_operand:DWIH 2 "register_operand"))]
4835 rtx bits = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
4837 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
4839 emit_move_insn (operands[3], operands[1]);
4841 /* Generate a cltd if possible and doing so it profitable. */
4842 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4843 && REGNO (operands[1]) == AX_REG
4844 && REGNO (operands[2]) == DX_REG)
4846 emit_insn (gen_ashr<mode>3_cvt (operands[2], operands[1], bits));
4850 emit_move_insn (operands[2], operands[1]);
4851 emit_insn (gen_ashr<mode>3_cvt (operands[2], operands[2], bits));
4853 emit_move_insn (operands[4], operands[2]);
4857 ;; Peepholes for the case where the source register does die, after
4858 ;; being split with the above splitter.
4860 [(set (match_operand:DWIH 0 "memory_operand")
4861 (match_operand:DWIH 1 "general_reg_operand"))
4862 (set (match_operand:DWIH 2 "general_reg_operand") (match_dup 1))
4863 (parallel [(set (match_dup 2)
4864 (ashiftrt:DWIH (match_dup 2)
4865 (match_operand 4 "const_int_operand")))
4866 (clobber (reg:CC FLAGS_REG))])
4867 (set (match_operand:DWIH 3 "memory_operand") (match_dup 2))]
4868 "REGNO (operands[1]) != REGNO (operands[2])
4869 && INTVAL (operands[4]) == (<MODE_SIZE> * BITS_PER_UNIT - 1)
4870 && peep2_reg_dead_p (2, operands[1])
4871 && peep2_reg_dead_p (4, operands[2])
4872 && !reg_mentioned_p (operands[2], operands[3])"
4873 [(set (match_dup 0) (match_dup 1))
4874 (parallel [(set (match_dup 1) (ashiftrt:DWIH (match_dup 1) (match_dup 4)))
4875 (clobber (reg:CC FLAGS_REG))])
4876 (set (match_dup 3) (match_dup 1))])
4879 [(set (match_operand:DWIH 0 "memory_operand")
4880 (match_operand:DWIH 1 "general_reg_operand"))
4881 (parallel [(set (match_operand:DWIH 2 "general_reg_operand")
4882 (ashiftrt:DWIH (match_dup 1)
4883 (match_operand 4 "const_int_operand")))
4884 (clobber (reg:CC FLAGS_REG))])
4885 (set (match_operand:DWIH 3 "memory_operand") (match_dup 2))]
4886 "/* cltd is shorter than sarl $31, %eax */
4887 !optimize_function_for_size_p (cfun)
4888 && REGNO (operands[1]) == AX_REG
4889 && REGNO (operands[2]) == DX_REG
4890 && INTVAL (operands[4]) == (<MODE_SIZE> * BITS_PER_UNIT - 1)
4891 && peep2_reg_dead_p (2, operands[1])
4892 && peep2_reg_dead_p (3, operands[2])
4893 && !reg_mentioned_p (operands[2], operands[3])"
4894 [(set (match_dup 0) (match_dup 1))
4895 (parallel [(set (match_dup 1) (ashiftrt:DWIH (match_dup 1) (match_dup 4)))
4896 (clobber (reg:CC FLAGS_REG))])
4897 (set (match_dup 3) (match_dup 1))])
4899 ;; Extend to register case. Optimize case where source and destination
4900 ;; registers match and cases where we can use cltd.
4902 [(set (match_operand:<DWI> 0 "register_operand")
4903 (sign_extend:<DWI> (match_operand:DWIH 1 "register_operand")))
4904 (clobber (reg:CC FLAGS_REG))
4905 (clobber (match_scratch:DWIH 2))]
4909 rtx bits = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
4911 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
4913 if (REGNO (operands[3]) != REGNO (operands[1]))
4914 emit_move_insn (operands[3], operands[1]);
4916 rtx src = operands[1];
4917 if (REGNO (operands[3]) == AX_REG)
4920 /* Generate a cltd if possible and doing so it profitable. */
4921 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4922 && REGNO (src) == AX_REG
4923 && REGNO (operands[4]) == DX_REG)
4925 emit_insn (gen_ashr<mode>3_cvt (operands[4], src, bits));
4929 if (REGNO (operands[4]) != REGNO (operands[1]))
4930 emit_move_insn (operands[4], operands[1]);
4932 emit_insn (gen_ashr<mode>3_cvt (operands[4], operands[4], bits));
4936 (define_insn "extend<mode>di2"
4937 [(set (match_operand:DI 0 "register_operand" "=r")
4939 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4941 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
4942 [(set_attr "type" "imovx")
4943 (set_attr "mode" "DI")])
4945 (define_insn "extendhisi2"
4946 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4947 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4950 switch (get_attr_prefix_0f (insn))
4953 return "{cwtl|cwde}";
4955 return "movs{wl|x}\t{%1, %0|%0, %1}";
4958 [(set_attr "type" "imovx")
4959 (set_attr "mode" "SI")
4960 (set (attr "prefix_0f")
4961 ;; movsx is short decodable while cwtl is vector decoded.
4962 (if_then_else (and (eq_attr "cpu" "!k6")
4963 (eq_attr "alternative" "0"))
4965 (const_string "1")))
4966 (set (attr "znver1_decode")
4967 (if_then_else (eq_attr "prefix_0f" "0")
4968 (const_string "double")
4969 (const_string "direct")))
4971 (if_then_else (eq_attr "prefix_0f" "0")
4973 (const_string "1")))])
4975 (define_insn "*extendhisi2_zext"
4976 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4979 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4982 switch (get_attr_prefix_0f (insn))
4985 return "{cwtl|cwde}";
4987 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4990 [(set_attr "type" "imovx")
4991 (set_attr "mode" "SI")
4992 (set (attr "prefix_0f")
4993 ;; movsx is short decodable while cwtl is vector decoded.
4994 (if_then_else (and (eq_attr "cpu" "!k6")
4995 (eq_attr "alternative" "0"))
4997 (const_string "1")))
4999 (if_then_else (eq_attr "prefix_0f" "0")
5001 (const_string "1")))])
5003 (define_insn "extendqisi2"
5004 [(set (match_operand:SI 0 "register_operand" "=r")
5005 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
5007 "movs{bl|x}\t{%1, %0|%0, %1}"
5008 [(set_attr "type" "imovx")
5009 (set_attr "mode" "SI")])
5011 (define_insn "*extendqisi2_zext"
5012 [(set (match_operand:DI 0 "register_operand" "=r")
5014 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
5016 "movs{bl|x}\t{%1, %k0|%k0, %1}"
5017 [(set_attr "type" "imovx")
5018 (set_attr "mode" "SI")])
5020 (define_insn "extendqihi2"
5021 [(set (match_operand:HI 0 "register_operand" "=*a,r")
5022 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
5025 switch (get_attr_prefix_0f (insn))
5028 return "{cbtw|cbw}";
5030 return "movs{bw|x}\t{%1, %0|%0, %1}";
5033 [(set_attr "type" "imovx")
5034 (set_attr "mode" "HI")
5035 (set (attr "prefix_0f")
5036 ;; movsx is short decodable while cwtl is vector decoded.
5037 (if_then_else (and (eq_attr "cpu" "!k6")
5038 (eq_attr "alternative" "0"))
5040 (const_string "1")))
5042 (if_then_else (eq_attr "prefix_0f" "0")
5044 (const_string "1")))])
5046 (define_insn "*extendqi<SWI24:mode>_ext_1"
5047 [(set (match_operand:SWI24 0 "register_operand" "=R")
5050 (match_operator:SWI248 2 "extract_operator"
5051 [(match_operand 1 "int248_register_operand" "Q")
5053 (const_int 8)]) 0)))]
5055 "movs{b<SWI24:imodesuffix>|x}\t{%h1, %0|%0, %h1}"
5056 [(set_attr "type" "imovx")
5057 (set_attr "mode" "<SWI24:MODE>")])
5059 ;; Conversions between float and double.
5061 ;; These are all no-ops in the model used for the 80387.
5062 ;; So just emit moves.
5064 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
5066 [(set (match_operand:DF 0 "push_operand")
5067 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
5069 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
5070 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
5073 [(set (match_operand:XF 0 "push_operand")
5074 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
5076 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
5077 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
5078 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
5080 (define_expand "extendsfdf2"
5081 [(set (match_operand:DF 0 "nonimm_ssenomem_operand")
5082 (float_extend:DF (match_operand:SF 1 "general_operand")))]
5083 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5085 /* ??? Needed for compress_float_constant since all fp constants
5086 are TARGET_LEGITIMATE_CONSTANT_P. */
5087 if (CONST_DOUBLE_P (operands[1]))
5089 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
5090 && standard_80387_constant_p (operands[1]) > 0)
5092 operands[1] = simplify_const_unary_operation
5093 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
5094 emit_move_insn_1 (operands[0], operands[1]);
5097 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
5101 (define_insn "*extendsfdf2"
5102 [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v,v")
5104 (match_operand:SF 1 "nonimmediate_operand" "fm,f,v,m")))]
5105 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5107 switch (which_alternative)
5111 return output_387_reg_move (insn, operands);
5114 return "%vcvtss2sd\t{%d1, %0|%0, %d1}";
5116 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
5122 [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
5123 (set_attr "avx_partial_xmm_update" "false,false,false,true")
5124 (set_attr "prefix" "orig,orig,maybe_vex,maybe_vex")
5125 (set_attr "mode" "SF,XF,DF,DF")
5126 (set (attr "enabled")
5128 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
5130 (eq_attr "alternative" "0,1")
5131 (symbol_ref "TARGET_MIX_SSE_I387")
5132 (symbol_ref "true"))
5134 (eq_attr "alternative" "0,1")
5136 (symbol_ref "false"))))])
5138 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
5140 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
5142 We do the conversion post reload to avoid producing of 128bit spills
5143 that might lead to ICE on 32bit target. The sequence unlikely combine
5146 [(set (match_operand:DF 0 "sse_reg_operand")
5148 (match_operand:SF 1 "nonimmediate_operand")))]
5149 "TARGET_USE_VECTOR_FP_CONVERTS
5150 && optimize_insn_for_speed_p ()
5152 && (!EXT_REX_SSE_REG_P (operands[0])
5153 || TARGET_AVX512VL || TARGET_EVEX512)"
5158 (parallel [(const_int 0) (const_int 1)]))))]
5160 operands[2] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5161 operands[3] = lowpart_subreg (V4SFmode, operands[0], DFmode);
5162 /* Use movss for loading from memory, unpcklps reg, reg for registers.
5163 Try to avoid move when unpacking can be done in source. */
5164 if (REG_P (operands[1]))
5166 /* If it is unsafe to overwrite upper half of source, we need
5167 to move to destination and unpack there. */
5168 if (REGNO (operands[0]) != REGNO (operands[1])
5169 || (EXT_REX_SSE_REG_P (operands[1])
5170 && !TARGET_AVX512VL))
5172 rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode);
5173 emit_move_insn (tmp, operands[1]);
5176 operands[3] = lowpart_subreg (V4SFmode, operands[1], SFmode);
5177 /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
5178 =v, v, then vbroadcastss will be only needed for AVX512F without
5180 if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3])))
5181 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
5185 rtx tmp = lowpart_subreg (V16SFmode, operands[3], V4SFmode);
5186 emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
5190 emit_insn (gen_vec_setv4sf_0 (operands[3],
5191 CONST0_RTX (V4SFmode), operands[1]));
5194 ;; It's more profitable to split and then extend in the same register.
5196 [(set (match_operand:DF 0 "sse_reg_operand")
5198 (match_operand:SF 1 "memory_operand")))]
5199 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
5200 && optimize_insn_for_speed_p ()"
5201 [(set (match_dup 2) (match_dup 1))
5202 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
5203 "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);")
5205 ;; Break partial SSE register dependency stall. This splitter should split
5206 ;; late in the pass sequence (after register rename pass), so allocated
5207 ;; registers won't change anymore
5210 [(set (match_operand:DF 0 "sse_reg_operand")
5212 (match_operand:SF 1 "nonimmediate_operand")))]
5214 && TARGET_SSE_PARTIAL_REG_FP_CONVERTS_DEPENDENCY
5215 && epilogue_completed
5216 && optimize_function_for_speed_p (cfun)
5217 && (!REG_P (operands[1])
5218 || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
5219 && (!EXT_REX_SSE_REG_P (operands[0])
5220 || TARGET_AVX512VL)"
5229 operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5230 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5233 (define_expand "extendhfsf2"
5234 [(set (match_operand:SF 0 "register_operand")
5236 (match_operand:HF 1 "nonimmediate_operand")))]
5237 "TARGET_AVX512FP16 || TARGET_F16C || TARGET_AVX512VL"
5239 if (!TARGET_AVX512FP16)
5241 rtx res = gen_reg_rtx (V4SFmode);
5242 rtx tmp = gen_reg_rtx (V8HFmode);
5243 rtx zero = force_reg (V8HFmode, CONST0_RTX (V8HFmode));
5245 emit_insn (gen_vec_setv8hf_0 (tmp, zero, operands[1]));
5246 emit_insn (gen_vcvtph2ps (res, gen_lowpart (V8HImode, tmp)));
5247 emit_move_insn (operands[0], gen_lowpart (SFmode, res));
5252 (define_expand "extendhfdf2"
5253 [(set (match_operand:DF 0 "register_operand")
5255 (match_operand:HF 1 "nonimmediate_operand")))]
5256 "TARGET_AVX512FP16")
5258 (define_insn "*extendhf<mode>2"
5259 [(set (match_operand:MODEF 0 "register_operand" "=v")
5261 (match_operand:HF 1 "nonimmediate_operand" "vm")))]
5263 "vcvtsh2<ssemodesuffix>\t{%1, %0, %0|%0, %0, %1}"
5264 [(set_attr "type" "ssecvt")
5265 (set_attr "prefix" "evex")
5266 (set_attr "mode" "<MODE>")])
5268 (define_expand "extendbfsf2"
5269 [(set (match_operand:SF 0 "register_operand")
5271 [(match_operand:BF 1 "register_operand")]
5273 "TARGET_SSE2 && !HONOR_NANS (BFmode)")
5275 ;; Don't use float_extend since psrlld doesn't raise
5276 ;; exceptions and turn a sNaN into a qNaN.
5277 (define_insn "extendbfsf2_1"
5278 [(set (match_operand:SF 0 "register_operand" "=x,Yv,v")
5280 [(match_operand:BF 1 "register_operand" " 0,Yv,v")]
5284 pslld\t{$16, %0|%0, 16}
5285 vpslld\t{$16, %1, %0|%0, %1, 16}
5286 vpslld\t{$16, %g1, %g0|%g0, %g1, 16}"
5287 [(set_attr "isa" "noavx,avx,*")
5288 (set_attr "type" "sseishft1")
5289 (set_attr "length_immediate" "1")
5290 (set_attr "prefix_data16" "1,*,*")
5291 (set_attr "prefix" "orig,maybe_evex,evex")
5292 (set_attr "mode" "TI,TI,XI")
5293 (set_attr "memory" "none")
5294 (set (attr "enabled")
5295 (if_then_else (eq_attr "alternative" "2")
5296 (symbol_ref "TARGET_AVX512F && TARGET_EVEX512
5297 && !TARGET_AVX512VL && !TARGET_PREFER_AVX256")
5298 (const_string "*")))])
5300 (define_expand "extend<mode>xf2"
5301 [(set (match_operand:XF 0 "nonimmediate_operand")
5302 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
5305 /* ??? Needed for compress_float_constant since all fp constants
5306 are TARGET_LEGITIMATE_CONSTANT_P. */
5307 if (CONST_DOUBLE_P (operands[1]))
5309 if (standard_80387_constant_p (operands[1]) > 0)
5311 operands[1] = simplify_const_unary_operation
5312 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
5313 emit_move_insn_1 (operands[0], operands[1]);
5316 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
5320 (define_insn "*extend<mode>xf2_i387"
5321 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
5323 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
5325 "* return output_387_reg_move (insn, operands);"
5326 [(set_attr "type" "fmov")
5327 (set_attr "mode" "<MODE>,XF")])
5329 ;; %%% This seems like bad news.
5330 ;; This cannot output into an f-reg because there is no way to be sure
5331 ;; of truncating in that case. Otherwise this is just like a simple move
5332 ;; insn. So we pretend we can output to a reg in order to get better
5333 ;; register preferencing, but we really use a stack slot.
5335 ;; Conversion from DFmode to SFmode.
5337 (define_insn "truncdfsf2"
5338 [(set (match_operand:SF 0 "nonimm_ssenomem_operand" "=m,f,v,v")
5340 (match_operand:DF 1 "register_ssemem_operand" "f,f,v,m")))]
5341 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5343 switch (which_alternative)
5347 return output_387_reg_move (insn, operands);
5350 return "%vcvtsd2ss\t{%d1, %0|%0, %d1}";
5352 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
5358 [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
5359 (set_attr "avx_partial_xmm_update" "false,false,false,true")
5360 (set_attr "mode" "SF")
5361 (set (attr "enabled")
5363 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
5364 (cond [(eq_attr "alternative" "0")
5365 (symbol_ref "TARGET_MIX_SSE_I387")
5366 (eq_attr "alternative" "1")
5367 (symbol_ref "TARGET_MIX_SSE_I387
5368 && flag_unsafe_math_optimizations")
5370 (symbol_ref "true"))
5371 (cond [(eq_attr "alternative" "0")
5373 (eq_attr "alternative" "1")
5374 (symbol_ref "flag_unsafe_math_optimizations")
5376 (symbol_ref "false"))))])
5378 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
5380 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
5382 We do the conversion post reload to avoid producing of 128bit spills
5383 that might lead to ICE on 32bit target. The sequence unlikely combine
5386 [(set (match_operand:SF 0 "sse_reg_operand")
5388 (match_operand:DF 1 "nonimmediate_operand")))]
5389 "TARGET_USE_VECTOR_FP_CONVERTS
5390 && optimize_insn_for_speed_p ()
5392 && (!EXT_REX_SSE_REG_P (operands[0])
5393 || TARGET_AVX512VL)"
5396 (float_truncate:V2SF
5400 operands[2] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5401 operands[3] = CONST0_RTX (V2SFmode);
5402 operands[4] = lowpart_subreg (V2DFmode, operands[0], SFmode);
5403 /* Use movsd for loading from memory, unpcklpd for registers.
5404 Try to avoid move when unpacking can be done in source, or SSE3
5405 movddup is available. */
5406 if (REG_P (operands[1]))
5408 if ((!TARGET_SSE3 && REGNO (operands[0]) != REGNO (operands[1]))
5409 || (EXT_REX_SSE_REG_P (operands[1]) && !TARGET_AVX512VL))
5411 rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode);
5412 emit_move_insn (tmp, operands[1]);
5415 else if (!TARGET_SSE3)
5416 operands[4] = lowpart_subreg (V2DFmode, operands[1], DFmode);
5417 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
5420 emit_insn (gen_vec_concatv2df (operands[4], operands[1],
5421 CONST0_RTX (DFmode)));
5424 ;; It's more profitable to split and then truncate in the same register.
5426 [(set (match_operand:SF 0 "sse_reg_operand")
5428 (match_operand:DF 1 "memory_operand")))]
5429 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
5430 && optimize_insn_for_speed_p ()"
5431 [(set (match_dup 2) (match_dup 1))
5432 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
5433 "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
5435 ;; Break partial SSE register dependency stall. This splitter should split
5436 ;; late in the pass sequence (after register rename pass), so allocated
5437 ;; registers won't change anymore
5440 [(set (match_operand:SF 0 "sse_reg_operand")
5442 (match_operand:DF 1 "nonimmediate_operand")))]
5444 && TARGET_SSE_PARTIAL_REG_FP_CONVERTS_DEPENDENCY
5445 && epilogue_completed
5446 && optimize_function_for_speed_p (cfun)
5447 && (!REG_P (operands[1])
5448 || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
5449 && (!EXT_REX_SSE_REG_P (operands[0])
5450 || TARGET_AVX512VL)"
5459 operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5460 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5463 ;; Conversion from XFmode to {SF,DF}mode
5465 (define_insn "truncxf<mode>2"
5466 [(set (match_operand:MODEF 0 "nonimmediate_operand" "=m,f")
5467 (float_truncate:MODEF
5468 (match_operand:XF 1 "register_operand" "f,f")))]
5470 "* return output_387_reg_move (insn, operands);"
5471 [(set_attr "type" "fmov")
5472 (set_attr "mode" "<MODE>")
5473 (set (attr "enabled")
5474 (cond [(eq_attr "alternative" "1")
5475 (symbol_ref "flag_unsafe_math_optimizations")
5477 (symbol_ref "true")))])
5479 ;; Conversion from {SF,DF}mode to HFmode.
5481 (define_expand "truncsfhf2"
5482 [(set (match_operand:HF 0 "register_operand")
5484 (match_operand:SF 1 "nonimmediate_operand")))]
5485 "TARGET_AVX512FP16 || TARGET_F16C || TARGET_AVX512VL"
5487 if (!TARGET_AVX512FP16)
5489 rtx res = gen_reg_rtx (V8HFmode);
5490 rtx tmp = gen_reg_rtx (V4SFmode);
5491 rtx zero = force_reg (V4SFmode, CONST0_RTX (V4SFmode));
5493 emit_insn (gen_vec_setv4sf_0 (tmp, zero, operands[1]));
5494 emit_insn (gen_vcvtps2ph (gen_lowpart (V8HImode, res), tmp, GEN_INT (4)));
5495 emit_move_insn (operands[0], gen_lowpart (HFmode, res));
5500 (define_expand "truncdfhf2"
5501 [(set (match_operand:HF 0 "register_operand")
5503 (match_operand:DF 1 "nonimmediate_operand")))]
5504 "TARGET_AVX512FP16")
5506 (define_insn "*trunc<mode>hf2"
5507 [(set (match_operand:HF 0 "register_operand" "=v")
5509 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5511 "vcvt<ssemodesuffix>2sh\t{%1, %d0|%d0, %1}"
5512 [(set_attr "type" "ssecvt")
5513 (set_attr "prefix" "evex")
5514 (set_attr "mode" "HF")])
5516 (define_insn "truncsfbf2"
5517 [(set (match_operand:BF 0 "register_operand" "=x, v")
5519 (match_operand:SF 1 "register_operand" "x,v")))]
5520 "((TARGET_AVX512BF16 && TARGET_AVX512VL) || TARGET_AVXNECONVERT)
5521 && !HONOR_NANS (BFmode) && flag_unsafe_math_optimizations"
5523 %{vex%} vcvtneps2bf16\t{%1, %0|%0, %1}
5524 vcvtneps2bf16\t{%1, %0|%0, %1}"
5525 [(set_attr "isa" "avxneconvert,avx512bf16vl")
5526 (set_attr "prefix" "vex,evex")])
5528 ;; Signed conversion to DImode.
5530 (define_expand "fix_truncxfdi2"
5531 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
5532 (fix:DI (match_operand:XF 1 "register_operand")))
5533 (clobber (reg:CC FLAGS_REG))])]
5538 emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
5543 (define_expand "fix_trunc<mode>di2"
5544 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
5545 (fix:DI (match_operand:MODEF 1 "register_operand")))
5546 (clobber (reg:CC FLAGS_REG))])]
5547 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
5550 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
5552 emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
5555 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
5557 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
5558 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
5559 if (out != operands[0])
5560 emit_move_insn (operands[0], out);
5565 (define_insn "fix<fixunssuffix>_trunchf<mode>2"
5566 [(set (match_operand:SWI48 0 "register_operand" "=r")
5568 (match_operand:HF 1 "nonimmediate_operand" "vm")))]
5570 "vcvttsh2<fixsuffix>si\t{%1, %0|%0, %1}"
5571 [(set_attr "type" "sseicvt")
5572 (set_attr "prefix" "evex")
5573 (set_attr "mode" "<MODE>")])
5575 ;; Signed conversion to SImode.
5577 (define_expand "fix_truncxfsi2"
5578 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
5579 (fix:SI (match_operand:XF 1 "register_operand")))
5580 (clobber (reg:CC FLAGS_REG))])]
5585 emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
5590 (define_expand "fix_trunc<mode>si2"
5591 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
5592 (fix:SI (match_operand:MODEF 1 "register_operand")))
5593 (clobber (reg:CC FLAGS_REG))])]
5594 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
5597 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
5599 emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
5602 if (SSE_FLOAT_MODE_P (<MODE>mode))
5604 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
5605 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
5606 if (out != operands[0])
5607 emit_move_insn (operands[0], out);
5612 ;; Signed conversion to HImode.
5614 (define_expand "fix_trunc<mode>hi2"
5615 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
5616 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
5617 (clobber (reg:CC FLAGS_REG))])]
5619 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
5623 emit_insn (gen_fix_trunchi_i387_fisttp (operands[0], operands[1]));
5628 ;; Unsigned conversion to DImode
5630 (define_insn "fixuns_trunc<mode>di2"
5631 [(set (match_operand:DI 0 "register_operand" "=r")
5633 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5634 "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
5635 "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
5636 [(set_attr "type" "sseicvt")
5637 (set_attr "prefix" "evex")
5638 (set_attr "mode" "DI")])
5640 ;; Unsigned conversion to SImode.
5642 (define_expand "fixuns_trunc<mode>si2"
5644 [(set (match_operand:SI 0 "register_operand")
5646 (match_operand:MODEF 1 "nonimmediate_operand")))
5648 (clobber (scratch:<ssevecmode>))
5649 (clobber (scratch:<ssevecmode>))])]
5650 "(!TARGET_64BIT || TARGET_AVX512F) && TARGET_SSE2 && TARGET_SSE_MATH"
5652 machine_mode mode = <MODE>mode;
5653 machine_mode vecmode = <ssevecmode>mode;
5654 REAL_VALUE_TYPE TWO31r;
5659 emit_insn (gen_fixuns_trunc<mode>si2_avx512f (operands[0], operands[1]));
5663 if (optimize_insn_for_size_p ())
5666 real_ldexp (&TWO31r, &dconst1, 31);
5667 two31 = const_double_from_real_value (TWO31r, mode);
5668 two31 = ix86_build_const_vector (vecmode, true, two31);
5669 operands[2] = force_reg (vecmode, two31);
5672 (define_insn "fixuns_trunc<mode>si2_avx512f"
5673 [(set (match_operand:SI 0 "register_operand" "=r")
5675 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5676 "TARGET_AVX512F && TARGET_SSE_MATH"
5677 "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
5678 [(set_attr "type" "sseicvt")
5679 (set_attr "prefix" "evex")
5680 (set_attr "mode" "SI")])
5682 (define_insn "*fixuns_trunchfsi2zext"
5683 [(set (match_operand:DI 0 "register_operand" "=r")
5686 (match_operand:HF 1 "nonimmediate_operand" "vm"))))]
5687 "TARGET_64BIT && TARGET_AVX512FP16"
5688 "vcvttsh2usi\t{%1, %k0|%k0, %1}"
5689 [(set_attr "type" "sseicvt")
5690 (set_attr "prefix" "evex")
5691 (set_attr "mode" "SI")])
5693 (define_insn "*fixuns_trunc<mode>si2_avx512f_zext"
5694 [(set (match_operand:DI 0 "register_operand" "=r")
5697 (match_operand:MODEF 1 "nonimmediate_operand" "vm"))))]
5698 "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
5699 "vcvtt<ssemodesuffix>2usi\t{%1, %k0|%k0, %1}"
5700 [(set_attr "type" "sseicvt")
5701 (set_attr "prefix" "evex")
5702 (set_attr "mode" "SI")])
5704 (define_insn_and_split "*fixuns_trunc<mode>_1"
5705 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
5707 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
5708 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
5709 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
5710 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
5711 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5712 && optimize_function_for_speed_p (cfun)"
5714 "&& reload_completed"
5717 ix86_split_convert_uns_si_sse (operands);
5721 ;; Unsigned conversion to HImode.
5722 ;; Without these patterns, we'll try the unsigned SI conversion which
5723 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
5725 (define_expand "fixuns_trunchfhi2"
5727 (fix:SI (match_operand:HF 1 "nonimmediate_operand")))
5728 (set (match_operand:HI 0 "nonimmediate_operand")
5729 (subreg:HI (match_dup 2) 0))]
5731 "operands[2] = gen_reg_rtx (SImode);")
5733 (define_expand "fixuns_trunc<mode>hi2"
5735 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
5736 (set (match_operand:HI 0 "nonimmediate_operand")
5737 (subreg:HI (match_dup 2) 0))]
5738 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
5739 "operands[2] = gen_reg_rtx (SImode);")
5741 ;; When SSE is available, it is always faster to use it!
5742 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
5743 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
5744 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
5745 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5746 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
5747 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
5748 [(set_attr "type" "sseicvt")
5749 (set_attr "prefix" "maybe_vex")
5750 (set (attr "prefix_rex")
5752 (match_test "<SWI48:MODE>mode == DImode")
5754 (const_string "*")))
5755 (set_attr "mode" "<MODEF:MODE>")
5756 (set_attr "athlon_decode" "double,vector")
5757 (set_attr "amdfam10_decode" "double,double")
5758 (set_attr "bdver1_decode" "double,double")])
5760 ;; Avoid vector decoded forms of the instruction.
5762 [(match_scratch:MODEF 2 "x")
5763 (set (match_operand:SWI48 0 "register_operand")
5764 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
5765 "TARGET_AVOID_VECTOR_DECODE
5766 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5767 && optimize_insn_for_speed_p ()"
5768 [(set (match_dup 2) (match_dup 1))
5769 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
5771 (define_insn "fix_trunc<mode>_i387_fisttp"
5772 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m")
5773 (fix:SWI248x (match_operand 1 "register_operand" "f")))
5774 (clobber (match_scratch:XF 2 "=&f"))]
5775 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5777 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5778 && (TARGET_64BIT || <MODE>mode != DImode))
5779 && TARGET_SSE_MATH)"
5780 "* return output_fix_trunc (insn, operands, true);"
5781 [(set_attr "type" "fisttp")
5782 (set_attr "mode" "<MODE>")])
5784 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5785 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5786 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5787 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5788 ;; function in i386.cc.
5789 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5790 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
5791 (fix:SWI248x (match_operand 1 "register_operand")))
5792 (clobber (reg:CC FLAGS_REG))]
5793 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5795 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5796 && (TARGET_64BIT || <MODE>mode != DImode))
5797 && ix86_pre_reload_split ()"
5802 ix86_optimize_mode_switching[I387_TRUNC] = 1;
5804 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5805 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5807 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5808 operands[2], operands[3]));
5811 [(set_attr "type" "fistp")
5812 (set_attr "i387_cw" "trunc")
5813 (set_attr "mode" "<MODE>")])
5815 (define_insn "fix_truncdi_i387"
5816 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
5817 (fix:DI (match_operand 1 "register_operand" "f")))
5818 (use (match_operand:HI 2 "memory_operand" "m"))
5819 (use (match_operand:HI 3 "memory_operand" "m"))
5820 (clobber (match_scratch:XF 4 "=&f"))]
5821 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5823 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5824 "* return output_fix_trunc (insn, operands, false);"
5825 [(set_attr "type" "fistp")
5826 (set_attr "i387_cw" "trunc")
5827 (set_attr "mode" "DI")])
5829 (define_insn "fix_trunc<mode>_i387"
5830 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
5831 (fix:SWI24 (match_operand 1 "register_operand" "f")))
5832 (use (match_operand:HI 2 "memory_operand" "m"))
5833 (use (match_operand:HI 3 "memory_operand" "m"))]
5834 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5836 && !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" "<MODE>")])
5842 (define_insn "x86_fnstcw_1"
5843 [(set (match_operand:HI 0 "memory_operand" "=m")
5844 (unspec:HI [(const_int 0)] UNSPEC_FSTCW))]
5847 [(set (attr "length")
5848 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5849 (set_attr "mode" "HI")
5850 (set_attr "unit" "i387")
5851 (set_attr "bdver1_decode" "vector")])
5853 ;; Conversion between fixed point and floating point.
5855 ;; Even though we only accept memory inputs, the backend _really_
5856 ;; wants to be able to do this between registers. Thankfully, LRA
5857 ;; will fix this up for us during register allocation.
5859 (define_insn "floathi<mode>2"
5860 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5861 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
5863 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5864 || TARGET_MIX_SSE_I387)"
5866 [(set_attr "type" "fmov")
5867 (set_attr "mode" "<MODE>")
5868 (set_attr "znver1_decode" "double")
5869 (set_attr "fp_int_src" "true")])
5871 (define_insn "float<SWI48x:mode>xf2"
5872 [(set (match_operand:XF 0 "register_operand" "=f")
5873 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5876 [(set_attr "type" "fmov")
5877 (set_attr "mode" "XF")
5878 (set_attr "znver1_decode" "double")
5879 (set_attr "fp_int_src" "true")])
5881 (define_expand "float<SWI48x:mode><MODEF:mode>2"
5882 [(set (match_operand:MODEF 0 "register_operand")
5883 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand")))]
5884 "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode))
5885 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5886 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT))")
5888 (define_insn "*float<SWI48:mode><MODEF:mode>2"
5889 [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
5891 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
5892 "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
5893 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
5896 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
5897 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5898 [(set_attr "type" "fmov,sseicvt,sseicvt")
5899 (set_attr "avx_partial_xmm_update" "false,true,true")
5900 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5901 (set_attr "mode" "<MODEF:MODE>")
5902 (set (attr "prefix_rex")
5904 (and (eq_attr "prefix" "maybe_vex")
5905 (match_test "<SWI48:MODE>mode == DImode"))
5907 (const_string "*")))
5908 (set_attr "unit" "i387,*,*")
5909 (set_attr "athlon_decode" "*,double,direct")
5910 (set_attr "amdfam10_decode" "*,vector,double")
5911 (set_attr "bdver1_decode" "*,double,direct")
5912 (set_attr "znver1_decode" "double,*,*")
5913 (set_attr "fp_int_src" "true")
5914 (set (attr "enabled")
5916 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
5918 (eq_attr "alternative" "0")
5919 (symbol_ref "TARGET_MIX_SSE_I387
5920 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
5922 (symbol_ref "true"))
5924 (eq_attr "alternative" "0")
5926 (symbol_ref "false"))))
5927 (set (attr "preferred_for_speed")
5928 (cond [(eq_attr "alternative" "1")
5929 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
5930 (symbol_ref "true")))])
5932 (define_insn "float<floatunssuffix><mode>hf2"
5933 [(set (match_operand:HF 0 "register_operand" "=v")
5935 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
5937 "vcvt<floatsuffix>si2sh<rex64suffix>\t{%1, %d0|%d0, %1}"
5938 [(set_attr "type" "sseicvt")
5939 (set_attr "prefix" "evex")
5940 (set_attr "mode" "HF")])
5942 (define_insn "*floatdi<MODEF:mode>2_i387"
5943 [(set (match_operand:MODEF 0 "register_operand" "=f")
5944 (float:MODEF (match_operand:DI 1 "nonimmediate_operand" "m")))]
5946 && TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, DImode)"
5948 [(set_attr "type" "fmov")
5949 (set_attr "mode" "<MODEF:MODE>")
5950 (set_attr "znver1_decode" "double")
5951 (set_attr "fp_int_src" "true")])
5953 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
5954 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
5955 ;; alternative in sse2_loadld.
5957 [(set (match_operand:MODEF 0 "sse_reg_operand")
5958 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5960 && TARGET_USE_VECTOR_CONVERTS
5961 && optimize_function_for_speed_p (cfun)
5963 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
5964 && (!EXT_REX_SSE_REG_P (operands[0])
5965 || TARGET_AVX512VL)"
5968 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode);
5969 operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode);
5971 emit_insn (gen_sse2_loadld (operands[4],
5972 CONST0_RTX (V4SImode), operands[1]));
5974 if (<ssevecmode>mode == V4SFmode)
5975 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5977 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5981 ;; Avoid store forwarding (partial memory) stall penalty
5982 ;; by passing DImode value through XMM registers. */
5985 [(set (match_operand:X87MODEF 0 "register_operand")
5987 (match_operand:DI 1 "register_operand")))]
5988 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
5989 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5990 && TARGET_SSE2 && optimize_function_for_speed_p (cfun)
5991 && can_create_pseudo_p ()"
5994 rtx s = assign_386_stack_local (DImode, SLOT_FLOATxFDI_387);
5995 emit_insn (gen_floatdi<mode>2_i387_with_xmm (operands[0], operands[1], s));
5999 (define_insn_and_split "floatdi<X87MODEF:mode>2_i387_with_xmm"
6000 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
6002 (match_operand:DI 1 "register_operand" "r,r")))
6003 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
6004 (clobber (match_scratch:V4SI 3 "=x,x"))
6005 (clobber (match_scratch:V4SI 4 "=X,x"))]
6006 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
6007 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6008 && TARGET_SSE2 && optimize_function_for_speed_p (cfun)"
6010 "&& reload_completed"
6011 [(set (match_dup 2) (match_dup 3))
6012 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
6014 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
6015 Assemble the 64-bit DImode value in an xmm register. */
6016 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
6017 gen_lowpart (SImode, operands[1])));
6019 emit_insn (gen_sse4_1_pinsrd (operands[3], operands[3],
6020 gen_highpart (SImode, operands[1]),
6024 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
6025 gen_highpart (SImode, operands[1])));
6026 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
6029 operands[3] = gen_lowpart (DImode, operands[3]);
6031 [(set_attr "isa" "sse4,*")
6032 (set_attr "type" "multi")
6033 (set_attr "mode" "<X87MODEF:MODE>")
6034 (set_attr "unit" "i387")
6035 (set_attr "fp_int_src" "true")])
6037 ;; Break partial SSE register dependency stall. This splitter should split
6038 ;; late in the pass sequence (after register rename pass), so allocated
6039 ;; registers won't change anymore
6042 [(set (match_operand:MODEF 0 "sse_reg_operand")
6043 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
6045 && TARGET_SSE_PARTIAL_REG_CONVERTS_DEPENDENCY
6046 && epilogue_completed
6047 && optimize_function_for_speed_p (cfun)
6048 && (!EXT_REX_SSE_REG_P (operands[0])
6049 || TARGET_AVX512VL)"
6051 (vec_merge:<MODEF:ssevecmode>
6052 (vec_duplicate:<MODEF:ssevecmode>
6058 const machine_mode vmode = <MODEF:ssevecmode>mode;
6060 operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode);
6061 emit_move_insn (operands[0], CONST0_RTX (vmode));
6064 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
6065 [(set (match_operand:MODEF 0 "register_operand")
6066 (unsigned_float:MODEF
6067 (match_operand:SWI12 1 "nonimmediate_operand")))]
6069 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
6071 operands[1] = convert_to_mode (SImode, operands[1], 1);
6072 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
6076 (define_insn "*floatuns<SWI48:mode><MODEF:mode>2_avx512"
6077 [(set (match_operand:MODEF 0 "register_operand" "=v")
6078 (unsigned_float:MODEF
6079 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
6080 "TARGET_AVX512F && TARGET_SSE_MATH"
6081 "vcvtusi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %0, %0|%0, %0, %1}"
6082 [(set_attr "type" "sseicvt")
6083 (set_attr "avx_partial_xmm_update" "true")
6084 (set_attr "prefix" "evex")
6085 (set_attr "mode" "<MODEF:MODE>")])
6087 ;; Avoid store forwarding (partial memory) stall penalty by extending
6088 ;; SImode value to DImode through XMM register instead of pushing two
6089 ;; SImode values to stack. Also note that fild loads from memory only.
6091 (define_insn_and_split "floatunssi<mode>2_i387_with_xmm"
6092 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
6093 (unsigned_float:X87MODEF
6094 (match_operand:SI 1 "nonimmediate_operand" "rm")))
6095 (clobber (match_operand:DI 2 "memory_operand" "=m"))
6096 (clobber (match_scratch:DI 3 "=x"))]
6098 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6099 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
6101 "&& reload_completed"
6102 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
6103 (set (match_dup 2) (match_dup 3))
6105 (float:X87MODEF (match_dup 2)))]
6107 [(set_attr "type" "multi")
6108 (set_attr "mode" "<MODE>")])
6110 (define_expand "floatunssi<mode>2"
6111 [(set (match_operand:X87MODEF 0 "register_operand")
6112 (unsigned_float:X87MODEF
6113 (match_operand:SI 1 "nonimmediate_operand")))]
6115 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6116 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
6117 || ((!TARGET_64BIT || TARGET_AVX512F)
6118 && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
6120 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
6122 emit_insn (gen_floatunssi<mode>2_i387_with_xmm
6123 (operands[0], operands[1],
6124 assign_386_stack_local (DImode, SLOT_TEMP)));
6127 if (!TARGET_AVX512F)
6129 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
6134 (define_expand "floatunsdisf2"
6135 [(set (match_operand:SF 0 "register_operand")
6137 (match_operand:DI 1 "nonimmediate_operand")))]
6138 "TARGET_64BIT && TARGET_SSE && TARGET_SSE_MATH"
6140 if (!TARGET_AVX512F)
6142 x86_emit_floatuns (operands);
6147 (define_expand "floatunsdidf2"
6148 [(set (match_operand:DF 0 "register_operand")
6150 (match_operand:DI 1 "nonimmediate_operand")))]
6151 "((TARGET_64BIT && TARGET_AVX512F)
6152 || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
6153 && TARGET_SSE2 && TARGET_SSE_MATH"
6157 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
6160 if (!TARGET_AVX512F)
6162 x86_emit_floatuns (operands);
6167 ;; Load effective address instructions
6169 (define_insn "*lea<mode>"
6170 [(set (match_operand:SWI48 0 "register_operand" "=r")
6171 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
6172 "ix86_hardreg_mov_ok (operands[0], operands[1])"
6174 if (SImode_address_operand (operands[1], VOIDmode))
6176 gcc_assert (TARGET_64BIT);
6177 return "lea{l}\t{%E1, %k0|%k0, %E1}";
6180 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
6182 [(set_attr "type" "lea")
6185 (match_operand 1 "SImode_address_operand")
6187 (const_string "<MODE>")))])
6190 [(set (match_operand:SWI48 0 "register_operand")
6191 (match_operand:SWI48 1 "address_no_seg_operand"))]
6192 "ix86_hardreg_mov_ok (operands[0], operands[1])
6193 && peep2_regno_dead_p (0, FLAGS_REG)
6194 && ix86_avoid_lea_for_addr (peep2_next_insn (0), operands)"
6197 machine_mode mode = <MODE>mode;
6199 /* Emit all operations in SImode for zero-extended addresses. */
6200 if (SImode_address_operand (operands[1], VOIDmode))
6203 ix86_split_lea_for_addr (peep2_next_insn (0), operands, mode);
6205 /* Zero-extend return register to DImode for zero-extended addresses. */
6206 if (mode != <MODE>mode)
6207 emit_insn (gen_zero_extendsidi2 (operands[0],
6208 gen_lowpart (mode, operands[0])));
6213 ;; ix86_split_lea_for_addr emits the shifts as MULT to avoid it from being
6214 ;; peephole2 optimized back into a lea. Split that into the shift during
6215 ;; the following split pass.
6217 [(set (match_operand:SWI48 0 "general_reg_operand")
6218 (mult:SWI48 (match_dup 0) (match_operand:SWI48 1 "const1248_operand")))
6219 (clobber (reg:CC FLAGS_REG))]
6221 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
6222 (clobber (reg:CC FLAGS_REG))])]
6223 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
6227 (define_expand "add<mode>3"
6228 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6229 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6230 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
6232 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
6234 (define_insn_and_split "*add<dwi>3_doubleword"
6235 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
6237 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
6238 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
6239 (clobber (reg:CC FLAGS_REG))]
6240 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
6242 "&& reload_completed"
6243 [(parallel [(set (reg:CCC FLAGS_REG)
6245 (plus:DWIH (match_dup 1) (match_dup 2))
6248 (plus:DWIH (match_dup 1) (match_dup 2)))])
6249 (parallel [(set (match_dup 3)
6252 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6255 (clobber (reg:CC FLAGS_REG))])]
6257 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6258 if (operands[2] == const0_rtx)
6260 if (operands[5] != const0_rtx)
6261 ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]);
6262 else if (!rtx_equal_p (operands[3], operands[4]))
6263 emit_move_insn (operands[3], operands[4]);
6265 emit_note (NOTE_INSN_DELETED);
6270 (define_insn_and_split "*add<dwi>3_doubleword_zext"
6271 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6274 (match_operand:DWIH 2 "nonimmediate_operand" "rm,r"))
6275 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")))
6276 (clobber (reg:CC FLAGS_REG))]
6277 "ix86_binary_operator_ok (UNKNOWN, <DWI>mode, operands)"
6279 "&& reload_completed"
6280 [(parallel [(set (reg:CCC FLAGS_REG)
6282 (plus:DWIH (match_dup 1) (match_dup 2))
6285 (plus:DWIH (match_dup 1) (match_dup 2)))])
6286 (parallel [(set (match_dup 3)
6289 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6292 (clobber (reg:CC FLAGS_REG))])]
6293 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[3]);")
6295 (define_insn_and_split "*add<dwi>3_doubleword_concat"
6296 [(set (match_operand:<DWI> 0 "register_operand" "=&r")
6301 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))
6302 (match_operand:QI 3 "const_int_operand"))
6304 (match_operand:DWIH 4 "nonimmediate_operand" "rm")))
6305 (match_operand:<DWI> 1 "register_operand" "0")))
6306 (clobber (reg:CC FLAGS_REG))]
6307 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
6309 "&& reload_completed"
6310 [(parallel [(set (reg:CCC FLAGS_REG)
6312 (plus:DWIH (match_dup 1) (match_dup 4))
6315 (plus:DWIH (match_dup 1) (match_dup 4)))])
6316 (parallel [(set (match_dup 5)
6319 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6322 (clobber (reg:CC FLAGS_REG))])]
6323 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[5]);")
6325 (define_insn_and_split "*add<dwi>3_doubleword_concat_zext"
6326 [(set (match_operand:<DWI> 0 "register_operand" "=&r")
6331 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))
6332 (match_operand:QI 3 "const_int_operand"))
6334 (match_operand:DWIH 4 "nonimmediate_operand" "rm")))
6336 (match_operand:DWIH 1 "nonimmediate_operand" "rm"))))
6337 (clobber (reg:CC FLAGS_REG))]
6338 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
6340 "&& reload_completed"
6341 [(set (match_dup 0) (match_dup 4))
6342 (set (match_dup 5) (match_dup 2))
6343 (parallel [(set (reg:CCC FLAGS_REG)
6345 (plus:DWIH (match_dup 0) (match_dup 1))
6348 (plus:DWIH (match_dup 0) (match_dup 1)))])
6349 (parallel [(set (match_dup 5)
6352 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6355 (clobber (reg:CC FLAGS_REG))])]
6356 "split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[5]);")
6358 (define_insn "*add<mode>_1"
6359 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,r")
6361 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
6362 (match_operand:SWI48 2 "x86_64_general_operand" "re,BM,0,le")))
6363 (clobber (reg:CC FLAGS_REG))]
6364 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6366 switch (get_attr_type (insn))
6372 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6373 if (operands[2] == const1_rtx)
6374 return "inc{<imodesuffix>}\t%0";
6377 gcc_assert (operands[2] == constm1_rtx);
6378 return "dec{<imodesuffix>}\t%0";
6382 /* For most processors, ADD is faster than LEA. This alternative
6383 was added to use ADD as much as possible. */
6384 if (which_alternative == 2)
6385 std::swap (operands[1], operands[2]);
6387 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6388 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6389 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6391 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6395 (cond [(eq_attr "alternative" "3")
6396 (const_string "lea")
6397 (match_operand:SWI48 2 "incdec_operand")
6398 (const_string "incdec")
6400 (const_string "alu")))
6401 (set (attr "length_immediate")
6403 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6405 (const_string "*")))
6406 (set_attr "mode" "<MODE>")])
6408 ;; It may seem that nonimmediate operand is proper one for operand 1.
6409 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6410 ;; we take care in ix86_binary_operator_ok to not allow two memory
6411 ;; operands so proper swapping will be done in reload. This allow
6412 ;; patterns constructed from addsi_1 to match.
6414 (define_insn "addsi_1_zext"
6415 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6417 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
6418 (match_operand:SI 2 "x86_64_general_operand" "rBMe,0,le"))))
6419 (clobber (reg:CC FLAGS_REG))]
6420 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6422 switch (get_attr_type (insn))
6428 if (operands[2] == const1_rtx)
6429 return "inc{l}\t%k0";
6432 gcc_assert (operands[2] == constm1_rtx);
6433 return "dec{l}\t%k0";
6437 /* For most processors, ADD is faster than LEA. This alternative
6438 was added to use ADD as much as possible. */
6439 if (which_alternative == 1)
6440 std::swap (operands[1], operands[2]);
6442 if (x86_maybe_negate_const_int (&operands[2], SImode))
6443 return "sub{l}\t{%2, %k0|%k0, %2}";
6445 return "add{l}\t{%2, %k0|%k0, %2}";
6449 (cond [(eq_attr "alternative" "2")
6450 (const_string "lea")
6451 (match_operand:SI 2 "incdec_operand")
6452 (const_string "incdec")
6454 (const_string "alu")))
6455 (set (attr "length_immediate")
6457 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6459 (const_string "*")))
6460 (set_attr "mode" "SI")])
6462 (define_insn "*addhi_1"
6463 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
6464 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
6465 (match_operand:HI 2 "general_operand" "rn,m,0,ln")))
6466 (clobber (reg:CC FLAGS_REG))]
6467 "ix86_binary_operator_ok (PLUS, HImode, operands)"
6469 switch (get_attr_type (insn))
6475 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6476 if (operands[2] == const1_rtx)
6477 return "inc{w}\t%0";
6480 gcc_assert (operands[2] == constm1_rtx);
6481 return "dec{w}\t%0";
6485 /* For most processors, ADD is faster than LEA. This alternative
6486 was added to use ADD as much as possible. */
6487 if (which_alternative == 2)
6488 std::swap (operands[1], operands[2]);
6490 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6491 if (x86_maybe_negate_const_int (&operands[2], HImode))
6492 return "sub{w}\t{%2, %0|%0, %2}";
6494 return "add{w}\t{%2, %0|%0, %2}";
6498 (cond [(eq_attr "alternative" "3")
6499 (const_string "lea")
6500 (match_operand:HI 2 "incdec_operand")
6501 (const_string "incdec")
6503 (const_string "alu")))
6504 (set (attr "length_immediate")
6506 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6508 (const_string "*")))
6509 (set_attr "mode" "HI,HI,HI,SI")])
6511 (define_insn "*addqi_1"
6512 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
6513 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
6514 (match_operand:QI 2 "general_operand" "qn,m,0,rn,0,ln")))
6515 (clobber (reg:CC FLAGS_REG))]
6516 "ix86_binary_operator_ok (PLUS, QImode, operands)"
6518 bool widen = (get_attr_mode (insn) != MODE_QI);
6520 switch (get_attr_type (insn))
6526 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6527 if (operands[2] == const1_rtx)
6528 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6531 gcc_assert (operands[2] == constm1_rtx);
6532 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6536 /* For most processors, ADD is faster than LEA. These alternatives
6537 were added to use ADD as much as possible. */
6538 if (which_alternative == 2 || which_alternative == 4)
6539 std::swap (operands[1], operands[2]);
6541 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6542 if (x86_maybe_negate_const_int (&operands[2], QImode))
6545 return "sub{l}\t{%2, %k0|%k0, %2}";
6547 return "sub{b}\t{%2, %0|%0, %2}";
6550 return "add{l}\t{%k2, %k0|%k0, %k2}";
6552 return "add{b}\t{%2, %0|%0, %2}";
6556 (cond [(eq_attr "alternative" "5")
6557 (const_string "lea")
6558 (match_operand:QI 2 "incdec_operand")
6559 (const_string "incdec")
6561 (const_string "alu")))
6562 (set (attr "length_immediate")
6564 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6566 (const_string "*")))
6567 (set_attr "mode" "QI,QI,QI,SI,SI,SI")
6568 ;; Potential partial reg stall on alternatives 3 and 4.
6569 (set (attr "preferred_for_speed")
6570 (cond [(eq_attr "alternative" "3,4")
6571 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
6572 (symbol_ref "true")))])
6574 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
6575 (define_insn_and_split "*add<mode>_1_slp"
6576 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
6577 (plus:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0,!<r>")
6578 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
6579 (clobber (reg:CC FLAGS_REG))]
6580 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6582 if (which_alternative)
6585 switch (get_attr_type (insn))
6588 if (operands[2] == const1_rtx)
6589 return "inc{<imodesuffix>}\t%0";
6592 gcc_assert (operands[2] == constm1_rtx);
6593 return "dec{<imodesuffix>}\t%0";
6597 if (x86_maybe_negate_const_int (&operands[2], QImode))
6598 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6600 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6603 "&& reload_completed
6604 && !(rtx_equal_p (operands[0], operands[1])
6605 || rtx_equal_p (operands[0], operands[2]))"
6606 [(set (strict_low_part (match_dup 0)) (match_dup 1))
6608 [(set (strict_low_part (match_dup 0))
6609 (plus:SWI12 (match_dup 0) (match_dup 2)))
6610 (clobber (reg:CC FLAGS_REG))])]
6613 (if_then_else (match_operand:QI 2 "incdec_operand")
6614 (const_string "incdec")
6615 (const_string "alu")))
6616 (set_attr "mode" "<MODE>")])
6618 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
6619 (define_insn_and_split "*addqi_ext<mode>_1_slp"
6620 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+Q,&Q"))
6623 (match_operator:SWI248 3 "extract_operator"
6624 [(match_operand 2 "int248_register_operand" "Q,Q")
6627 (match_operand:QI 1 "nonimmediate_operand" "0,!qm")))
6628 (clobber (reg:CC FLAGS_REG))]
6629 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6631 add{b}\t{%h2, %0|%0, %h2}
6633 "&& reload_completed
6634 && !rtx_equal_p (operands[0], operands[1])"
6635 [(set (strict_low_part (match_dup 0)) (match_dup 1))
6637 [(set (strict_low_part (match_dup 0))
6641 [(match_dup 2) (const_int 8) (const_int 8)]) 0)
6643 (clobber (reg:CC FLAGS_REG))])]
6645 [(set_attr "type" "alu")
6646 (set_attr "mode" "QI")])
6648 ;; Split non destructive adds if we cannot use lea.
6650 [(set (match_operand:SWI48 0 "register_operand")
6651 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
6652 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
6653 (clobber (reg:CC FLAGS_REG))]
6654 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
6655 [(set (match_dup 0) (match_dup 1))
6656 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
6657 (clobber (reg:CC FLAGS_REG))])])
6659 ;; Split non destructive adds if we cannot use lea.
6661 [(set (match_operand:DI 0 "register_operand")
6663 (plus:SI (match_operand:SI 1 "register_operand")
6664 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
6665 (clobber (reg:CC FLAGS_REG))]
6667 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
6668 [(set (match_dup 3) (match_dup 1))
6669 (parallel [(set (match_dup 0)
6670 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
6671 (clobber (reg:CC FLAGS_REG))])]
6672 "operands[3] = gen_lowpart (SImode, operands[0]);")
6674 ;; Convert add to the lea pattern to avoid flags dependency.
6676 [(set (match_operand:SWI 0 "register_operand")
6677 (plus:SWI (match_operand:SWI 1 "register_operand")
6678 (match_operand:SWI 2 "<nonmemory_operand>")))
6679 (clobber (reg:CC FLAGS_REG))]
6680 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
6682 (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
6684 if (<MODE>mode != <LEAMODE>mode)
6686 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
6687 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
6688 operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
6692 ;; Convert add to the lea pattern to avoid flags dependency.
6694 [(set (match_operand:DI 0 "register_operand")
6696 (plus:SI (match_operand:SI 1 "register_operand")
6697 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
6698 (clobber (reg:CC FLAGS_REG))]
6699 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
6701 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
6703 (define_insn "*add<mode>_2"
6704 [(set (reg FLAGS_REG)
6707 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
6708 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,0"))
6710 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,<r>")
6711 (plus:SWI (match_dup 1) (match_dup 2)))]
6712 "ix86_match_ccmode (insn, CCGOCmode)
6713 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6715 switch (get_attr_type (insn))
6718 if (operands[2] == const1_rtx)
6719 return "inc{<imodesuffix>}\t%0";
6722 gcc_assert (operands[2] == constm1_rtx);
6723 return "dec{<imodesuffix>}\t%0";
6727 if (which_alternative == 2)
6728 std::swap (operands[1], operands[2]);
6730 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6731 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6732 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6734 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6738 (if_then_else (match_operand:SWI 2 "incdec_operand")
6739 (const_string "incdec")
6740 (const_string "alu")))
6741 (set (attr "length_immediate")
6743 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6745 (const_string "*")))
6746 (set_attr "mode" "<MODE>")])
6748 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6749 (define_insn "*addsi_2_zext"
6750 [(set (reg FLAGS_REG)
6752 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6753 (match_operand:SI 2 "x86_64_general_operand" "rBMe,0"))
6755 (set (match_operand:DI 0 "register_operand" "=r,r")
6756 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6757 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6758 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6760 switch (get_attr_type (insn))
6763 if (operands[2] == const1_rtx)
6764 return "inc{l}\t%k0";
6767 gcc_assert (operands[2] == constm1_rtx);
6768 return "dec{l}\t%k0";
6772 if (which_alternative == 1)
6773 std::swap (operands[1], operands[2]);
6775 if (x86_maybe_negate_const_int (&operands[2], SImode))
6776 return "sub{l}\t{%2, %k0|%k0, %2}";
6778 return "add{l}\t{%2, %k0|%k0, %2}";
6782 (if_then_else (match_operand:SI 2 "incdec_operand")
6783 (const_string "incdec")
6784 (const_string "alu")))
6785 (set (attr "length_immediate")
6787 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6789 (const_string "*")))
6790 (set_attr "mode" "SI")])
6792 (define_insn "*add<mode>_3"
6793 [(set (reg FLAGS_REG)
6795 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6796 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
6797 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6798 "ix86_match_ccmode (insn, CCZmode)
6799 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6801 switch (get_attr_type (insn))
6804 if (operands[2] == const1_rtx)
6805 return "inc{<imodesuffix>}\t%0";
6808 gcc_assert (operands[2] == constm1_rtx);
6809 return "dec{<imodesuffix>}\t%0";
6813 if (which_alternative == 1)
6814 std::swap (operands[1], operands[2]);
6816 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6817 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6818 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6820 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6824 (if_then_else (match_operand:SWI 2 "incdec_operand")
6825 (const_string "incdec")
6826 (const_string "alu")))
6827 (set (attr "length_immediate")
6829 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6831 (const_string "*")))
6832 (set_attr "mode" "<MODE>")])
6834 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6835 (define_insn "*addsi_3_zext"
6836 [(set (reg FLAGS_REG)
6838 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rBMe,0"))
6839 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
6840 (set (match_operand:DI 0 "register_operand" "=r,r")
6841 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6842 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6843 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6845 switch (get_attr_type (insn))
6848 if (operands[2] == const1_rtx)
6849 return "inc{l}\t%k0";
6852 gcc_assert (operands[2] == constm1_rtx);
6853 return "dec{l}\t%k0";
6857 if (which_alternative == 1)
6858 std::swap (operands[1], operands[2]);
6860 if (x86_maybe_negate_const_int (&operands[2], SImode))
6861 return "sub{l}\t{%2, %k0|%k0, %2}";
6863 return "add{l}\t{%2, %k0|%k0, %2}";
6867 (if_then_else (match_operand:SI 2 "incdec_operand")
6868 (const_string "incdec")
6869 (const_string "alu")))
6870 (set (attr "length_immediate")
6872 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6874 (const_string "*")))
6875 (set_attr "mode" "SI")])
6877 ; For comparisons against 1, -1 and 128, we may generate better code
6878 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6879 ; is matched then. We can't accept general immediate, because for
6880 ; case of overflows, the result is messed up.
6881 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6882 ; only for comparisons not depending on it.
6884 (define_insn "*adddi_4"
6885 [(set (reg FLAGS_REG)
6887 (match_operand:DI 1 "nonimmediate_operand" "0")
6888 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6889 (clobber (match_scratch:DI 0 "=r"))]
6891 && ix86_match_ccmode (insn, CCGCmode)"
6893 switch (get_attr_type (insn))
6896 if (operands[2] == constm1_rtx)
6897 return "inc{q}\t%0";
6900 gcc_assert (operands[2] == const1_rtx);
6901 return "dec{q}\t%0";
6905 if (x86_maybe_negate_const_int (&operands[2], DImode))
6906 return "add{q}\t{%2, %0|%0, %2}";
6908 return "sub{q}\t{%2, %0|%0, %2}";
6912 (if_then_else (match_operand:DI 2 "incdec_operand")
6913 (const_string "incdec")
6914 (const_string "alu")))
6915 (set (attr "length_immediate")
6917 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6919 (const_string "*")))
6920 (set_attr "mode" "DI")])
6922 ; For comparisons against 1, -1 and 128, we may generate better code
6923 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6924 ; is matched then. We can't accept general immediate, because for
6925 ; case of overflows, the result is messed up.
6926 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6927 ; only for comparisons not depending on it.
6929 (define_insn "*add<mode>_4"
6930 [(set (reg FLAGS_REG)
6932 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6933 (match_operand:SWI124 2 "const_int_operand")))
6934 (clobber (match_scratch:SWI124 0 "=<r>"))]
6935 "ix86_match_ccmode (insn, CCGCmode)"
6937 switch (get_attr_type (insn))
6940 if (operands[2] == constm1_rtx)
6941 return "inc{<imodesuffix>}\t%0";
6944 gcc_assert (operands[2] == const1_rtx);
6945 return "dec{<imodesuffix>}\t%0";
6949 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6950 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6952 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6956 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6957 (const_string "incdec")
6958 (const_string "alu")))
6959 (set (attr "length_immediate")
6961 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6963 (const_string "*")))
6964 (set_attr "mode" "<MODE>")])
6966 (define_insn "*add<mode>_5"
6967 [(set (reg FLAGS_REG)
6970 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6971 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6973 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6974 "ix86_match_ccmode (insn, CCGOCmode)
6975 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6977 switch (get_attr_type (insn))
6980 if (operands[2] == const1_rtx)
6981 return "inc{<imodesuffix>}\t%0";
6984 gcc_assert (operands[2] == constm1_rtx);
6985 return "dec{<imodesuffix>}\t%0";
6989 if (which_alternative == 1)
6990 std::swap (operands[1], operands[2]);
6992 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6993 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6994 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6996 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
7000 (if_then_else (match_operand:SWI 2 "incdec_operand")
7001 (const_string "incdec")
7002 (const_string "alu")))
7003 (set (attr "length_immediate")
7005 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
7007 (const_string "*")))
7008 (set_attr "mode" "<MODE>")])
7010 (define_insn "*addqi_ext<mode>_0"
7011 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn")
7014 (match_operator:SWI248 3 "extract_operator"
7015 [(match_operand 2 "int248_register_operand" "Q")
7018 (match_operand:QI 1 "nonimmediate_operand" "0")))
7019 (clobber (reg:CC FLAGS_REG))]
7021 "add{b}\t{%h2, %0|%0, %h2}"
7022 [(set_attr "addr" "gpr8")
7023 (set_attr "type" "alu")
7024 (set_attr "mode" "QI")])
7026 (define_expand "addqi_ext_1"
7028 [(set (zero_extract:HI (match_operand:HI 0 "register_operand")
7034 (zero_extract:HI (match_operand:HI 1 "register_operand")
7037 (match_operand:QI 2 "const_int_operand")) 0))
7038 (clobber (reg:CC FLAGS_REG))])])
7040 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
7041 (define_insn_and_split "*addqi_ext<mode>_1"
7042 [(set (zero_extract:SWI248
7043 (match_operand 0 "int248_register_operand" "+Q,&Q")
7049 (match_operator:SWI248 3 "extract_operator"
7050 [(match_operand 1 "int248_register_operand" "0,!Q")
7053 (match_operand:QI 2 "general_operand" "QnBn,QnBn")) 0))
7054 (clobber (reg:CC FLAGS_REG))]
7057 if (which_alternative)
7060 switch (get_attr_type (insn))
7063 if (operands[2] == const1_rtx)
7064 return "inc{b}\t%h0";
7067 gcc_assert (operands[2] == constm1_rtx);
7068 return "dec{b}\t%h0";
7072 return "add{b}\t{%2, %h0|%h0, %2}";
7076 && !rtx_equal_p (operands[0], operands[1])"
7077 [(set (zero_extract:SWI248
7078 (match_dup 0) (const_int 8) (const_int 8))
7079 (zero_extract:SWI248
7080 (match_dup 1) (const_int 8) (const_int 8)))
7082 [(set (zero_extract:SWI248
7083 (match_dup 0) (const_int 8) (const_int 8))
7088 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
7090 (clobber (reg:CC FLAGS_REG))])]
7092 [(set_attr "addr" "gpr8")
7094 (if_then_else (match_operand:QI 2 "incdec_operand")
7095 (const_string "incdec")
7096 (const_string "alu")))
7097 (set_attr "mode" "QI")])
7099 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
7100 (define_insn_and_split "*<insn>qi_ext<mode>_2"
7101 [(set (zero_extract:SWI248
7102 (match_operand 0 "int248_register_operand" "+Q,&Q")
7108 (match_operator:SWI248 3 "extract_operator"
7109 [(match_operand 1 "int248_register_operand" "<comm>0,!Q")
7113 (match_operator:SWI248 4 "extract_operator"
7114 [(match_operand 2 "int248_register_operand" "Q,Q")
7116 (const_int 8)]) 0)) 0))
7117 (clobber (reg:CC FLAGS_REG))]
7120 <insn>{b}\t{%h2, %h0|%h0, %h2}
7123 && !(rtx_equal_p (operands[0], operands[1])
7124 || (<CODE> == PLUS && rtx_equal_p (operands[0], operands[2])))"
7125 [(set (zero_extract:SWI248
7126 (match_dup 0) (const_int 8) (const_int 8))
7127 (zero_extract:SWI248
7128 (match_dup 1) (const_int 8) (const_int 8)))
7130 [(set (zero_extract:SWI248
7131 (match_dup 0) (const_int 8) (const_int 8))
7136 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
7139 [(match_dup 2) (const_int 8) (const_int 8)]) 0)) 0))
7140 (clobber (reg:CC FLAGS_REG))])]
7142 [(set_attr "type" "alu")
7143 (set_attr "mode" "QI")])
7145 ;; Like DWI, but use POImode instead of OImode.
7146 (define_mode_attr DPWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI") (TI "POI")])
7148 ;; Add with jump on overflow.
7149 (define_expand "addv<mode>4"
7150 [(parallel [(set (reg:CCO FLAGS_REG)
7154 (match_operand:SWIDWI 1 "nonimmediate_operand"))
7157 (plus:SWIDWI (match_dup 1)
7158 (match_operand:SWIDWI 2
7159 "<general_hilo_operand>")))))
7160 (set (match_operand:SWIDWI 0 "register_operand")
7161 (plus:SWIDWI (match_dup 1) (match_dup 2)))])
7162 (set (pc) (if_then_else
7163 (eq (reg:CCO FLAGS_REG) (const_int 0))
7164 (label_ref (match_operand 3))
7168 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
7169 if (CONST_SCALAR_INT_P (operands[2]))
7170 operands[4] = operands[2];
7172 operands[4] = gen_rtx_SIGN_EXTEND (<DPWI>mode, operands[2]);
7175 (define_insn "*addv<mode>4"
7176 [(set (reg:CCO FLAGS_REG)
7179 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
7181 (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m")))
7183 (plus:SWI (match_dup 1) (match_dup 2)))))
7184 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7185 (plus:SWI (match_dup 1) (match_dup 2)))]
7186 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7187 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7188 [(set_attr "type" "alu")
7189 (set_attr "mode" "<MODE>")])
7191 (define_insn "addv<mode>4_1"
7192 [(set (reg:CCO FLAGS_REG)
7195 (match_operand:SWI 1 "nonimmediate_operand" "0"))
7196 (match_operand:<DWI> 3 "const_int_operand"))
7200 (match_operand:SWI 2 "x86_64_immediate_operand" "<i>")))))
7201 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
7202 (plus:SWI (match_dup 1) (match_dup 2)))]
7203 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
7204 && CONST_INT_P (operands[2])
7205 && INTVAL (operands[2]) == INTVAL (operands[3])"
7206 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7207 [(set_attr "type" "alu")
7208 (set_attr "mode" "<MODE>")
7209 (set (attr "length_immediate")
7210 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7212 (match_test "<MODE_SIZE> == 8")
7214 (const_string "<MODE_SIZE>")))])
7216 ;; Quad word integer modes as mode attribute.
7217 (define_mode_attr QPWI [(SI "TI") (DI "POI")])
7219 (define_insn_and_split "*addv<dwi>4_doubleword"
7220 [(set (reg:CCO FLAGS_REG)
7224 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0"))
7226 (match_operand:<DWI> 2 "nonimmediate_operand" "r,o")))
7228 (plus:<DWI> (match_dup 1) (match_dup 2)))))
7229 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
7230 (plus:<DWI> (match_dup 1) (match_dup 2)))]
7231 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
7233 "&& reload_completed"
7234 [(parallel [(set (reg:CCC FLAGS_REG)
7236 (plus:DWIH (match_dup 1) (match_dup 2))
7239 (plus:DWIH (match_dup 1) (match_dup 2)))])
7240 (parallel [(set (reg:CCO FLAGS_REG)
7244 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7245 (sign_extend:<DWI> (match_dup 4)))
7246 (sign_extend:<DWI> (match_dup 5)))
7250 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7256 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7260 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7263 (define_insn_and_split "*addv<dwi>4_doubleword_1"
7264 [(set (reg:CCO FLAGS_REG)
7268 (match_operand:<DWI> 1 "nonimmediate_operand" "%0"))
7269 (match_operand:<QPWI> 3 "const_scalar_int_operand" "n"))
7273 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>")))))
7274 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
7275 (plus:<DWI> (match_dup 1) (match_dup 2)))]
7276 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)
7277 && CONST_SCALAR_INT_P (operands[2])
7278 && rtx_equal_p (operands[2], operands[3])"
7280 "&& reload_completed"
7281 [(parallel [(set (reg:CCC FLAGS_REG)
7283 (plus:DWIH (match_dup 1) (match_dup 2))
7286 (plus:DWIH (match_dup 1) (match_dup 2)))])
7287 (parallel [(set (reg:CCO FLAGS_REG)
7291 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7292 (sign_extend:<DWI> (match_dup 4)))
7297 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7303 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7307 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7308 if (operands[2] == const0_rtx)
7310 emit_insn (gen_addv<mode>4_1 (operands[3], operands[4], operands[5],
7316 (define_insn "*addv<mode>4_overflow_1"
7317 [(set (reg:CCO FLAGS_REG)
7321 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7322 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7324 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")))
7326 (match_operand:SWI 2 "<general_sext_operand>" "rWe,m")))
7330 (match_operator:SWI 5 "ix86_carry_flag_operator"
7331 [(match_dup 3) (const_int 0)])
7334 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r")
7337 (match_op_dup 5 [(match_dup 3) (const_int 0)])
7340 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7341 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
7342 [(set_attr "type" "alu")
7343 (set_attr "mode" "<MODE>")])
7345 (define_insn "*addv<mode>4_overflow_2"
7346 [(set (reg:CCO FLAGS_REG)
7350 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7351 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7353 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
7354 (match_operand:<DWI> 6 "const_int_operand" "n"))
7358 (match_operator:SWI 5 "ix86_carry_flag_operator"
7359 [(match_dup 3) (const_int 0)])
7361 (match_operand:SWI 2 "x86_64_immediate_operand" "e")))))
7362 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm")
7365 (match_op_dup 5 [(match_dup 3) (const_int 0)])
7368 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
7369 && CONST_INT_P (operands[2])
7370 && INTVAL (operands[2]) == INTVAL (operands[6])"
7371 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
7372 [(set_attr "type" "alu")
7373 (set_attr "mode" "<MODE>")
7374 (set (attr "length_immediate")
7375 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7377 (const_string "4")))])
7379 (define_expand "uaddv<mode>4"
7380 [(parallel [(set (reg:CCC FLAGS_REG)
7383 (match_operand:SWIDWI 1 "nonimmediate_operand")
7384 (match_operand:SWIDWI 2 "<general_hilo_operand>"))
7386 (set (match_operand:SWIDWI 0 "register_operand")
7387 (plus:SWIDWI (match_dup 1) (match_dup 2)))])
7388 (set (pc) (if_then_else
7389 (ltu (reg:CCC FLAGS_REG) (const_int 0))
7390 (label_ref (match_operand 3))
7393 "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
7395 ;; The lea patterns for modes less than 32 bits need to be matched by
7396 ;; several insns converted to real lea by splitters.
7398 (define_insn_and_split "*lea<mode>_general_1"
7399 [(set (match_operand:SWI12 0 "register_operand" "=r")
7401 (plus:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7402 (match_operand:SWI12 2 "register_operand" "r"))
7403 (match_operand:SWI12 3 "immediate_operand" "i")))]
7404 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7406 "&& reload_completed"
7409 (plus:SI (match_dup 1) (match_dup 2))
7412 operands[0] = gen_lowpart (SImode, operands[0]);
7413 operands[1] = gen_lowpart (SImode, operands[1]);
7414 operands[2] = gen_lowpart (SImode, operands[2]);
7415 operands[3] = gen_lowpart (SImode, operands[3]);
7417 [(set_attr "type" "lea")
7418 (set_attr "mode" "SI")])
7420 (define_insn_and_split "*lea<mode>_general_2"
7421 [(set (match_operand:SWI12 0 "register_operand" "=r")
7423 (mult:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7424 (match_operand 2 "const248_operand" "n"))
7425 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
7426 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7428 "&& reload_completed"
7431 (mult:SI (match_dup 1) (match_dup 2))
7434 operands[0] = gen_lowpart (SImode, operands[0]);
7435 operands[1] = gen_lowpart (SImode, operands[1]);
7436 operands[3] = gen_lowpart (SImode, operands[3]);
7438 [(set_attr "type" "lea")
7439 (set_attr "mode" "SI")])
7441 (define_insn_and_split "*lea<mode>_general_2b"
7442 [(set (match_operand:SWI12 0 "register_operand" "=r")
7444 (ashift:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7445 (match_operand 2 "const123_operand" "n"))
7446 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
7447 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7449 "&& reload_completed"
7452 (ashift:SI (match_dup 1) (match_dup 2))
7455 operands[0] = gen_lowpart (SImode, operands[0]);
7456 operands[1] = gen_lowpart (SImode, operands[1]);
7457 operands[3] = gen_lowpart (SImode, operands[3]);
7459 [(set_attr "type" "lea")
7460 (set_attr "mode" "SI")])
7462 (define_insn_and_split "*lea<mode>_general_3"
7463 [(set (match_operand:SWI12 0 "register_operand" "=r")
7466 (mult:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7467 (match_operand 2 "const248_operand" "n"))
7468 (match_operand:SWI12 3 "register_operand" "r"))
7469 (match_operand:SWI12 4 "immediate_operand" "i")))]
7470 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7472 "&& reload_completed"
7476 (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]);
7483 operands[4] = gen_lowpart (SImode, operands[4]);
7485 [(set_attr "type" "lea")
7486 (set_attr "mode" "SI")])
7488 (define_insn_and_split "*lea<mode>_general_3b"
7489 [(set (match_operand:SWI12 0 "register_operand" "=r")
7492 (ashift:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7493 (match_operand 2 "const123_operand" "n"))
7494 (match_operand:SWI12 3 "register_operand" "r"))
7495 (match_operand:SWI12 4 "immediate_operand" "i")))]
7496 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7498 "&& reload_completed"
7502 (ashift:SI (match_dup 1) (match_dup 2))
7506 operands[0] = gen_lowpart (SImode, operands[0]);
7507 operands[1] = gen_lowpart (SImode, operands[1]);
7508 operands[3] = gen_lowpart (SImode, operands[3]);
7509 operands[4] = gen_lowpart (SImode, operands[4]);
7511 [(set_attr "type" "lea")
7512 (set_attr "mode" "SI")])
7514 (define_insn_and_split "*lea<mode>_general_4"
7515 [(set (match_operand:SWI12 0 "register_operand" "=r")
7518 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7519 (match_operand 2 "const_0_to_3_operand"))
7520 (match_operand 3 "const_int_operand")))]
7521 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7522 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
7523 < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
7525 "&& reload_completed"
7528 (mult:SI (match_dup 1) (match_dup 2))
7531 operands[0] = gen_lowpart (SImode, operands[0]);
7532 operands[1] = gen_lowpart (SImode, operands[1]);
7533 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
7535 [(set_attr "type" "lea")
7536 (set_attr "mode" "SI")])
7538 (define_insn_and_split "*lea<mode>_general_4"
7539 [(set (match_operand:SWI48 0 "register_operand" "=r")
7542 (match_operand:SWI48 1 "register_no_SP_operand" "l")
7543 (match_operand 2 "const_0_to_3_operand"))
7544 (match_operand 3 "const_int_operand")))]
7545 "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
7546 < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
7548 "&& reload_completed"
7551 (mult:SWI48 (match_dup 1) (match_dup 2))
7553 "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
7554 [(set_attr "type" "lea")
7555 (set_attr "mode" "<MODE>")])
7557 ;; Subtract instructions
7559 (define_expand "sub<mode>3"
7560 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
7561 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
7562 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
7564 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
7566 (define_insn_and_split "*sub<dwi>3_doubleword"
7567 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
7569 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7570 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
7571 (clobber (reg:CC FLAGS_REG))]
7572 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7574 "&& reload_completed"
7575 [(parallel [(set (reg:CC FLAGS_REG)
7576 (compare:CC (match_dup 1) (match_dup 2)))
7578 (minus:DWIH (match_dup 1) (match_dup 2)))])
7579 (parallel [(set (match_dup 3)
7583 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7585 (clobber (reg:CC FLAGS_REG))])]
7587 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7588 if (operands[2] == const0_rtx)
7590 ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
7595 (define_insn_and_split "*sub<dwi>3_doubleword_zext"
7596 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
7598 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7600 (match_operand:DWIH 2 "nonimmediate_operand" "rm,r"))))
7601 (clobber (reg:CC FLAGS_REG))]
7602 "ix86_binary_operator_ok (UNKNOWN, <DWI>mode, operands)"
7604 "&& reload_completed"
7605 [(parallel [(set (reg:CC FLAGS_REG)
7606 (compare:CC (match_dup 1) (match_dup 2)))
7608 (minus:DWIH (match_dup 1) (match_dup 2)))])
7609 (parallel [(set (match_dup 3)
7613 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7615 (clobber (reg:CC FLAGS_REG))])]
7616 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[3]);")
7618 (define_insn "*sub<mode>_1"
7619 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7621 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7622 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
7623 (clobber (reg:CC FLAGS_REG))]
7624 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7625 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7626 [(set_attr "type" "alu")
7627 (set_attr "mode" "<MODE>")])
7629 (define_insn "*subsi_1_zext"
7630 [(set (match_operand:DI 0 "register_operand" "=r")
7632 (minus:SI (match_operand:SI 1 "register_operand" "0")
7633 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
7634 (clobber (reg:CC FLAGS_REG))]
7635 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7636 "sub{l}\t{%2, %k0|%k0, %2}"
7637 [(set_attr "type" "alu")
7638 (set_attr "mode" "SI")])
7640 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
7641 (define_insn_and_split "*sub<mode>_1_slp"
7642 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
7643 (minus:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
7644 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
7645 (clobber (reg:CC FLAGS_REG))]
7646 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7648 sub{<imodesuffix>}\t{%2, %0|%0, %2}
7650 "&& reload_completed
7651 && !(rtx_equal_p (operands[0], operands[1]))"
7652 [(set (strict_low_part (match_dup 0)) (match_dup 1))
7654 [(set (strict_low_part (match_dup 0))
7655 (minus:SWI12 (match_dup 0) (match_dup 2)))
7656 (clobber (reg:CC FLAGS_REG))])]
7658 [(set_attr "type" "alu")
7659 (set_attr "mode" "<MODE>")])
7661 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
7662 (define_insn_and_split "*subqi_ext<mode>_1_slp"
7663 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+Q,&Q"))
7665 (match_operand:QI 1 "nonimmediate_operand" "0,!qm")
7667 (match_operator:SWI248 3 "extract_operator"
7668 [(match_operand 2 "int248_register_operand" "Q,Q")
7670 (const_int 8)]) 0)))
7671 (clobber (reg:CC FLAGS_REG))]
7672 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7674 sub{b}\t{%h2, %0|%0, %h2}
7676 "&& reload_completed
7677 && !rtx_equal_p (operands[0], operands[1])"
7678 [(set (strict_low_part (match_dup 0)) (match_dup 1))
7680 [(set (strict_low_part (match_dup 0))
7685 [(match_dup 2) (const_int 8) (const_int 8)]) 0)))
7686 (clobber (reg:CC FLAGS_REG))])]
7688 [(set_attr "type" "alu")
7689 (set_attr "mode" "QI")])
7691 (define_insn "*sub<mode>_2"
7692 [(set (reg FLAGS_REG)
7695 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7696 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
7698 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7699 (minus:SWI (match_dup 1) (match_dup 2)))]
7700 "ix86_match_ccmode (insn, CCGOCmode)
7701 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7702 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7703 [(set_attr "type" "alu")
7704 (set_attr "mode" "<MODE>")])
7706 (define_insn "*subsi_2_zext"
7707 [(set (reg FLAGS_REG)
7709 (minus:SI (match_operand:SI 1 "register_operand" "0")
7710 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
7712 (set (match_operand:DI 0 "register_operand" "=r")
7714 (minus:SI (match_dup 1)
7716 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7717 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7718 "sub{l}\t{%2, %k0|%k0, %2}"
7719 [(set_attr "type" "alu")
7720 (set_attr "mode" "SI")])
7722 (define_insn "*subqi_ext<mode>_0"
7723 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn")
7725 (match_operand:QI 1 "nonimmediate_operand" "0")
7727 (match_operator:SWI248 3 "extract_operator"
7728 [(match_operand 2 "int248_register_operand" "Q")
7730 (const_int 8)]) 0)))
7731 (clobber (reg:CC FLAGS_REG))]
7733 "sub{b}\t{%h2, %0|%0, %h2}"
7734 [(set_attr "addr" "gpr8")
7735 (set_attr "type" "alu")
7736 (set_attr "mode" "QI")])
7738 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
7739 (define_insn_and_split "*subqi_ext<mode>_1"
7740 [(set (zero_extract:SWI248
7741 (match_operand 0 "int248_register_operand" "+Q,&Q")
7747 (match_operator:SWI248 3 "extract_operator"
7748 [(match_operand 1 "int248_register_operand" "0,!Q")
7751 (match_operand:QI 2 "general_operand" "QnBn,QnBn")) 0))
7752 (clobber (reg:CC FLAGS_REG))]
7755 sub{b}\t{%2, %h0|%h0, %2}
7758 && !(rtx_equal_p (operands[0], operands[1]))"
7759 [(set (zero_extract:SWI248
7760 (match_dup 0) (const_int 8) (const_int 8))
7761 (zero_extract:SWI248
7762 (match_dup 1) (const_int 8) (const_int 8)))
7764 [(set (zero_extract:SWI248
7765 (match_dup 0) (const_int 8) (const_int 8))
7770 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
7772 (clobber (reg:CC FLAGS_REG))])]
7774 [(set_attr "addr" "gpr8")
7775 (set_attr "type" "alu")
7776 (set_attr "mode" "QI")])
7778 ;; Subtract with jump on overflow.
7779 (define_expand "subv<mode>4"
7780 [(parallel [(set (reg:CCO FLAGS_REG)
7784 (match_operand:SWIDWI 1 "nonimmediate_operand"))
7787 (minus:SWIDWI (match_dup 1)
7788 (match_operand:SWIDWI 2
7789 "<general_hilo_operand>")))))
7790 (set (match_operand:SWIDWI 0 "register_operand")
7791 (minus:SWIDWI (match_dup 1) (match_dup 2)))])
7792 (set (pc) (if_then_else
7793 (eq (reg:CCO FLAGS_REG) (const_int 0))
7794 (label_ref (match_operand 3))
7798 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
7799 if (CONST_SCALAR_INT_P (operands[2]))
7800 operands[4] = operands[2];
7802 operands[4] = gen_rtx_SIGN_EXTEND (<DPWI>mode, operands[2]);
7805 (define_insn "*subv<mode>4"
7806 [(set (reg:CCO FLAGS_REG)
7807 (eq:CCO (minus:<DWI>
7809 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
7811 (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m")))
7813 (minus:SWI (match_dup 1) (match_dup 2)))))
7814 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7815 (minus:SWI (match_dup 1) (match_dup 2)))]
7816 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7817 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7818 [(set_attr "type" "alu")
7819 (set_attr "mode" "<MODE>")])
7821 (define_insn "subv<mode>4_1"
7822 [(set (reg:CCO FLAGS_REG)
7823 (eq:CCO (minus:<DWI>
7825 (match_operand:SWI 1 "nonimmediate_operand" "0"))
7826 (match_operand:<DWI> 3 "const_int_operand"))
7830 (match_operand:SWI 2 "x86_64_immediate_operand" "<i>")))))
7831 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
7832 (minus:SWI (match_dup 1) (match_dup 2)))]
7833 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7834 && CONST_INT_P (operands[2])
7835 && INTVAL (operands[2]) == INTVAL (operands[3])"
7836 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7837 [(set_attr "type" "alu")
7838 (set_attr "mode" "<MODE>")
7839 (set (attr "length_immediate")
7840 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7842 (match_test "<MODE_SIZE> == 8")
7844 (const_string "<MODE_SIZE>")))])
7846 (define_insn_and_split "*subv<dwi>4_doubleword"
7847 [(set (reg:CCO FLAGS_REG)
7851 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0"))
7853 (match_operand:<DWI> 2 "nonimmediate_operand" "r,o")))
7855 (minus:<DWI> (match_dup 1) (match_dup 2)))))
7856 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
7857 (minus:<DWI> (match_dup 1) (match_dup 2)))]
7858 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7860 "&& reload_completed"
7861 [(parallel [(set (reg:CC FLAGS_REG)
7862 (compare:CC (match_dup 1) (match_dup 2)))
7864 (minus:DWIH (match_dup 1) (match_dup 2)))])
7865 (parallel [(set (reg:CCO FLAGS_REG)
7869 (sign_extend:<DWI> (match_dup 4))
7870 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))
7871 (sign_extend:<DWI> (match_dup 5)))
7876 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7882 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7885 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7888 (define_insn_and_split "*subv<dwi>4_doubleword_1"
7889 [(set (reg:CCO FLAGS_REG)
7893 (match_operand:<DWI> 1 "nonimmediate_operand" "0"))
7894 (match_operand:<QPWI> 3 "const_scalar_int_operand"))
7898 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>")))))
7899 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
7900 (minus:<DWI> (match_dup 1) (match_dup 2)))]
7901 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7902 && CONST_SCALAR_INT_P (operands[2])
7903 && rtx_equal_p (operands[2], operands[3])"
7905 "&& reload_completed"
7906 [(parallel [(set (reg:CC FLAGS_REG)
7907 (compare:CC (match_dup 1) (match_dup 2)))
7909 (minus:DWIH (match_dup 1) (match_dup 2)))])
7910 (parallel [(set (reg:CCO FLAGS_REG)
7914 (sign_extend:<DWI> (match_dup 4))
7915 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))
7921 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7927 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7930 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7931 if (operands[2] == const0_rtx)
7933 emit_insn (gen_subv<mode>4_1 (operands[3], operands[4], operands[5],
7939 (define_insn "*subv<mode>4_overflow_1"
7940 [(set (reg:CCO FLAGS_REG)
7945 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
7946 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7947 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
7949 (match_operand:SWI 2 "<general_sext_operand>" "rWe,m")))
7954 (match_operator:SWI 5 "ix86_carry_flag_operator"
7955 [(match_dup 3) (const_int 0)]))
7957 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r")
7961 (match_op_dup 5 [(match_dup 3) (const_int 0)]))
7963 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7964 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7965 [(set_attr "type" "alu")
7966 (set_attr "mode" "<MODE>")])
7968 (define_insn "*subv<mode>4_overflow_2"
7969 [(set (reg:CCO FLAGS_REG)
7974 (match_operand:SWI 1 "nonimmediate_operand" "%0"))
7975 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7976 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
7977 (match_operand:<DWI> 6 "const_int_operand" "n"))
7982 (match_operator:SWI 5 "ix86_carry_flag_operator"
7983 [(match_dup 3) (const_int 0)]))
7984 (match_operand:SWI 2 "x86_64_immediate_operand" "e")))))
7985 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm")
7989 (match_op_dup 5 [(match_dup 3) (const_int 0)]))
7991 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7992 && CONST_INT_P (operands[2])
7993 && INTVAL (operands[2]) == INTVAL (operands[6])"
7994 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7995 [(set_attr "type" "alu")
7996 (set_attr "mode" "<MODE>")
7997 (set (attr "length_immediate")
7998 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
8000 (const_string "4")))])
8002 (define_expand "usubv<mode>4"
8003 [(parallel [(set (reg:CC FLAGS_REG)
8005 (match_operand:SWI 1 "nonimmediate_operand")
8006 (match_operand:SWI 2 "<general_operand>")))
8007 (set (match_operand:SWI 0 "register_operand")
8008 (minus:SWI (match_dup 1) (match_dup 2)))])
8009 (set (pc) (if_then_else
8010 (ltu (reg:CC FLAGS_REG) (const_int 0))
8011 (label_ref (match_operand 3))
8014 "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
8016 (define_insn "*sub<mode>_3"
8017 [(set (reg FLAGS_REG)
8018 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
8019 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
8020 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
8021 (minus:SWI (match_dup 1) (match_dup 2)))]
8022 "ix86_match_ccmode (insn, CCmode)
8023 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
8024 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
8025 [(set_attr "type" "alu")
8026 (set_attr "mode" "<MODE>")])
8030 [(set (reg:CC FLAGS_REG)
8031 (compare:CC (match_operand:SWI 0 "general_reg_operand")
8032 (match_operand:SWI 1 "general_gr_operand")))
8034 (minus:SWI (match_dup 0) (match_dup 1)))])]
8035 "find_regno_note (peep2_next_insn (0), REG_UNUSED, REGNO (operands[0])) != 0"
8036 [(set (reg:CC FLAGS_REG)
8037 (compare:CC (match_dup 0) (match_dup 1)))])
8040 [(set (match_operand:SWI 0 "general_reg_operand")
8041 (match_operand:SWI 1 "memory_operand"))
8042 (parallel [(set (reg:CC FLAGS_REG)
8043 (compare:CC (match_dup 0)
8044 (match_operand:SWI 2 "memory_operand")))
8046 (minus:SWI (match_dup 0) (match_dup 2)))])
8047 (set (match_dup 1) (match_dup 0))]
8048 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8049 && peep2_reg_dead_p (3, operands[0])
8050 && !reg_overlap_mentioned_p (operands[0], operands[1])
8051 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8052 [(set (match_dup 0) (match_dup 2))
8053 (parallel [(set (reg:CC FLAGS_REG)
8054 (compare:CC (match_dup 1) (match_dup 0)))
8056 (minus:SWI (match_dup 1) (match_dup 0)))])])
8058 ;; decl %eax; cmpl $-1, %eax; jne .Lxx; can be optimized into
8059 ;; subl $1, %eax; jnc .Lxx;
8062 [(set (match_operand:SWI 0 "general_reg_operand")
8063 (plus:SWI (match_dup 0) (const_int -1)))
8064 (clobber (reg FLAGS_REG))])
8065 (set (reg:CCZ FLAGS_REG)
8066 (compare:CCZ (match_dup 0) (const_int -1)))
8068 (if_then_else (match_operator 1 "bt_comparison_operator"
8069 [(reg:CCZ FLAGS_REG) (const_int 0)])
8072 "peep2_regno_dead_p (3, FLAGS_REG)"
8074 [(set (reg:CC FLAGS_REG)
8075 (compare:CC (match_dup 0) (const_int 1)))
8077 (minus:SWI (match_dup 0) (const_int 1)))])
8079 (if_then_else (match_dup 3)
8083 rtx cc = gen_rtx_REG (CCmode, FLAGS_REG);
8084 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE
8085 ? GEU : LTU, VOIDmode, cc, const0_rtx);
8088 ;; Help combine use borrow flag to test for -1 after dec (add $-1).
8089 (define_insn_and_split "*dec_cmov<mode>"
8090 [(set (match_operand:SWI248 0 "register_operand" "=r")
8091 (if_then_else:SWI248
8092 (match_operator 1 "bt_comparison_operator"
8093 [(match_operand:SWI248 2 "register_operand" "0") (const_int 0)])
8094 (plus:SWI248 (match_dup 2) (const_int -1))
8095 (match_operand:SWI248 3 "nonimmediate_operand" "rm")))
8096 (clobber (reg:CC FLAGS_REG))]
8099 "&& reload_completed"
8100 [(parallel [(set (reg:CC FLAGS_REG)
8101 (compare:CC (match_dup 2) (const_int 1)))
8102 (set (match_dup 0) (minus:SWI248 (match_dup 2) (const_int 1)))])
8104 (if_then_else:SWI248 (match_dup 4) (match_dup 0) (match_dup 3)))]
8106 rtx cc = gen_rtx_REG (CCCmode, FLAGS_REG);
8107 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE
8108 ? GEU : LTU, VOIDmode, cc, const0_rtx);
8111 (define_insn "*subsi_3_zext"
8112 [(set (reg FLAGS_REG)
8113 (compare (match_operand:SI 1 "register_operand" "0")
8114 (match_operand:SI 2 "x86_64_general_operand" "rBMe")))
8115 (set (match_operand:DI 0 "register_operand" "=r")
8117 (minus:SI (match_dup 1)
8119 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
8120 && ix86_binary_operator_ok (MINUS, SImode, operands)"
8121 "sub{l}\t{%2, %1|%1, %2}"
8122 [(set_attr "type" "alu")
8123 (set_attr "mode" "SI")])
8125 ;; Add with carry and subtract with borrow
8127 (define_insn "@add<mode>3_carry"
8128 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
8131 (match_operator:SWI 4 "ix86_carry_flag_operator"
8132 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8133 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
8134 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
8135 (clobber (reg:CC FLAGS_REG))]
8136 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
8137 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
8138 [(set_attr "type" "alu")
8139 (set_attr "use_carry" "1")
8140 (set_attr "pent_pair" "pu")
8141 (set_attr "mode" "<MODE>")])
8144 [(set (match_operand:SWI 0 "general_reg_operand")
8145 (match_operand:SWI 1 "memory_operand"))
8146 (parallel [(set (match_dup 0)
8149 (match_operator:SWI 4 "ix86_carry_flag_operator"
8150 [(match_operand 3 "flags_reg_operand")
8153 (match_operand:SWI 2 "memory_operand")))
8154 (clobber (reg:CC FLAGS_REG))])
8155 (set (match_dup 1) (match_dup 0))]
8156 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8157 && peep2_reg_dead_p (3, operands[0])
8158 && !reg_overlap_mentioned_p (operands[0], operands[1])
8159 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8160 [(set (match_dup 0) (match_dup 2))
8161 (parallel [(set (match_dup 1)
8162 (plus:SWI (plus:SWI (match_op_dup 4
8163 [(match_dup 3) (const_int 0)])
8166 (clobber (reg:CC FLAGS_REG))])])
8169 [(set (match_operand:SWI 0 "general_reg_operand")
8170 (match_operand:SWI 1 "memory_operand"))
8171 (parallel [(set (match_dup 0)
8174 (match_operator:SWI 4 "ix86_carry_flag_operator"
8175 [(match_operand 3 "flags_reg_operand")
8178 (match_operand:SWI 2 "memory_operand")))
8179 (clobber (reg:CC FLAGS_REG))])
8180 (set (match_operand:SWI 5 "general_reg_operand") (match_dup 0))
8181 (set (match_dup 1) (match_dup 5))]
8182 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8183 && peep2_reg_dead_p (3, operands[0])
8184 && peep2_reg_dead_p (4, operands[5])
8185 && !reg_overlap_mentioned_p (operands[0], operands[1])
8186 && !reg_overlap_mentioned_p (operands[0], operands[2])
8187 && !reg_overlap_mentioned_p (operands[5], operands[1])"
8188 [(set (match_dup 0) (match_dup 2))
8189 (parallel [(set (match_dup 1)
8190 (plus:SWI (plus:SWI (match_op_dup 4
8191 [(match_dup 3) (const_int 0)])
8194 (clobber (reg:CC FLAGS_REG))])])
8196 (define_insn "*add<mode>3_carry_0"
8197 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8199 (match_operator:SWI 2 "ix86_carry_flag_operator"
8200 [(reg FLAGS_REG) (const_int 0)])
8201 (match_operand:SWI 1 "nonimmediate_operand" "0")))
8202 (clobber (reg:CC FLAGS_REG))]
8203 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8204 "adc{<imodesuffix>}\t{$0, %0|%0, 0}"
8205 [(set_attr "type" "alu")
8206 (set_attr "use_carry" "1")
8207 (set_attr "pent_pair" "pu")
8208 (set_attr "mode" "<MODE>")])
8210 (define_insn "*add<mode>3_carry_0r"
8211 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8213 (match_operator:SWI 2 "ix86_carry_flag_unset_operator"
8214 [(reg FLAGS_REG) (const_int 0)])
8215 (match_operand:SWI 1 "nonimmediate_operand" "0")))
8216 (clobber (reg:CC FLAGS_REG))]
8217 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8218 "sbb{<imodesuffix>}\t{$-1, %0|%0, -1}"
8219 [(set_attr "type" "alu")
8220 (set_attr "use_carry" "1")
8221 (set_attr "pent_pair" "pu")
8222 (set_attr "mode" "<MODE>")])
8224 (define_insn "*addsi3_carry_zext"
8225 [(set (match_operand:DI 0 "register_operand" "=r")
8228 (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
8229 [(reg FLAGS_REG) (const_int 0)])
8230 (match_operand:SI 1 "register_operand" "%0"))
8231 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
8232 (clobber (reg:CC FLAGS_REG))]
8233 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
8234 "adc{l}\t{%2, %k0|%k0, %2}"
8235 [(set_attr "type" "alu")
8236 (set_attr "use_carry" "1")
8237 (set_attr "pent_pair" "pu")
8238 (set_attr "mode" "SI")])
8240 (define_insn "*addsi3_carry_zext_0"
8241 [(set (match_operand:DI 0 "register_operand" "=r")
8243 (plus:SI (match_operator:SI 2 "ix86_carry_flag_operator"
8244 [(reg FLAGS_REG) (const_int 0)])
8245 (match_operand:SI 1 "register_operand" "0"))))
8246 (clobber (reg:CC FLAGS_REG))]
8248 "adc{l}\t{$0, %k0|%k0, 0}"
8249 [(set_attr "type" "alu")
8250 (set_attr "use_carry" "1")
8251 (set_attr "pent_pair" "pu")
8252 (set_attr "mode" "SI")])
8254 (define_insn "*addsi3_carry_zext_0r"
8255 [(set (match_operand:DI 0 "register_operand" "=r")
8257 (plus:SI (match_operator:SI 2 "ix86_carry_flag_unset_operator"
8258 [(reg FLAGS_REG) (const_int 0)])
8259 (match_operand:SI 1 "register_operand" "0"))))
8260 (clobber (reg:CC FLAGS_REG))]
8262 "sbb{l}\t{$-1, %k0|%k0, -1}"
8263 [(set_attr "type" "alu")
8264 (set_attr "use_carry" "1")
8265 (set_attr "pent_pair" "pu")
8266 (set_attr "mode" "SI")])
8268 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
8270 (define_insn "addcarry<mode>"
8271 [(set (reg:CCC FLAGS_REG)
8276 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8277 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8278 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0"))
8279 (match_operand:SWI48 2 "nonimmediate_operand" "r,rm")))
8281 (zero_extend:<DWI> (match_dup 2))
8282 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8283 [(match_dup 3) (const_int 0)]))))
8284 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
8285 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8286 [(match_dup 3) (const_int 0)])
8289 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
8290 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
8291 [(set_attr "type" "alu")
8292 (set_attr "use_carry" "1")
8293 (set_attr "pent_pair" "pu")
8294 (set_attr "mode" "<MODE>")])
8297 [(parallel [(set (reg:CCC FLAGS_REG)
8302 (match_operator:SWI48 4 "ix86_carry_flag_operator"
8303 [(match_operand 2 "flags_reg_operand")
8305 (match_operand:SWI48 0 "general_reg_operand"))
8306 (match_operand:SWI48 1 "memory_operand")))
8308 (zero_extend:<DWI> (match_dup 1))
8309 (match_operator:<DWI> 3 "ix86_carry_flag_operator"
8310 [(match_dup 2) (const_int 0)]))))
8312 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8313 [(match_dup 2) (const_int 0)])
8316 (set (match_dup 1) (match_dup 0))]
8317 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8318 && peep2_reg_dead_p (2, operands[0])
8319 && !reg_overlap_mentioned_p (operands[0], operands[1])"
8320 [(parallel [(set (reg:CCC FLAGS_REG)
8326 [(match_dup 2) (const_int 0)])
8330 (zero_extend:<DWI> (match_dup 0))
8332 [(match_dup 2) (const_int 0)]))))
8334 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8335 [(match_dup 2) (const_int 0)])
8340 [(set (match_operand:SWI48 0 "general_reg_operand")
8341 (match_operand:SWI48 1 "memory_operand"))
8342 (parallel [(set (reg:CCC FLAGS_REG)
8347 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8348 [(match_operand 3 "flags_reg_operand")
8351 (match_operand:SWI48 2 "memory_operand")))
8353 (zero_extend:<DWI> (match_dup 2))
8354 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8355 [(match_dup 3) (const_int 0)]))))
8357 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8358 [(match_dup 3) (const_int 0)])
8361 (set (match_dup 1) (match_dup 0))]
8362 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8363 && peep2_reg_dead_p (3, operands[0])
8364 && !reg_overlap_mentioned_p (operands[0], operands[1])
8365 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8366 [(set (match_dup 0) (match_dup 2))
8367 (parallel [(set (reg:CCC FLAGS_REG)
8373 [(match_dup 3) (const_int 0)])
8377 (zero_extend:<DWI> (match_dup 0))
8379 [(match_dup 3) (const_int 0)]))))
8381 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8382 [(match_dup 3) (const_int 0)])
8387 [(parallel [(set (reg:CCC FLAGS_REG)
8392 (match_operator:SWI48 4 "ix86_carry_flag_operator"
8393 [(match_operand 2 "flags_reg_operand")
8395 (match_operand:SWI48 0 "general_reg_operand"))
8396 (match_operand:SWI48 1 "memory_operand")))
8398 (zero_extend:<DWI> (match_dup 1))
8399 (match_operator:<DWI> 3 "ix86_carry_flag_operator"
8400 [(match_dup 2) (const_int 0)]))))
8402 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8403 [(match_dup 2) (const_int 0)])
8406 (set (match_operand:QI 5 "general_reg_operand")
8407 (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8408 (set (match_operand:SWI48 6 "general_reg_operand")
8409 (zero_extend:SWI48 (match_dup 5)))
8410 (set (match_dup 1) (match_dup 0))]
8411 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8412 && peep2_reg_dead_p (4, operands[0])
8413 && !reg_overlap_mentioned_p (operands[0], operands[1])
8414 && !reg_overlap_mentioned_p (operands[0], operands[5])
8415 && !reg_overlap_mentioned_p (operands[5], operands[1])
8416 && !reg_overlap_mentioned_p (operands[0], operands[6])
8417 && !reg_overlap_mentioned_p (operands[6], operands[1])"
8418 [(parallel [(set (reg:CCC FLAGS_REG)
8424 [(match_dup 2) (const_int 0)])
8428 (zero_extend:<DWI> (match_dup 0))
8430 [(match_dup 2) (const_int 0)]))))
8432 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8433 [(match_dup 2) (const_int 0)])
8436 (set (match_dup 5) (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8437 (set (match_dup 6) (zero_extend:SWI48 (match_dup 5)))])
8439 (define_expand "addcarry<mode>_0"
8441 [(set (reg:CCC FLAGS_REG)
8444 (match_operand:SWI48 1 "nonimmediate_operand")
8445 (match_operand:SWI48 2 "x86_64_general_operand"))
8447 (set (match_operand:SWI48 0 "nonimmediate_operand")
8448 (plus:SWI48 (match_dup 1) (match_dup 2)))])]
8449 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)")
8451 (define_insn "*addcarry<mode>_1"
8452 [(set (reg:CCC FLAGS_REG)
8457 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8458 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8459 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
8460 (match_operand:SWI48 2 "x86_64_immediate_operand" "e")))
8462 (match_operand:<DWI> 6 "const_scalar_int_operand")
8463 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8464 [(match_dup 3) (const_int 0)]))))
8465 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
8466 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8467 [(match_dup 3) (const_int 0)])
8470 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
8471 && CONST_INT_P (operands[2])
8472 /* Check that operands[6] is operands[2] zero extended from
8473 <MODE>mode to <DWI>mode. */
8474 && ((<MODE>mode == SImode || INTVAL (operands[2]) >= 0)
8475 ? (CONST_INT_P (operands[6])
8476 && UINTVAL (operands[6]) == (UINTVAL (operands[2])
8477 & GET_MODE_MASK (<MODE>mode)))
8478 : (CONST_WIDE_INT_P (operands[6])
8479 && CONST_WIDE_INT_NUNITS (operands[6]) == 2
8480 && ((unsigned HOST_WIDE_INT) CONST_WIDE_INT_ELT (operands[6], 0)
8481 == UINTVAL (operands[2]))
8482 && CONST_WIDE_INT_ELT (operands[6], 1) == 0))"
8483 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
8484 [(set_attr "type" "alu")
8485 (set_attr "use_carry" "1")
8486 (set_attr "pent_pair" "pu")
8487 (set_attr "mode" "<MODE>")
8488 (set (attr "length_immediate")
8489 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
8491 (const_string "4")))])
8493 (define_insn "@sub<mode>3_carry"
8494 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
8497 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
8498 (match_operator:SWI 4 "ix86_carry_flag_operator"
8499 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
8500 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
8501 (clobber (reg:CC FLAGS_REG))]
8502 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
8503 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8504 [(set_attr "type" "alu")
8505 (set_attr "use_carry" "1")
8506 (set_attr "pent_pair" "pu")
8507 (set_attr "mode" "<MODE>")])
8510 [(set (match_operand:SWI 0 "general_reg_operand")
8511 (match_operand:SWI 1 "memory_operand"))
8512 (parallel [(set (match_dup 0)
8516 (match_operator:SWI 4 "ix86_carry_flag_operator"
8517 [(match_operand 3 "flags_reg_operand")
8519 (match_operand:SWI 2 "memory_operand")))
8520 (clobber (reg:CC FLAGS_REG))])
8521 (set (match_dup 1) (match_dup 0))]
8522 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8523 && peep2_reg_dead_p (3, operands[0])
8524 && !reg_overlap_mentioned_p (operands[0], operands[1])
8525 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8526 [(set (match_dup 0) (match_dup 2))
8527 (parallel [(set (match_dup 1)
8528 (minus:SWI (minus:SWI (match_dup 1)
8530 [(match_dup 3) (const_int 0)]))
8532 (clobber (reg:CC FLAGS_REG))])])
8535 [(set (match_operand:SWI 0 "general_reg_operand")
8536 (match_operand:SWI 1 "memory_operand"))
8537 (parallel [(set (match_dup 0)
8541 (match_operator:SWI 4 "ix86_carry_flag_operator"
8542 [(match_operand 3 "flags_reg_operand")
8544 (match_operand:SWI 2 "memory_operand")))
8545 (clobber (reg:CC FLAGS_REG))])
8546 (set (match_operand:SWI 5 "general_reg_operand") (match_dup 0))
8547 (set (match_dup 1) (match_dup 5))]
8548 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8549 && peep2_reg_dead_p (3, operands[0])
8550 && peep2_reg_dead_p (4, operands[5])
8551 && !reg_overlap_mentioned_p (operands[0], operands[1])
8552 && !reg_overlap_mentioned_p (operands[0], operands[2])
8553 && !reg_overlap_mentioned_p (operands[5], operands[1])"
8554 [(set (match_dup 0) (match_dup 2))
8555 (parallel [(set (match_dup 1)
8556 (minus:SWI (minus:SWI (match_dup 1)
8558 [(match_dup 3) (const_int 0)]))
8560 (clobber (reg:CC FLAGS_REG))])])
8562 (define_insn "*sub<mode>3_carry_0"
8563 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8565 (match_operand:SWI 1 "nonimmediate_operand" "0")
8566 (match_operator:SWI 2 "ix86_carry_flag_operator"
8567 [(reg FLAGS_REG) (const_int 0)])))
8568 (clobber (reg:CC FLAGS_REG))]
8569 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8570 "sbb{<imodesuffix>}\t{$0, %0|%0, 0}"
8571 [(set_attr "type" "alu")
8572 (set_attr "use_carry" "1")
8573 (set_attr "pent_pair" "pu")
8574 (set_attr "mode" "<MODE>")])
8576 (define_insn "*sub<mode>3_carry_0r"
8577 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8579 (match_operand:SWI 1 "nonimmediate_operand" "0")
8580 (match_operator:SWI 2 "ix86_carry_flag_unset_operator"
8581 [(reg FLAGS_REG) (const_int 0)])))
8582 (clobber (reg:CC FLAGS_REG))]
8583 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8584 "adc{<imodesuffix>}\t{$-1, %0|%0, -1}"
8585 [(set_attr "type" "alu")
8586 (set_attr "use_carry" "1")
8587 (set_attr "pent_pair" "pu")
8588 (set_attr "mode" "<MODE>")])
8590 (define_insn "*subsi3_carry_zext"
8591 [(set (match_operand:DI 0 "register_operand" "=r")
8595 (match_operand:SI 1 "register_operand" "0")
8596 (match_operator:SI 3 "ix86_carry_flag_operator"
8597 [(reg FLAGS_REG) (const_int 0)]))
8598 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
8599 (clobber (reg:CC FLAGS_REG))]
8600 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
8601 "sbb{l}\t{%2, %k0|%k0, %2}"
8602 [(set_attr "type" "alu")
8603 (set_attr "use_carry" "1")
8604 (set_attr "pent_pair" "pu")
8605 (set_attr "mode" "SI")])
8607 (define_insn "*subsi3_carry_zext_0"
8608 [(set (match_operand:DI 0 "register_operand" "=r")
8611 (match_operand:SI 1 "register_operand" "0")
8612 (match_operator:SI 2 "ix86_carry_flag_operator"
8613 [(reg FLAGS_REG) (const_int 0)]))))
8614 (clobber (reg:CC FLAGS_REG))]
8616 "sbb{l}\t{$0, %k0|%k0, 0}"
8617 [(set_attr "type" "alu")
8618 (set_attr "use_carry" "1")
8619 (set_attr "pent_pair" "pu")
8620 (set_attr "mode" "SI")])
8622 (define_insn "*subsi3_carry_zext_0r"
8623 [(set (match_operand:DI 0 "register_operand" "=r")
8626 (match_operand:SI 1 "register_operand" "0")
8627 (match_operator:SI 2 "ix86_carry_flag_unset_operator"
8628 [(reg FLAGS_REG) (const_int 0)]))))
8629 (clobber (reg:CC FLAGS_REG))]
8631 "adc{l}\t{$-1, %k0|%k0, -1}"
8632 [(set_attr "type" "alu")
8633 (set_attr "use_carry" "1")
8634 (set_attr "pent_pair" "pu")
8635 (set_attr "mode" "SI")])
8637 (define_insn "@sub<mode>3_carry_ccc"
8638 [(set (reg:CCC FLAGS_REG)
8640 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
8642 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
8644 (match_operand:DWIH 2 "x86_64_sext_operand" "rmWe")))))
8645 (clobber (match_scratch:DWIH 0 "=r"))]
8647 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8648 [(set_attr "type" "alu")
8649 (set_attr "mode" "<MODE>")])
8651 (define_insn "*sub<mode>3_carry_ccc_1"
8652 [(set (reg:CCC FLAGS_REG)
8654 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
8656 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
8657 (match_operand:<DWI> 2 "x86_64_dwzext_immediate_operand" "Wf"))))
8658 (clobber (match_scratch:DWIH 0 "=r"))]
8661 operands[3] = simplify_subreg (<MODE>mode, operands[2], <DWI>mode, 0);
8662 return "sbb{<imodesuffix>}\t{%3, %0|%0, %3}";
8664 [(set_attr "type" "alu")
8665 (set_attr "mode" "<MODE>")])
8667 ;; The sign flag is set from the
8668 ;; (compare (match_dup 1) (plus:DWIH (ltu:DWIH ...) (match_dup 2)))
8669 ;; result, the overflow flag likewise, but the overflow flag is also
8670 ;; set if the (plus:DWIH (ltu:DWIH ...) (match_dup 2)) overflows.
8671 (define_insn "@sub<mode>3_carry_ccgz"
8672 [(set (reg:CCGZ FLAGS_REG)
8673 (unspec:CCGZ [(match_operand:DWIH 1 "register_operand" "0")
8674 (match_operand:DWIH 2 "x86_64_general_operand" "rBMe")
8675 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))]
8677 (clobber (match_scratch:DWIH 0 "=r"))]
8679 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8680 [(set_attr "type" "alu")
8681 (set_attr "mode" "<MODE>")])
8683 (define_insn "subborrow<mode>"
8684 [(set (reg:CCC FLAGS_REG)
8687 (match_operand:SWI48 1 "nonimmediate_operand" "0,0"))
8689 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8690 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8692 (match_operand:SWI48 2 "nonimmediate_operand" "r,rm")))))
8693 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
8694 (minus:SWI48 (minus:SWI48
8696 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8697 [(match_dup 3) (const_int 0)]))
8699 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
8700 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8701 [(set_attr "type" "alu")
8702 (set_attr "use_carry" "1")
8703 (set_attr "pent_pair" "pu")
8704 (set_attr "mode" "<MODE>")])
8707 [(set (match_operand:SWI48 0 "general_reg_operand")
8708 (match_operand:SWI48 1 "memory_operand"))
8709 (parallel [(set (reg:CCC FLAGS_REG)
8711 (zero_extend:<DWI> (match_dup 0))
8713 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8714 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8716 (match_operand:SWI48 2 "memory_operand")))))
8721 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8722 [(match_dup 3) (const_int 0)]))
8724 (set (match_dup 1) (match_dup 0))]
8725 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8726 && peep2_reg_dead_p (3, operands[0])
8727 && !reg_overlap_mentioned_p (operands[0], operands[1])
8728 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8729 [(set (match_dup 0) (match_dup 2))
8730 (parallel [(set (reg:CCC FLAGS_REG)
8732 (zero_extend:<DWI> (match_dup 1))
8733 (plus:<DWI> (match_op_dup 4
8734 [(match_dup 3) (const_int 0)])
8735 (zero_extend:<DWI> (match_dup 0)))))
8737 (minus:SWI48 (minus:SWI48 (match_dup 1)
8739 [(match_dup 3) (const_int 0)]))
8743 [(set (match_operand:SWI48 6 "general_reg_operand")
8744 (match_operand:SWI48 7 "memory_operand"))
8745 (set (match_operand:SWI48 8 "general_reg_operand")
8746 (match_operand:SWI48 9 "memory_operand"))
8747 (parallel [(set (reg:CCC FLAGS_REG)
8750 (match_operand:SWI48 0 "general_reg_operand"))
8752 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8753 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8755 (match_operand:SWI48 2 "general_reg_operand")))))
8760 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8761 [(match_dup 3) (const_int 0)]))
8763 (set (match_operand:SWI48 1 "memory_operand") (match_dup 0))]
8764 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8765 && peep2_reg_dead_p (4, operands[0])
8766 && peep2_reg_dead_p (3, operands[2])
8767 && !reg_overlap_mentioned_p (operands[0], operands[1])
8768 && !reg_overlap_mentioned_p (operands[2], operands[1])
8769 && !reg_overlap_mentioned_p (operands[6], operands[9])
8770 && (rtx_equal_p (operands[6], operands[0])
8771 ? (rtx_equal_p (operands[7], operands[1])
8772 && rtx_equal_p (operands[8], operands[2]))
8773 : (rtx_equal_p (operands[8], operands[0])
8774 && rtx_equal_p (operands[9], operands[1])
8775 && rtx_equal_p (operands[6], operands[2])))"
8776 [(set (match_dup 0) (match_dup 9))
8777 (parallel [(set (reg:CCC FLAGS_REG)
8779 (zero_extend:<DWI> (match_dup 1))
8780 (plus:<DWI> (match_op_dup 4
8781 [(match_dup 3) (const_int 0)])
8782 (zero_extend:<DWI> (match_dup 0)))))
8784 (minus:SWI48 (minus:SWI48 (match_dup 1)
8786 [(match_dup 3) (const_int 0)]))
8789 if (!rtx_equal_p (operands[6], operands[0]))
8790 operands[9] = operands[7];
8794 [(set (match_operand:SWI48 6 "general_reg_operand")
8795 (match_operand:SWI48 7 "memory_operand"))
8796 (set (match_operand:SWI48 8 "general_reg_operand")
8797 (match_operand:SWI48 9 "memory_operand"))
8798 (parallel [(set (reg:CCC FLAGS_REG)
8801 (match_operand:SWI48 0 "general_reg_operand"))
8803 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8804 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8806 (match_operand:SWI48 2 "general_reg_operand")))))
8811 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8812 [(match_dup 3) (const_int 0)]))
8814 (set (match_operand:QI 10 "general_reg_operand")
8815 (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8816 (set (match_operand:SWI48 11 "general_reg_operand")
8817 (zero_extend:SWI48 (match_dup 10)))
8818 (set (match_operand:SWI48 1 "memory_operand") (match_dup 0))]
8819 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8820 && peep2_reg_dead_p (6, operands[0])
8821 && peep2_reg_dead_p (3, operands[2])
8822 && !reg_overlap_mentioned_p (operands[0], operands[1])
8823 && !reg_overlap_mentioned_p (operands[2], operands[1])
8824 && !reg_overlap_mentioned_p (operands[6], operands[9])
8825 && !reg_overlap_mentioned_p (operands[0], operands[10])
8826 && !reg_overlap_mentioned_p (operands[10], operands[1])
8827 && !reg_overlap_mentioned_p (operands[0], operands[11])
8828 && !reg_overlap_mentioned_p (operands[11], operands[1])
8829 && (rtx_equal_p (operands[6], operands[0])
8830 ? (rtx_equal_p (operands[7], operands[1])
8831 && rtx_equal_p (operands[8], operands[2]))
8832 : (rtx_equal_p (operands[8], operands[0])
8833 && rtx_equal_p (operands[9], operands[1])
8834 && rtx_equal_p (operands[6], operands[2])))"
8835 [(set (match_dup 0) (match_dup 9))
8836 (parallel [(set (reg:CCC FLAGS_REG)
8838 (zero_extend:<DWI> (match_dup 1))
8839 (plus:<DWI> (match_op_dup 4
8840 [(match_dup 3) (const_int 0)])
8841 (zero_extend:<DWI> (match_dup 0)))))
8843 (minus:SWI48 (minus:SWI48 (match_dup 1)
8845 [(match_dup 3) (const_int 0)]))
8847 (set (match_dup 10) (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8848 (set (match_dup 11) (zero_extend:SWI48 (match_dup 10)))]
8850 if (!rtx_equal_p (operands[6], operands[0]))
8851 operands[9] = operands[7];
8854 (define_expand "subborrow<mode>_0"
8856 [(set (reg:CC FLAGS_REG)
8858 (match_operand:SWI48 1 "nonimmediate_operand")
8859 (match_operand:SWI48 2 "<general_operand>")))
8860 (set (match_operand:SWI48 0 "register_operand")
8861 (minus:SWI48 (match_dup 1) (match_dup 2)))])]
8862 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)")
8864 (define_expand "uaddc<mode>5"
8865 [(match_operand:SWI48 0 "register_operand")
8866 (match_operand:SWI48 1 "register_operand")
8867 (match_operand:SWI48 2 "register_operand")
8868 (match_operand:SWI48 3 "register_operand")
8869 (match_operand:SWI48 4 "nonmemory_operand")]
8872 rtx cf = gen_rtx_REG (CCCmode, FLAGS_REG), pat, pat2;
8873 if (operands[4] == const0_rtx)
8874 emit_insn (gen_addcarry<mode>_0 (operands[0], operands[2], operands[3]));
8877 ix86_expand_carry (operands[4]);
8878 pat = gen_rtx_LTU (<DWI>mode, cf, const0_rtx);
8879 pat2 = gen_rtx_LTU (<MODE>mode, cf, const0_rtx);
8880 emit_insn (gen_addcarry<mode> (operands[0], operands[2], operands[3],
8883 rtx cc = gen_reg_rtx (QImode);
8884 pat = gen_rtx_LTU (QImode, cf, const0_rtx);
8885 emit_insn (gen_rtx_SET (cc, pat));
8886 emit_insn (gen_zero_extendqi<mode>2 (operands[1], cc));
8890 (define_expand "usubc<mode>5"
8891 [(match_operand:SWI48 0 "register_operand")
8892 (match_operand:SWI48 1 "register_operand")
8893 (match_operand:SWI48 2 "register_operand")
8894 (match_operand:SWI48 3 "register_operand")
8895 (match_operand:SWI48 4 "nonmemory_operand")]
8899 if (operands[4] == const0_rtx)
8901 cf = gen_rtx_REG (CCmode, FLAGS_REG);
8902 emit_insn (gen_subborrow<mode>_0 (operands[0], operands[2],
8907 cf = gen_rtx_REG (CCCmode, FLAGS_REG);
8908 ix86_expand_carry (operands[4]);
8909 pat = gen_rtx_LTU (<DWI>mode, cf, const0_rtx);
8910 pat2 = gen_rtx_LTU (<MODE>mode, cf, const0_rtx);
8911 emit_insn (gen_subborrow<mode> (operands[0], operands[2], operands[3],
8914 rtx cc = gen_reg_rtx (QImode);
8915 pat = gen_rtx_LTU (QImode, cf, const0_rtx);
8916 emit_insn (gen_rtx_SET (cc, pat));
8917 emit_insn (gen_zero_extendqi<mode>2 (operands[1], cc));
8921 (define_mode_iterator CC_CCC [CC CCC])
8923 ;; Pre-reload splitter to optimize
8924 ;; *setcc_qi followed by *addqi3_cconly_overflow_1 with the same QI
8925 ;; operand and no intervening flags modifications into nothing.
8926 (define_insn_and_split "*setcc_qi_addqi3_cconly_overflow_1_<mode>"
8927 [(set (reg:CCC FLAGS_REG)
8928 (compare:CCC (neg:QI (geu:QI (reg:CC_CCC FLAGS_REG) (const_int 0)))
8929 (ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))))]
8930 "ix86_pre_reload_split ()"
8934 "emit_note (NOTE_INSN_DELETED); DONE;")
8936 ;; Set the carry flag from the carry flag.
8937 (define_insn_and_split "*setccc"
8938 [(set (reg:CCC FLAGS_REG)
8939 (reg:CCC FLAGS_REG))]
8940 "ix86_pre_reload_split ()"
8944 "emit_note (NOTE_INSN_DELETED); DONE;")
8946 ;; Set the carry flag from the carry flag.
8947 (define_insn_and_split "*setcc_qi_negqi_ccc_1_<mode>"
8948 [(set (reg:CCC FLAGS_REG)
8949 (ltu:CCC (reg:CC_CCC FLAGS_REG) (const_int 0)))]
8950 "ix86_pre_reload_split ()"
8954 "emit_note (NOTE_INSN_DELETED); DONE;")
8956 ;; Set the carry flag from the carry flag.
8957 (define_insn_and_split "*setcc_qi_negqi_ccc_2_<mode>"
8958 [(set (reg:CCC FLAGS_REG)
8959 (unspec:CCC [(ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))
8960 (const_int 0)] UNSPEC_CC_NE))]
8961 "ix86_pre_reload_split ()"
8965 "emit_note (NOTE_INSN_DELETED); DONE;")
8967 ;; Overflow setting add instructions
8969 (define_expand "addqi3_cconly_overflow"
8971 [(set (reg:CCC FLAGS_REG)
8974 (match_operand:QI 0 "nonimmediate_operand")
8975 (match_operand:QI 1 "general_operand"))
8977 (clobber (scratch:QI))])]
8978 "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
8980 (define_insn "*add<mode>3_cconly_overflow_1"
8981 [(set (reg:CCC FLAGS_REG)
8984 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8985 (match_operand:SWI 2 "<general_operand>" "<g>"))
8987 (clobber (match_scratch:SWI 0 "=<r>"))]
8988 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8989 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
8990 [(set_attr "type" "alu")
8991 (set_attr "mode" "<MODE>")])
8993 (define_insn "@add<mode>3_cc_overflow_1"
8994 [(set (reg:CCC FLAGS_REG)
8997 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8998 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
9000 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
9001 (plus:SWI (match_dup 1) (match_dup 2)))]
9002 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
9003 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
9004 [(set_attr "type" "alu")
9005 (set_attr "mode" "<MODE>")])
9008 [(parallel [(set (reg:CCC FLAGS_REG)
9010 (plus:SWI (match_operand:SWI 0 "general_reg_operand")
9011 (match_operand:SWI 1 "memory_operand"))
9013 (set (match_dup 0) (plus:SWI (match_dup 0) (match_dup 1)))])
9014 (set (match_dup 1) (match_dup 0))]
9015 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
9016 && peep2_reg_dead_p (2, operands[0])
9017 && !reg_overlap_mentioned_p (operands[0], operands[1])"
9018 [(parallel [(set (reg:CCC FLAGS_REG)
9020 (plus:SWI (match_dup 1) (match_dup 0))
9022 (set (match_dup 1) (plus:SWI (match_dup 1) (match_dup 0)))])])
9025 [(set (match_operand:SWI 0 "general_reg_operand")
9026 (match_operand:SWI 1 "memory_operand"))
9027 (parallel [(set (reg:CCC FLAGS_REG)
9029 (plus:SWI (match_dup 0)
9030 (match_operand:SWI 2 "memory_operand"))
9032 (set (match_dup 0) (plus:SWI (match_dup 0) (match_dup 2)))])
9033 (set (match_dup 1) (match_dup 0))]
9034 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
9035 && peep2_reg_dead_p (3, operands[0])
9036 && !reg_overlap_mentioned_p (operands[0], operands[1])
9037 && !reg_overlap_mentioned_p (operands[0], operands[2])"
9038 [(set (match_dup 0) (match_dup 2))
9039 (parallel [(set (reg:CCC FLAGS_REG)
9041 (plus:SWI (match_dup 1) (match_dup 0))
9043 (set (match_dup 1) (plus:SWI (match_dup 1) (match_dup 0)))])])
9045 (define_insn "*addsi3_zext_cc_overflow_1"
9046 [(set (reg:CCC FLAGS_REG)
9049 (match_operand:SI 1 "nonimmediate_operand" "%0")
9050 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
9052 (set (match_operand:DI 0 "register_operand" "=r")
9053 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
9054 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
9055 "add{l}\t{%2, %k0|%k0, %2}"
9056 [(set_attr "type" "alu")
9057 (set_attr "mode" "SI")])
9059 (define_insn "*add<mode>3_cconly_overflow_2"
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_2"
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>")])
9086 (define_insn "*addsi3_zext_cc_overflow_2"
9087 [(set (reg:CCC FLAGS_REG)
9090 (match_operand:SI 1 "nonimmediate_operand" "%0")
9091 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
9093 (set (match_operand:DI 0 "register_operand" "=r")
9094 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
9095 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
9096 "add{l}\t{%2, %k0|%k0, %2}"
9097 [(set_attr "type" "alu")
9098 (set_attr "mode" "SI")])
9100 (define_insn_and_split "*add<dwi>3_doubleword_cc_overflow_1"
9101 [(set (reg:CCC FLAGS_REG)
9104 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
9105 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o"))
9107 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
9108 (plus:<DWI> (match_dup 1) (match_dup 2)))]
9109 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
9111 "&& reload_completed"
9112 [(parallel [(set (reg:CCC FLAGS_REG)
9114 (plus:DWIH (match_dup 1) (match_dup 2))
9117 (plus:DWIH (match_dup 1) (match_dup 2)))])
9118 (parallel [(set (reg:CCC FLAGS_REG)
9123 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9128 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))))
9131 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9135 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
9136 if (operands[2] == const0_rtx)
9138 emit_insn (gen_addcarry<mode>_0 (operands[3], operands[4], operands[5]));
9141 if (CONST_INT_P (operands[5]))
9142 operands[6] = simplify_unary_operation (ZERO_EXTEND, <DWI>mode,
9143 operands[5], <MODE>mode);
9145 operands[6] = gen_rtx_ZERO_EXTEND (<DWI>mode, operands[5]);
9148 ;; x == 0 with zero flag test can be done also as x < 1U with carry flag
9149 ;; test, where the latter is preferrable if we have some carry consuming
9151 ;; For x != 0, we need to use x < 1U with negation of carry, i.e.
9153 (define_insn_and_split "*add<mode>3_eq"
9154 [(set (match_operand:SWI 0 "nonimmediate_operand")
9157 (eq:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0))
9158 (match_operand:SWI 1 "nonimmediate_operand"))
9159 (match_operand:SWI 2 "<general_operand>")))
9160 (clobber (reg:CC FLAGS_REG))]
9161 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
9162 && ix86_pre_reload_split ()"
9165 [(set (reg:CC FLAGS_REG)
9166 (compare:CC (match_dup 3) (const_int 1)))
9167 (parallel [(set (match_dup 0)
9169 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9172 (clobber (reg:CC FLAGS_REG))])])
9174 (define_insn_and_split "*add<mode>3_ne"
9175 [(set (match_operand:SWI 0 "nonimmediate_operand")
9178 (ne:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0))
9179 (match_operand:SWI 1 "nonimmediate_operand"))
9180 (match_operand:SWI 2 "<immediate_operand>")))
9181 (clobber (reg:CC FLAGS_REG))]
9182 "CONST_INT_P (operands[2])
9183 && (<MODE>mode != DImode
9184 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
9185 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
9186 && ix86_pre_reload_split ()"
9189 [(set (reg:CC FLAGS_REG)
9190 (compare:CC (match_dup 3) (const_int 1)))
9191 (parallel [(set (match_dup 0)
9193 (minus:SWI (match_dup 1)
9194 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9196 (clobber (reg:CC FLAGS_REG))])]
9198 operands[2] = gen_int_mode (~INTVAL (operands[2]),
9199 <MODE>mode == DImode ? SImode : <MODE>mode);
9202 (define_insn_and_split "*add<mode>3_eq_0"
9203 [(set (match_operand:SWI 0 "nonimmediate_operand")
9205 (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))
9206 (match_operand:SWI 1 "<general_operand>")))
9207 (clobber (reg:CC FLAGS_REG))]
9208 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)
9209 && ix86_pre_reload_split ()"
9212 [(set (reg:CC FLAGS_REG)
9213 (compare:CC (match_dup 2) (const_int 1)))
9214 (parallel [(set (match_dup 0)
9215 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9217 (clobber (reg:CC FLAGS_REG))])]
9219 if (!nonimmediate_operand (operands[1], <MODE>mode))
9220 operands[1] = force_reg (<MODE>mode, operands[1]);
9223 (define_insn_and_split "*add<mode>3_ne_0"
9224 [(set (match_operand:SWI 0 "nonimmediate_operand")
9226 (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))
9227 (match_operand:SWI 1 "<general_operand>")))
9228 (clobber (reg:CC FLAGS_REG))]
9229 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)
9230 && ix86_pre_reload_split ()"
9233 [(set (reg:CC FLAGS_REG)
9234 (compare:CC (match_dup 2) (const_int 1)))
9235 (parallel [(set (match_dup 0)
9236 (minus:SWI (minus:SWI
9238 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9240 (clobber (reg:CC FLAGS_REG))])]
9242 if (!nonimmediate_operand (operands[1], <MODE>mode))
9243 operands[1] = force_reg (<MODE>mode, operands[1]);
9246 (define_insn_and_split "*sub<mode>3_eq"
9247 [(set (match_operand:SWI 0 "nonimmediate_operand")
9250 (match_operand:SWI 1 "nonimmediate_operand")
9251 (eq:SWI (match_operand 3 "int_nonimmediate_operand")
9253 (match_operand:SWI 2 "<general_operand>")))
9254 (clobber (reg:CC FLAGS_REG))]
9255 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
9256 && ix86_pre_reload_split ()"
9259 [(set (reg:CC FLAGS_REG)
9260 (compare:CC (match_dup 3) (const_int 1)))
9261 (parallel [(set (match_dup 0)
9263 (minus:SWI (match_dup 1)
9264 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9266 (clobber (reg:CC FLAGS_REG))])])
9268 (define_insn_and_split "*sub<mode>3_ne"
9269 [(set (match_operand:SWI 0 "nonimmediate_operand")
9272 (match_operand:SWI 1 "nonimmediate_operand")
9273 (ne:SWI (match_operand 3 "int_nonimmediate_operand")
9275 (match_operand:SWI 2 "<immediate_operand>")))
9276 (clobber (reg:CC FLAGS_REG))]
9277 "CONST_INT_P (operands[2])
9278 && (<MODE>mode != DImode
9279 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
9280 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
9281 && ix86_pre_reload_split ()"
9284 [(set (reg:CC FLAGS_REG)
9285 (compare:CC (match_dup 3) (const_int 1)))
9286 (parallel [(set (match_dup 0)
9288 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9291 (clobber (reg:CC FLAGS_REG))])]
9293 operands[2] = gen_int_mode (INTVAL (operands[2]) - 1,
9294 <MODE>mode == DImode ? SImode : <MODE>mode);
9297 (define_insn_and_split "*sub<mode>3_eq_1"
9298 [(set (match_operand:SWI 0 "nonimmediate_operand")
9301 (match_operand:SWI 1 "nonimmediate_operand")
9302 (eq:SWI (match_operand 3 "int_nonimmediate_operand")
9304 (match_operand:SWI 2 "<immediate_operand>")))
9305 (clobber (reg:CC FLAGS_REG))]
9306 "CONST_INT_P (operands[2])
9307 && (<MODE>mode != DImode
9308 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
9309 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
9310 && ix86_pre_reload_split ()"
9313 [(set (reg:CC FLAGS_REG)
9314 (compare:CC (match_dup 3) (const_int 1)))
9315 (parallel [(set (match_dup 0)
9317 (minus:SWI (match_dup 1)
9318 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9320 (clobber (reg:CC FLAGS_REG))])]
9322 operands[2] = gen_int_mode (-INTVAL (operands[2]),
9323 <MODE>mode == DImode ? SImode : <MODE>mode);
9326 (define_insn_and_split "*sub<mode>3_eq_0"
9327 [(set (match_operand:SWI 0 "nonimmediate_operand")
9329 (match_operand:SWI 1 "<general_operand>")
9330 (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))))
9331 (clobber (reg:CC FLAGS_REG))]
9332 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)
9333 && ix86_pre_reload_split ()"
9336 [(set (reg:CC FLAGS_REG)
9337 (compare:CC (match_dup 2) (const_int 1)))
9338 (parallel [(set (match_dup 0)
9339 (minus:SWI (match_dup 1)
9340 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))))
9341 (clobber (reg:CC FLAGS_REG))])]
9343 if (!nonimmediate_operand (operands[1], <MODE>mode))
9344 operands[1] = force_reg (<MODE>mode, operands[1]);
9347 (define_insn_and_split "*sub<mode>3_ne_0"
9348 [(set (match_operand:SWI 0 "nonimmediate_operand")
9350 (match_operand:SWI 1 "<general_operand>")
9351 (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))))
9352 (clobber (reg:CC FLAGS_REG))]
9353 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)
9354 && ix86_pre_reload_split ()"
9357 [(set (reg:CC FLAGS_REG)
9358 (compare:CC (match_dup 2) (const_int 1)))
9359 (parallel [(set (match_dup 0)
9361 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9364 (clobber (reg:CC FLAGS_REG))])]
9366 if (!nonimmediate_operand (operands[1], <MODE>mode))
9367 operands[1] = force_reg (<MODE>mode, operands[1]);
9370 ;; The patterns that match these are at the end of this file.
9372 (define_expand "<insn>xf3"
9373 [(set (match_operand:XF 0 "register_operand")
9375 (match_operand:XF 1 "register_operand")
9376 (match_operand:XF 2 "register_operand")))]
9379 (define_expand "<insn>hf3"
9380 [(set (match_operand:HF 0 "register_operand")
9382 (match_operand:HF 1 "register_operand")
9383 (match_operand:HF 2 "nonimmediate_operand")))]
9384 "TARGET_AVX512FP16")
9386 (define_expand "<insn><mode>3"
9387 [(set (match_operand:MODEF 0 "register_operand")
9389 (match_operand:MODEF 1 "register_operand")
9390 (match_operand:MODEF 2 "nonimmediate_operand")))]
9391 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
9392 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
9394 ;; Multiply instructions
9396 (define_expand "mul<mode>3"
9397 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
9399 (match_operand:SWIM248 1 "register_operand")
9400 (match_operand:SWIM248 2 "<general_operand>")))
9401 (clobber (reg:CC FLAGS_REG))])])
9403 (define_expand "mulqi3"
9404 [(parallel [(set (match_operand:QI 0 "register_operand")
9406 (match_operand:QI 1 "register_operand")
9407 (match_operand:QI 2 "nonimmediate_operand")))
9408 (clobber (reg:CC FLAGS_REG))])]
9409 "TARGET_QIMODE_MATH")
9412 ;; IMUL reg32/64, reg32/64, imm8 Direct
9413 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
9414 ;; IMUL reg32/64, reg32/64, imm32 Direct
9415 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
9416 ;; IMUL reg32/64, reg32/64 Direct
9417 ;; IMUL reg32/64, mem32/64 Direct
9419 ;; On BDVER1, all above IMULs use DirectPath
9422 ;; IMUL reg16, reg16, imm8 VectorPath
9423 ;; IMUL reg16, mem16, imm8 VectorPath
9424 ;; IMUL reg16, reg16, imm16 VectorPath
9425 ;; IMUL reg16, mem16, imm16 VectorPath
9426 ;; IMUL reg16, reg16 Direct
9427 ;; IMUL reg16, mem16 Direct
9429 ;; On BDVER1, all HI MULs use DoublePath
9431 (define_insn "*mul<mode>3_1"
9432 [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
9434 (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
9435 (match_operand:SWIM248 2 "<general_operand>" "K,<i>,<m>r")))
9436 (clobber (reg:CC FLAGS_REG))]
9437 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9439 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9440 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9441 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
9442 [(set_attr "type" "imul")
9443 (set_attr "prefix_0f" "0,0,1")
9444 (set (attr "athlon_decode")
9445 (cond [(eq_attr "cpu" "athlon")
9446 (const_string "vector")
9447 (eq_attr "alternative" "1")
9448 (const_string "vector")
9449 (and (eq_attr "alternative" "2")
9450 (ior (match_test "<MODE>mode == HImode")
9451 (match_operand 1 "memory_operand")))
9452 (const_string "vector")]
9453 (const_string "direct")))
9454 (set (attr "amdfam10_decode")
9455 (cond [(and (eq_attr "alternative" "0,1")
9456 (ior (match_test "<MODE>mode == HImode")
9457 (match_operand 1 "memory_operand")))
9458 (const_string "vector")]
9459 (const_string "direct")))
9460 (set (attr "bdver1_decode")
9462 (match_test "<MODE>mode == HImode")
9463 (const_string "double")
9464 (const_string "direct")))
9465 (set_attr "mode" "<MODE>")])
9467 (define_insn "*mulsi3_1_zext"
9468 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9470 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
9471 (match_operand:SI 2 "x86_64_general_operand" "K,e,BMr"))))
9472 (clobber (reg:CC FLAGS_REG))]
9474 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9476 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
9477 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
9478 imul{l}\t{%2, %k0|%k0, %2}"
9479 [(set_attr "type" "imul")
9480 (set_attr "prefix_0f" "0,0,1")
9481 (set (attr "athlon_decode")
9482 (cond [(eq_attr "cpu" "athlon")
9483 (const_string "vector")
9484 (eq_attr "alternative" "1")
9485 (const_string "vector")
9486 (and (eq_attr "alternative" "2")
9487 (match_operand 1 "memory_operand"))
9488 (const_string "vector")]
9489 (const_string "direct")))
9490 (set (attr "amdfam10_decode")
9491 (cond [(and (eq_attr "alternative" "0,1")
9492 (match_operand 1 "memory_operand"))
9493 (const_string "vector")]
9494 (const_string "direct")))
9495 (set_attr "bdver1_decode" "direct")
9496 (set_attr "mode" "SI")])
9498 ;;On AMDFAM10 and BDVER1
9502 (define_insn "*mulqi3_1"
9503 [(set (match_operand:QI 0 "register_operand" "=a")
9504 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9505 (match_operand:QI 2 "nonimmediate_operand" "qm")))
9506 (clobber (reg:CC FLAGS_REG))]
9508 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9510 [(set_attr "type" "imul")
9511 (set_attr "length_immediate" "0")
9512 (set (attr "athlon_decode")
9513 (if_then_else (eq_attr "cpu" "athlon")
9514 (const_string "vector")
9515 (const_string "direct")))
9516 (set_attr "amdfam10_decode" "direct")
9517 (set_attr "bdver1_decode" "direct")
9518 (set_attr "mode" "QI")])
9520 ;; Multiply with jump on overflow.
9521 (define_expand "mulv<mode>4"
9522 [(parallel [(set (reg:CCO FLAGS_REG)
9525 (match_operand:SWI248 1 "register_operand"))
9528 (mult:SWI248 (match_dup 1)
9529 (match_operand:SWI248 2
9530 "<general_operand>")))))
9531 (set (match_operand:SWI248 0 "register_operand")
9532 (mult:SWI248 (match_dup 1) (match_dup 2)))])
9533 (set (pc) (if_then_else
9534 (eq (reg:CCO FLAGS_REG) (const_int 0))
9535 (label_ref (match_operand 3))
9539 if (CONST_INT_P (operands[2]))
9540 operands[4] = operands[2];
9542 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
9545 (define_insn "*mulv<mode>4"
9546 [(set (reg:CCO FLAGS_REG)
9549 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
9551 (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
9553 (mult:SWI48 (match_dup 1) (match_dup 2)))))
9554 (set (match_operand:SWI48 0 "register_operand" "=r,r")
9555 (mult:SWI48 (match_dup 1) (match_dup 2)))]
9556 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9558 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9559 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
9560 [(set_attr "type" "imul")
9561 (set_attr "prefix_0f" "0,1")
9562 (set (attr "athlon_decode")
9563 (cond [(eq_attr "cpu" "athlon")
9564 (const_string "vector")
9565 (eq_attr "alternative" "0")
9566 (const_string "vector")
9567 (and (eq_attr "alternative" "1")
9568 (match_operand 1 "memory_operand"))
9569 (const_string "vector")]
9570 (const_string "direct")))
9571 (set (attr "amdfam10_decode")
9572 (cond [(and (eq_attr "alternative" "1")
9573 (match_operand 1 "memory_operand"))
9574 (const_string "vector")]
9575 (const_string "direct")))
9576 (set_attr "bdver1_decode" "direct")
9577 (set_attr "mode" "<MODE>")])
9579 (define_insn "*mulvhi4"
9580 [(set (reg:CCO FLAGS_REG)
9583 (match_operand:HI 1 "nonimmediate_operand" "%0"))
9585 (match_operand:HI 2 "nonimmediate_operand" "mr")))
9587 (mult:HI (match_dup 1) (match_dup 2)))))
9588 (set (match_operand:HI 0 "register_operand" "=r")
9589 (mult:HI (match_dup 1) (match_dup 2)))]
9590 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9591 "imul{w}\t{%2, %0|%0, %2}"
9592 [(set_attr "type" "imul")
9593 (set_attr "prefix_0f" "1")
9594 (set_attr "athlon_decode" "vector")
9595 (set_attr "amdfam10_decode" "direct")
9596 (set_attr "bdver1_decode" "double")
9597 (set_attr "mode" "HI")])
9599 (define_insn "*mulv<mode>4_1"
9600 [(set (reg:CCO FLAGS_REG)
9603 (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
9604 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
9606 (mult:SWI248 (match_dup 1)
9607 (match_operand:SWI248 2
9608 "<immediate_operand>" "K,<i>")))))
9609 (set (match_operand:SWI248 0 "register_operand" "=r,r")
9610 (mult:SWI248 (match_dup 1) (match_dup 2)))]
9611 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
9612 && CONST_INT_P (operands[2])
9613 && INTVAL (operands[2]) == INTVAL (operands[3])"
9614 "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
9615 [(set_attr "type" "imul")
9616 (set (attr "prefix_0f")
9618 (match_test "<MODE>mode == HImode")
9620 (const_string "*")))
9621 (set (attr "athlon_decode")
9622 (cond [(eq_attr "cpu" "athlon")
9623 (const_string "vector")
9624 (eq_attr "alternative" "1")
9625 (const_string "vector")]
9626 (const_string "direct")))
9627 (set (attr "amdfam10_decode")
9628 (cond [(ior (match_test "<MODE>mode == HImode")
9629 (match_operand 1 "memory_operand"))
9630 (const_string "vector")]
9631 (const_string "direct")))
9632 (set (attr "bdver1_decode")
9634 (match_test "<MODE>mode == HImode")
9635 (const_string "double")
9636 (const_string "direct")))
9637 (set_attr "mode" "<MODE>")
9638 (set (attr "length_immediate")
9639 (cond [(eq_attr "alternative" "0")
9641 (match_test "<MODE_SIZE> == 8")
9643 (const_string "<MODE_SIZE>")))])
9645 (define_expand "umulv<mode>4"
9646 [(parallel [(set (reg:CCO FLAGS_REG)
9649 (match_operand:SWI248 1
9650 "nonimmediate_operand"))
9652 (match_operand:SWI248 2
9653 "nonimmediate_operand")))
9655 (mult:SWI248 (match_dup 1) (match_dup 2)))))
9656 (set (match_operand:SWI248 0 "register_operand")
9657 (mult:SWI248 (match_dup 1) (match_dup 2)))
9658 (clobber (scratch:SWI248))])
9659 (set (pc) (if_then_else
9660 (eq (reg:CCO FLAGS_REG) (const_int 0))
9661 (label_ref (match_operand 3))
9665 if (MEM_P (operands[1]) && MEM_P (operands[2]))
9666 operands[1] = force_reg (<MODE>mode, operands[1]);
9669 (define_insn "*umulv<mode>4"
9670 [(set (reg:CCO FLAGS_REG)
9673 (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
9675 (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
9677 (mult:SWI248 (match_dup 1) (match_dup 2)))))
9678 (set (match_operand:SWI248 0 "register_operand" "=a")
9679 (mult:SWI248 (match_dup 1) (match_dup 2)))
9680 (clobber (match_scratch:SWI248 3 "=d"))]
9681 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9682 "mul{<imodesuffix>}\t%2"
9683 [(set_attr "type" "imul")
9684 (set_attr "length_immediate" "0")
9685 (set (attr "athlon_decode")
9686 (if_then_else (eq_attr "cpu" "athlon")
9687 (const_string "vector")
9688 (const_string "double")))
9689 (set_attr "amdfam10_decode" "double")
9690 (set_attr "bdver1_decode" "direct")
9691 (set_attr "mode" "<MODE>")])
9693 (define_expand "<u>mulvqi4"
9694 [(parallel [(set (reg:CCO FLAGS_REG)
9697 (match_operand:QI 1 "nonimmediate_operand"))
9699 (match_operand:QI 2 "nonimmediate_operand")))
9701 (mult:QI (match_dup 1) (match_dup 2)))))
9702 (set (match_operand:QI 0 "register_operand")
9703 (mult:QI (match_dup 1) (match_dup 2)))])
9704 (set (pc) (if_then_else
9705 (eq (reg:CCO FLAGS_REG) (const_int 0))
9706 (label_ref (match_operand 3))
9708 "TARGET_QIMODE_MATH"
9710 if (MEM_P (operands[1]) && MEM_P (operands[2]))
9711 operands[1] = force_reg (QImode, operands[1]);
9714 (define_insn "*<u>mulvqi4"
9715 [(set (reg:CCO FLAGS_REG)
9718 (match_operand:QI 1 "nonimmediate_operand" "%0"))
9720 (match_operand:QI 2 "nonimmediate_operand" "qm")))
9722 (mult:QI (match_dup 1) (match_dup 2)))))
9723 (set (match_operand:QI 0 "register_operand" "=a")
9724 (mult:QI (match_dup 1) (match_dup 2)))]
9726 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9727 "<sgnprefix>mul{b}\t%2"
9728 [(set_attr "type" "imul")
9729 (set_attr "length_immediate" "0")
9730 (set (attr "athlon_decode")
9731 (if_then_else (eq_attr "cpu" "athlon")
9732 (const_string "vector")
9733 (const_string "direct")))
9734 (set_attr "amdfam10_decode" "direct")
9735 (set_attr "bdver1_decode" "direct")
9736 (set_attr "mode" "QI")])
9738 (define_expand "<u>mul<mode><dwi>3"
9739 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
9742 (match_operand:DWIH 1 "register_operand"))
9744 (match_operand:DWIH 2 "nonimmediate_operand"))))
9745 (clobber (reg:CC FLAGS_REG))])])
9747 (define_expand "<u>mulqihi3"
9748 [(parallel [(set (match_operand:HI 0 "register_operand")
9751 (match_operand:QI 1 "register_operand"))
9753 (match_operand:QI 2 "nonimmediate_operand"))))
9754 (clobber (reg:CC FLAGS_REG))])]
9755 "TARGET_QIMODE_MATH")
9757 (define_insn "*bmi2_umul<mode><dwi>3_1"
9758 [(set (match_operand:DWIH 0 "register_operand" "=r")
9760 (match_operand:DWIH 2 "register_operand" "%d")
9761 (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
9762 (set (match_operand:DWIH 1 "register_operand" "=r")
9763 (umul_highpart:DWIH (match_dup 2) (match_dup 3)))]
9765 "mulx\t{%3, %0, %1|%1, %0, %3}"
9766 [(set_attr "type" "imulx")
9767 (set_attr "prefix" "vex")
9768 (set_attr "mode" "<MODE>")])
9770 ;; Tweak *bmi2_umul<mode><dwi>3_1 to eliminate following mov.
9772 [(parallel [(set (match_operand:DWIH 0 "general_reg_operand")
9773 (mult:DWIH (match_operand:DWIH 2 "register_operand")
9774 (match_operand:DWIH 3 "nonimmediate_operand")))
9775 (set (match_operand:DWIH 1 "general_reg_operand")
9776 (umul_highpart:DWIH (match_dup 2) (match_dup 3)))])
9777 (set (match_operand:DWIH 4 "general_reg_operand")
9778 (match_operand:DWIH 5 "general_reg_operand"))]
9780 && ((REGNO (operands[5]) == REGNO (operands[0])
9781 && REGNO (operands[1]) != REGNO (operands[4]))
9782 || (REGNO (operands[5]) == REGNO (operands[1])
9783 && REGNO (operands[0]) != REGNO (operands[4])))
9784 && peep2_reg_dead_p (2, operands[5])"
9785 [(parallel [(set (match_dup 0) (mult:DWIH (match_dup 2) (match_dup 3)))
9787 (umul_highpart:DWIH (match_dup 2) (match_dup 3)))])]
9789 if (REGNO (operands[5]) == REGNO (operands[0]))
9790 operands[0] = operands[4];
9792 operands[1] = operands[4];
9795 (define_insn "*umul<mode><dwi>3_1"
9796 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
9799 (match_operand:DWIH 1 "register_operand" "%d,a"))
9801 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
9802 (clobber (reg:CC FLAGS_REG))]
9803 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9806 mul{<imodesuffix>}\t%2"
9807 [(set_attr "isa" "bmi2,*")
9808 (set_attr "type" "imulx,imul")
9809 (set_attr "length_immediate" "*,0")
9810 (set (attr "athlon_decode")
9811 (cond [(eq_attr "alternative" "1")
9812 (if_then_else (eq_attr "cpu" "athlon")
9813 (const_string "vector")
9814 (const_string "double"))]
9815 (const_string "*")))
9816 (set_attr "amdfam10_decode" "*,double")
9817 (set_attr "bdver1_decode" "*,direct")
9818 (set_attr "prefix" "vex,orig")
9819 (set_attr "mode" "<MODE>")])
9821 ;; Convert mul to the mulx pattern to avoid flags dependency.
9823 [(set (match_operand:<DWI> 0 "register_operand")
9826 (match_operand:DWIH 1 "register_operand"))
9828 (match_operand:DWIH 2 "nonimmediate_operand"))))
9829 (clobber (reg:CC FLAGS_REG))]
9830 "TARGET_BMI2 && reload_completed
9831 && REGNO (operands[1]) == DX_REG"
9832 [(parallel [(set (match_dup 3)
9833 (mult:DWIH (match_dup 1) (match_dup 2)))
9835 (umul_highpart:DWIH (match_dup 1) (match_dup 2)))])]
9837 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
9839 operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
9842 (define_insn "*mul<mode><dwi>3_1"
9843 [(set (match_operand:<DWI> 0 "register_operand" "=A")
9846 (match_operand:DWIH 1 "register_operand" "%a"))
9848 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
9849 (clobber (reg:CC FLAGS_REG))]
9850 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9851 "imul{<imodesuffix>}\t%2"
9852 [(set_attr "type" "imul")
9853 (set_attr "length_immediate" "0")
9854 (set (attr "athlon_decode")
9855 (if_then_else (eq_attr "cpu" "athlon")
9856 (const_string "vector")
9857 (const_string "double")))
9858 (set_attr "amdfam10_decode" "double")
9859 (set_attr "bdver1_decode" "direct")
9860 (set_attr "mode" "<MODE>")])
9862 (define_insn "*<u>mulqihi3_1"
9863 [(set (match_operand:HI 0 "register_operand" "=a")
9866 (match_operand:QI 1 "register_operand" "%0"))
9868 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
9869 (clobber (reg:CC FLAGS_REG))]
9871 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9872 "<sgnprefix>mul{b}\t%2"
9873 [(set_attr "type" "imul")
9874 (set_attr "length_immediate" "0")
9875 (set (attr "athlon_decode")
9876 (if_then_else (eq_attr "cpu" "athlon")
9877 (const_string "vector")
9878 (const_string "direct")))
9879 (set_attr "amdfam10_decode" "direct")
9880 (set_attr "bdver1_decode" "direct")
9881 (set_attr "mode" "QI")])
9883 ;; Widening multiplication peephole2s to tweak register allocation.
9884 ;; mov imm,%rdx; mov %rdi,%rax; mulq %rdx -> mov imm,%rax; mulq %rdi
9886 [(set (match_operand:DWIH 0 "general_reg_operand")
9887 (match_operand:DWIH 1 "immediate_operand"))
9888 (set (match_operand:DWIH 2 "general_reg_operand")
9889 (match_operand:DWIH 3 "general_reg_operand"))
9890 (parallel [(set (match_operand:<DWI> 4 "general_reg_operand")
9891 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
9892 (zero_extend:<DWI> (match_dup 0))))
9893 (clobber (reg:CC FLAGS_REG))])]
9894 "REGNO (operands[3]) != AX_REG
9895 && REGNO (operands[0]) != REGNO (operands[2])
9896 && REGNO (operands[0]) != REGNO (operands[3])
9897 && (REGNO (operands[0]) == REGNO (operands[4])
9898 || REGNO (operands[0]) == DX_REG
9899 || peep2_reg_dead_p (3, operands[0]))"
9900 [(set (match_dup 2) (match_dup 1))
9901 (parallel [(set (match_dup 4)
9902 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
9903 (zero_extend:<DWI> (match_dup 3))))
9904 (clobber (reg:CC FLAGS_REG))])])
9906 ;; mov imm,%rax; mov %rdi,%rdx; mulx %rax -> mov imm,%rdx; mulx %rdi
9908 [(set (match_operand:DWIH 0 "general_reg_operand")
9909 (match_operand:DWIH 1 "immediate_operand"))
9910 (set (match_operand:DWIH 2 "general_reg_operand")
9911 (match_operand:DWIH 3 "general_reg_operand"))
9912 (parallel [(set (match_operand:DWIH 4 "general_reg_operand")
9913 (mult:DWIH (match_dup 2) (match_dup 0)))
9914 (set (match_operand:DWIH 5 "general_reg_operand")
9915 (umul_highpart:DWIH (match_dup 2) (match_dup 0)))])]
9916 "REGNO (operands[3]) != DX_REG
9917 && REGNO (operands[0]) != REGNO (operands[2])
9918 && REGNO (operands[0]) != REGNO (operands[3])
9919 && (REGNO (operands[0]) == REGNO (operands[4])
9920 || REGNO (operands[0]) == REGNO (operands[5])
9921 || peep2_reg_dead_p (3, operands[0]))"
9922 [(set (match_dup 2) (match_dup 1))
9923 (parallel [(set (match_dup 4)
9924 (mult:DWIH (match_dup 2) (match_dup 3)))
9926 (umul_highpart:DWIH (match_dup 2) (match_dup 3)))])])
9928 ;; Highpart multiplication patterns
9929 (define_insn "<s>mul<mode>3_highpart"
9930 [(set (match_operand:DWIH 0 "register_operand" "=d")
9931 (any_mul_highpart:DWIH
9932 (match_operand:DWIH 1 "register_operand" "%a")
9933 (match_operand:DWIH 2 "nonimmediate_operand" "rm")))
9934 (clobber (match_scratch:DWIH 3 "=1"))
9935 (clobber (reg:CC FLAGS_REG))]
9937 "<sgnprefix>mul{<imodesuffix>}\t%2"
9938 [(set_attr "type" "imul")
9939 (set_attr "length_immediate" "0")
9940 (set (attr "athlon_decode")
9941 (if_then_else (eq_attr "cpu" "athlon")
9942 (const_string "vector")
9943 (const_string "double")))
9944 (set_attr "amdfam10_decode" "double")
9945 (set_attr "bdver1_decode" "direct")
9946 (set_attr "mode" "<MODE>")])
9948 (define_insn "*<s>mulsi3_highpart_zext"
9949 [(set (match_operand:DI 0 "register_operand" "=d")
9951 (any_mul_highpart:SI
9952 (match_operand:SI 1 "register_operand" "%a")
9953 (match_operand:SI 2 "nonimmediate_operand" "rm"))))
9954 (clobber (match_scratch:SI 3 "=1"))
9955 (clobber (reg:CC FLAGS_REG))]
9957 "<sgnprefix>mul{l}\t%2"
9958 [(set_attr "type" "imul")
9959 (set_attr "length_immediate" "0")
9960 (set (attr "athlon_decode")
9961 (if_then_else (eq_attr "cpu" "athlon")
9962 (const_string "vector")
9963 (const_string "double")))
9964 (set_attr "amdfam10_decode" "double")
9965 (set_attr "bdver1_decode" "direct")
9966 (set_attr "mode" "SI")])
9968 (define_insn "*<s>muldi3_highpart_1"
9969 [(set (match_operand:DI 0 "register_operand" "=d")
9974 (match_operand:DI 1 "nonimmediate_operand" "%a"))
9976 (match_operand:DI 2 "nonimmediate_operand" "rm")))
9978 (clobber (match_scratch:DI 3 "=1"))
9979 (clobber (reg:CC FLAGS_REG))]
9981 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9982 "<sgnprefix>mul{q}\t%2"
9983 [(set_attr "type" "imul")
9984 (set_attr "length_immediate" "0")
9985 (set (attr "athlon_decode")
9986 (if_then_else (eq_attr "cpu" "athlon")
9987 (const_string "vector")
9988 (const_string "double")))
9989 (set_attr "amdfam10_decode" "double")
9990 (set_attr "bdver1_decode" "direct")
9991 (set_attr "mode" "DI")])
9993 (define_insn "*<s>mulsi3_highpart_zext"
9994 [(set (match_operand:DI 0 "register_operand" "=d")
9995 (zero_extend:DI (truncate:SI
9997 (mult:DI (any_extend:DI
9998 (match_operand:SI 1 "nonimmediate_operand" "%a"))
10000 (match_operand:SI 2 "nonimmediate_operand" "rm")))
10002 (clobber (match_scratch:SI 3 "=1"))
10003 (clobber (reg:CC FLAGS_REG))]
10005 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10006 "<sgnprefix>mul{l}\t%2"
10007 [(set_attr "type" "imul")
10008 (set_attr "length_immediate" "0")
10009 (set (attr "athlon_decode")
10010 (if_then_else (eq_attr "cpu" "athlon")
10011 (const_string "vector")
10012 (const_string "double")))
10013 (set_attr "amdfam10_decode" "double")
10014 (set_attr "bdver1_decode" "direct")
10015 (set_attr "mode" "SI")])
10017 (define_insn "*<s>mulsi3_highpart_1"
10018 [(set (match_operand:SI 0 "register_operand" "=d")
10023 (match_operand:SI 1 "nonimmediate_operand" "%a"))
10025 (match_operand:SI 2 "nonimmediate_operand" "rm")))
10027 (clobber (match_scratch:SI 3 "=1"))
10028 (clobber (reg:CC FLAGS_REG))]
10029 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
10030 "<sgnprefix>mul{l}\t%2"
10031 [(set_attr "type" "imul")
10032 (set_attr "length_immediate" "0")
10033 (set (attr "athlon_decode")
10034 (if_then_else (eq_attr "cpu" "athlon")
10035 (const_string "vector")
10036 (const_string "double")))
10037 (set_attr "amdfam10_decode" "double")
10038 (set_attr "bdver1_decode" "direct")
10039 (set_attr "mode" "SI")])
10041 ;; Highpart multiplication peephole2s to tweak register allocation.
10042 ;; mov imm,%rdx; mov %rdi,%rax; imulq %rdx -> mov imm,%rax; imulq %rdi
10044 [(set (match_operand:SWI48 0 "general_reg_operand")
10045 (match_operand:SWI48 1 "immediate_operand"))
10046 (set (match_operand:SWI48 2 "general_reg_operand")
10047 (match_operand:SWI48 3 "general_reg_operand"))
10048 (parallel [(set (match_operand:SWI48 4 "general_reg_operand")
10049 (any_mul_highpart:SWI48 (match_dup 2) (match_dup 0)))
10050 (clobber (match_dup 2))
10051 (clobber (reg:CC FLAGS_REG))])]
10052 "REGNO (operands[3]) != AX_REG
10053 && REGNO (operands[0]) != REGNO (operands[2])
10054 && REGNO (operands[0]) != REGNO (operands[3])
10055 && (REGNO (operands[0]) == REGNO (operands[4])
10056 || peep2_reg_dead_p (3, operands[0]))"
10057 [(set (match_dup 2) (match_dup 1))
10058 (parallel [(set (match_dup 4)
10059 (any_mul_highpart:SWI48 (match_dup 2) (match_dup 3)))
10060 (clobber (match_dup 2))
10061 (clobber (reg:CC FLAGS_REG))])])
10064 [(set (match_operand:SI 0 "general_reg_operand")
10065 (match_operand:SI 1 "immediate_operand"))
10066 (set (match_operand:SI 2 "general_reg_operand")
10067 (match_operand:SI 3 "general_reg_operand"))
10068 (parallel [(set (match_operand:DI 4 "general_reg_operand")
10070 (any_mul_highpart:SI (match_dup 2) (match_dup 0))))
10071 (clobber (match_dup 2))
10072 (clobber (reg:CC FLAGS_REG))])]
10074 && REGNO (operands[3]) != AX_REG
10075 && REGNO (operands[0]) != REGNO (operands[2])
10076 && REGNO (operands[2]) != REGNO (operands[3])
10077 && REGNO (operands[0]) != REGNO (operands[3])
10078 && (REGNO (operands[0]) == REGNO (operands[4])
10079 || peep2_reg_dead_p (3, operands[0]))"
10080 [(set (match_dup 2) (match_dup 1))
10081 (parallel [(set (match_dup 4)
10083 (any_mul_highpart:SI (match_dup 2) (match_dup 3))))
10084 (clobber (match_dup 2))
10085 (clobber (reg:CC FLAGS_REG))])])
10087 ;; The patterns that match these are at the end of this file.
10089 (define_expand "mulxf3"
10090 [(set (match_operand:XF 0 "register_operand")
10091 (mult:XF (match_operand:XF 1 "register_operand")
10092 (match_operand:XF 2 "register_operand")))]
10095 (define_expand "mulhf3"
10096 [(set (match_operand:HF 0 "register_operand")
10097 (mult:HF (match_operand:HF 1 "register_operand")
10098 (match_operand:HF 2 "nonimmediate_operand")))]
10099 "TARGET_AVX512FP16")
10101 (define_expand "mul<mode>3"
10102 [(set (match_operand:MODEF 0 "register_operand")
10103 (mult:MODEF (match_operand:MODEF 1 "register_operand")
10104 (match_operand:MODEF 2 "nonimmediate_operand")))]
10105 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
10106 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
10108 ;; Divide instructions
10110 ;; The patterns that match these are at the end of this file.
10112 (define_expand "divxf3"
10113 [(set (match_operand:XF 0 "register_operand")
10114 (div:XF (match_operand:XF 1 "register_operand")
10115 (match_operand:XF 2 "register_operand")))]
10118 /* There is no more precision loss than Newton-Rhapson approximation
10119 when using HFmode rcp/rsqrt, so do the transformation directly under
10120 TARGET_RECIP_DIV and fast-math. */
10121 (define_expand "divhf3"
10122 [(set (match_operand:HF 0 "register_operand")
10123 (div:HF (match_operand:HF 1 "register_operand")
10124 (match_operand:HF 2 "nonimmediate_operand")))]
10125 "TARGET_AVX512FP16"
10127 if (TARGET_RECIP_DIV
10128 && optimize_insn_for_speed_p ()
10129 && flag_finite_math_only && !flag_trapping_math
10130 && flag_unsafe_math_optimizations)
10132 rtx op = gen_reg_rtx (HFmode);
10133 operands[2] = force_reg (HFmode, operands[2]);
10134 emit_insn (gen_rcphf2 (op, operands[2]));
10135 emit_insn (gen_mulhf3 (operands[0], operands[1], op));
10140 (define_expand "div<mode>3"
10141 [(set (match_operand:MODEF 0 "register_operand")
10142 (div:MODEF (match_operand:MODEF 1 "register_operand")
10143 (match_operand:MODEF 2 "nonimmediate_operand")))]
10144 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
10145 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10147 if (<MODE>mode == SFmode
10148 && TARGET_SSE && TARGET_SSE_MATH
10149 && TARGET_RECIP_DIV
10150 && optimize_insn_for_speed_p ()
10151 && flag_finite_math_only && !flag_trapping_math
10152 && flag_unsafe_math_optimizations)
10154 ix86_emit_swdivsf (operands[0], operands[1],
10155 operands[2], SFmode);
10160 ;; Divmod instructions.
10162 (define_code_iterator any_div [div udiv])
10163 (define_code_attr paired_mod [(div "mod") (udiv "umod")])
10165 (define_expand "<u>divmod<mode>4"
10166 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
10168 (match_operand:SWIM248 1 "register_operand")
10169 (match_operand:SWIM248 2 "nonimmediate_operand")))
10170 (set (match_operand:SWIM248 3 "register_operand")
10171 (<paired_mod>:SWIM248 (match_dup 1) (match_dup 2)))
10172 (clobber (reg:CC FLAGS_REG))])])
10174 ;; Split with 8bit unsigned divide:
10175 ;; if (dividend an divisor are in [0-255])
10176 ;; use 8bit unsigned integer divide
10178 ;; use original integer divide
10180 [(set (match_operand:SWI48 0 "register_operand")
10181 (any_div:SWI48 (match_operand:SWI48 2 "register_operand")
10182 (match_operand:SWI48 3 "nonimmediate_operand")))
10183 (set (match_operand:SWI48 1 "register_operand")
10184 (<paired_mod>:SWI48 (match_dup 2) (match_dup 3)))
10185 (clobber (reg:CC FLAGS_REG))]
10186 "TARGET_USE_8BIT_IDIV
10187 && TARGET_QIMODE_MATH
10188 && can_create_pseudo_p ()
10189 && !optimize_insn_for_size_p ()"
10191 "ix86_split_idivmod (<MODE>mode, operands, <u_bool>); DONE;")
10194 [(set (match_operand:DI 0 "register_operand")
10196 (any_div:SI (match_operand:SI 2 "register_operand")
10197 (match_operand:SI 3 "nonimmediate_operand"))))
10198 (set (match_operand:SI 1 "register_operand")
10199 (<paired_mod>:SI (match_dup 2) (match_dup 3)))
10200 (clobber (reg:CC FLAGS_REG))]
10202 && TARGET_USE_8BIT_IDIV
10203 && TARGET_QIMODE_MATH
10204 && can_create_pseudo_p ()
10205 && !optimize_insn_for_size_p ()"
10207 "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
10210 [(set (match_operand:DI 1 "register_operand")
10212 (<paired_mod>:SI (match_operand:SI 2 "register_operand")
10213 (match_operand:SI 3 "nonimmediate_operand"))))
10214 (set (match_operand:SI 0 "register_operand")
10215 (any_div:SI (match_dup 2) (match_dup 3)))
10216 (clobber (reg:CC FLAGS_REG))]
10218 && TARGET_USE_8BIT_IDIV
10219 && TARGET_QIMODE_MATH
10220 && can_create_pseudo_p ()
10221 && !optimize_insn_for_size_p ()"
10223 "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
10225 (define_insn_and_split "divmod<mode>4_1"
10226 [(set (match_operand:SWI48 0 "register_operand" "=a")
10227 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
10228 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
10229 (set (match_operand:SWI48 1 "register_operand" "=&d")
10230 (mod:SWI48 (match_dup 2) (match_dup 3)))
10231 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10232 (clobber (reg:CC FLAGS_REG))]
10236 [(parallel [(set (match_dup 1)
10237 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
10238 (clobber (reg:CC FLAGS_REG))])
10239 (parallel [(set (match_dup 0)
10240 (div:SWI48 (match_dup 2) (match_dup 3)))
10242 (mod:SWI48 (match_dup 2) (match_dup 3)))
10243 (use (match_dup 1))
10244 (clobber (reg:CC FLAGS_REG))])]
10246 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
10248 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10249 operands[4] = operands[2];
10252 /* Avoid use of cltd in favor of a mov+shift. */
10253 emit_move_insn (operands[1], operands[2]);
10254 operands[4] = operands[1];
10257 [(set_attr "type" "multi")
10258 (set_attr "mode" "<MODE>")])
10260 (define_insn_and_split "udivmod<mode>4_1"
10261 [(set (match_operand:SWI48 0 "register_operand" "=a")
10262 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
10263 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
10264 (set (match_operand:SWI48 1 "register_operand" "=&d")
10265 (umod:SWI48 (match_dup 2) (match_dup 3)))
10266 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10267 (clobber (reg:CC FLAGS_REG))]
10271 [(set (match_dup 1) (const_int 0))
10272 (parallel [(set (match_dup 0)
10273 (udiv:SWI48 (match_dup 2) (match_dup 3)))
10275 (umod:SWI48 (match_dup 2) (match_dup 3)))
10276 (use (match_dup 1))
10277 (clobber (reg:CC FLAGS_REG))])]
10279 [(set_attr "type" "multi")
10280 (set_attr "mode" "<MODE>")])
10282 (define_insn_and_split "divmodsi4_zext_1"
10283 [(set (match_operand:DI 0 "register_operand" "=a")
10285 (div:SI (match_operand:SI 2 "register_operand" "0")
10286 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10287 (set (match_operand:SI 1 "register_operand" "=&d")
10288 (mod:SI (match_dup 2) (match_dup 3)))
10289 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10290 (clobber (reg:CC FLAGS_REG))]
10293 "&& reload_completed"
10294 [(parallel [(set (match_dup 1)
10295 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10296 (clobber (reg:CC FLAGS_REG))])
10297 (parallel [(set (match_dup 0)
10298 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
10300 (mod:SI (match_dup 2) (match_dup 3)))
10301 (use (match_dup 1))
10302 (clobber (reg:CC FLAGS_REG))])]
10304 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10306 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10307 operands[4] = operands[2];
10310 /* Avoid use of cltd in favor of a mov+shift. */
10311 emit_move_insn (operands[1], operands[2]);
10312 operands[4] = operands[1];
10315 [(set_attr "type" "multi")
10316 (set_attr "mode" "SI")])
10318 (define_insn_and_split "udivmodsi4_zext_1"
10319 [(set (match_operand:DI 0 "register_operand" "=a")
10321 (udiv:SI (match_operand:SI 2 "register_operand" "0")
10322 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10323 (set (match_operand:SI 1 "register_operand" "=&d")
10324 (umod:SI (match_dup 2) (match_dup 3)))
10325 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10326 (clobber (reg:CC FLAGS_REG))]
10329 "&& reload_completed"
10330 [(set (match_dup 1) (const_int 0))
10331 (parallel [(set (match_dup 0)
10332 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
10334 (umod:SI (match_dup 2) (match_dup 3)))
10335 (use (match_dup 1))
10336 (clobber (reg:CC FLAGS_REG))])]
10338 [(set_attr "type" "multi")
10339 (set_attr "mode" "SI")])
10341 (define_insn_and_split "divmodsi4_zext_2"
10342 [(set (match_operand:DI 1 "register_operand" "=&d")
10344 (mod:SI (match_operand:SI 2 "register_operand" "0")
10345 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10346 (set (match_operand:SI 0 "register_operand" "=a")
10347 (div:SI (match_dup 2) (match_dup 3)))
10348 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10349 (clobber (reg:CC FLAGS_REG))]
10352 "&& reload_completed"
10353 [(parallel [(set (match_dup 6)
10354 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10355 (clobber (reg:CC FLAGS_REG))])
10356 (parallel [(set (match_dup 1)
10357 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
10359 (div:SI (match_dup 2) (match_dup 3)))
10360 (use (match_dup 6))
10361 (clobber (reg:CC FLAGS_REG))])]
10363 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10364 operands[6] = gen_lowpart (SImode, operands[1]);
10366 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10367 operands[4] = operands[2];
10370 /* Avoid use of cltd in favor of a mov+shift. */
10371 emit_move_insn (operands[6], operands[2]);
10372 operands[4] = operands[6];
10375 [(set_attr "type" "multi")
10376 (set_attr "mode" "SI")])
10378 (define_insn_and_split "udivmodsi4_zext_2"
10379 [(set (match_operand:DI 1 "register_operand" "=&d")
10381 (umod:SI (match_operand:SI 2 "register_operand" "0")
10382 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10383 (set (match_operand:SI 0 "register_operand" "=a")
10384 (udiv:SI (match_dup 2) (match_dup 3)))
10385 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10386 (clobber (reg:CC FLAGS_REG))]
10389 "&& reload_completed"
10390 [(set (match_dup 4) (const_int 0))
10391 (parallel [(set (match_dup 1)
10392 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
10394 (udiv:SI (match_dup 2) (match_dup 3)))
10395 (use (match_dup 4))
10396 (clobber (reg:CC FLAGS_REG))])]
10397 "operands[4] = gen_lowpart (SImode, operands[1]);"
10398 [(set_attr "type" "multi")
10399 (set_attr "mode" "SI")])
10401 (define_insn_and_split "*divmod<mode>4"
10402 [(set (match_operand:SWIM248 0 "register_operand" "=a")
10403 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
10404 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
10405 (set (match_operand:SWIM248 1 "register_operand" "=&d")
10406 (mod:SWIM248 (match_dup 2) (match_dup 3)))
10407 (clobber (reg:CC FLAGS_REG))]
10411 [(parallel [(set (match_dup 1)
10412 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
10413 (clobber (reg:CC FLAGS_REG))])
10414 (parallel [(set (match_dup 0)
10415 (div:SWIM248 (match_dup 2) (match_dup 3)))
10417 (mod:SWIM248 (match_dup 2) (match_dup 3)))
10418 (use (match_dup 1))
10419 (clobber (reg:CC FLAGS_REG))])]
10421 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
10423 if (<MODE>mode != HImode
10424 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
10425 operands[4] = operands[2];
10428 /* Avoid use of cltd in favor of a mov+shift. */
10429 emit_move_insn (operands[1], operands[2]);
10430 operands[4] = operands[1];
10433 [(set_attr "type" "multi")
10434 (set_attr "mode" "<MODE>")])
10436 (define_insn_and_split "*udivmod<mode>4"
10437 [(set (match_operand:SWIM248 0 "register_operand" "=a")
10438 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
10439 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
10440 (set (match_operand:SWIM248 1 "register_operand" "=&d")
10441 (umod:SWIM248 (match_dup 2) (match_dup 3)))
10442 (clobber (reg:CC FLAGS_REG))]
10446 [(set (match_dup 1) (const_int 0))
10447 (parallel [(set (match_dup 0)
10448 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
10450 (umod:SWIM248 (match_dup 2) (match_dup 3)))
10451 (use (match_dup 1))
10452 (clobber (reg:CC FLAGS_REG))])]
10454 [(set_attr "type" "multi")
10455 (set_attr "mode" "<MODE>")])
10457 ;; Optimize division or modulo by constant power of 2, if the constant
10458 ;; materializes only after expansion.
10459 (define_insn_and_split "*udivmod<mode>4_pow2"
10460 [(set (match_operand:SWI48 0 "register_operand" "=r")
10461 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
10462 (match_operand:SWI48 3 "const_int_operand")))
10463 (set (match_operand:SWI48 1 "register_operand" "=r")
10464 (umod:SWI48 (match_dup 2) (match_dup 3)))
10465 (clobber (reg:CC FLAGS_REG))]
10466 "IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
10468 "&& reload_completed"
10469 [(set (match_dup 1) (match_dup 2))
10470 (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
10471 (clobber (reg:CC FLAGS_REG))])
10472 (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
10473 (clobber (reg:CC FLAGS_REG))])]
10475 int v = exact_log2 (UINTVAL (operands[3]));
10476 operands[4] = GEN_INT (v);
10477 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
10479 [(set_attr "type" "multi")
10480 (set_attr "mode" "<MODE>")])
10482 (define_insn_and_split "*divmodsi4_zext_1"
10483 [(set (match_operand:DI 0 "register_operand" "=a")
10485 (div:SI (match_operand:SI 2 "register_operand" "0")
10486 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10487 (set (match_operand:SI 1 "register_operand" "=&d")
10488 (mod:SI (match_dup 2) (match_dup 3)))
10489 (clobber (reg:CC FLAGS_REG))]
10492 "&& reload_completed"
10493 [(parallel [(set (match_dup 1)
10494 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10495 (clobber (reg:CC FLAGS_REG))])
10496 (parallel [(set (match_dup 0)
10497 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
10499 (mod:SI (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 (SImode)-1);
10505 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10506 operands[4] = operands[2];
10509 /* Avoid use of cltd in favor of a mov+shift. */
10510 emit_move_insn (operands[1], operands[2]);
10511 operands[4] = operands[1];
10514 [(set_attr "type" "multi")
10515 (set_attr "mode" "SI")])
10517 (define_insn_and_split "*udivmodsi4_zext_1"
10518 [(set (match_operand:DI 0 "register_operand" "=a")
10520 (udiv:SI (match_operand:SI 2 "register_operand" "0")
10521 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10522 (set (match_operand:SI 1 "register_operand" "=&d")
10523 (umod:SI (match_dup 2) (match_dup 3)))
10524 (clobber (reg:CC FLAGS_REG))]
10527 "&& reload_completed"
10528 [(set (match_dup 1) (const_int 0))
10529 (parallel [(set (match_dup 0)
10530 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
10532 (umod:SI (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" "SI")])
10539 (define_insn_and_split "*udivmodsi4_pow2_zext_1"
10540 [(set (match_operand:DI 0 "register_operand" "=r")
10542 (udiv:SI (match_operand:SI 2 "register_operand" "0")
10543 (match_operand:SI 3 "const_int_operand"))))
10544 (set (match_operand:SI 1 "register_operand" "=r")
10545 (umod:SI (match_dup 2) (match_dup 3)))
10546 (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)
10553 (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4))))
10554 (clobber (reg:CC FLAGS_REG))])
10555 (parallel [(set (match_dup 1) (and:SI (match_dup 1) (match_dup 5)))
10556 (clobber (reg:CC FLAGS_REG))])]
10558 int v = exact_log2 (UINTVAL (operands[3]));
10559 operands[4] = GEN_INT (v);
10560 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
10562 [(set_attr "type" "multi")
10563 (set_attr "mode" "SI")])
10565 (define_insn_and_split "*divmodsi4_zext_2"
10566 [(set (match_operand:DI 1 "register_operand" "=&d")
10568 (mod:SI (match_operand:SI 2 "register_operand" "0")
10569 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10570 (set (match_operand:SI 0 "register_operand" "=a")
10571 (div:SI (match_dup 2) (match_dup 3)))
10572 (clobber (reg:CC FLAGS_REG))]
10575 "&& reload_completed"
10576 [(parallel [(set (match_dup 6)
10577 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10578 (clobber (reg:CC FLAGS_REG))])
10579 (parallel [(set (match_dup 1)
10580 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
10582 (div:SI (match_dup 2) (match_dup 3)))
10583 (use (match_dup 6))
10584 (clobber (reg:CC FLAGS_REG))])]
10586 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10587 operands[6] = gen_lowpart (SImode, operands[1]);
10589 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10590 operands[4] = operands[2];
10593 /* Avoid use of cltd in favor of a mov+shift. */
10594 emit_move_insn (operands[6], operands[2]);
10595 operands[4] = operands[6];
10598 [(set_attr "type" "multi")
10599 (set_attr "mode" "SI")])
10601 (define_insn_and_split "*udivmodsi4_zext_2"
10602 [(set (match_operand:DI 1 "register_operand" "=&d")
10604 (umod:SI (match_operand:SI 2 "register_operand" "0")
10605 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10606 (set (match_operand:SI 0 "register_operand" "=a")
10607 (udiv:SI (match_dup 2) (match_dup 3)))
10608 (clobber (reg:CC FLAGS_REG))]
10611 "&& reload_completed"
10612 [(set (match_dup 4) (const_int 0))
10613 (parallel [(set (match_dup 1)
10614 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
10616 (udiv:SI (match_dup 2) (match_dup 3)))
10617 (use (match_dup 4))
10618 (clobber (reg:CC FLAGS_REG))])]
10619 "operands[4] = gen_lowpart (SImode, operands[1]);"
10620 [(set_attr "type" "multi")
10621 (set_attr "mode" "SI")])
10623 (define_insn_and_split "*udivmodsi4_pow2_zext_2"
10624 [(set (match_operand:DI 1 "register_operand" "=r")
10626 (umod:SI (match_operand:SI 2 "register_operand" "0")
10627 (match_operand:SI 3 "const_int_operand"))))
10628 (set (match_operand:SI 0 "register_operand" "=r")
10629 (udiv:SI (match_dup 2) (match_dup 3)))
10630 (clobber (reg:CC FLAGS_REG))]
10632 && IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
10634 "&& reload_completed"
10635 [(set (match_dup 1) (match_dup 2))
10636 (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4)))
10637 (clobber (reg:CC FLAGS_REG))])
10638 (parallel [(set (match_dup 1)
10639 (zero_extend:DI (and:SI (match_dup 1) (match_dup 5))))
10640 (clobber (reg:CC FLAGS_REG))])]
10642 int v = exact_log2 (UINTVAL (operands[3]));
10643 operands[4] = GEN_INT (v);
10644 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
10646 [(set_attr "type" "multi")
10647 (set_attr "mode" "SI")])
10649 (define_insn "*<u>divmod<mode>4_noext"
10650 [(set (match_operand:SWIM248 0 "register_operand" "=a")
10652 (match_operand:SWIM248 2 "register_operand" "0")
10653 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
10654 (set (match_operand:SWIM248 1 "register_operand" "=d")
10655 (<paired_mod>:SWIM248 (match_dup 2) (match_dup 3)))
10656 (use (match_operand:SWIM248 4 "register_operand" "1"))
10657 (clobber (reg:CC FLAGS_REG))]
10659 "<sgnprefix>div{<imodesuffix>}\t%3"
10660 [(set_attr "type" "idiv")
10661 (set_attr "mode" "<MODE>")])
10663 (define_insn "*<u>divmodsi4_noext_zext_1"
10664 [(set (match_operand:DI 0 "register_operand" "=a")
10666 (any_div:SI (match_operand:SI 2 "register_operand" "0")
10667 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10668 (set (match_operand:SI 1 "register_operand" "=d")
10669 (<paired_mod>:SI (match_dup 2) (match_dup 3)))
10670 (use (match_operand:SI 4 "register_operand" "1"))
10671 (clobber (reg:CC FLAGS_REG))]
10673 "<sgnprefix>div{l}\t%3"
10674 [(set_attr "type" "idiv")
10675 (set_attr "mode" "SI")])
10677 (define_insn "*<u>divmodsi4_noext_zext_2"
10678 [(set (match_operand:DI 1 "register_operand" "=d")
10680 (<paired_mod>:SI (match_operand:SI 2 "register_operand" "0")
10681 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10682 (set (match_operand:SI 0 "register_operand" "=a")
10683 (any_div:SI (match_dup 2) (match_dup 3)))
10684 (use (match_operand:SI 4 "register_operand" "1"))
10685 (clobber (reg:CC FLAGS_REG))]
10687 "<sgnprefix>div{l}\t%3"
10688 [(set_attr "type" "idiv")
10689 (set_attr "mode" "SI")])
10691 ;; Avoid sign-extension (using cdq) for constant numerators.
10692 (define_insn_and_split "*divmodsi4_const"
10693 [(set (match_operand:SI 0 "register_operand" "=&a")
10694 (div:SI (match_operand:SI 2 "const_int_operand")
10695 (match_operand:SI 3 "nonimmediate_operand" "rm")))
10696 (set (match_operand:SI 1 "register_operand" "=&d")
10697 (mod:SI (match_dup 2) (match_dup 3)))
10698 (clobber (reg:CC FLAGS_REG))]
10699 "!optimize_function_for_size_p (cfun)"
10701 "&& reload_completed"
10702 [(set (match_dup 0) (match_dup 2))
10703 (set (match_dup 1) (match_dup 4))
10704 (parallel [(set (match_dup 0)
10705 (div:SI (match_dup 0) (match_dup 3)))
10707 (mod:SI (match_dup 0) (match_dup 3)))
10708 (use (match_dup 1))
10709 (clobber (reg:CC FLAGS_REG))])]
10711 operands[4] = INTVAL (operands[2]) < 0 ? constm1_rtx : const0_rtx;
10713 [(set_attr "type" "multi")
10714 (set_attr "mode" "SI")])
10716 (define_expand "divmodqi4"
10717 [(parallel [(set (match_operand:QI 0 "register_operand")
10719 (match_operand:QI 1 "register_operand")
10720 (match_operand:QI 2 "nonimmediate_operand")))
10721 (set (match_operand:QI 3 "register_operand")
10722 (mod:QI (match_dup 1) (match_dup 2)))
10723 (clobber (reg:CC FLAGS_REG))])]
10724 "TARGET_QIMODE_MATH"
10729 tmp0 = gen_reg_rtx (HImode);
10730 tmp1 = gen_reg_rtx (HImode);
10732 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
10733 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
10734 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
10736 /* Extract remainder from AH. */
10737 tmp1 = gen_rtx_ZERO_EXTRACT (HImode, tmp0, GEN_INT (8), GEN_INT (8));
10738 tmp1 = lowpart_subreg (QImode, tmp1, HImode);
10739 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
10741 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
10742 set_unique_reg_note (insn, REG_EQUAL, mod);
10744 /* Extract quotient from AL. */
10745 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
10747 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
10748 set_unique_reg_note (insn, REG_EQUAL, div);
10753 (define_expand "udivmodqi4"
10754 [(parallel [(set (match_operand:QI 0 "register_operand")
10756 (match_operand:QI 1 "register_operand")
10757 (match_operand:QI 2 "nonimmediate_operand")))
10758 (set (match_operand:QI 3 "register_operand")
10759 (umod:QI (match_dup 1) (match_dup 2)))
10760 (clobber (reg:CC FLAGS_REG))])]
10761 "TARGET_QIMODE_MATH"
10766 tmp0 = gen_reg_rtx (HImode);
10767 tmp1 = gen_reg_rtx (HImode);
10769 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
10770 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
10771 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
10773 /* Extract remainder from AH. */
10774 tmp1 = gen_rtx_ZERO_EXTRACT (HImode, tmp0, GEN_INT (8), GEN_INT (8));
10775 tmp1 = lowpart_subreg (QImode, tmp1, HImode);
10776 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
10778 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
10779 set_unique_reg_note (insn, REG_EQUAL, mod);
10781 /* Extract quotient from AL. */
10782 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
10784 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
10785 set_unique_reg_note (insn, REG_EQUAL, div);
10790 ;; Divide AX by r/m8, with result stored in
10793 ;; Change div/mod to HImode and extend the second argument to HImode
10794 ;; so that mode of div/mod matches with mode of arguments. Otherwise
10795 ;; combine may fail.
10796 (define_insn "<u>divmodhiqi3"
10797 [(set (match_operand:HI 0 "register_operand" "=a")
10802 (mod:HI (match_operand:HI 1 "register_operand" "0")
10804 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
10808 (div:HI (match_dup 1) (any_extend:HI (match_dup 2)))))))
10809 (clobber (reg:CC FLAGS_REG))]
10810 "TARGET_QIMODE_MATH"
10811 "<sgnprefix>div{b}\t%2"
10812 [(set_attr "type" "idiv")
10813 (set_attr "mode" "QI")])
10815 ;; We cannot use div/idiv for double division, because it causes
10816 ;; "division by zero" on the overflow and that's not what we expect
10817 ;; from truncate. Because true (non truncating) double division is
10818 ;; never generated, we can't create this insn anyway.
10821 ; [(set (match_operand:SI 0 "register_operand" "=a")
10823 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
10825 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
10826 ; (set (match_operand:SI 3 "register_operand" "=d")
10828 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
10829 ; (clobber (reg:CC FLAGS_REG))]
10831 ; "div{l}\t{%2, %0|%0, %2}"
10832 ; [(set_attr "type" "idiv")])
10834 ;;- Logical AND instructions
10836 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
10837 ;; Note that this excludes ah.
10839 (define_expand "@test<mode>_ccno_1"
10840 [(set (reg:CCNO FLAGS_REG)
10843 (match_operand:SWI48 0 "nonimmediate_operand")
10844 (match_operand:SWI48 1 "<nonmemory_szext_operand>"))
10847 (define_expand "testqi_ccz_1"
10848 [(set (reg:CCZ FLAGS_REG)
10851 (match_operand:QI 0 "nonimmediate_operand")
10852 (match_operand:QI 1 "nonmemory_operand"))
10855 (define_insn "*testdi_1"
10856 [(set (reg FLAGS_REG)
10859 (match_operand:DI 0 "nonimmediate_operand" "%r,rm")
10860 (match_operand:DI 1 "x86_64_szext_nonmemory_operand" "Z,re"))
10863 && ix86_match_ccmode
10865 /* If we are going to emit testl instead of testq, and the operands[1]
10866 constant might have the SImode sign bit set, make sure the sign
10867 flag isn't tested, because the instruction will set the sign flag
10868 based on bit 31 rather than bit 63. If it isn't CONST_INT,
10869 conservatively assume it might have bit 31 set. */
10870 (satisfies_constraint_Z (operands[1])
10871 && (!CONST_INT_P (operands[1])
10872 || val_signbit_known_set_p (SImode, INTVAL (operands[1]))))
10873 ? CCZmode : CCNOmode)"
10875 test{l}\t{%k1, %k0|%k0, %k1}
10876 test{q}\t{%1, %0|%0, %1}"
10877 [(set_attr "type" "test")
10878 (set_attr "mode" "SI,DI")])
10880 (define_insn "*testqi_1_maybe_si"
10881 [(set (reg FLAGS_REG)
10884 (match_operand:QI 0 "nonimmediate_operand" "%qm,qm,r")
10885 (match_operand:QI 1 "nonmemory_operand" "q,n,n"))
10887 "ix86_match_ccmode (insn,
10888 CONST_INT_P (operands[1])
10889 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
10891 if (get_attr_mode (insn) == MODE_SI)
10893 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
10894 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
10895 return "test{l}\t{%1, %k0|%k0, %1}";
10897 return "test{b}\t{%1, %0|%0, %1}";
10899 [(set_attr "type" "test")
10901 (cond [(eq_attr "alternative" "2")
10902 (const_string "SI")
10903 (and (match_test "optimize_insn_for_size_p ()")
10904 (and (match_operand 0 "ext_QIreg_operand")
10905 (match_operand 1 "const_0_to_127_operand")))
10906 (const_string "SI")
10908 (const_string "QI")))
10909 (set_attr "pent_pair" "uv,np,np")])
10911 (define_insn "*test<mode>_1"
10912 [(set (reg FLAGS_REG)
10915 (match_operand:SWI124 0 "nonimmediate_operand" "%<r>m,*a,<r>m")
10916 (match_operand:SWI124 1 "<nonmemory_szext_operand>" "<r>,<i>,<i>"))
10918 "ix86_match_ccmode (insn, CCNOmode)"
10919 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
10920 [(set_attr "type" "test")
10921 (set_attr "mode" "<MODE>")
10922 (set_attr "pent_pair" "uv,uv,np")])
10924 (define_expand "testqi_ext_1_ccno"
10925 [(set (reg:CCNO FLAGS_REG)
10930 (match_operand:HI 0 "register_operand")
10933 (match_operand:QI 1 "const_int_operand"))
10936 (define_insn "*testqi_ext<mode>_1"
10937 [(set (reg FLAGS_REG)
10941 (match_operator:SWI248 2 "extract_operator"
10942 [(match_operand 0 "int248_register_operand" "Q")
10945 (match_operand:QI 1 "general_operand" "QnBn"))
10947 "ix86_match_ccmode (insn, CCNOmode)"
10948 "test{b}\t{%1, %h0|%h0, %1}"
10949 [(set_attr "addr" "gpr8")
10950 (set_attr "type" "test")
10951 (set_attr "mode" "QI")])
10953 (define_insn "*testqi_ext<mode>_2"
10954 [(set (reg FLAGS_REG)
10958 (match_operator:SWI248 2 "extract_operator"
10959 [(match_operand 0 "int248_register_operand" "Q")
10963 (match_operator:SWI248 3 "extract_operator"
10964 [(match_operand 1 "int248_register_operand" "Q")
10966 (const_int 8)]) 0))
10968 "ix86_match_ccmode (insn, CCNOmode)"
10969 "test{b}\t{%h1, %h0|%h0, %h1}"
10970 [(set_attr "type" "test")
10971 (set_attr "mode" "QI")])
10973 ;; Provide a *testti instruction that STV can implement using ptest.
10974 ;; This pattern splits into *andti3_doubleword and *cmpti_doubleword.
10975 (define_insn_and_split "*testti_doubleword"
10976 [(set (reg:CCZ FLAGS_REG)
10978 (and:TI (match_operand:TI 0 "register_operand")
10979 (match_operand:TI 1 "general_operand"))
10982 && ix86_pre_reload_split ()"
10985 [(parallel [(set (match_dup 2) (and:TI (match_dup 0) (match_dup 1)))
10986 (clobber (reg:CC FLAGS_REG))])
10987 (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 2) (const_int 0)))]
10989 operands[2] = gen_reg_rtx (TImode);
10990 if (!x86_64_hilo_general_operand (operands[1], TImode))
10991 operands[1] = force_reg (TImode, operands[1]);
10994 ;; Combine likes to form bit extractions for some tests. Humor it.
10995 (define_insn_and_split "*testqi_ext_3"
10996 [(set (match_operand 0 "flags_reg_operand")
10997 (match_operator 1 "compare_operator"
10998 [(zero_extract:SWI248
10999 (match_operand 2 "int_nonimmediate_operand" "rm")
11000 (match_operand:QI 3 "const_int_operand")
11001 (match_operand:QI 4 "const_int_operand"))
11003 "/* Ensure that resulting mask is zero or sign extended operand. */
11004 INTVAL (operands[4]) >= 0
11005 && ((INTVAL (operands[3]) > 0
11006 && INTVAL (operands[3]) + INTVAL (operands[4]) <= 32)
11007 || (<MODE>mode == DImode
11008 && INTVAL (operands[3]) > 32
11009 && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))
11010 && ix86_match_ccmode (insn,
11011 /* If zero_extract mode precision is the same
11012 as len, the SF of the zero_extract
11013 comparison will be the most significant
11014 extracted bit, but this could be matched
11015 after splitting only for pos 0 len all bits
11016 trivial extractions. Require CCZmode. */
11017 (GET_MODE_PRECISION (<MODE>mode)
11018 == INTVAL (operands[3]))
11019 /* Otherwise, require CCZmode if we'd use a mask
11020 with the most significant bit set and can't
11021 widen it to wider mode. *testdi_1 also
11022 requires CCZmode if the mask has bit
11023 31 set and all bits above it clear. */
11024 || (INTVAL (operands[3]) + INTVAL (operands[4])
11026 /* We can't widen also if val is not a REG. */
11027 || (INTVAL (operands[3]) + INTVAL (operands[4])
11028 == GET_MODE_PRECISION (GET_MODE (operands[2]))
11029 && !register_operand (operands[2],
11030 GET_MODE (operands[2])))
11031 /* And we shouldn't widen if
11032 TARGET_PARTIAL_REG_STALL. */
11033 || (TARGET_PARTIAL_REG_STALL
11034 && (INTVAL (operands[3]) + INTVAL (operands[4])
11035 >= (paradoxical_subreg_p (operands[2])
11037 (GET_MODE (SUBREG_REG (operands[2])))
11039 ? GET_MODE_PRECISION
11040 (GET_MODE (SUBREG_REG (operands[2])))
11041 : GET_MODE_PRECISION
11042 (GET_MODE (operands[2])))))
11043 ? CCZmode : CCNOmode)"
11046 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11048 rtx val = operands[2];
11049 HOST_WIDE_INT len = INTVAL (operands[3]);
11050 HOST_WIDE_INT pos = INTVAL (operands[4]);
11051 machine_mode mode = GET_MODE (val);
11053 if (SUBREG_P (val))
11055 machine_mode submode = GET_MODE (SUBREG_REG (val));
11057 /* Narrow paradoxical subregs to prevent partial register stalls. */
11058 if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)
11059 && GET_MODE_CLASS (submode) == MODE_INT
11060 && (GET_MODE (operands[0]) == CCZmode
11061 || pos + len < GET_MODE_PRECISION (submode)
11062 || REG_P (SUBREG_REG (val))))
11064 val = SUBREG_REG (val);
11069 /* Small HImode tests can be converted to QImode. */
11071 && register_operand (val, HImode))
11073 rtx nval = gen_lowpart (QImode, val);
11075 || GET_MODE (operands[0]) == CCZmode
11083 gcc_assert (pos + len <= GET_MODE_PRECISION (mode));
11085 /* If the mask is going to have the sign bit set in the mode
11086 we want to do the comparison in and user isn't interested just
11087 in the zero flag, then we must widen the target mode. */
11088 if (pos + len == GET_MODE_PRECISION (mode)
11089 && GET_MODE (operands[0]) != CCZmode)
11091 gcc_assert (pos + len < 32 && !MEM_P (val));
11093 val = gen_lowpart (mode, val);
11097 = wi::shifted_mask (pos, len, false, GET_MODE_PRECISION (mode));
11099 operands[2] = gen_rtx_AND (mode, val, immed_wide_int_const (mask, mode));
11102 ;; Split and;cmp (as optimized by combine) into not;test
11103 ;; Except when TARGET_BMI provides andn (*andn_<mode>_ccno).
11104 (define_insn_and_split "*test<mode>_not"
11105 [(set (reg:CCZ FLAGS_REG)
11108 (not:SWI (match_operand:SWI 0 "register_operand"))
11109 (match_operand:SWI 1 "<nonmemory_szext_operand>"))
11111 "ix86_pre_reload_split ()
11112 && (!TARGET_BMI || !REG_P (operands[1]))"
11115 [(set (match_dup 2) (not:SWI (match_dup 0)))
11116 (set (reg:CCZ FLAGS_REG)
11117 (compare:CCZ (and:SWI (match_dup 2) (match_dup 1))
11119 "operands[2] = gen_reg_rtx (<MODE>mode);")
11121 ;; Split and;cmp (as optimized by combine) into andn;cmp $0
11122 (define_insn_and_split "*test<mode>_not_doubleword"
11123 [(set (reg:CCZ FLAGS_REG)
11126 (not:DWI (match_operand:DWI 0 "nonimmediate_operand"))
11127 (match_operand:DWI 1 "nonimmediate_operand"))
11129 "ix86_pre_reload_split ()"
11133 [(set (match_dup 2) (and:DWI (not:DWI (match_dup 0)) (match_dup 1)))
11134 (clobber (reg:CC FLAGS_REG))])
11135 (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 2) (const_int 0)))]
11137 operands[0] = force_reg (<MODE>mode, operands[0]);
11138 operands[2] = gen_reg_rtx (<MODE>mode);
11141 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
11142 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
11143 ;; this is relatively important trick.
11144 ;; Do the conversion only post-reload to avoid limiting of the register class
11147 [(set (match_operand 0 "flags_reg_operand")
11148 (match_operator 1 "compare_operator"
11149 [(and (match_operand 2 "QIreg_operand")
11150 (match_operand 3 "const_int_operand"))
11153 && GET_MODE (operands[2]) != QImode
11154 && ((ix86_match_ccmode (insn, CCZmode)
11155 && !(INTVAL (operands[3]) & ~(255 << 8)))
11156 || (ix86_match_ccmode (insn, CCNOmode)
11157 && !(INTVAL (operands[3]) & ~(127 << 8))))"
11158 [(set (match_dup 0)
11162 (zero_extract:HI (match_dup 2)
11168 operands[2] = gen_lowpart (HImode, operands[2]);
11169 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, QImode);
11173 [(set (match_operand 0 "flags_reg_operand")
11174 (match_operator 1 "compare_operator"
11175 [(and (match_operand 2 "nonimmediate_operand")
11176 (match_operand 3 "const_int_operand"))
11179 && GET_MODE (operands[2]) != QImode
11180 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
11181 && ((ix86_match_ccmode (insn, CCZmode)
11182 && !(INTVAL (operands[3]) & ~255))
11183 || (ix86_match_ccmode (insn, CCNOmode)
11184 && !(INTVAL (operands[3]) & ~127)))"
11185 [(set (match_dup 0)
11186 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
11189 operands[2] = gen_lowpart (QImode, operands[2]);
11190 operands[3] = gen_int_mode (INTVAL (operands[3]), QImode);
11193 ;; Narrow test instructions with immediate operands that test
11194 ;; memory locations for zero. E.g. testl $0x00aa0000, mem can be
11195 ;; converted to testb $0xaa, mem+2. Reject volatile locations and
11196 ;; targets where reading (possibly unaligned) part of memory
11197 ;; location after a large write to the same address causes
11198 ;; store-to-load forwarding stall.
11200 [(set (reg:CCZ FLAGS_REG)
11202 (and:SWI248 (match_operand:SWI248 0 "memory_operand")
11203 (match_operand 1 "const_int_operand"))
11205 "!TARGET_PARTIAL_MEMORY_READ_STALL && !MEM_VOLATILE_P (operands[0])"
11206 [(set (reg:CCZ FLAGS_REG)
11207 (compare:CCZ (match_dup 2) (const_int 0)))]
11209 unsigned HOST_WIDE_INT ival = UINTVAL (operands[1]);
11210 int first_nonzero_byte, bitsize;
11211 rtx new_addr, new_const;
11212 machine_mode new_mode;
11217 /* Clear bits outside mode width. */
11218 ival &= GET_MODE_MASK (<MODE>mode);
11220 first_nonzero_byte = ctz_hwi (ival) / BITS_PER_UNIT;
11222 ival >>= first_nonzero_byte * BITS_PER_UNIT;
11224 bitsize = sizeof (ival) * BITS_PER_UNIT - clz_hwi (ival);
11226 if (bitsize <= GET_MODE_BITSIZE (QImode))
11228 else if (bitsize <= GET_MODE_BITSIZE (HImode))
11230 else if (bitsize <= GET_MODE_BITSIZE (SImode))
11235 if (GET_MODE_SIZE (new_mode) >= GET_MODE_SIZE (<MODE>mode))
11238 new_addr = adjust_address (operands[0], new_mode, first_nonzero_byte);
11239 new_const = gen_int_mode (ival, new_mode);
11241 operands[2] = gen_rtx_AND (new_mode, new_addr, new_const);
11244 ;; %%% This used to optimize known byte-wide and operations to memory,
11245 ;; and sometimes to QImode registers. If this is considered useful,
11246 ;; it should be done with splitters.
11248 (define_expand "and<mode>3"
11249 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
11250 (and:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
11251 (match_operand:SDWIM 2 "<general_szext_operand>")))]
11254 machine_mode mode = <MODE>mode;
11256 if (GET_MODE_SIZE (<MODE>mode) > UNITS_PER_WORD
11257 && !x86_64_hilo_general_operand (operands[2], <MODE>mode))
11258 operands[2] = force_reg (<MODE>mode, operands[2]);
11260 if (GET_MODE_SIZE (<MODE>mode) <= UNITS_PER_WORD
11261 && const_int_operand (operands[2], <MODE>mode)
11262 && register_operand (operands[0], <MODE>mode)
11263 && !(TARGET_ZERO_EXTEND_WITH_AND
11264 && optimize_function_for_speed_p (cfun)))
11266 unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
11268 if (ival == GET_MODE_MASK (SImode))
11270 else if (ival == GET_MODE_MASK (HImode))
11272 else if (ival == GET_MODE_MASK (QImode))
11276 if (mode != <MODE>mode)
11277 emit_insn (gen_extend_insn
11278 (operands[0], gen_lowpart (mode, operands[1]),
11279 <MODE>mode, mode, 1));
11281 ix86_expand_binary_operator (AND, <MODE>mode, operands);
11286 (define_insn_and_split "*and<dwi>3_doubleword"
11287 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
11289 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
11290 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
11291 (clobber (reg:CC FLAGS_REG))]
11292 "ix86_binary_operator_ok (AND, <DWI>mode, operands)"
11294 "&& reload_completed"
11295 [(const_int:DWIH 0)]
11297 bool emit_insn_deleted_note_p = false;
11299 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
11301 if (operands[2] == const0_rtx)
11302 emit_move_insn (operands[0], const0_rtx);
11303 else if (operands[2] == constm1_rtx)
11304 emit_insn_deleted_note_p = true;
11306 ix86_expand_binary_operator (AND, <MODE>mode, &operands[0]);
11308 if (operands[5] == const0_rtx)
11309 emit_move_insn (operands[3], const0_rtx);
11310 else if (operands[5] == constm1_rtx)
11312 if (emit_insn_deleted_note_p)
11313 emit_note (NOTE_INSN_DELETED);
11316 ix86_expand_binary_operator (AND, <MODE>mode, &operands[3]);
11321 (define_insn "*anddi_1"
11322 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,?k")
11324 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
11325 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m,L,k")))
11326 (clobber (reg:CC FLAGS_REG))]
11327 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
11329 and{l}\t{%k2, %k0|%k0, %k2}
11330 and{q}\t{%2, %0|%0, %2}
11331 and{q}\t{%2, %0|%0, %2}
11334 [(set_attr "isa" "x64,x64,x64,x64,avx512bw_512")
11335 (set_attr "type" "alu,alu,alu,imovx,msklog")
11336 (set_attr "length_immediate" "*,*,*,0,*")
11337 (set (attr "prefix_rex")
11339 (and (eq_attr "type" "imovx")
11340 (and (match_test "INTVAL (operands[2]) == 0xff")
11341 (match_operand 1 "ext_QIreg_operand")))
11343 (const_string "*")))
11344 (set_attr "mode" "SI,DI,DI,SI,DI")])
11346 (define_insn_and_split "*anddi_1_btr"
11347 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11349 (match_operand:DI 1 "nonimmediate_operand" "%0")
11350 (match_operand:DI 2 "const_int_operand" "n")))
11351 (clobber (reg:CC FLAGS_REG))]
11352 "TARGET_64BIT && TARGET_USE_BT
11353 && ix86_binary_operator_ok (AND, DImode, operands)
11354 && IN_RANGE (exact_log2 (~INTVAL (operands[2])), 31, 63)"
11356 "&& reload_completed"
11357 [(parallel [(set (zero_extract:DI (match_dup 0)
11361 (clobber (reg:CC FLAGS_REG))])]
11362 "operands[3] = GEN_INT (exact_log2 (~INTVAL (operands[2])));"
11363 [(set_attr "type" "alu1")
11364 (set_attr "prefix_0f" "1")
11365 (set_attr "znver1_decode" "double")
11366 (set_attr "mode" "DI")])
11368 ;; Turn *anddi_1 into *andsi_1_zext if possible.
11370 [(set (match_operand:DI 0 "register_operand")
11371 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
11372 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
11373 (clobber (reg:CC FLAGS_REG))]
11375 [(parallel [(set (match_dup 0)
11376 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
11377 (clobber (reg:CC FLAGS_REG))])]
11379 if (GET_CODE (operands[2]) == SYMBOL_REF
11380 || GET_CODE (operands[2]) == LABEL_REF)
11382 operands[2] = shallow_copy_rtx (operands[2]);
11383 PUT_MODE (operands[2], SImode);
11385 else if (GET_CODE (operands[2]) == CONST)
11387 /* (const:DI (plus:DI (symbol_ref:DI ("...")) (const_int N))) */
11388 operands[2] = copy_rtx (operands[2]);
11389 PUT_MODE (operands[2], SImode);
11390 PUT_MODE (XEXP (operands[2], 0), SImode);
11391 PUT_MODE (XEXP (XEXP (operands[2], 0), 0), SImode);
11394 operands[2] = gen_lowpart (SImode, operands[2]);
11397 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
11398 (define_insn "*andsi_1_zext"
11399 [(set (match_operand:DI 0 "register_operand" "=r")
11401 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
11402 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
11403 (clobber (reg:CC FLAGS_REG))]
11404 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
11405 "and{l}\t{%2, %k0|%k0, %2}"
11406 [(set_attr "type" "alu")
11407 (set_attr "mode" "SI")])
11409 (define_insn "*and<mode>_1"
11410 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya,?k")
11411 (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm,k")
11412 (match_operand:SWI24 2 "<general_operand>" "r<i>,<m>,L,k")))
11413 (clobber (reg:CC FLAGS_REG))]
11414 "ix86_binary_operator_ok (AND, <MODE>mode, operands)"
11416 and{<imodesuffix>}\t{%2, %0|%0, %2}
11417 and{<imodesuffix>}\t{%2, %0|%0, %2}
11421 (cond [(eq_attr "alternative" "3")
11422 (if_then_else (eq_attr "mode" "SI")
11423 (const_string "avx512bw")
11424 (const_string "avx512f"))
11426 (const_string "*")))
11427 (set_attr "type" "alu,alu,imovx,msklog")
11428 (set_attr "length_immediate" "*,*,0,*")
11429 (set (attr "prefix_rex")
11431 (and (eq_attr "type" "imovx")
11432 (and (match_test "INTVAL (operands[2]) == 0xff")
11433 (match_operand 1 "ext_QIreg_operand")))
11435 (const_string "*")))
11436 (set_attr "mode" "<MODE>,<MODE>,SI,<MODE>")])
11438 (define_insn "*andqi_1"
11439 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,?k")
11440 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
11441 (match_operand:QI 2 "general_operand" "qn,m,rn,k")))
11442 (clobber (reg:CC FLAGS_REG))]
11443 "ix86_binary_operator_ok (AND, QImode, operands)"
11445 and{b}\t{%2, %0|%0, %2}
11446 and{b}\t{%2, %0|%0, %2}
11447 and{l}\t{%k2, %k0|%k0, %k2}
11449 [(set_attr "type" "alu,alu,alu,msklog")
11451 (cond [(eq_attr "alternative" "2")
11452 (const_string "SI")
11453 (and (eq_attr "alternative" "3")
11454 (match_test "!TARGET_AVX512DQ"))
11455 (const_string "HI")
11457 (const_string "QI")))
11458 ;; Potential partial reg stall on alternative 2.
11459 (set (attr "preferred_for_speed")
11460 (cond [(eq_attr "alternative" "2")
11461 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
11462 (symbol_ref "true")))])
11464 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
11465 (define_insn_and_split "*<code><mode>_1_slp"
11466 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
11467 (any_logic:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0,!<r>")
11468 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
11469 (clobber (reg:CC FLAGS_REG))]
11470 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
11472 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
11474 "&& reload_completed
11475 && !(rtx_equal_p (operands[0], operands[1])
11476 || rtx_equal_p (operands[0], operands[2]))"
11477 [(set (strict_low_part (match_dup 0)) (match_dup 1))
11479 [(set (strict_low_part (match_dup 0))
11480 (any_logic:SWI12 (match_dup 0) (match_dup 2)))
11481 (clobber (reg:CC FLAGS_REG))])]
11483 [(set_attr "type" "alu")
11484 (set_attr "mode" "<MODE>")])
11486 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
11487 (define_insn_and_split "*<code>qi_ext<mode>_1_slp"
11488 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+Q,&Q"))
11491 (match_operator:SWI248 3 "extract_operator"
11492 [(match_operand 2 "int248_register_operand" "Q,Q")
11495 (match_operand:QI 1 "nonimmediate_operand" "0,!qm")))
11496 (clobber (reg:CC FLAGS_REG))]
11497 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
11499 <logic>{b}\t{%h2, %0|%0, %h2}
11501 "&& reload_completed
11502 && !rtx_equal_p (operands[0], operands[1])"
11503 [(set (strict_low_part (match_dup 0)) (match_dup 1))
11505 [(set (strict_low_part (match_dup 0))
11509 [(match_dup 2) (const_int 8) (const_int 8)]) 0)))
11511 (clobber (reg:CC FLAGS_REG))])]
11513 [(set_attr "type" "alu")
11514 (set_attr "mode" "QI")])
11517 [(set (match_operand:SWI248 0 "register_operand")
11518 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
11519 (match_operand:SWI248 2 "const_int_operand")))
11520 (clobber (reg:CC FLAGS_REG))]
11522 && (!REG_P (operands[1])
11523 || REGNO (operands[0]) != REGNO (operands[1]))"
11526 unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
11529 if (ival == GET_MODE_MASK (SImode))
11531 else if (ival == GET_MODE_MASK (HImode))
11533 else if (ival == GET_MODE_MASK (QImode))
11536 gcc_unreachable ();
11538 /* Zero extend to SImode to avoid partial register stalls. */
11539 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
11540 operands[0] = gen_lowpart (SImode, operands[0]);
11542 emit_insn (gen_extend_insn
11543 (operands[0], gen_lowpart (mode, operands[1]),
11544 GET_MODE (operands[0]), mode, 1));
11549 [(set (match_operand:SWI48 0 "register_operand")
11550 (and:SWI48 (match_dup 0)
11551 (const_int -65536)))
11552 (clobber (reg:CC FLAGS_REG))]
11553 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
11554 || optimize_function_for_size_p (cfun)"
11555 [(set (strict_low_part (match_dup 1)) (const_int 0))]
11556 "operands[1] = gen_lowpart (HImode, operands[0]);")
11559 [(set (match_operand:SWI248 0 "any_QIreg_operand")
11560 (and:SWI248 (match_dup 0)
11562 (clobber (reg:CC FLAGS_REG))]
11563 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11564 && reload_completed"
11565 [(set (strict_low_part (match_dup 1)) (const_int 0))]
11566 "operands[1] = gen_lowpart (QImode, operands[0]);")
11569 [(set (match_operand:SWI248 0 "QIreg_operand")
11570 (and:SWI248 (match_dup 0)
11571 (const_int -65281)))
11572 (clobber (reg:CC FLAGS_REG))]
11573 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11574 && reload_completed"
11576 [(set (zero_extract:HI (match_dup 0)
11582 (zero_extract:HI (match_dup 0)
11586 (zero_extract:HI (match_dup 0)
11588 (const_int 8)) 0)) 0))
11589 (clobber (reg:CC FLAGS_REG))])]
11590 "operands[0] = gen_lowpart (HImode, operands[0]);")
11592 (define_insn "*anddi_2"
11593 [(set (reg FLAGS_REG)
11596 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
11597 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m"))
11599 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
11600 (and:DI (match_dup 1) (match_dup 2)))]
11602 && ix86_match_ccmode
11604 /* If we are going to emit andl instead of andq, and the operands[2]
11605 constant might have the SImode sign bit set, make sure the sign
11606 flag isn't tested, because the instruction will set the sign flag
11607 based on bit 31 rather than bit 63. If it isn't CONST_INT,
11608 conservatively assume it might have bit 31 set. */
11609 (satisfies_constraint_Z (operands[2])
11610 && (!CONST_INT_P (operands[2])
11611 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
11612 ? CCZmode : CCNOmode)
11613 && ix86_binary_operator_ok (AND, DImode, operands)"
11615 and{l}\t{%k2, %k0|%k0, %k2}
11616 and{q}\t{%2, %0|%0, %2}
11617 and{q}\t{%2, %0|%0, %2}"
11618 [(set_attr "type" "alu")
11619 (set_attr "mode" "SI,DI,DI")])
11621 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
11622 (define_insn "*andsi_2_zext"
11623 [(set (reg FLAGS_REG)
11625 (match_operand:SI 1 "nonimmediate_operand" "%0")
11626 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
11628 (set (match_operand:DI 0 "register_operand" "=r")
11629 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
11630 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
11631 && ix86_binary_operator_ok (AND, SImode, operands)"
11632 "and{l}\t{%2, %k0|%k0, %2}"
11633 [(set_attr "type" "alu")
11634 (set_attr "mode" "SI")])
11636 (define_insn "*andqi_2_maybe_si"
11637 [(set (reg FLAGS_REG)
11639 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
11640 (match_operand:QI 2 "general_operand" "qn,m,n"))
11642 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
11643 (and:QI (match_dup 1) (match_dup 2)))]
11644 "ix86_binary_operator_ok (AND, QImode, operands)
11645 && ix86_match_ccmode (insn,
11646 CONST_INT_P (operands[2])
11647 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
11649 if (get_attr_mode (insn) == MODE_SI)
11651 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
11652 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
11653 return "and{l}\t{%2, %k0|%k0, %2}";
11655 return "and{b}\t{%2, %0|%0, %2}";
11657 [(set_attr "type" "alu")
11659 (cond [(eq_attr "alternative" "2")
11660 (const_string "SI")
11661 (and (match_test "optimize_insn_for_size_p ()")
11662 (and (match_operand 0 "ext_QIreg_operand")
11663 (match_operand 2 "const_0_to_127_operand")))
11664 (const_string "SI")
11666 (const_string "QI")))
11667 ;; Potential partial reg stall on alternative 2.
11668 (set (attr "preferred_for_speed")
11669 (cond [(eq_attr "alternative" "2")
11670 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
11671 (symbol_ref "true")))])
11673 (define_insn "*and<mode>_2"
11674 [(set (reg FLAGS_REG)
11675 (compare (and:SWI124
11676 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
11677 (match_operand:SWI124 2 "<general_operand>" "<r><i>,<m>"))
11679 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>m,<r>")
11680 (and:SWI124 (match_dup 1) (match_dup 2)))]
11681 "ix86_match_ccmode (insn, CCNOmode)
11682 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
11683 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
11684 [(set_attr "type" "alu")
11685 (set_attr "mode" "<MODE>")])
11687 (define_insn "*<code>qi_ext<mode>_0"
11688 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn")
11691 (match_operator:SWI248 3 "extract_operator"
11692 [(match_operand 2 "int248_register_operand" "Q")
11695 (match_operand:QI 1 "nonimmediate_operand" "0")))
11696 (clobber (reg:CC FLAGS_REG))]
11698 "<logic>{b}\t{%h2, %0|%0, %h2}"
11699 [(set_attr "addr" "gpr8")
11700 (set_attr "type" "alu")
11701 (set_attr "mode" "QI")])
11703 (define_expand "andqi_ext_1"
11705 [(set (zero_extract:HI (match_operand:HI 0 "register_operand")
11711 (zero_extract:HI (match_operand:HI 1 "register_operand")
11714 (match_operand:QI 2 "const_int_operand")) 0))
11715 (clobber (reg:CC FLAGS_REG))])])
11717 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
11718 (define_insn_and_split "*<code>qi_ext<mode>_1"
11719 [(set (zero_extract:SWI248
11720 (match_operand 0 "int248_register_operand" "+Q,&Q")
11726 (match_operator:SWI248 3 "extract_operator"
11727 [(match_operand 1 "int248_register_operand" "0,!Q")
11730 (match_operand:QI 2 "general_operand" "QnBn,QnBn")) 0))
11731 (clobber (reg:CC FLAGS_REG))]
11734 <logic>{b}\t{%2, %h0|%h0, %2}
11737 && !(rtx_equal_p (operands[0], operands[1]))"
11738 [(set (zero_extract:SWI248
11739 (match_dup 0) (const_int 8) (const_int 8))
11740 (zero_extract:SWI248
11741 (match_dup 1) (const_int 8) (const_int 8)))
11743 [(set (zero_extract:SWI248
11744 (match_dup 0) (const_int 8) (const_int 8))
11749 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
11751 (clobber (reg:CC FLAGS_REG))])]
11753 [(set_attr "addr" "gpr8")
11754 (set_attr "type" "alu")
11755 (set_attr "mode" "QI")])
11757 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
11758 (define_insn_and_split "*<code>qi_ext<mode>_1_cc"
11759 [(set (match_operand 4 "flags_reg_operand")
11760 (match_operator 5 "compare_operator"
11763 (match_operator:SWI248 3 "extract_operator"
11764 [(match_operand 1 "int248_register_operand" "0,!Q")
11767 (match_operand:QI 2 "general_operand" "QnBn,QnBn"))
11769 (set (zero_extract:SWI248
11770 (match_operand 0 "int248_register_operand" "+Q,&Q")
11777 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
11778 (match_dup 2)) 0))]
11779 "ix86_match_ccmode (insn, CCNOmode)"
11781 <logic>{b}\t{%2, %h0|%h0, %2}
11783 "&& reload_completed
11784 && !(rtx_equal_p (operands[0], operands[1]))"
11785 [(set (zero_extract:SWI248
11786 (match_dup 0) (const_int 8) (const_int 8))
11787 (zero_extract:SWI248
11788 (match_dup 1) (const_int 8) (const_int 8)))
11790 [(set (match_dup 4)
11795 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
11798 (set (zero_extract:SWI248
11799 (match_dup 0) (const_int 8) (const_int 8))
11804 [(match_dup 1) (const_int 8) (const_int 8)]) 0)
11805 (match_dup 2)) 0))])]
11807 [(set_attr "addr" "gpr8")
11808 (set_attr "type" "alu")
11809 (set_attr "mode" "QI")])
11811 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
11812 (define_insn_and_split "*<code>qi_ext<mode>_2"
11813 [(set (zero_extract:SWI248
11814 (match_operand 0 "int248_register_operand" "+Q,&Q")
11820 (match_operator:SWI248 3 "extract_operator"
11821 [(match_operand 1 "int248_register_operand" "%0,!Q")
11825 (match_operator:SWI248 4 "extract_operator"
11826 [(match_operand 2 "int248_register_operand" "Q,Q")
11828 (const_int 8)]) 0)) 0))
11829 (clobber (reg:CC FLAGS_REG))]
11832 <logic>{b}\t{%h2, %h0|%h0, %h2}
11835 && !(rtx_equal_p (operands[0], operands[1])
11836 || rtx_equal_p (operands[0], operands[2]))"
11837 [(set (zero_extract:SWI248
11838 (match_dup 0) (const_int 8) (const_int 8))
11839 (zero_extract:SWI248
11840 (match_dup 1) (const_int 8) (const_int 8)))
11842 [(set (zero_extract:SWI248
11843 (match_dup 0) (const_int 8) (const_int 8))
11848 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
11851 [(match_dup 2) (const_int 8) (const_int 8)]) 0)) 0))
11852 (clobber (reg:CC FLAGS_REG))])]
11854 [(set_attr "type" "alu")
11855 (set_attr "mode" "QI")])
11857 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
11858 (define_insn_and_split "*<code>qi_ext<mode>_3"
11859 [(set (zero_extract:SWI248
11860 (match_operand 0 "int248_register_operand" "+Q,&Q")
11863 (match_operator:SWI248 3 "extract_operator"
11865 (match_operand 1 "int248_register_operand" "%0,!Q")
11866 (match_operand 2 "int248_register_operand" "Q,Q"))
11869 (clobber (reg:CC FLAGS_REG))]
11870 "GET_MODE (operands[1]) == GET_MODE (operands[2])"
11872 <logic>{b}\t{%h2, %h0|%h0, %h2}
11874 "&& reload_completed
11875 && !(rtx_equal_p (operands[0], operands[1])
11876 || rtx_equal_p (operands[0], operands[2]))"
11877 [(set (zero_extract:SWI248
11878 (match_dup 0) (const_int 8) (const_int 8))
11879 (zero_extract:SWI248
11880 (match_dup 1) (const_int 8) (const_int 8)))
11882 [(set (zero_extract:SWI248
11883 (match_dup 0) (const_int 8) (const_int 8))
11885 [(any_logic (match_dup 4) (match_dup 2))
11886 (const_int 8) (const_int 8)]))
11887 (clobber (reg:CC FLAGS_REG))])]
11888 "operands[4] = gen_lowpart (GET_MODE (operands[1]), operands[0]);"
11889 [(set_attr "type" "alu")
11890 (set_attr "mode" "QI")])
11892 ;; Convert wide AND instructions with immediate operand to shorter QImode
11893 ;; equivalents when possible.
11894 ;; Don't do the splitting with memory operands, since it introduces risk
11895 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
11896 ;; for size, but that can (should?) be handled by generic code instead.
11898 [(set (match_operand:SWI248 0 "QIreg_operand")
11899 (and:SWI248 (match_operand:SWI248 1 "register_operand")
11900 (match_operand:SWI248 2 "const_int_operand")))
11901 (clobber (reg:CC FLAGS_REG))]
11903 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11904 && !(~INTVAL (operands[2]) & ~(255 << 8))"
11906 [(set (zero_extract:HI (match_dup 0)
11912 (zero_extract:HI (match_dup 1)
11916 (clobber (reg:CC FLAGS_REG))])]
11918 operands[0] = gen_lowpart (HImode, operands[0]);
11919 operands[1] = gen_lowpart (HImode, operands[1]);
11920 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
11923 ;; Since AND can be encoded with sign extended immediate, this is only
11924 ;; profitable when 7th bit is not set.
11926 [(set (match_operand:SWI248 0 "any_QIreg_operand")
11927 (and:SWI248 (match_operand:SWI248 1 "general_operand")
11928 (match_operand:SWI248 2 "const_int_operand")))
11929 (clobber (reg:CC FLAGS_REG))]
11931 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11932 && !(~INTVAL (operands[2]) & ~255)
11933 && !(INTVAL (operands[2]) & 128)"
11934 [(parallel [(set (strict_low_part (match_dup 0))
11935 (and:QI (match_dup 1)
11937 (clobber (reg:CC FLAGS_REG))])]
11939 operands[0] = gen_lowpart (QImode, operands[0]);
11940 operands[1] = gen_lowpart (QImode, operands[1]);
11941 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
11944 (define_insn_and_split "*andn<dwi>3_doubleword_bmi"
11945 [(set (match_operand:<DWI> 0 "register_operand" "=&r,r,r")
11947 (not:<DWI> (match_operand:<DWI> 1 "register_operand" "r,0,r"))
11948 (match_operand:<DWI> 2 "nonimmediate_operand" "ro,ro,0")))
11949 (clobber (reg:CC FLAGS_REG))]
11952 "&& reload_completed"
11953 [(parallel [(set (match_dup 0)
11954 (and:DWIH (not:DWIH (match_dup 1)) (match_dup 2)))
11955 (clobber (reg:CC FLAGS_REG))])
11956 (parallel [(set (match_dup 3)
11957 (and:DWIH (not:DWIH (match_dup 4)) (match_dup 5)))
11958 (clobber (reg:CC FLAGS_REG))])]
11959 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
11961 (define_insn_and_split "*andn<mode>3_doubleword"
11962 [(set (match_operand:DWI 0 "register_operand")
11964 (not:DWI (match_operand:DWI 1 "register_operand"))
11965 (match_operand:DWI 2 "nonimmediate_operand")))
11966 (clobber (reg:CC FLAGS_REG))]
11968 && ix86_pre_reload_split ()"
11971 [(set (match_dup 3) (not:DWI (match_dup 1)))
11972 (parallel [(set (match_dup 0)
11973 (and:DWI (match_dup 3) (match_dup 2)))
11974 (clobber (reg:CC FLAGS_REG))])]
11975 "operands[3] = gen_reg_rtx (<MODE>mode);")
11977 (define_insn "*andn<mode>_1"
11978 [(set (match_operand:SWI48 0 "register_operand" "=r,r,?k")
11980 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r,k"))
11981 (match_operand:SWI48 2 "nonimmediate_operand" "r,m,k")))
11982 (clobber (reg:CC FLAGS_REG))]
11984 || (TARGET_AVX512BW && (<MODE>mode == SImode || TARGET_EVEX512))"
11986 andn\t{%2, %1, %0|%0, %1, %2}
11987 andn\t{%2, %1, %0|%0, %1, %2}
11989 [(set_attr "isa" "bmi,bmi,<kmov_isa>")
11990 (set_attr "type" "bitmanip,bitmanip,msklog")
11991 (set_attr "btver2_decode" "direct, double,*")
11992 (set_attr "mode" "<MODE>")])
11994 (define_insn "*andn<mode>_1"
11995 [(set (match_operand:SWI12 0 "register_operand" "=r,?k")
11997 (not:SWI12 (match_operand:SWI12 1 "register_operand" "r,k"))
11998 (match_operand:SWI12 2 "register_operand" "r,k")))
11999 (clobber (reg:CC FLAGS_REG))]
12000 "TARGET_BMI || TARGET_AVX512BW"
12002 andn\t{%k2, %k1, %k0|%k0, %k1, %k2}
12004 [(set_attr "isa" "bmi,avx512f")
12005 (set_attr "type" "bitmanip,msklog")
12006 (set_attr "btver2_decode" "direct,*")
12008 (cond [(eq_attr "alternative" "0")
12009 (const_string "SI")
12010 (and (eq_attr "alternative" "1")
12011 (match_test "!TARGET_AVX512DQ"))
12012 (const_string "HI")
12014 (const_string "<MODE>")))])
12016 (define_insn "*andn_<mode>_ccno"
12017 [(set (reg FLAGS_REG)
12020 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
12021 (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
12023 (clobber (match_scratch:SWI48 0 "=r,r"))]
12024 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
12025 "andn\t{%2, %1, %0|%0, %1, %2}"
12026 [(set_attr "type" "bitmanip")
12027 (set_attr "btver2_decode" "direct, double")
12028 (set_attr "mode" "<MODE>")])
12030 ;; Split *andnsi_1 after reload with -Oz when not;and is shorter.
12032 [(set (match_operand:SI 0 "register_operand")
12033 (and:SI (not:SI (match_operand:SI 1 "register_operand"))
12034 (match_operand:SI 2 "nonimmediate_operand")))
12035 (clobber (reg:CC FLAGS_REG))]
12037 && optimize_insn_for_size_p () && optimize_size > 1
12038 && REGNO (operands[0]) == REGNO (operands[1])
12039 && LEGACY_INT_REG_P (operands[0])
12040 && !REX_INT_REG_P (operands[2])
12041 && !reg_overlap_mentioned_p (operands[0], operands[2])"
12042 [(set (match_dup 0) (not:SI (match_dup 1)))
12043 (parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
12044 (clobber (reg:CC FLAGS_REG))])])
12046 ;; Split *andn_si_ccno with -Oz when not;test is shorter.
12048 [(set (match_operand 0 "flags_reg_operand")
12049 (match_operator 1 "compare_operator"
12050 [(and:SI (not:SI (match_operand:SI 2 "general_reg_operand"))
12051 (match_operand:SI 3 "nonimmediate_operand"))
12053 (clobber (match_dup 2))]
12055 && optimize_insn_for_size_p () && optimize_size > 1
12056 && LEGACY_INT_REG_P (operands[2])
12057 && !REX_INT_REG_P (operands[3])
12058 && !reg_overlap_mentioned_p (operands[2], operands[3])"
12059 [(set (match_dup 2) (not:SI (match_dup 2)))
12060 (set (match_dup 0) (match_op_dup 1
12061 [(and:SI (match_dup 3) (match_dup 2))
12064 ;; Variant 1 of 4: Split ((A | B) ^ A) ^ C as (B & ~A) ^ C.
12066 [(set (match_operand:SWI48 0 "register_operand")
12069 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
12070 (match_operand:SWI48 2 "nonimmediate_operand"))
12072 (match_operand:SWI48 3 "nonimmediate_operand")))
12073 (clobber (reg:CC FLAGS_REG))]
12076 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 1)) (match_dup 2)))
12077 (clobber (reg:CC FLAGS_REG))])
12079 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
12080 (clobber (reg:CC FLAGS_REG))])]
12081 "operands[4] = gen_reg_rtx (<MODE>mode);")
12083 ;; Variant 2 of 4: Split ((A | B) ^ B) ^ C as (A & ~B) ^ C.
12085 [(set (match_operand:SWI48 0 "register_operand")
12088 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
12089 (match_operand:SWI48 2 "register_operand"))
12091 (match_operand:SWI48 3 "nonimmediate_operand")))
12092 (clobber (reg:CC FLAGS_REG))]
12095 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 2)) (match_dup 1)))
12096 (clobber (reg:CC FLAGS_REG))])
12098 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
12099 (clobber (reg:CC FLAGS_REG))])]
12100 "operands[4] = gen_reg_rtx (<MODE>mode);")
12102 ;; Variant 3 of 4: Split ((A | B) ^ C) ^ A as (B & ~A) ^ C.
12104 [(set (match_operand:SWI48 0 "register_operand")
12107 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
12108 (match_operand:SWI48 2 "nonimmediate_operand"))
12109 (match_operand:SWI48 3 "nonimmediate_operand"))
12111 (clobber (reg:CC FLAGS_REG))]
12114 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 1)) (match_dup 2)))
12115 (clobber (reg:CC FLAGS_REG))])
12117 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
12118 (clobber (reg:CC FLAGS_REG))])]
12119 "operands[4] = gen_reg_rtx (<MODE>mode);")
12121 ;; Variant 4 of 4: Split ((A | B) ^ C) ^ B as (A & ~B) ^ C.
12123 [(set (match_operand:SWI48 0 "register_operand")
12126 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
12127 (match_operand:SWI48 2 "register_operand"))
12128 (match_operand:SWI48 3 "nonimmediate_operand"))
12130 (clobber (reg:CC FLAGS_REG))]
12133 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 2)) (match_dup 1)))
12134 (clobber (reg:CC FLAGS_REG))])
12136 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
12137 (clobber (reg:CC FLAGS_REG))])]
12138 "operands[4] = gen_reg_rtx (<MODE>mode);")
12140 ;; Logical inclusive and exclusive OR instructions
12142 ;; %%% This used to optimize known byte-wide and operations to memory.
12143 ;; If this is considered useful, it should be done with splitters.
12145 (define_expand "<code><mode>3"
12146 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
12147 (any_or:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
12148 (match_operand:SDWIM 2 "<general_operand>")))]
12151 if (GET_MODE_SIZE (<MODE>mode) > UNITS_PER_WORD
12152 && !x86_64_hilo_general_operand (operands[2], <MODE>mode))
12153 operands[2] = force_reg (<MODE>mode, operands[2]);
12155 ix86_expand_binary_operator (<CODE>, <MODE>mode, operands);
12159 (define_insn_and_split "*<code><dwi>3_doubleword"
12160 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
12162 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
12163 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
12164 (clobber (reg:CC FLAGS_REG))]
12165 "ix86_binary_operator_ok (<CODE>, <DWI>mode, operands)"
12167 "&& reload_completed"
12168 [(const_int:DWIH 0)]
12170 /* This insn may disappear completely when operands[2] == const0_rtx
12171 and operands[0] == operands[1], which requires a NOTE_INSN_DELETED. */
12172 bool emit_insn_deleted_note_p = false;
12174 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
12176 if (operands[2] == const0_rtx)
12177 emit_insn_deleted_note_p = true;
12178 else if (operands[2] == constm1_rtx)
12181 emit_move_insn (operands[0], constm1_rtx);
12183 ix86_expand_unary_operator (NOT, <MODE>mode, &operands[0]);
12186 ix86_expand_binary_operator (<CODE>, <MODE>mode, &operands[0]);
12188 if (operands[5] == const0_rtx)
12190 if (emit_insn_deleted_note_p)
12191 emit_note (NOTE_INSN_DELETED);
12193 else if (operands[5] == constm1_rtx)
12196 emit_move_insn (operands[3], constm1_rtx);
12198 ix86_expand_unary_operator (NOT, <MODE>mode, &operands[3]);
12201 ix86_expand_binary_operator (<CODE>, <MODE>mode, &operands[3]);
12206 (define_insn "*<code><mode>_1"
12207 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,?k")
12209 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,k")
12210 (match_operand:SWI248 2 "<general_operand>" "r<i>,<m>,k")))
12211 (clobber (reg:CC FLAGS_REG))]
12212 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
12214 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
12215 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
12217 [(set_attr "isa" "*,*,<kmov_isa>")
12218 (set_attr "type" "alu, alu, msklog")
12219 (set_attr "mode" "<MODE>")])
12221 (define_insn_and_split "*notxor<mode>_1"
12222 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,?k")
12225 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,k")
12226 (match_operand:SWI248 2 "<general_operand>" "r<i>,<m>,k"))))
12227 (clobber (reg:CC FLAGS_REG))]
12228 "ix86_binary_operator_ok (XOR, <MODE>mode, operands)"
12230 "&& reload_completed"
12232 [(set (match_dup 0)
12233 (xor:SWI248 (match_dup 1) (match_dup 2)))
12234 (clobber (reg:CC FLAGS_REG))])
12236 (not:SWI248 (match_dup 0)))]
12238 if (MASK_REG_P (operands[0]))
12240 emit_insn (gen_kxnor<mode> (operands[0], operands[1], operands[2]));
12244 [(set_attr "isa" "*,*,<kmov_isa>")
12245 (set_attr "type" "alu, alu, msklog")
12246 (set_attr "mode" "<MODE>")])
12248 (define_insn_and_split "*iordi_1_bts"
12249 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12251 (match_operand:DI 1 "nonimmediate_operand" "%0")
12252 (match_operand:DI 2 "const_int_operand" "n")))
12253 (clobber (reg:CC FLAGS_REG))]
12254 "TARGET_64BIT && TARGET_USE_BT
12255 && ix86_binary_operator_ok (IOR, DImode, operands)
12256 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
12258 "&& reload_completed"
12259 [(parallel [(set (zero_extract:DI (match_dup 0)
12263 (clobber (reg:CC FLAGS_REG))])]
12264 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
12265 [(set_attr "type" "alu1")
12266 (set_attr "prefix_0f" "1")
12267 (set_attr "znver1_decode" "double")
12268 (set_attr "mode" "DI")])
12270 (define_insn_and_split "*xordi_1_btc"
12271 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12273 (match_operand:DI 1 "nonimmediate_operand" "%0")
12274 (match_operand:DI 2 "const_int_operand" "n")))
12275 (clobber (reg:CC FLAGS_REG))]
12276 "TARGET_64BIT && TARGET_USE_BT
12277 && ix86_binary_operator_ok (XOR, DImode, operands)
12278 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
12280 "&& reload_completed"
12281 [(parallel [(set (zero_extract:DI (match_dup 0)
12284 (not:DI (zero_extract:DI (match_dup 0)
12287 (clobber (reg:CC FLAGS_REG))])]
12288 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
12289 [(set_attr "type" "alu1")
12290 (set_attr "prefix_0f" "1")
12291 (set_attr "znver1_decode" "double")
12292 (set_attr "mode" "DI")])
12294 ;; Optimize a ^ ((a ^ b) & mask) to (~mask & a) | (b & mask)
12295 (define_insn_and_split "*xor2andn"
12296 [(set (match_operand:SWI248 0 "register_operand")
12300 (match_operand:SWI248 1 "nonimmediate_operand")
12301 (match_operand:SWI248 2 "nonimmediate_operand"))
12302 (match_operand:SWI248 3 "nonimmediate_operand"))
12304 (clobber (reg:CC FLAGS_REG))]
12305 "TARGET_BMI && ix86_pre_reload_split ()"
12308 [(parallel [(set (match_dup 4)
12313 (clobber (reg:CC FLAGS_REG))])
12314 (parallel [(set (match_dup 5)
12318 (clobber (reg:CC FLAGS_REG))])
12319 (parallel [(set (match_dup 0)
12323 (clobber (reg:CC FLAGS_REG))])]
12325 operands[1] = force_reg (<MODE>mode, operands[1]);
12326 operands[3] = force_reg (<MODE>mode, operands[3]);
12327 operands[4] = gen_reg_rtx (<MODE>mode);
12328 operands[5] = gen_reg_rtx (<MODE>mode);
12331 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
12332 (define_insn "*<code>si_1_zext"
12333 [(set (match_operand:DI 0 "register_operand" "=r")
12335 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
12336 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
12337 (clobber (reg:CC FLAGS_REG))]
12338 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12339 "<logic>{l}\t{%2, %k0|%k0, %2}"
12340 [(set_attr "type" "alu")
12341 (set_attr "mode" "SI")])
12343 (define_insn "*<code>si_1_zext_imm"
12344 [(set (match_operand:DI 0 "register_operand" "=r")
12346 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
12347 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
12348 (clobber (reg:CC FLAGS_REG))]
12349 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12350 "<logic>{l}\t{%2, %k0|%k0, %2}"
12351 [(set_attr "type" "alu")
12352 (set_attr "mode" "SI")])
12354 (define_insn "*<code>qi_1"
12355 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,?k")
12356 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
12357 (match_operand:QI 2 "general_operand" "qn,m,rn,k")))
12358 (clobber (reg:CC FLAGS_REG))]
12359 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
12361 <logic>{b}\t{%2, %0|%0, %2}
12362 <logic>{b}\t{%2, %0|%0, %2}
12363 <logic>{l}\t{%k2, %k0|%k0, %k2}
12365 [(set_attr "isa" "*,*,*,avx512f")
12366 (set_attr "type" "alu,alu,alu,msklog")
12368 (cond [(eq_attr "alternative" "2")
12369 (const_string "SI")
12370 (and (eq_attr "alternative" "3")
12371 (match_test "!TARGET_AVX512DQ"))
12372 (const_string "HI")
12374 (const_string "QI")))
12375 ;; Potential partial reg stall on alternative 2.
12376 (set (attr "preferred_for_speed")
12377 (cond [(eq_attr "alternative" "2")
12378 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
12379 (symbol_ref "true")))])
12381 (define_insn_and_split "*notxorqi_1"
12382 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,?k")
12384 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
12385 (match_operand:QI 2 "general_operand" "qn,m,rn,k"))))
12386 (clobber (reg:CC FLAGS_REG))]
12387 "ix86_binary_operator_ok (XOR, QImode, operands)"
12389 "&& reload_completed"
12391 [(set (match_dup 0)
12392 (xor:QI (match_dup 1) (match_dup 2)))
12393 (clobber (reg:CC FLAGS_REG))])
12395 (not:QI (match_dup 0)))]
12397 if (mask_reg_operand (operands[0], QImode))
12399 emit_insn (gen_kxnorqi (operands[0], operands[1], operands[2]));
12403 [(set_attr "isa" "*,*,*,avx512f")
12404 (set_attr "type" "alu,alu,alu,msklog")
12406 (cond [(eq_attr "alternative" "2")
12407 (const_string "SI")
12408 (and (eq_attr "alternative" "3")
12409 (match_test "!TARGET_AVX512DQ"))
12410 (const_string "HI")
12412 (const_string "QI")))
12413 ;; Potential partial reg stall on alternative 2.
12414 (set (attr "preferred_for_speed")
12415 (cond [(eq_attr "alternative" "2")
12416 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
12417 (symbol_ref "true")))])
12419 ;; convert (sign_extend:WIDE (any_logic:NARROW (memory, immediate)))
12420 ;; to (any_logic:WIDE (sign_extend (memory)), (sign_extend (immediate))).
12421 ;; This eliminates sign extension after logic operation.
12424 [(set (match_operand:SWI248 0 "register_operand")
12425 (sign_extend:SWI248
12426 (any_logic:QI (match_operand:QI 1 "memory_operand")
12427 (match_operand:QI 2 "const_int_operand"))))]
12429 [(set (match_dup 3) (sign_extend:SWI248 (match_dup 1)))
12430 (set (match_dup 0) (any_logic:SWI248 (match_dup 3) (match_dup 2)))]
12431 "operands[3] = gen_reg_rtx (<MODE>mode);")
12434 [(set (match_operand:SWI48 0 "register_operand")
12436 (any_logic:HI (match_operand:HI 1 "memory_operand")
12437 (match_operand:HI 2 "const_int_operand"))))]
12439 [(set (match_dup 3) (sign_extend:SWI48 (match_dup 1)))
12440 (set (match_dup 0) (any_logic:SWI48 (match_dup 3) (match_dup 2)))]
12441 "operands[3] = gen_reg_rtx (<MODE>mode);")
12444 [(set (match_operand:DI 0 "register_operand")
12446 (any_logic:SI (match_operand:SI 1 "memory_operand")
12447 (match_operand:SI 2 "const_int_operand"))))]
12449 [(set (match_dup 3) (sign_extend:DI (match_dup 1)))
12450 (set (match_dup 0) (any_logic:DI (match_dup 3) (match_dup 2)))]
12451 "operands[3] = gen_reg_rtx (DImode);")
12453 (define_insn "*<code><mode>_2"
12454 [(set (reg FLAGS_REG)
12455 (compare (any_or:SWI
12456 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
12457 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
12459 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
12460 (any_or:SWI (match_dup 1) (match_dup 2)))]
12461 "ix86_match_ccmode (insn, CCNOmode)
12462 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
12463 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
12464 [(set_attr "type" "alu")
12465 (set_attr "mode" "<MODE>")])
12467 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
12468 ;; ??? Special case for immediate operand is missing - it is tricky.
12469 (define_insn "*<code>si_2_zext"
12470 [(set (reg FLAGS_REG)
12471 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
12472 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
12474 (set (match_operand:DI 0 "register_operand" "=r")
12475 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
12476 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
12477 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12478 "<logic>{l}\t{%2, %k0|%k0, %2}"
12479 [(set_attr "type" "alu")
12480 (set_attr "mode" "SI")])
12482 (define_insn "*<code>si_2_zext_imm"
12483 [(set (reg FLAGS_REG)
12484 (compare (any_or:SI
12485 (match_operand:SI 1 "nonimmediate_operand" "%0")
12486 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
12488 (set (match_operand:DI 0 "register_operand" "=r")
12489 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12490 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
12491 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12492 "<logic>{l}\t{%2, %k0|%k0, %2}"
12493 [(set_attr "type" "alu")
12494 (set_attr "mode" "SI")])
12496 (define_insn "*<code><mode>_3"
12497 [(set (reg FLAGS_REG)
12498 (compare (any_or:SWI
12499 (match_operand:SWI 1 "nonimmediate_operand" "%0")
12500 (match_operand:SWI 2 "<general_operand>" "<g>"))
12502 (clobber (match_scratch:SWI 0 "=<r>"))]
12503 "ix86_match_ccmode (insn, CCNOmode)
12504 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12505 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
12506 [(set_attr "type" "alu")
12507 (set_attr "mode" "<MODE>")])
12509 ;; Convert wide OR instructions with immediate operand to shorter QImode
12510 ;; equivalents when possible.
12511 ;; Don't do the splitting with memory operands, since it introduces risk
12512 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
12513 ;; for size, but that can (should?) be handled by generic code instead.
12515 [(set (match_operand:SWI248 0 "QIreg_operand")
12516 (any_or:SWI248 (match_operand:SWI248 1 "register_operand")
12517 (match_operand:SWI248 2 "const_int_operand")))
12518 (clobber (reg:CC FLAGS_REG))]
12520 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12521 && !(INTVAL (operands[2]) & ~(255 << 8))"
12523 [(set (zero_extract:HI (match_dup 0)
12529 (zero_extract:HI (match_dup 1)
12533 (clobber (reg:CC FLAGS_REG))])]
12535 /* Handle the case where INTVAL (operands[2]) == 0. */
12536 if (operands[2] == const0_rtx)
12538 if (!rtx_equal_p (operands[0], operands[1]))
12539 emit_move_insn (operands[0], operands[1]);
12541 emit_note (NOTE_INSN_DELETED);
12544 operands[0] = gen_lowpart (HImode, operands[0]);
12545 operands[1] = gen_lowpart (HImode, operands[1]);
12546 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
12549 ;; Since OR can be encoded with sign extended immediate, this is only
12550 ;; profitable when 7th bit is set.
12552 [(set (match_operand:SWI248 0 "any_QIreg_operand")
12553 (any_or:SWI248 (match_operand:SWI248 1 "general_operand")
12554 (match_operand:SWI248 2 "const_int_operand")))
12555 (clobber (reg:CC FLAGS_REG))]
12557 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12558 && !(INTVAL (operands[2]) & ~255)
12559 && (INTVAL (operands[2]) & 128)"
12560 [(parallel [(set (strict_low_part (match_dup 0))
12561 (any_or:QI (match_dup 1)
12563 (clobber (reg:CC FLAGS_REG))])]
12565 operands[0] = gen_lowpart (QImode, operands[0]);
12566 operands[1] = gen_lowpart (QImode, operands[1]);
12567 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
12570 (define_expand "xorqi_ext_1_cc"
12572 [(set (reg:CCNO FLAGS_REG)
12576 (zero_extract:HI (match_operand:HI 1 "register_operand")
12579 (match_operand:QI 2 "const_int_operand"))
12581 (set (zero_extract:HI (match_operand:HI 0 "register_operand")
12587 (zero_extract:HI (match_dup 1)
12590 (match_dup 2)) 0))])])
12592 ;; Peephole2 rega = 0; rega op= regb into rega = regb.
12594 [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
12596 (clobber (reg:CC FLAGS_REG))])
12597 (parallel [(set (match_dup 0)
12598 (any_or_plus:SWI (match_dup 0)
12599 (match_operand:SWI 1 "<general_operand>")))
12600 (clobber (reg:CC FLAGS_REG))])]
12601 "!reg_mentioned_p (operands[0], operands[1])"
12602 [(set (match_dup 0) (match_dup 1))])
12604 ;; Peephole2 dead instruction in rega = 0; rega op= rega.
12606 [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
12608 (clobber (reg:CC FLAGS_REG))])
12609 (parallel [(set (match_dup 0)
12610 (any_or_plus:SWI (match_dup 0) (match_dup 0)))
12611 (clobber (reg:CC FLAGS_REG))])]
12613 [(parallel [(set (match_dup 0) (const_int 0))
12614 (clobber (reg:CC FLAGS_REG))])])
12616 ;; Split DST = (HI<<32)|LO early to minimize register usage.
12617 (define_insn_and_split "*concat<mode><dwi>3_1"
12618 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
12620 (ashift:<DWI> (match_operand:<DWI> 1 "register_operand" "r,r")
12621 (match_operand:QI 2 "const_int_operand"))
12623 (match_operand:DWIH 3 "nonimmediate_operand" "r,m"))))]
12624 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT"
12626 "&& reload_completed"
12629 split_double_concat (<DWI>mode, operands[0], operands[3],
12630 gen_lowpart (<MODE>mode, operands[1]));
12634 (define_insn_and_split "*concat<mode><dwi>3_2"
12635 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
12638 (match_operand:DWIH 1 "nonimmediate_operand" "r,m"))
12639 (ashift:<DWI> (match_operand:<DWI> 2 "register_operand" "r,r")
12640 (match_operand:QI 3 "const_int_operand"))))]
12641 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12643 "&& reload_completed"
12646 split_double_concat (<DWI>mode, operands[0], operands[1],
12647 gen_lowpart (<MODE>mode, operands[2]));
12651 (define_insn_and_split "*concat<mode><dwi>3_3"
12652 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,r,&r,x")
12656 (match_operand:DWIH 1 "nonimmediate_operand" "r,m,r,m,x"))
12657 (match_operand:QI 2 "const_int_operand"))
12659 (match_operand:DWIH 3 "nonimmediate_operand" "r,r,m,m,0"))))]
12660 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT"
12662 "&& reload_completed"
12665 if (SSE_REG_P (operands[0]))
12667 rtx tmp = gen_rtx_REG (V2DImode, REGNO (operands[0]));
12668 emit_insn (gen_vec_concatv2di (tmp, operands[3], operands[1]));
12671 split_double_concat (<DWI>mode, operands[0], operands[3], operands[1]);
12674 [(set_attr "isa" "*,*,*,x64,x64")])
12676 (define_insn_and_split "*concat<mode><dwi>3_4"
12677 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,r,&r")
12680 (match_operand:DWIH 1 "nonimmediate_operand" "r,m,r,m"))
12683 (match_operand:DWIH 2 "nonimmediate_operand" "r,r,m,m"))
12684 (match_operand:QI 3 "const_int_operand"))))]
12685 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12687 "&& reload_completed"
12690 split_double_concat (<DWI>mode, operands[0], operands[1], operands[2]);
12693 [(set_attr "isa" "*,*,*,x64")])
12695 (define_insn_and_split "*concat<half><mode>3_5"
12696 [(set (match_operand:DWI 0 "nonimmediate_operand" "=r,o,o")
12698 (ashift:DWI (match_operand:DWI 1 "register_operand" "r,r,r")
12699 (match_operand:QI 2 "const_int_operand"))
12700 (match_operand:DWI 3 "const_scalar_int_operand" "n,n,Wd")))]
12701 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT / 2
12702 && (<MODE>mode == DImode
12703 ? CONST_INT_P (operands[3])
12704 && (UINTVAL (operands[3]) & ~GET_MODE_MASK (SImode)) == 0
12705 : CONST_INT_P (operands[3])
12706 ? INTVAL (operands[3]) >= 0
12707 : CONST_WIDE_INT_NUNITS (operands[3]) == 2
12708 && CONST_WIDE_INT_ELT (operands[3], 1) == 0)
12709 && !(CONST_INT_P (operands[3])
12710 ? ix86_endbr_immediate_operand (operands[3], VOIDmode)
12711 : ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[3],
12715 "&& reload_completed"
12718 rtx op3 = simplify_subreg (<HALF>mode, operands[3], <MODE>mode, 0);
12719 split_double_concat (<MODE>mode, operands[0], op3,
12720 gen_lowpart (<HALF>mode, operands[1]));
12723 [(set_attr "isa" "*,nox64,x64")])
12725 (define_insn_and_split "*concat<mode><dwi>3_6"
12726 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,o,r")
12730 (match_operand:DWIH 1 "nonimmediate_operand" "r,r,r,m"))
12731 (match_operand:QI 2 "const_int_operand"))
12732 (match_operand:<DWI> 3 "const_scalar_int_operand" "n,n,Wd,n")))]
12733 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT
12734 && (<DWI>mode == DImode
12735 ? CONST_INT_P (operands[3])
12736 && (UINTVAL (operands[3]) & ~GET_MODE_MASK (SImode)) == 0
12737 : CONST_INT_P (operands[3])
12738 ? INTVAL (operands[3]) >= 0
12739 : CONST_WIDE_INT_NUNITS (operands[3]) == 2
12740 && CONST_WIDE_INT_ELT (operands[3], 1) == 0)
12741 && !(CONST_INT_P (operands[3])
12742 ? ix86_endbr_immediate_operand (operands[3], VOIDmode)
12743 : ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[3],
12747 "&& reload_completed"
12750 rtx op3 = simplify_subreg (<MODE>mode, operands[3], <DWI>mode, 0);
12751 split_double_concat (<DWI>mode, operands[0], op3, operands[1]);
12754 [(set_attr "isa" "*,nox64,x64,*")])
12756 (define_insn_and_split "*concat<mode><dwi>3_7"
12757 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,o,r")
12760 (match_operand:DWIH 1 "nonimmediate_operand" "r,r,r,m"))
12761 (match_operand:<DWI> 2 "const_scalar_int_operand" "n,n,Wd,n")))]
12762 "<DWI>mode == DImode
12763 ? CONST_INT_P (operands[2])
12764 && (UINTVAL (operands[2]) & GET_MODE_MASK (SImode)) == 0
12765 && !ix86_endbr_immediate_operand (operands[2], VOIDmode)
12766 : CONST_WIDE_INT_P (operands[2])
12767 && CONST_WIDE_INT_NUNITS (operands[2]) == 2
12768 && CONST_WIDE_INT_ELT (operands[2], 0) == 0
12769 && !ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[2],
12773 "&& reload_completed"
12777 if (<DWI>mode == DImode)
12778 op2 = gen_int_mode (INTVAL (operands[2]) >> 32, <MODE>mode);
12780 op2 = gen_int_mode (CONST_WIDE_INT_ELT (operands[2], 1), <MODE>mode);
12781 split_double_concat (<DWI>mode, operands[0], operands[1], op2);
12784 [(set_attr "isa" "*,nox64,x64,*")])
12786 ;; Negation instructions
12788 (define_expand "neg<mode>2"
12789 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
12790 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
12792 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
12794 (define_insn_and_split "*neg<dwi>2_doubleword"
12795 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
12796 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
12797 (clobber (reg:CC FLAGS_REG))]
12798 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
12800 "&& reload_completed"
12802 [(set (reg:CCC FLAGS_REG)
12803 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
12804 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
12806 [(set (match_dup 2)
12807 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
12810 (clobber (reg:CC FLAGS_REG))])
12812 [(set (match_dup 2)
12813 (neg:DWIH (match_dup 2)))
12814 (clobber (reg:CC FLAGS_REG))])]
12815 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
12828 [(set (match_operand:SWI48 0 "general_reg_operand")
12829 (match_operand:SWI48 1 "nonimmediate_gr_operand"))
12831 [(set (reg:CCC FLAGS_REG)
12832 (unspec:CCC [(match_operand:SWI48 2 "general_reg_operand")
12833 (const_int 0)] UNSPEC_CC_NE))
12834 (set (match_dup 2) (neg:SWI48 (match_dup 2)))])
12836 [(set (match_dup 0)
12837 (plus:SWI48 (plus:SWI48
12838 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
12841 (clobber (reg:CC FLAGS_REG))])
12843 [(set (match_dup 0)
12844 (neg:SWI48 (match_dup 0)))
12845 (clobber (reg:CC FLAGS_REG))])]
12846 "REGNO (operands[0]) != REGNO (operands[2])
12847 && !reg_mentioned_p (operands[0], operands[1])
12848 && !reg_mentioned_p (operands[2], operands[1])"
12850 [(set (reg:CCC FLAGS_REG)
12851 (unspec:CCC [(match_dup 2) (const_int 0)] UNSPEC_CC_NE))
12852 (set (match_dup 2) (neg:SWI48 (match_dup 2)))])
12854 [(set (match_dup 0)
12855 (minus:SWI48 (minus:SWI48
12857 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0)))
12859 (clobber (reg:CC FLAGS_REG))])]
12860 "ix86_expand_clear (operands[0]);")
12869 ;; sbbl %edx, %edx // *x86_mov<mode>cc_0_m1
12873 [(set (match_operand:SWI48 0 "general_reg_operand") (const_int 0))
12874 (clobber (reg:CC FLAGS_REG))])
12876 [(set (reg:CCC FLAGS_REG)
12877 (unspec:CCC [(match_operand:SWI48 1 "general_reg_operand")
12878 (const_int 0)] UNSPEC_CC_NE))
12879 (set (match_dup 1) (neg:SWI48 (match_dup 1)))])
12881 [(set (match_dup 0)
12882 (plus:SWI48 (plus:SWI48
12883 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
12886 (clobber (reg:CC FLAGS_REG))])
12888 [(set (match_dup 0)
12889 (neg:SWI48 (match_dup 0)))
12890 (clobber (reg:CC FLAGS_REG))])]
12891 "REGNO (operands[0]) != REGNO (operands[1])"
12893 [(set (reg:CCC FLAGS_REG)
12894 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
12895 (set (match_dup 1) (neg:SWI48 (match_dup 1)))])
12897 [(set (match_dup 0)
12898 (if_then_else:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
12901 (clobber (reg:CC FLAGS_REG))])])
12903 (define_insn "*neg<mode>_1"
12904 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
12905 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
12906 (clobber (reg:CC FLAGS_REG))]
12907 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
12908 "neg{<imodesuffix>}\t%0"
12909 [(set_attr "type" "negnot")
12910 (set_attr "mode" "<MODE>")])
12912 (define_insn "*negsi_1_zext"
12913 [(set (match_operand:DI 0 "register_operand" "=r")
12915 (neg:SI (match_operand:SI 1 "register_operand" "0"))))
12916 (clobber (reg:CC FLAGS_REG))]
12917 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
12919 [(set_attr "type" "negnot")
12920 (set_attr "mode" "SI")])
12922 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
12923 (define_insn_and_split "*neg<mode>_1_slp"
12924 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
12925 (neg:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")))
12926 (clobber (reg:CC FLAGS_REG))]
12927 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
12929 neg{<imodesuffix>}\t%0
12931 "&& reload_completed
12932 && !(rtx_equal_p (operands[0], operands[1]))"
12933 [(set (strict_low_part (match_dup 0)) (match_dup 1))
12935 [(set (strict_low_part (match_dup 0))
12936 (neg:SWI12 (match_dup 0)))
12937 (clobber (reg:CC FLAGS_REG))])]
12939 [(set_attr "type" "negnot")
12940 (set_attr "mode" "<MODE>")])
12942 (define_insn "*neg<mode>_2"
12943 [(set (reg FLAGS_REG)
12945 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
12947 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
12948 (neg:SWI (match_dup 1)))]
12949 "ix86_match_ccmode (insn, CCGOCmode)
12950 && ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
12951 "neg{<imodesuffix>}\t%0"
12952 [(set_attr "type" "negnot")
12953 (set_attr "mode" "<MODE>")])
12955 (define_insn "*negsi_2_zext"
12956 [(set (reg FLAGS_REG)
12958 (neg:SI (match_operand:SI 1 "register_operand" "0"))
12960 (set (match_operand:DI 0 "register_operand" "=r")
12962 (neg:SI (match_dup 1))))]
12963 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12964 && ix86_unary_operator_ok (NEG, SImode, operands)"
12966 [(set_attr "type" "negnot")
12967 (set_attr "mode" "SI")])
12969 (define_insn "*neg<mode>_ccc_1"
12970 [(set (reg:CCC FLAGS_REG)
12972 [(match_operand:SWI 1 "nonimmediate_operand" "0")
12973 (const_int 0)] UNSPEC_CC_NE))
12974 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
12975 (neg:SWI (match_dup 1)))]
12977 "neg{<imodesuffix>}\t%0"
12978 [(set_attr "type" "negnot")
12979 (set_attr "mode" "<MODE>")])
12981 (define_insn "*neg<mode>_ccc_2"
12982 [(set (reg:CCC FLAGS_REG)
12984 [(match_operand:SWI 1 "nonimmediate_operand" "0")
12985 (const_int 0)] UNSPEC_CC_NE))
12986 (clobber (match_scratch:SWI 0 "=<r>"))]
12988 "neg{<imodesuffix>}\t%0"
12989 [(set_attr "type" "negnot")
12990 (set_attr "mode" "<MODE>")])
12992 (define_expand "x86_neg<mode>_ccc"
12994 [(set (reg:CCC FLAGS_REG)
12995 (unspec:CCC [(match_operand:SWI48 1 "register_operand")
12996 (const_int 0)] UNSPEC_CC_NE))
12997 (set (match_operand:SWI48 0 "register_operand")
12998 (neg:SWI48 (match_dup 1)))])])
13000 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
13001 (define_insn_and_split "*negqi_ext<mode>_1"
13002 [(set (zero_extract:SWI248
13003 (match_operand 0 "int248_register_operand" "+Q,&Q")
13009 (match_operator:SWI248 2 "extract_operator"
13010 [(match_operand 1 "int248_register_operand" "0,!Q")
13012 (const_int 8)]) 0)) 0))
13013 (clobber (reg:CC FLAGS_REG))]
13019 && !(rtx_equal_p (operands[0], operands[1]))"
13020 [(set (zero_extract:SWI248
13021 (match_dup 0) (const_int 8) (const_int 8))
13022 (zero_extract:SWI248
13023 (match_dup 1) (const_int 8) (const_int 8)))
13025 [(set (zero_extract:SWI248
13026 (match_dup 0) (const_int 8) (const_int 8))
13031 [(match_dup 0) (const_int 8) (const_int 8)]) 0)) 0))
13032 (clobber (reg:CC FLAGS_REG))])]
13034 [(set_attr "type" "negnot")
13035 (set_attr "mode" "QI")])
13037 ;; Negate with jump on overflow.
13038 (define_expand "negv<mode>3"
13039 [(parallel [(set (reg:CCO FLAGS_REG)
13041 [(match_operand:SWI 1 "register_operand")
13042 (match_dup 3)] UNSPEC_CC_NE))
13043 (set (match_operand:SWI 0 "register_operand")
13044 (neg:SWI (match_dup 1)))])
13045 (set (pc) (if_then_else
13046 (eq (reg:CCO FLAGS_REG) (const_int 0))
13047 (label_ref (match_operand 2))
13052 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
13056 (define_insn "*negv<mode>3"
13057 [(set (reg:CCO FLAGS_REG)
13058 (unspec:CCO [(match_operand:SWI 1 "nonimmediate_operand" "0")
13059 (match_operand:SWI 2 "const_int_operand")]
13061 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
13062 (neg:SWI (match_dup 1)))]
13063 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
13064 && mode_signbit_p (<MODE>mode, operands[2])"
13065 "neg{<imodesuffix>}\t%0"
13066 [(set_attr "type" "negnot")
13067 (set_attr "mode" "<MODE>")])
13069 ;; Optimize *negsi_1 followed by *cmpsi_ccno_1 (PR target/91384)
13071 [(set (match_operand:SWI 0 "general_reg_operand")
13072 (match_operand:SWI 1 "general_reg_operand"))
13073 (parallel [(set (match_dup 0) (neg:SWI (match_dup 0)))
13074 (clobber (reg:CC FLAGS_REG))])
13075 (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))]
13077 [(set (match_dup 0) (match_dup 1))
13078 (parallel [(set (reg:CCZ FLAGS_REG)
13079 (compare:CCZ (neg:SWI (match_dup 0)) (const_int 0)))
13080 (set (match_dup 0) (neg:SWI (match_dup 0)))])])
13082 ;; Special expand pattern to handle integer mode abs
13084 (define_expand "abs<mode>2"
13086 [(set (match_operand:SDWIM 0 "register_operand")
13088 (match_operand:SDWIM 1 "general_operand")))
13089 (clobber (reg:CC FLAGS_REG))])]
13091 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)"
13093 if (TARGET_EXPAND_ABS)
13095 machine_mode mode = <MODE>mode;
13096 operands[1] = force_reg (mode, operands[1]);
13098 /* Generate rtx abs using:
13099 abs (x) = (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)) */
13101 rtx shift_amount = gen_int_mode (GET_MODE_PRECISION (mode) - 1, QImode);
13102 rtx shift_dst = expand_simple_binop (mode, ASHIFTRT, operands[1],
13103 shift_amount, NULL_RTX,
13105 rtx xor_dst = expand_simple_binop (mode, XOR, shift_dst, operands[1],
13106 operands[0], 0, OPTAB_DIRECT);
13107 rtx minus_dst = expand_simple_binop (mode, MINUS, xor_dst, shift_dst,
13108 operands[0], 0, OPTAB_DIRECT);
13109 if (!rtx_equal_p (minus_dst, operands[0]))
13110 emit_move_insn (operands[0], minus_dst);
13115 (define_insn_and_split "*abs<dwi>2_doubleword"
13116 [(set (match_operand:<DWI> 0 "register_operand")
13118 (match_operand:<DWI> 1 "general_operand")))
13119 (clobber (reg:CC FLAGS_REG))]
13121 && ix86_pre_reload_split ()"
13125 [(set (reg:CCC FLAGS_REG)
13126 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
13127 (set (match_dup 2) (neg:DWIH (match_dup 1)))])
13129 [(set (match_dup 5)
13130 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
13133 (clobber (reg:CC FLAGS_REG))])
13135 [(set (reg:CCGOC FLAGS_REG)
13137 (neg:DWIH (match_dup 5))
13140 (neg:DWIH (match_dup 5)))])
13143 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
13148 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
13152 operands[1] = force_reg (<DWI>mode, operands[1]);
13153 operands[2] = gen_reg_rtx (<DWI>mode);
13155 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
13158 (define_insn_and_split "*nabs<dwi>2_doubleword"
13159 [(set (match_operand:<DWI> 0 "register_operand")
13162 (match_operand:<DWI> 1 "general_operand"))))
13163 (clobber (reg:CC FLAGS_REG))]
13165 && ix86_pre_reload_split ()"
13169 [(set (reg:CCC FLAGS_REG)
13170 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
13171 (set (match_dup 2) (neg:DWIH (match_dup 1)))])
13173 [(set (match_dup 5)
13174 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
13177 (clobber (reg:CC FLAGS_REG))])
13179 [(set (reg:CCGOC FLAGS_REG)
13181 (neg:DWIH (match_dup 5))
13184 (neg:DWIH (match_dup 5)))])
13187 (lt (reg:CCGOC FLAGS_REG) (const_int 0))
13192 (lt (reg:CCGOC FLAGS_REG) (const_int 0))
13196 operands[1] = force_reg (<DWI>mode, operands[1]);
13197 operands[2] = gen_reg_rtx (<DWI>mode);
13199 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
13202 (define_insn_and_split "*abs<mode>2_1"
13203 [(set (match_operand:SWI 0 "register_operand")
13205 (match_operand:SWI 1 "general_operand")))
13206 (clobber (reg:CC FLAGS_REG))]
13208 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
13209 && ix86_pre_reload_split ()"
13213 [(set (reg:CCGOC FLAGS_REG)
13215 (neg:SWI (match_dup 1))
13218 (neg:SWI (match_dup 1)))])
13221 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
13225 operands[1] = force_reg (<MODE>mode, operands[1]);
13226 operands[2] = gen_reg_rtx (<MODE>mode);
13229 (define_insn_and_split "*nabs<mode>2_1"
13230 [(set (match_operand:SWI 0 "register_operand")
13233 (match_operand:SWI 1 "general_operand"))))
13234 (clobber (reg:CC FLAGS_REG))]
13236 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
13237 && ix86_pre_reload_split ()"
13241 [(set (reg:CCGOC FLAGS_REG)
13243 (neg:SWI (match_dup 1))
13246 (neg:SWI (match_dup 1)))])
13249 (lt (reg:CCGOC FLAGS_REG) (const_int 0))
13253 operands[1] = force_reg (<MODE>mode, operands[1]);
13254 operands[2] = gen_reg_rtx (<MODE>mode);
13257 (define_expand "<code>tf2"
13258 [(set (match_operand:TF 0 "register_operand")
13259 (absneg:TF (match_operand:TF 1 "register_operand")))]
13261 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
13263 (define_insn_and_split "*<code>tf2_1"
13264 [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
13266 (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m")))
13267 (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))]
13270 "&& reload_completed"
13271 [(set (match_dup 0)
13272 (<absneg_op>:TF (match_dup 1) (match_dup 2)))]
13276 if (MEM_P (operands[1]))
13277 std::swap (operands[1], operands[2]);
13281 if (operands_match_p (operands[0], operands[2]))
13282 std::swap (operands[1], operands[2]);
13285 [(set_attr "isa" "noavx,noavx,avx,avx")])
13287 (define_insn_and_split "*nabstf2_1"
13288 [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
13291 (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m"))))
13292 (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))]
13295 "&& reload_completed"
13296 [(set (match_dup 0)
13297 (ior:TF (match_dup 1) (match_dup 2)))]
13301 if (MEM_P (operands[1]))
13302 std::swap (operands[1], operands[2]);
13306 if (operands_match_p (operands[0], operands[2]))
13307 std::swap (operands[1], operands[2]);
13310 [(set_attr "isa" "noavx,noavx,avx,avx")])
13312 (define_expand "<code>hf2"
13313 [(set (match_operand:HF 0 "register_operand")
13314 (absneg:HF (match_operand:HF 1 "register_operand")))]
13315 "TARGET_AVX512FP16"
13316 "ix86_expand_fp_absneg_operator (<CODE>, HFmode, operands); DONE;")
13318 (define_expand "<code><mode>2"
13319 [(set (match_operand:X87MODEF 0 "register_operand")
13320 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
13321 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13322 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
13324 ;; Changing of sign for FP values is doable using integer unit too.
13325 (define_insn "*<code><mode>2_i387_1"
13326 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
13328 (match_operand:X87MODEF 1 "register_operand" "0,0")))
13329 (clobber (reg:CC FLAGS_REG))]
13330 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13334 [(set (match_operand:X87MODEF 0 "fp_register_operand")
13335 (absneg:X87MODEF (match_operand:X87MODEF 1 "fp_register_operand")))
13336 (clobber (reg:CC FLAGS_REG))]
13337 "TARGET_80387 && reload_completed"
13338 [(set (match_dup 0) (absneg:X87MODEF (match_dup 1)))])
13341 [(set (match_operand:X87MODEF 0 "general_reg_operand")
13342 (absneg:X87MODEF (match_operand:X87MODEF 1 "general_reg_operand")))
13343 (clobber (reg:CC FLAGS_REG))]
13344 "TARGET_80387 && reload_completed"
13346 "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
13348 (define_insn_and_split "*<code>hf2_1"
13349 [(set (match_operand:HF 0 "register_operand" "=Yv")
13351 (match_operand:HF 1 "register_operand" "Yv")))
13352 (use (match_operand:V8HF 2 "vector_operand" "Yvm"))
13353 (clobber (reg:CC FLAGS_REG))]
13354 "TARGET_AVX512FP16"
13356 "&& reload_completed"
13357 [(set (match_dup 0)
13358 (<absneg_op>:V8HF (match_dup 1) (match_dup 2)))]
13360 operands[0] = lowpart_subreg (V8HFmode, operands[0], HFmode);
13361 operands[1] = lowpart_subreg (V8HFmode, operands[1], HFmode);
13364 (define_insn "*<code><mode>2_1"
13365 [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv,f,!r")
13367 (match_operand:MODEF 1 "register_operand" "0,x,Yv,0,0")))
13368 (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm,X,X"))
13369 (clobber (reg:CC FLAGS_REG))]
13370 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13372 [(set_attr "isa" "noavx,noavx,avx,*,*")
13373 (set (attr "enabled")
13375 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
13377 (eq_attr "alternative" "3,4")
13378 (symbol_ref "TARGET_MIX_SSE_I387")
13379 (const_string "*"))
13381 (eq_attr "alternative" "3,4")
13382 (symbol_ref "true")
13383 (symbol_ref "false"))))])
13386 [(set (match_operand:MODEF 0 "sse_reg_operand")
13388 (match_operand:MODEF 1 "sse_reg_operand")))
13389 (use (match_operand:<ssevecmodef> 2 "vector_operand"))
13390 (clobber (reg:CC FLAGS_REG))]
13391 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13392 && reload_completed"
13393 [(set (match_dup 0)
13394 (<absneg_op>:<ssevecmodef> (match_dup 1) (match_dup 2)))]
13396 machine_mode mode = <MODE>mode;
13397 machine_mode vmode = <ssevecmodef>mode;
13399 operands[0] = lowpart_subreg (vmode, operands[0], mode);
13400 operands[1] = lowpart_subreg (vmode, operands[1], mode);
13402 if (!TARGET_AVX && operands_match_p (operands[0], operands[2]))
13403 std::swap (operands[1], operands[2]);
13407 [(set (match_operand:MODEF 0 "fp_register_operand")
13408 (absneg:MODEF (match_operand:MODEF 1 "fp_register_operand")))
13409 (use (match_operand 2))
13410 (clobber (reg:CC FLAGS_REG))]
13411 "TARGET_80387 && reload_completed"
13412 [(set (match_dup 0) (absneg:MODEF (match_dup 1)))])
13415 [(set (match_operand:MODEF 0 "general_reg_operand")
13416 (absneg:MODEF (match_operand:MODEF 1 "general_reg_operand")))
13417 (use (match_operand 2))
13418 (clobber (reg:CC FLAGS_REG))]
13419 "TARGET_80387 && reload_completed"
13421 "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
13423 (define_insn_and_split "*nabs<mode>2_1"
13424 [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv")
13427 (match_operand:MODEF 1 "register_operand" "0,x,Yv"))))
13428 (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm"))]
13429 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13431 "&& reload_completed"
13432 [(set (match_dup 0)
13433 (ior:<ssevecmodef> (match_dup 1) (match_dup 2)))]
13435 machine_mode mode = <MODE>mode;
13436 machine_mode vmode = <ssevecmodef>mode;
13438 operands[0] = lowpart_subreg (vmode, operands[0], mode);
13439 operands[1] = lowpart_subreg (vmode, operands[1], mode);
13441 if (!TARGET_AVX && operands_match_p (operands[0], operands[2]))
13442 std::swap (operands[1], operands[2]);
13444 [(set_attr "isa" "noavx,noavx,avx")])
13446 ;; Conditionalize these after reload. If they match before reload, we
13447 ;; lose the clobber and ability to use integer instructions.
13449 (define_insn "*<code><mode>2_i387"
13450 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
13451 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
13452 "TARGET_80387 && reload_completed"
13453 "<absneg_mnemonic>"
13454 [(set_attr "type" "fsgn")
13455 (set_attr "mode" "<MODE>")])
13457 ;; Copysign instructions
13459 (define_expand "copysign<mode>3"
13460 [(match_operand:SSEMODEF 0 "register_operand")
13461 (match_operand:SSEMODEF 1 "nonmemory_operand")
13462 (match_operand:SSEMODEF 2 "register_operand")]
13463 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13464 || (TARGET_SSE && (<MODE>mode == TFmode))
13465 || (TARGET_AVX512FP16 && (<MODE>mode ==HFmode))"
13466 "ix86_expand_copysign (operands); DONE;")
13468 (define_expand "xorsign<mode>3"
13469 [(match_operand:MODEFH 0 "register_operand")
13470 (match_operand:MODEFH 1 "register_operand")
13471 (match_operand:MODEFH 2 "register_operand")]
13472 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13473 || <MODE>mode == HFmode"
13475 if (rtx_equal_p (operands[1], operands[2]))
13476 emit_insn (gen_abs<mode>2 (operands[0], operands[1]));
13478 ix86_expand_xorsign (operands);
13482 ;; One complement instructions
13484 (define_expand "one_cmpl<mode>2"
13485 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
13486 (not:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
13488 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
13490 (define_insn_and_split "*one_cmpl<dwi>2_doubleword"
13491 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
13492 (not:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))]
13493 "ix86_unary_operator_ok (NOT, <DWI>mode, operands)"
13495 "&& reload_completed"
13496 [(set (match_dup 0)
13497 (not:DWIH (match_dup 1)))
13499 (not:DWIH (match_dup 3)))]
13500 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
13502 (define_insn "*one_cmpl<mode>2_1"
13503 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,?k")
13504 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0,k")))]
13505 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
13507 not{<imodesuffix>}\t%0
13509 [(set_attr "isa" "*,<kmov_isa>")
13510 (set_attr "type" "negnot,msklog")
13511 (set_attr "mode" "<MODE>")])
13513 (define_insn "*one_cmplsi2_1_zext"
13514 [(set (match_operand:DI 0 "register_operand" "=r,?k")
13516 (not:SI (match_operand:SI 1 "register_operand" "0,k"))))]
13517 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
13521 [(set_attr "isa" "x64,avx512bw_512")
13522 (set_attr "type" "negnot,msklog")
13523 (set_attr "mode" "SI,SI")])
13525 (define_insn "*one_cmplqi2_1"
13526 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,?k")
13527 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
13528 "ix86_unary_operator_ok (NOT, QImode, operands)"
13533 [(set_attr "isa" "*,*,avx512f")
13534 (set_attr "type" "negnot,negnot,msklog")
13536 (cond [(eq_attr "alternative" "1")
13537 (const_string "SI")
13538 (and (eq_attr "alternative" "2")
13539 (match_test "!TARGET_AVX512DQ"))
13540 (const_string "HI")
13542 (const_string "QI")))
13543 ;; Potential partial reg stall on alternative 1.
13544 (set (attr "preferred_for_speed")
13545 (cond [(eq_attr "alternative" "1")
13546 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
13547 (symbol_ref "true")))])
13549 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
13550 (define_insn_and_split "*one_cmpl<mode>_1_slp"
13551 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
13552 (not:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")))]
13553 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
13555 not{<imodesuffix>}\t%0
13557 "&& reload_completed
13558 && !(rtx_equal_p (operands[0], operands[1]))"
13559 [(set (strict_low_part (match_dup 0)) (match_dup 1))
13560 (set (strict_low_part (match_dup 0))
13561 (not:SWI12 (match_dup 0)))]
13563 [(set_attr "type" "negnot")
13564 (set_attr "mode" "<MODE>")])
13566 (define_insn "*one_cmpl<mode>2_2"
13567 [(set (reg FLAGS_REG)
13568 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
13570 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
13571 (not:SWI (match_dup 1)))]
13572 "ix86_match_ccmode (insn, CCNOmode)
13573 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
13575 [(set_attr "type" "alu1")
13576 (set_attr "mode" "<MODE>")])
13579 [(set (match_operand 0 "flags_reg_operand")
13580 (match_operator 2 "compare_operator"
13581 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
13583 (set (match_operand:SWI 1 "nonimmediate_operand")
13584 (not:SWI (match_dup 3)))]
13585 "ix86_match_ccmode (insn, CCNOmode)"
13586 [(parallel [(set (match_dup 0)
13587 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
13590 (xor:SWI (match_dup 3) (const_int -1)))])])
13592 (define_insn "*one_cmplsi2_2_zext"
13593 [(set (reg FLAGS_REG)
13594 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
13596 (set (match_operand:DI 0 "register_operand" "=r")
13597 (zero_extend:DI (not:SI (match_dup 1))))]
13598 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
13599 && ix86_unary_operator_ok (NOT, SImode, operands)"
13601 [(set_attr "type" "alu1")
13602 (set_attr "mode" "SI")])
13605 [(set (match_operand 0 "flags_reg_operand")
13606 (match_operator 2 "compare_operator"
13607 [(not:SI (match_operand:SI 3 "register_operand"))
13609 (set (match_operand:DI 1 "register_operand")
13610 (zero_extend:DI (not:SI (match_dup 3))))]
13611 "ix86_match_ccmode (insn, CCNOmode)"
13612 [(parallel [(set (match_dup 0)
13613 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
13616 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
13618 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
13619 (define_insn_and_split "*one_cmplqi_ext<mode>_1"
13620 [(set (zero_extract:SWI248
13621 (match_operand 0 "int248_register_operand" "+Q,&Q")
13627 (match_operator:SWI248 2 "extract_operator"
13628 [(match_operand 1 "int248_register_operand" "0,!Q")
13630 (const_int 8)]) 0)) 0))]
13636 && !(rtx_equal_p (operands[0], operands[1]))"
13637 [(set (zero_extract:SWI248
13638 (match_dup 0) (const_int 8) (const_int 8))
13639 (zero_extract:SWI248
13640 (match_dup 1) (const_int 8) (const_int 8)))
13641 (set (zero_extract:SWI248
13642 (match_dup 0) (const_int 8) (const_int 8))
13647 [(match_dup 0) (const_int 8) (const_int 8)]) 0)) 0))]
13649 [(set_attr "type" "negnot")
13650 (set_attr "mode" "QI")])
13652 ;; Shift instructions
13654 ;; DImode shifts are implemented using the i386 "shift double" opcode,
13655 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
13656 ;; is variable, then the count is in %cl and the "imm" operand is dropped
13657 ;; from the assembler input.
13659 ;; This instruction shifts the target reg/mem as usual, but instead of
13660 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
13661 ;; is a left shift double, bits are taken from the high order bits of
13662 ;; reg, else if the insn is a shift right double, bits are taken from the
13663 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
13664 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
13666 ;; Since sh[lr]d does not change the `reg' operand, that is done
13667 ;; separately, making all shifts emit pairs of shift double and normal
13668 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
13669 ;; support a 63 bit shift, each shift where the count is in a reg expands
13670 ;; to a pair of shifts, a branch, a shift by 32 and a label.
13672 ;; If the shift count is a constant, we need never emit more than one
13673 ;; shift pair, instead using moves and sign extension for counts greater
13676 (define_expand "ashl<mode>3"
13677 [(set (match_operand:SDWIM 0 "<shift_operand>")
13678 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
13679 (match_operand:QI 2 "nonmemory_operand")))]
13681 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
13683 (define_insn_and_split "*ashl<dwi>3_doubleword_mask"
13684 [(set (match_operand:<DWI> 0 "register_operand")
13686 (match_operand:<DWI> 1 "register_operand")
13689 (match_operand 2 "int248_register_operand" "c")
13690 (match_operand 3 "const_int_operand")) 0)))
13691 (clobber (reg:CC FLAGS_REG))]
13692 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
13693 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
13694 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
13695 && ix86_pre_reload_split ()"
13699 [(set (match_dup 6)
13700 (ior:DWIH (ashift:DWIH (match_dup 6)
13701 (and:QI (match_dup 2) (match_dup 8)))
13703 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
13704 (minus:QI (match_dup 9)
13705 (and:QI (match_dup 2) (match_dup 8)))) 0)))
13706 (clobber (reg:CC FLAGS_REG))])
13708 [(set (match_dup 4)
13709 (ashift:DWIH (match_dup 5) (match_dup 2)))
13710 (clobber (reg:CC FLAGS_REG))])]
13712 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
13714 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
13715 operands[2] = gen_lowpart (QImode, operands[2]);
13716 emit_insn (gen_ashl<dwi>3_doubleword (operands[0], operands[1],
13721 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
13723 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
13724 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
13726 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13727 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13730 xops[0] = gen_reg_rtx (GET_MODE (operands[2]));
13731 xops[1] = operands[2];
13732 xops[2] = GEN_INT (INTVAL (operands[3])
13733 & ((<MODE_SIZE> * BITS_PER_UNIT) - 1));
13734 ix86_expand_binary_operator (AND, GET_MODE (operands[2]), xops);
13735 operands[2] = xops[0];
13738 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
13739 operands[2] = gen_lowpart (QImode, operands[2]);
13741 if (!rtx_equal_p (operands[6], operands[7]))
13742 emit_move_insn (operands[6], operands[7]);
13745 (define_insn_and_split "*ashl<dwi>3_doubleword_mask_1"
13746 [(set (match_operand:<DWI> 0 "register_operand")
13748 (match_operand:<DWI> 1 "register_operand")
13750 (match_operand:QI 2 "register_operand" "c")
13751 (match_operand:QI 3 "const_int_operand"))))
13752 (clobber (reg:CC FLAGS_REG))]
13753 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
13754 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
13755 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
13756 && ix86_pre_reload_split ()"
13760 [(set (match_dup 6)
13761 (ior:DWIH (ashift:DWIH (match_dup 6)
13762 (and:QI (match_dup 2) (match_dup 8)))
13764 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
13765 (minus:QI (match_dup 9)
13766 (and:QI (match_dup 2) (match_dup 8)))) 0)))
13767 (clobber (reg:CC FLAGS_REG))])
13769 [(set (match_dup 4)
13770 (ashift:DWIH (match_dup 5) (match_dup 2)))
13771 (clobber (reg:CC FLAGS_REG))])]
13773 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
13775 emit_insn (gen_ashl<dwi>3_doubleword (operands[0], operands[1],
13780 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
13782 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
13783 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
13785 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13786 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13788 rtx tem = gen_reg_rtx (QImode);
13789 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
13793 if (!rtx_equal_p (operands[6], operands[7]))
13794 emit_move_insn (operands[6], operands[7]);
13797 (define_insn "ashl<mode>3_doubleword"
13798 [(set (match_operand:DWI 0 "register_operand" "=&r")
13799 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n")
13800 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
13801 (clobber (reg:CC FLAGS_REG))]
13804 [(set_attr "type" "multi")])
13807 [(set (match_operand:DWI 0 "register_operand")
13808 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
13809 (match_operand:QI 2 "nonmemory_operand")))
13810 (clobber (reg:CC FLAGS_REG))]
13811 "epilogue_completed"
13813 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
13815 ;; By default we don't ask for a scratch register, because when DWImode
13816 ;; values are manipulated, registers are already at a premium. But if
13817 ;; we have one handy, we won't turn it away.
13820 [(match_scratch:DWIH 3 "r")
13821 (parallel [(set (match_operand:<DWI> 0 "register_operand")
13823 (match_operand:<DWI> 1 "nonmemory_operand")
13824 (match_operand:QI 2 "nonmemory_operand")))
13825 (clobber (reg:CC FLAGS_REG))])
13829 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
13831 (define_insn_and_split "*ashl<dwi>3_doubleword_highpart"
13832 [(set (match_operand:<DWI> 0 "register_operand" "=r")
13834 (any_extend:<DWI> (match_operand:DWIH 1 "nonimmediate_operand" "rm"))
13835 (match_operand:QI 2 "const_int_operand")))
13836 (clobber (reg:CC FLAGS_REG))]
13837 "INTVAL (operands[2]) >= <MODE_SIZE> * BITS_PER_UNIT
13838 && INTVAL (operands[2]) < <MODE_SIZE> * BITS_PER_UNIT * 2"
13840 "&& reload_completed"
13843 split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[3]);
13844 int bits = INTVAL (operands[2]) - (<MODE_SIZE> * BITS_PER_UNIT);
13845 if (!rtx_equal_p (operands[3], operands[1]))
13846 emit_move_insn (operands[3], operands[1]);
13848 emit_insn (gen_ashl<mode>3 (operands[3], operands[3], GEN_INT (bits)));
13849 ix86_expand_clear (operands[0]);
13853 (define_insn "x86_64_shld"
13854 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
13855 (ior:DI (ashift:DI (match_dup 0)
13856 (and:QI (match_operand:QI 2 "nonmemory_operand" "Jc")
13861 (match_operand:DI 1 "register_operand" "r"))
13862 (minus:QI (const_int 64)
13863 (and:QI (match_dup 2) (const_int 63)))) 0)))
13864 (clobber (reg:CC FLAGS_REG))]
13866 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
13867 [(set_attr "type" "ishift")
13868 (set_attr "prefix_0f" "1")
13869 (set_attr "mode" "DI")
13870 (set_attr "athlon_decode" "vector")
13871 (set_attr "amdfam10_decode" "vector")
13872 (set_attr "bdver1_decode" "vector")])
13874 (define_insn "x86_64_shld_1"
13875 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
13876 (ior:DI (ashift:DI (match_dup 0)
13877 (match_operand:QI 2 "const_0_to_63_operand"))
13881 (match_operand:DI 1 "register_operand" "r"))
13882 (match_operand:QI 3 "const_0_to_255_operand")) 0)))
13883 (clobber (reg:CC FLAGS_REG))]
13885 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])"
13886 "shld{q}\t{%2, %1, %0|%0, %1, %2}"
13887 [(set_attr "type" "ishift")
13888 (set_attr "prefix_0f" "1")
13889 (set_attr "mode" "DI")
13890 (set_attr "length_immediate" "1")
13891 (set_attr "athlon_decode" "vector")
13892 (set_attr "amdfam10_decode" "vector")
13893 (set_attr "bdver1_decode" "vector")])
13895 (define_insn_and_split "*x86_64_shld_shrd_1_nozext"
13896 [(set (match_operand:DI 0 "nonimmediate_operand")
13897 (ior:DI (ashift:DI (match_operand:DI 4 "nonimmediate_operand")
13898 (match_operand:QI 2 "const_0_to_63_operand"))
13900 (match_operand:DI 1 "nonimmediate_operand")
13901 (match_operand:QI 3 "const_0_to_63_operand"))))
13902 (clobber (reg:CC FLAGS_REG))]
13904 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])
13905 && ix86_pre_reload_split ()"
13910 if (rtx_equal_p (operands[4], operands[0]))
13912 operands[1] = force_reg (DImode, operands[1]);
13913 emit_insn (gen_x86_64_shld_1 (operands[0], operands[1], operands[2], operands[3]));
13915 else if (rtx_equal_p (operands[1], operands[0]))
13917 operands[4] = force_reg (DImode, operands[4]);
13918 emit_insn (gen_x86_64_shrd_1 (operands[0], operands[4], operands[3], operands[2]));
13922 operands[1] = force_reg (DImode, operands[1]);
13923 rtx tmp = gen_reg_rtx (DImode);
13924 emit_move_insn (tmp, operands[4]);
13925 emit_insn (gen_x86_64_shld_1 (tmp, operands[1], operands[2], operands[3]));
13926 emit_move_insn (operands[0], tmp);
13931 (define_insn_and_split "*x86_64_shld_2"
13932 [(set (match_operand:DI 0 "nonimmediate_operand")
13933 (ior:DI (ashift:DI (match_dup 0)
13934 (match_operand:QI 2 "nonmemory_operand"))
13935 (lshiftrt:DI (match_operand:DI 1 "register_operand")
13936 (minus:QI (const_int 64) (match_dup 2)))))
13937 (clobber (reg:CC FLAGS_REG))]
13938 "TARGET_64BIT && ix86_pre_reload_split ()"
13941 [(parallel [(set (match_dup 0)
13942 (ior:DI (ashift:DI (match_dup 0)
13943 (and:QI (match_dup 2) (const_int 63)))
13946 (zero_extend:TI (match_dup 1))
13947 (minus:QI (const_int 64)
13948 (and:QI (match_dup 2)
13949 (const_int 63)))) 0)))
13950 (clobber (reg:CC FLAGS_REG))])])
13952 (define_insn "x86_shld"
13953 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
13954 (ior:SI (ashift:SI (match_dup 0)
13955 (and:QI (match_operand:QI 2 "nonmemory_operand" "Ic")
13960 (match_operand:SI 1 "register_operand" "r"))
13961 (minus:QI (const_int 32)
13962 (and:QI (match_dup 2) (const_int 31)))) 0)))
13963 (clobber (reg:CC FLAGS_REG))]
13965 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
13966 [(set_attr "type" "ishift")
13967 (set_attr "prefix_0f" "1")
13968 (set_attr "mode" "SI")
13969 (set_attr "pent_pair" "np")
13970 (set_attr "athlon_decode" "vector")
13971 (set_attr "amdfam10_decode" "vector")
13972 (set_attr "bdver1_decode" "vector")])
13974 (define_insn "x86_shld_1"
13975 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
13976 (ior:SI (ashift:SI (match_dup 0)
13977 (match_operand:QI 2 "const_0_to_31_operand"))
13981 (match_operand:SI 1 "register_operand" "r"))
13982 (match_operand:QI 3 "const_0_to_63_operand")) 0)))
13983 (clobber (reg:CC FLAGS_REG))]
13984 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])"
13985 "shld{l}\t{%2, %1, %0|%0, %1, %2}"
13986 [(set_attr "type" "ishift")
13987 (set_attr "prefix_0f" "1")
13988 (set_attr "length_immediate" "1")
13989 (set_attr "mode" "SI")
13990 (set_attr "pent_pair" "np")
13991 (set_attr "athlon_decode" "vector")
13992 (set_attr "amdfam10_decode" "vector")
13993 (set_attr "bdver1_decode" "vector")])
13995 (define_insn_and_split "*x86_shld_shrd_1_nozext"
13996 [(set (match_operand:SI 0 "nonimmediate_operand")
13997 (ior:SI (ashift:SI (match_operand:SI 4 "nonimmediate_operand")
13998 (match_operand:QI 2 "const_0_to_31_operand"))
14000 (match_operand:SI 1 "nonimmediate_operand")
14001 (match_operand:QI 3 "const_0_to_31_operand"))))
14002 (clobber (reg:CC FLAGS_REG))]
14003 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])
14004 && ix86_pre_reload_split ()"
14009 if (rtx_equal_p (operands[4], operands[0]))
14011 operands[1] = force_reg (SImode, operands[1]);
14012 emit_insn (gen_x86_shld_1 (operands[0], operands[1], operands[2], operands[3]));
14014 else if (rtx_equal_p (operands[1], operands[0]))
14016 operands[4] = force_reg (SImode, operands[4]);
14017 emit_insn (gen_x86_shrd_1 (operands[0], operands[4], operands[3], operands[2]));
14021 operands[1] = force_reg (SImode, operands[1]);
14022 rtx tmp = gen_reg_rtx (SImode);
14023 emit_move_insn (tmp, operands[4]);
14024 emit_insn (gen_x86_shld_1 (tmp, operands[1], operands[2], operands[3]));
14025 emit_move_insn (operands[0], tmp);
14030 (define_insn_and_split "*x86_shld_2"
14031 [(set (match_operand:SI 0 "nonimmediate_operand")
14032 (ior:SI (ashift:SI (match_dup 0)
14033 (match_operand:QI 2 "nonmemory_operand"))
14034 (lshiftrt:SI (match_operand:SI 1 "register_operand")
14035 (minus:QI (const_int 32) (match_dup 2)))))
14036 (clobber (reg:CC FLAGS_REG))]
14037 "TARGET_64BIT && ix86_pre_reload_split ()"
14040 [(parallel [(set (match_dup 0)
14041 (ior:SI (ashift:SI (match_dup 0)
14042 (and:QI (match_dup 2) (const_int 31)))
14045 (zero_extend:DI (match_dup 1))
14046 (minus:QI (const_int 32)
14047 (and:QI (match_dup 2)
14048 (const_int 31)))) 0)))
14049 (clobber (reg:CC FLAGS_REG))])])
14051 (define_expand "@x86_shift<mode>_adj_1"
14052 [(set (reg:CCZ FLAGS_REG)
14053 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
14056 (set (match_operand:SWI48 0 "register_operand")
14057 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
14058 (match_operand:SWI48 1 "register_operand")
14061 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
14062 (match_operand:SWI48 3 "register_operand")
14065 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
14067 (define_expand "@x86_shift<mode>_adj_2"
14068 [(use (match_operand:SWI48 0 "register_operand"))
14069 (use (match_operand:SWI48 1 "register_operand"))
14070 (use (match_operand:QI 2 "register_operand"))]
14073 rtx_code_label *label = gen_label_rtx ();
14076 emit_insn (gen_testqi_ccz_1 (operands[2],
14077 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
14079 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
14080 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
14081 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
14082 gen_rtx_LABEL_REF (VOIDmode, label),
14084 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
14085 JUMP_LABEL (tmp) = label;
14087 emit_move_insn (operands[0], operands[1]);
14088 ix86_expand_clear (operands[1]);
14090 emit_label (label);
14091 LABEL_NUSES (label) = 1;
14096 ;; Avoid useless masking of count operand.
14097 (define_insn_and_split "*ashl<mode>3_mask"
14098 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14100 (match_operand:SWI48 1 "nonimmediate_operand")
14103 (match_operand 2 "int248_register_operand" "c,r")
14104 (match_operand 3 "const_int_operand")) 0)))
14105 (clobber (reg:CC FLAGS_REG))]
14106 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
14107 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
14108 == GET_MODE_BITSIZE (<MODE>mode)-1
14109 && ix86_pre_reload_split ()"
14113 [(set (match_dup 0)
14114 (ashift:SWI48 (match_dup 1)
14116 (clobber (reg:CC FLAGS_REG))])]
14118 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14119 operands[2] = gen_lowpart (QImode, operands[2]);
14121 [(set_attr "isa" "*,bmi2")])
14123 (define_insn_and_split "*ashl<mode>3_mask_1"
14124 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14126 (match_operand:SWI48 1 "nonimmediate_operand")
14128 (match_operand:QI 2 "register_operand" "c,r")
14129 (match_operand:QI 3 "const_int_operand"))))
14130 (clobber (reg:CC FLAGS_REG))]
14131 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
14132 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
14133 == GET_MODE_BITSIZE (<MODE>mode)-1
14134 && ix86_pre_reload_split ()"
14138 [(set (match_dup 0)
14139 (ashift:SWI48 (match_dup 1)
14141 (clobber (reg:CC FLAGS_REG))])]
14143 [(set_attr "isa" "*,bmi2")])
14145 (define_insn "*bmi2_ashl<mode>3_1"
14146 [(set (match_operand:SWI48 0 "register_operand" "=r")
14147 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14148 (match_operand:SWI48 2 "register_operand" "r")))]
14150 "shlx\t{%2, %1, %0|%0, %1, %2}"
14151 [(set_attr "type" "ishiftx")
14152 (set_attr "mode" "<MODE>")])
14154 (define_insn "*ashl<mode>3_1"
14155 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,?k")
14156 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm,k")
14157 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r,<KS>")))
14158 (clobber (reg:CC FLAGS_REG))]
14159 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
14161 switch (get_attr_type (insn))
14169 gcc_assert (operands[2] == const1_rtx);
14170 gcc_assert (rtx_equal_p (operands[0], operands[1]));
14171 return "add{<imodesuffix>}\t%0, %0";
14174 if (operands[2] == const1_rtx
14175 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14176 return "sal{<imodesuffix>}\t%0";
14178 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14181 [(set_attr "isa" "*,*,bmi2,<kmov_isa>")
14183 (cond [(eq_attr "alternative" "1")
14184 (const_string "lea")
14185 (eq_attr "alternative" "2")
14186 (const_string "ishiftx")
14187 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14188 (match_operand 0 "register_operand"))
14189 (match_operand 2 "const1_operand"))
14190 (const_string "alu")
14191 (eq_attr "alternative" "3")
14192 (const_string "msklog")
14194 (const_string "ishift")))
14195 (set (attr "length_immediate")
14197 (ior (eq_attr "type" "alu")
14198 (and (eq_attr "type" "ishift")
14199 (and (match_operand 2 "const1_operand")
14200 (ior (match_test "TARGET_SHIFT1")
14201 (match_test "optimize_function_for_size_p (cfun)")))))
14203 (const_string "*")))
14204 (set_attr "mode" "<MODE>")])
14206 ;; Convert shift to the shiftx pattern to avoid flags dependency.
14208 [(set (match_operand:SWI48 0 "register_operand")
14209 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
14210 (match_operand:QI 2 "register_operand")))
14211 (clobber (reg:CC FLAGS_REG))]
14212 "TARGET_BMI2 && reload_completed"
14213 [(set (match_dup 0)
14214 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
14215 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
14217 (define_insn "*bmi2_ashlsi3_1_zext"
14218 [(set (match_operand:DI 0 "register_operand" "=r")
14220 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
14221 (match_operand:SI 2 "register_operand" "r"))))]
14222 "TARGET_64BIT && TARGET_BMI2"
14223 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
14224 [(set_attr "type" "ishiftx")
14225 (set_attr "mode" "SI")])
14227 (define_insn "*ashlsi3_1_zext"
14228 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
14230 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
14231 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
14232 (clobber (reg:CC FLAGS_REG))]
14233 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
14235 switch (get_attr_type (insn))
14242 gcc_assert (operands[2] == const1_rtx);
14243 return "add{l}\t%k0, %k0";
14246 if (operands[2] == const1_rtx
14247 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14248 return "sal{l}\t%k0";
14250 return "sal{l}\t{%2, %k0|%k0, %2}";
14253 [(set_attr "isa" "*,*,bmi2")
14255 (cond [(eq_attr "alternative" "1")
14256 (const_string "lea")
14257 (eq_attr "alternative" "2")
14258 (const_string "ishiftx")
14259 (and (match_test "TARGET_DOUBLE_WITH_ADD")
14260 (match_operand 2 "const1_operand"))
14261 (const_string "alu")
14263 (const_string "ishift")))
14264 (set (attr "length_immediate")
14266 (ior (eq_attr "type" "alu")
14267 (and (eq_attr "type" "ishift")
14268 (and (match_operand 2 "const1_operand")
14269 (ior (match_test "TARGET_SHIFT1")
14270 (match_test "optimize_function_for_size_p (cfun)")))))
14272 (const_string "*")))
14273 (set_attr "mode" "SI")])
14275 ;; Convert shift to the shiftx pattern to avoid flags dependency.
14277 [(set (match_operand:DI 0 "register_operand")
14279 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
14280 (match_operand:QI 2 "register_operand"))))
14281 (clobber (reg:CC FLAGS_REG))]
14282 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
14283 [(set (match_dup 0)
14284 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
14285 "operands[2] = gen_lowpart (SImode, operands[2]);")
14287 (define_insn "*ashlhi3_1"
14288 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp,?k")
14289 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l,k")
14290 (match_operand:QI 2 "nonmemory_operand" "cI,M,Ww")))
14291 (clobber (reg:CC FLAGS_REG))]
14292 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
14294 switch (get_attr_type (insn))
14301 gcc_assert (operands[2] == const1_rtx);
14302 return "add{w}\t%0, %0";
14305 if (operands[2] == const1_rtx
14306 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14307 return "sal{w}\t%0";
14309 return "sal{w}\t{%2, %0|%0, %2}";
14312 [(set_attr "isa" "*,*,avx512f")
14314 (cond [(eq_attr "alternative" "1")
14315 (const_string "lea")
14316 (eq_attr "alternative" "2")
14317 (const_string "msklog")
14318 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14319 (match_operand 0 "register_operand"))
14320 (match_operand 2 "const1_operand"))
14321 (const_string "alu")
14323 (const_string "ishift")))
14324 (set (attr "length_immediate")
14326 (ior (eq_attr "type" "alu")
14327 (and (eq_attr "type" "ishift")
14328 (and (match_operand 2 "const1_operand")
14329 (ior (match_test "TARGET_SHIFT1")
14330 (match_test "optimize_function_for_size_p (cfun)")))))
14332 (const_string "*")))
14333 (set_attr "mode" "HI,SI,HI")])
14335 (define_insn "*ashlqi3_1"
14336 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp,?k")
14337 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l,k")
14338 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M,Wb")))
14339 (clobber (reg:CC FLAGS_REG))]
14340 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
14342 switch (get_attr_type (insn))
14349 gcc_assert (operands[2] == const1_rtx);
14350 if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
14351 return "add{l}\t%k0, %k0";
14353 return "add{b}\t%0, %0";
14356 if (operands[2] == const1_rtx
14357 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14359 if (get_attr_mode (insn) == MODE_SI)
14360 return "sal{l}\t%k0";
14362 return "sal{b}\t%0";
14366 if (get_attr_mode (insn) == MODE_SI)
14367 return "sal{l}\t{%2, %k0|%k0, %2}";
14369 return "sal{b}\t{%2, %0|%0, %2}";
14373 [(set_attr "isa" "*,*,*,avx512dq")
14375 (cond [(eq_attr "alternative" "2")
14376 (const_string "lea")
14377 (eq_attr "alternative" "3")
14378 (const_string "msklog")
14379 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14380 (match_operand 0 "register_operand"))
14381 (match_operand 2 "const1_operand"))
14382 (const_string "alu")
14384 (const_string "ishift")))
14385 (set (attr "length_immediate")
14387 (ior (eq_attr "type" "alu")
14388 (and (eq_attr "type" "ishift")
14389 (and (match_operand 2 "const1_operand")
14390 (ior (match_test "TARGET_SHIFT1")
14391 (match_test "optimize_function_for_size_p (cfun)")))))
14393 (const_string "*")))
14394 (set_attr "mode" "QI,SI,SI,QI")
14395 ;; Potential partial reg stall on alternative 1.
14396 (set (attr "preferred_for_speed")
14397 (cond [(eq_attr "alternative" "1")
14398 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
14399 (symbol_ref "true")))])
14401 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
14402 (define_insn_and_split "*ashl<mode>3_1_slp"
14403 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
14404 (ashift:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
14405 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
14406 (clobber (reg:CC FLAGS_REG))]
14407 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
14409 if (which_alternative)
14412 switch (get_attr_type (insn))
14415 gcc_assert (operands[2] == const1_rtx);
14416 return "add{<imodesuffix>}\t%0, %0";
14419 if (operands[2] == const1_rtx
14420 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14421 return "sal{<imodesuffix>}\t%0";
14423 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14426 "&& reload_completed
14427 && !(rtx_equal_p (operands[0], operands[1]))"
14428 [(set (strict_low_part (match_dup 0)) (match_dup 1))
14430 [(set (strict_low_part (match_dup 0))
14431 (ashift:SWI12 (match_dup 0) (match_dup 2)))
14432 (clobber (reg:CC FLAGS_REG))])]
14434 [(set (attr "type")
14435 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
14436 (match_operand 2 "const1_operand"))
14437 (const_string "alu")
14439 (const_string "ishift")))
14440 (set (attr "length_immediate")
14442 (ior (eq_attr "type" "alu")
14443 (and (eq_attr "type" "ishift")
14444 (and (match_operand 2 "const1_operand")
14445 (ior (match_test "TARGET_SHIFT1")
14446 (match_test "optimize_function_for_size_p (cfun)")))))
14448 (const_string "*")))
14449 (set_attr "mode" "<MODE>")])
14451 ;; Convert ashift to the lea pattern to avoid flags dependency.
14453 [(set (match_operand:SWI 0 "general_reg_operand")
14454 (ashift:SWI (match_operand:SWI 1 "index_reg_operand")
14455 (match_operand 2 "const_0_to_3_operand")))
14456 (clobber (reg:CC FLAGS_REG))]
14458 && REGNO (operands[0]) != REGNO (operands[1])"
14459 [(set (match_dup 0)
14460 (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
14462 if (<MODE>mode != <LEAMODE>mode)
14464 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
14465 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
14467 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
14470 ;; Convert ashift to the lea pattern to avoid flags dependency.
14472 [(set (match_operand:DI 0 "general_reg_operand")
14474 (ashift:SI (match_operand:SI 1 "index_reg_operand")
14475 (match_operand 2 "const_0_to_3_operand"))))
14476 (clobber (reg:CC FLAGS_REG))]
14477 "TARGET_64BIT && reload_completed
14478 && REGNO (operands[0]) != REGNO (operands[1])"
14479 [(set (match_dup 0)
14480 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
14482 operands[1] = gen_lowpart (SImode, operands[1]);
14483 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
14486 ;; This pattern can't accept a variable shift count, since shifts by
14487 ;; zero don't affect the flags. We assume that shifts by constant
14488 ;; zero are optimized away.
14489 (define_insn "*ashl<mode>3_cmp"
14490 [(set (reg FLAGS_REG)
14492 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
14493 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
14495 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
14496 (ashift:SWI (match_dup 1) (match_dup 2)))]
14497 "(optimize_function_for_size_p (cfun)
14498 || !TARGET_PARTIAL_FLAG_REG_STALL
14499 || (operands[2] == const1_rtx
14501 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
14502 && ix86_match_ccmode (insn, CCGOCmode)
14503 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
14505 switch (get_attr_type (insn))
14508 gcc_assert (operands[2] == const1_rtx);
14509 return "add{<imodesuffix>}\t%0, %0";
14512 if (operands[2] == const1_rtx
14513 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14514 return "sal{<imodesuffix>}\t%0";
14516 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14519 [(set (attr "type")
14520 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14521 (match_operand 0 "register_operand"))
14522 (match_operand 2 "const1_operand"))
14523 (const_string "alu")
14525 (const_string "ishift")))
14526 (set (attr "length_immediate")
14528 (ior (eq_attr "type" "alu")
14529 (and (eq_attr "type" "ishift")
14530 (and (match_operand 2 "const1_operand")
14531 (ior (match_test "TARGET_SHIFT1")
14532 (match_test "optimize_function_for_size_p (cfun)")))))
14534 (const_string "*")))
14535 (set_attr "mode" "<MODE>")])
14537 (define_insn "*ashlsi3_cmp_zext"
14538 [(set (reg FLAGS_REG)
14540 (ashift:SI (match_operand:SI 1 "register_operand" "0")
14541 (match_operand:QI 2 "const_1_to_31_operand"))
14543 (set (match_operand:DI 0 "register_operand" "=r")
14544 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
14546 && (optimize_function_for_size_p (cfun)
14547 || !TARGET_PARTIAL_FLAG_REG_STALL
14548 || (operands[2] == const1_rtx
14550 || TARGET_DOUBLE_WITH_ADD)))
14551 && ix86_match_ccmode (insn, CCGOCmode)
14552 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
14554 switch (get_attr_type (insn))
14557 gcc_assert (operands[2] == const1_rtx);
14558 return "add{l}\t%k0, %k0";
14561 if (operands[2] == const1_rtx
14562 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14563 return "sal{l}\t%k0";
14565 return "sal{l}\t{%2, %k0|%k0, %2}";
14568 [(set (attr "type")
14569 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
14570 (match_operand 2 "const1_operand"))
14571 (const_string "alu")
14573 (const_string "ishift")))
14574 (set (attr "length_immediate")
14576 (ior (eq_attr "type" "alu")
14577 (and (eq_attr "type" "ishift")
14578 (and (match_operand 2 "const1_operand")
14579 (ior (match_test "TARGET_SHIFT1")
14580 (match_test "optimize_function_for_size_p (cfun)")))))
14582 (const_string "*")))
14583 (set_attr "mode" "SI")])
14585 (define_insn "*ashl<mode>3_cconly"
14586 [(set (reg FLAGS_REG)
14588 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
14589 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
14591 (clobber (match_scratch:SWI 0 "=<r>"))]
14592 "(optimize_function_for_size_p (cfun)
14593 || !TARGET_PARTIAL_FLAG_REG_STALL
14594 || (operands[2] == const1_rtx
14596 || TARGET_DOUBLE_WITH_ADD)))
14597 && ix86_match_ccmode (insn, CCGOCmode)"
14599 switch (get_attr_type (insn))
14602 gcc_assert (operands[2] == const1_rtx);
14603 return "add{<imodesuffix>}\t%0, %0";
14606 if (operands[2] == const1_rtx
14607 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14608 return "sal{<imodesuffix>}\t%0";
14610 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14613 [(set (attr "type")
14614 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14615 (match_operand 0 "register_operand"))
14616 (match_operand 2 "const1_operand"))
14617 (const_string "alu")
14619 (const_string "ishift")))
14620 (set (attr "length_immediate")
14622 (ior (eq_attr "type" "alu")
14623 (and (eq_attr "type" "ishift")
14624 (and (match_operand 2 "const1_operand")
14625 (ior (match_test "TARGET_SHIFT1")
14626 (match_test "optimize_function_for_size_p (cfun)")))))
14628 (const_string "*")))
14629 (set_attr "mode" "<MODE>")])
14631 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
14632 (define_insn_and_split "*ashlqi_ext<mode>_1"
14633 [(set (zero_extract:SWI248
14634 (match_operand 0 "int248_register_operand" "+Q,&Q")
14640 (match_operator:SWI248 3 "extract_operator"
14641 [(match_operand 1 "int248_register_operand" "0,!Q")
14644 (match_operand:QI 2 "nonmemory_operand" "cI,cI")) 0))
14645 (clobber (reg:CC FLAGS_REG))]
14648 if (which_alternative)
14651 switch (get_attr_type (insn))
14654 gcc_assert (operands[2] == const1_rtx);
14655 return "add{b}\t%h0, %h0";
14658 if (operands[2] == const1_rtx
14659 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14660 return "sal{b}\t%h0";
14662 return "sal{b}\t{%2, %h0|%h0, %2}";
14666 && !(rtx_equal_p (operands[0], operands[1]))"
14667 [(set (zero_extract:SWI248
14668 (match_dup 0) (const_int 8) (const_int 8))
14671 [(set (zero_extract:SWI248
14672 (match_dup 0) (const_int 8) (const_int 8))
14677 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
14679 (clobber (reg:CC FLAGS_REG))])]
14681 [(set (attr "type")
14682 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
14683 (match_operand 2 "const1_operand"))
14684 (const_string "alu")
14686 (const_string "ishift")))
14687 (set (attr "length_immediate")
14689 (ior (eq_attr "type" "alu")
14690 (and (eq_attr "type" "ishift")
14691 (and (match_operand 2 "const1_operand")
14692 (ior (match_test "TARGET_SHIFT1")
14693 (match_test "optimize_function_for_size_p (cfun)")))))
14695 (const_string "*")))
14696 (set_attr "mode" "QI")])
14698 ;; See comment above `ashl<mode>3' about how this works.
14700 (define_expand "<insn><mode>3"
14701 [(set (match_operand:SDWIM 0 "<shift_operand>")
14702 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
14703 (match_operand:QI 2 "nonmemory_operand")))]
14705 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
14707 ;; Avoid useless masking of count operand.
14708 (define_insn_and_split "*<insn><mode>3_mask"
14709 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14711 (match_operand:SWI48 1 "nonimmediate_operand")
14714 (match_operand 2 "int248_register_operand" "c,r")
14715 (match_operand 3 "const_int_operand")) 0)))
14716 (clobber (reg:CC FLAGS_REG))]
14717 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
14718 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
14719 == GET_MODE_BITSIZE (<MODE>mode)-1
14720 && ix86_pre_reload_split ()"
14724 [(set (match_dup 0)
14725 (any_shiftrt:SWI48 (match_dup 1)
14727 (clobber (reg:CC FLAGS_REG))])]
14729 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14730 operands[2] = gen_lowpart (QImode, operands[2]);
14732 [(set_attr "isa" "*,bmi2")])
14734 (define_insn_and_split "*<insn><mode>3_mask_1"
14735 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14737 (match_operand:SWI48 1 "nonimmediate_operand")
14739 (match_operand:QI 2 "register_operand" "c,r")
14740 (match_operand:QI 3 "const_int_operand"))))
14741 (clobber (reg:CC FLAGS_REG))]
14742 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
14743 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
14744 == GET_MODE_BITSIZE (<MODE>mode)-1
14745 && ix86_pre_reload_split ()"
14749 [(set (match_dup 0)
14750 (any_shiftrt:SWI48 (match_dup 1)
14752 (clobber (reg:CC FLAGS_REG))])]
14754 [(set_attr "isa" "*,bmi2")])
14756 (define_insn_and_split "*<insn><dwi>3_doubleword_mask"
14757 [(set (match_operand:<DWI> 0 "register_operand")
14759 (match_operand:<DWI> 1 "register_operand")
14762 (match_operand 2 "int248_register_operand" "c")
14763 (match_operand 3 "const_int_operand")) 0)))
14764 (clobber (reg:CC FLAGS_REG))]
14765 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
14766 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
14767 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
14768 && ix86_pre_reload_split ()"
14772 [(set (match_dup 4)
14773 (ior:DWIH (lshiftrt:DWIH (match_dup 4)
14774 (and:QI (match_dup 2) (match_dup 8)))
14776 (ashift:<DWI> (zero_extend:<DWI> (match_dup 7))
14777 (minus:QI (match_dup 9)
14778 (and:QI (match_dup 2) (match_dup 8)))) 0)))
14779 (clobber (reg:CC FLAGS_REG))])
14781 [(set (match_dup 6)
14782 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
14783 (clobber (reg:CC FLAGS_REG))])]
14785 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
14787 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14788 operands[2] = gen_lowpart (QImode, operands[2]);
14789 emit_insn (gen_<insn><dwi>3_doubleword (operands[0], operands[1],
14794 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
14796 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
14797 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
14799 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14800 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14803 xops[0] = gen_reg_rtx (GET_MODE (operands[2]));
14804 xops[1] = operands[2];
14805 xops[2] = GEN_INT (INTVAL (operands[3])
14806 & ((<MODE_SIZE> * BITS_PER_UNIT) - 1));
14807 ix86_expand_binary_operator (AND, GET_MODE (operands[2]), xops);
14808 operands[2] = xops[0];
14811 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14812 operands[2] = gen_lowpart (QImode, operands[2]);
14814 if (!rtx_equal_p (operands[4], operands[5]))
14815 emit_move_insn (operands[4], operands[5]);
14818 (define_insn_and_split "*<insn><dwi>3_doubleword_mask_1"
14819 [(set (match_operand:<DWI> 0 "register_operand")
14821 (match_operand:<DWI> 1 "register_operand")
14823 (match_operand:QI 2 "register_operand" "c")
14824 (match_operand:QI 3 "const_int_operand"))))
14825 (clobber (reg:CC FLAGS_REG))]
14826 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
14827 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
14828 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
14829 && ix86_pre_reload_split ()"
14833 [(set (match_dup 4)
14834 (ior:DWIH (lshiftrt:DWIH (match_dup 4)
14835 (and:QI (match_dup 2) (match_dup 8)))
14837 (ashift:<DWI> (zero_extend:<DWI> (match_dup 7))
14838 (minus:QI (match_dup 9)
14839 (and:QI (match_dup 2) (match_dup 8)))) 0)))
14840 (clobber (reg:CC FLAGS_REG))])
14842 [(set (match_dup 6)
14843 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
14844 (clobber (reg:CC FLAGS_REG))])]
14846 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
14848 emit_insn (gen_<insn><dwi>3_doubleword (operands[0], operands[1],
14853 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
14855 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
14856 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
14858 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14859 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14861 rtx tem = gen_reg_rtx (QImode);
14862 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
14866 if (!rtx_equal_p (operands[4], operands[5]))
14867 emit_move_insn (operands[4], operands[5]);
14870 (define_insn_and_split "<insn><mode>3_doubleword"
14871 [(set (match_operand:DWI 0 "register_operand" "=&r")
14872 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
14873 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
14874 (clobber (reg:CC FLAGS_REG))]
14877 "epilogue_completed"
14879 "ix86_split_<insn> (operands, NULL_RTX, <MODE>mode); DONE;"
14880 [(set_attr "type" "multi")])
14882 ;; By default we don't ask for a scratch register, because when DWImode
14883 ;; values are manipulated, registers are already at a premium. But if
14884 ;; we have one handy, we won't turn it away.
14887 [(match_scratch:DWIH 3 "r")
14888 (parallel [(set (match_operand:<DWI> 0 "register_operand")
14890 (match_operand:<DWI> 1 "register_operand")
14891 (match_operand:QI 2 "nonmemory_operand")))
14892 (clobber (reg:CC FLAGS_REG))])
14896 "ix86_split_<insn> (operands, operands[3], <DWI>mode); DONE;")
14898 ;; Split truncations of double word right shifts into x86_shrd_1.
14899 (define_insn_and_split "<insn><dwi>3_doubleword_lowpart"
14900 [(set (match_operand:DWIH 0 "register_operand" "=&r")
14902 (any_shiftrt:<DWI> (match_operand:<DWI> 1 "register_operand" "r")
14903 (match_operand:QI 2 "const_int_operand")) 0))
14904 (clobber (reg:CC FLAGS_REG))]
14905 "UINTVAL (operands[2]) < <MODE_SIZE> * BITS_PER_UNIT"
14907 "&& reload_completed"
14909 [(set (match_dup 0)
14910 (ior:DWIH (lshiftrt:DWIH (match_dup 0) (match_dup 2))
14912 (ashift:<DWI> (zero_extend:<DWI> (match_dup 3))
14913 (match_dup 4)) 0)))
14914 (clobber (reg:CC FLAGS_REG))])]
14916 split_double_mode (<DWI>mode, &operands[1], 1, &operands[1], &operands[3]);
14917 operands[4] = GEN_INT ((<MODE_SIZE> * BITS_PER_UNIT) - INTVAL (operands[2]));
14918 if (!rtx_equal_p (operands[0], operands[1]))
14919 emit_move_insn (operands[0], operands[1]);
14922 (define_insn "x86_64_shrd"
14923 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
14924 (ior:DI (lshiftrt:DI (match_dup 0)
14925 (and:QI (match_operand:QI 2 "nonmemory_operand" "Jc")
14930 (match_operand:DI 1 "register_operand" "r"))
14931 (minus:QI (const_int 64)
14932 (and:QI (match_dup 2) (const_int 63)))) 0)))
14933 (clobber (reg:CC FLAGS_REG))]
14935 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
14936 [(set_attr "type" "ishift")
14937 (set_attr "prefix_0f" "1")
14938 (set_attr "mode" "DI")
14939 (set_attr "athlon_decode" "vector")
14940 (set_attr "amdfam10_decode" "vector")
14941 (set_attr "bdver1_decode" "vector")])
14943 (define_insn "x86_64_shrd_1"
14944 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
14945 (ior:DI (lshiftrt:DI (match_dup 0)
14946 (match_operand:QI 2 "const_0_to_63_operand"))
14950 (match_operand:DI 1 "register_operand" "r"))
14951 (match_operand:QI 3 "const_0_to_255_operand")) 0)))
14952 (clobber (reg:CC FLAGS_REG))]
14954 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])"
14955 "shrd{q}\t{%2, %1, %0|%0, %1, %2}"
14956 [(set_attr "type" "ishift")
14957 (set_attr "prefix_0f" "1")
14958 (set_attr "length_immediate" "1")
14959 (set_attr "mode" "DI")
14960 (set_attr "athlon_decode" "vector")
14961 (set_attr "amdfam10_decode" "vector")
14962 (set_attr "bdver1_decode" "vector")])
14964 (define_insn_and_split "*x86_64_shrd_shld_1_nozext"
14965 [(set (match_operand:DI 0 "nonimmediate_operand")
14966 (ior:DI (lshiftrt:DI (match_operand:DI 4 "nonimmediate_operand")
14967 (match_operand:QI 2 "const_0_to_63_operand"))
14969 (match_operand:DI 1 "nonimmediate_operand")
14970 (match_operand:QI 3 "const_0_to_63_operand"))))
14971 (clobber (reg:CC FLAGS_REG))]
14973 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])
14974 && ix86_pre_reload_split ()"
14979 if (rtx_equal_p (operands[4], operands[0]))
14981 operands[1] = force_reg (DImode, operands[1]);
14982 emit_insn (gen_x86_64_shrd_1 (operands[0], operands[1], operands[2], operands[3]));
14984 else if (rtx_equal_p (operands[1], operands[0]))
14986 operands[4] = force_reg (DImode, operands[4]);
14987 emit_insn (gen_x86_64_shld_1 (operands[0], operands[4], operands[3], operands[2]));
14991 operands[1] = force_reg (DImode, operands[1]);
14992 rtx tmp = gen_reg_rtx (DImode);
14993 emit_move_insn (tmp, operands[4]);
14994 emit_insn (gen_x86_64_shrd_1 (tmp, operands[1], operands[2], operands[3]));
14995 emit_move_insn (operands[0], tmp);
15000 (define_insn_and_split "*x86_64_shrd_2"
15001 [(set (match_operand:DI 0 "nonimmediate_operand")
15002 (ior:DI (lshiftrt:DI (match_dup 0)
15003 (match_operand:QI 2 "nonmemory_operand"))
15004 (ashift:DI (match_operand:DI 1 "register_operand")
15005 (minus:QI (const_int 64) (match_dup 2)))))
15006 (clobber (reg:CC FLAGS_REG))]
15007 "TARGET_64BIT && ix86_pre_reload_split ()"
15010 [(parallel [(set (match_dup 0)
15011 (ior:DI (lshiftrt:DI (match_dup 0)
15012 (and:QI (match_dup 2) (const_int 63)))
15015 (zero_extend:TI (match_dup 1))
15016 (minus:QI (const_int 64)
15017 (and:QI (match_dup 2)
15018 (const_int 63)))) 0)))
15019 (clobber (reg:CC FLAGS_REG))])])
15021 (define_insn "x86_shrd"
15022 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
15023 (ior:SI (lshiftrt:SI (match_dup 0)
15024 (and:QI (match_operand:QI 2 "nonmemory_operand" "Ic")
15029 (match_operand:SI 1 "register_operand" "r"))
15030 (minus:QI (const_int 32)
15031 (and:QI (match_dup 2) (const_int 31)))) 0)))
15032 (clobber (reg:CC FLAGS_REG))]
15034 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
15035 [(set_attr "type" "ishift")
15036 (set_attr "prefix_0f" "1")
15037 (set_attr "mode" "SI")
15038 (set_attr "pent_pair" "np")
15039 (set_attr "athlon_decode" "vector")
15040 (set_attr "amdfam10_decode" "vector")
15041 (set_attr "bdver1_decode" "vector")])
15043 (define_insn "x86_shrd_1"
15044 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
15045 (ior:SI (lshiftrt:SI (match_dup 0)
15046 (match_operand:QI 2 "const_0_to_31_operand"))
15050 (match_operand:SI 1 "register_operand" "r"))
15051 (match_operand:QI 3 "const_0_to_63_operand")) 0)))
15052 (clobber (reg:CC FLAGS_REG))]
15053 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])"
15054 "shrd{l}\t{%2, %1, %0|%0, %1, %2}"
15055 [(set_attr "type" "ishift")
15056 (set_attr "prefix_0f" "1")
15057 (set_attr "length_immediate" "1")
15058 (set_attr "mode" "SI")
15059 (set_attr "pent_pair" "np")
15060 (set_attr "athlon_decode" "vector")
15061 (set_attr "amdfam10_decode" "vector")
15062 (set_attr "bdver1_decode" "vector")])
15064 (define_insn_and_split "*x86_shrd_shld_1_nozext"
15065 [(set (match_operand:SI 0 "nonimmediate_operand")
15066 (ior:SI (lshiftrt:SI (match_operand:SI 4 "nonimmediate_operand")
15067 (match_operand:QI 2 "const_0_to_31_operand"))
15069 (match_operand:SI 1 "nonimmediate_operand")
15070 (match_operand:QI 3 "const_0_to_31_operand"))))
15071 (clobber (reg:CC FLAGS_REG))]
15072 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])
15073 && ix86_pre_reload_split ()"
15078 if (rtx_equal_p (operands[4], operands[0]))
15080 operands[1] = force_reg (SImode, operands[1]);
15081 emit_insn (gen_x86_shrd_1 (operands[0], operands[1], operands[2], operands[3]));
15083 else if (rtx_equal_p (operands[1], operands[0]))
15085 operands[4] = force_reg (SImode, operands[4]);
15086 emit_insn (gen_x86_shld_1 (operands[0], operands[4], operands[3], operands[2]));
15090 operands[1] = force_reg (SImode, operands[1]);
15091 rtx tmp = gen_reg_rtx (SImode);
15092 emit_move_insn (tmp, operands[4]);
15093 emit_insn (gen_x86_shrd_1 (tmp, operands[1], operands[2], operands[3]));
15094 emit_move_insn (operands[0], tmp);
15099 (define_insn_and_split "*x86_shrd_2"
15100 [(set (match_operand:SI 0 "nonimmediate_operand")
15101 (ior:SI (lshiftrt:SI (match_dup 0)
15102 (match_operand:QI 2 "nonmemory_operand"))
15103 (ashift:SI (match_operand:SI 1 "register_operand")
15104 (minus:QI (const_int 32) (match_dup 2)))))
15105 (clobber (reg:CC FLAGS_REG))]
15106 "TARGET_64BIT && ix86_pre_reload_split ()"
15109 [(parallel [(set (match_dup 0)
15110 (ior:SI (lshiftrt:SI (match_dup 0)
15111 (and:QI (match_dup 2) (const_int 31)))
15114 (zero_extend:DI (match_dup 1))
15115 (minus:QI (const_int 32)
15116 (and:QI (match_dup 2)
15117 (const_int 31)))) 0)))
15118 (clobber (reg:CC FLAGS_REG))])])
15120 ;; Base name for insn mnemonic.
15121 (define_mode_attr cvt_mnemonic
15122 [(SI "{cltd|cdq}") (DI "{cqto|cqo}")])
15124 (define_insn "ashr<mode>3_cvt"
15125 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=*d,rm")
15127 (match_operand:SWI48 1 "nonimmediate_operand" "*a,0")
15128 (match_operand:QI 2 "const_int_operand")))
15129 (clobber (reg:CC FLAGS_REG))]
15130 "INTVAL (operands[2]) == GET_MODE_BITSIZE (<MODE>mode)-1
15131 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
15132 && ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
15135 sar{<imodesuffix>}\t{%2, %0|%0, %2}"
15136 [(set_attr "type" "imovx,ishift")
15137 (set_attr "prefix_0f" "0,*")
15138 (set_attr "length_immediate" "0,*")
15139 (set_attr "modrm" "0,1")
15140 (set_attr "mode" "<MODE>")])
15142 (define_insn "*ashrsi3_cvt_zext"
15143 [(set (match_operand:DI 0 "register_operand" "=*d,r")
15145 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
15146 (match_operand:QI 2 "const_int_operand"))))
15147 (clobber (reg:CC FLAGS_REG))]
15148 "TARGET_64BIT && INTVAL (operands[2]) == 31
15149 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
15150 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
15153 sar{l}\t{%2, %k0|%k0, %2}"
15154 [(set_attr "type" "imovx,ishift")
15155 (set_attr "prefix_0f" "0,*")
15156 (set_attr "length_immediate" "0,*")
15157 (set_attr "modrm" "0,1")
15158 (set_attr "mode" "SI")])
15160 (define_expand "@x86_shift<mode>_adj_3"
15161 [(use (match_operand:SWI48 0 "register_operand"))
15162 (use (match_operand:SWI48 1 "register_operand"))
15163 (use (match_operand:QI 2 "register_operand"))]
15166 rtx_code_label *label = gen_label_rtx ();
15169 emit_insn (gen_testqi_ccz_1 (operands[2],
15170 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
15172 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
15173 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
15174 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
15175 gen_rtx_LABEL_REF (VOIDmode, label),
15177 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
15178 JUMP_LABEL (tmp) = label;
15180 emit_move_insn (operands[0], operands[1]);
15181 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
15182 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
15183 emit_label (label);
15184 LABEL_NUSES (label) = 1;
15189 (define_insn "*bmi2_<insn><mode>3_1"
15190 [(set (match_operand:SWI48 0 "register_operand" "=r")
15191 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
15192 (match_operand:SWI48 2 "register_operand" "r")))]
15194 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
15195 [(set_attr "type" "ishiftx")
15196 (set_attr "mode" "<MODE>")])
15198 (define_insn "*ashr<mode>3_1"
15199 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
15201 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
15202 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
15203 (clobber (reg:CC FLAGS_REG))]
15204 "ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
15206 switch (get_attr_type (insn))
15212 if (operands[2] == const1_rtx
15213 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15214 return "sar{<imodesuffix>}\t%0";
15216 return "sar{<imodesuffix>}\t{%2, %0|%0, %2}";
15219 [(set_attr "isa" "*,bmi2")
15220 (set_attr "type" "ishift,ishiftx")
15221 (set (attr "length_immediate")
15223 (and (match_operand 2 "const1_operand")
15224 (ior (match_test "TARGET_SHIFT1")
15225 (match_test "optimize_function_for_size_p (cfun)")))
15227 (const_string "*")))
15228 (set_attr "mode" "<MODE>")])
15230 ;; Specialization of *lshr<mode>3_1 below, extracting the SImode
15231 ;; highpart of a DI to be extracted, but allowing it to be clobbered.
15232 (define_insn_and_split "*highpartdisi2"
15233 [(set (subreg:DI (match_operand:SI 0 "register_operand" "=r,x,?k") 0)
15234 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0,k")
15236 (clobber (reg:CC FLAGS_REG))]
15239 "&& reload_completed"
15241 [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 32)))
15242 (clobber (reg:CC FLAGS_REG))])]
15244 if (SSE_REG_P (operands[0]))
15246 rtx tmp = gen_rtx_REG (V4SImode, REGNO (operands[0]));
15247 emit_insn (gen_sse_shufps_v4si (tmp, tmp, tmp,
15248 const1_rtx, const1_rtx,
15249 GEN_INT (5), GEN_INT (5)));
15252 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
15255 (define_insn "*lshr<mode>3_1"
15256 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,?k")
15258 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm,k")
15259 (match_operand:QI 2 "nonmemory_operand" "c<S>,r,<KS>")))
15260 (clobber (reg:CC FLAGS_REG))]
15261 "ix86_binary_operator_ok (LSHIFTRT, <MODE>mode, operands)"
15263 switch (get_attr_type (insn))
15270 if (operands[2] == const1_rtx
15271 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15272 return "shr{<imodesuffix>}\t%0";
15274 return "shr{<imodesuffix>}\t{%2, %0|%0, %2}";
15277 [(set_attr "isa" "*,bmi2,<kmov_isa>")
15278 (set_attr "type" "ishift,ishiftx,msklog")
15279 (set (attr "length_immediate")
15281 (and (and (match_operand 2 "const1_operand")
15282 (eq_attr "alternative" "0"))
15283 (ior (match_test "TARGET_SHIFT1")
15284 (match_test "optimize_function_for_size_p (cfun)")))
15286 (const_string "*")))
15287 (set_attr "mode" "<MODE>")])
15289 ;; Convert shift to the shiftx pattern to avoid flags dependency.
15291 [(set (match_operand:SWI48 0 "register_operand")
15292 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
15293 (match_operand:QI 2 "register_operand")))
15294 (clobber (reg:CC FLAGS_REG))]
15295 "TARGET_BMI2 && reload_completed"
15296 [(set (match_dup 0)
15297 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
15298 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
15300 (define_insn "*bmi2_<insn>si3_1_zext"
15301 [(set (match_operand:DI 0 "register_operand" "=r")
15303 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
15304 (match_operand:SI 2 "register_operand" "r"))))]
15305 "TARGET_64BIT && TARGET_BMI2"
15306 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
15307 [(set_attr "type" "ishiftx")
15308 (set_attr "mode" "SI")])
15310 (define_insn "*<insn>si3_1_zext"
15311 [(set (match_operand:DI 0 "register_operand" "=r,r")
15313 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
15314 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
15315 (clobber (reg:CC FLAGS_REG))]
15316 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
15318 switch (get_attr_type (insn))
15324 if (operands[2] == const1_rtx
15325 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15326 return "<shift>{l}\t%k0";
15328 return "<shift>{l}\t{%2, %k0|%k0, %2}";
15331 [(set_attr "isa" "*,bmi2")
15332 (set_attr "type" "ishift,ishiftx")
15333 (set (attr "length_immediate")
15335 (and (match_operand 2 "const1_operand")
15336 (ior (match_test "TARGET_SHIFT1")
15337 (match_test "optimize_function_for_size_p (cfun)")))
15339 (const_string "*")))
15340 (set_attr "mode" "SI")])
15342 ;; Convert shift to the shiftx pattern to avoid flags dependency.
15344 [(set (match_operand:DI 0 "register_operand")
15346 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
15347 (match_operand:QI 2 "register_operand"))))
15348 (clobber (reg:CC FLAGS_REG))]
15349 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
15350 [(set (match_dup 0)
15351 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
15352 "operands[2] = gen_lowpart (SImode, operands[2]);")
15354 (define_insn "*ashr<mode>3_1"
15355 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
15357 (match_operand:SWI12 1 "nonimmediate_operand" "0")
15358 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
15359 (clobber (reg:CC FLAGS_REG))]
15360 "ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
15362 if (operands[2] == const1_rtx
15363 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15364 return "sar{<imodesuffix>}\t%0";
15366 return "sar{<imodesuffix>}\t{%2, %0|%0, %2}";
15368 [(set_attr "type" "ishift")
15369 (set (attr "length_immediate")
15371 (and (match_operand 2 "const1_operand")
15372 (ior (match_test "TARGET_SHIFT1")
15373 (match_test "optimize_function_for_size_p (cfun)")))
15375 (const_string "*")))
15376 (set_attr "mode" "<MODE>")])
15378 (define_insn "*lshrqi3_1"
15379 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,?k")
15381 (match_operand:QI 1 "nonimmediate_operand" "0, k")
15382 (match_operand:QI 2 "nonmemory_operand" "cI,Wb")))
15383 (clobber (reg:CC FLAGS_REG))]
15384 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
15386 switch (get_attr_type (insn))
15389 if (operands[2] == const1_rtx
15390 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15391 return "shr{b}\t%0";
15393 return "shr{b}\t{%2, %0|%0, %2}";
15397 gcc_unreachable ();
15400 [(set_attr "isa" "*,avx512dq")
15401 (set_attr "type" "ishift,msklog")
15402 (set (attr "length_immediate")
15404 (and (and (match_operand 2 "const1_operand")
15405 (eq_attr "alternative" "0"))
15406 (ior (match_test "TARGET_SHIFT1")
15407 (match_test "optimize_function_for_size_p (cfun)")))
15409 (const_string "*")))
15410 (set_attr "mode" "QI")])
15412 (define_insn "*lshrhi3_1"
15413 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm, ?k")
15415 (match_operand:HI 1 "nonimmediate_operand" "0, k")
15416 (match_operand:QI 2 "nonmemory_operand" "cI, Ww")))
15417 (clobber (reg:CC FLAGS_REG))]
15418 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
15420 switch (get_attr_type (insn))
15423 if (operands[2] == const1_rtx
15424 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15425 return "shr{w}\t%0";
15427 return "shr{w}\t{%2, %0|%0, %2}";
15431 gcc_unreachable ();
15434 [(set_attr "isa" "*, avx512f")
15435 (set_attr "type" "ishift,msklog")
15436 (set (attr "length_immediate")
15438 (and (and (match_operand 2 "const1_operand")
15439 (eq_attr "alternative" "0"))
15440 (ior (match_test "TARGET_SHIFT1")
15441 (match_test "optimize_function_for_size_p (cfun)")))
15443 (const_string "*")))
15444 (set_attr "mode" "HI")])
15446 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
15447 (define_insn_and_split "*<insn><mode>3_1_slp"
15448 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
15449 (any_shiftrt:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
15450 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
15451 (clobber (reg:CC FLAGS_REG))]
15452 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
15454 if (which_alternative)
15457 if (operands[2] == const1_rtx
15458 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15459 return "<shift>{<imodesuffix>}\t%0";
15461 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
15463 "&& reload_completed
15464 && !(rtx_equal_p (operands[0], operands[1]))"
15465 [(set (strict_low_part (match_dup 0)) (match_dup 1))
15467 [(set (strict_low_part (match_dup 0))
15468 (any_shiftrt:SWI12 (match_dup 0) (match_dup 2)))
15469 (clobber (reg:CC FLAGS_REG))])]
15471 [(set_attr "type" "ishift")
15472 (set (attr "length_immediate")
15474 (and (match_operand 2 "const1_operand")
15475 (ior (match_test "TARGET_SHIFT1")
15476 (match_test "optimize_function_for_size_p (cfun)")))
15478 (const_string "*")))
15479 (set_attr "mode" "<MODE>")])
15481 ;; This pattern can't accept a variable shift count, since shifts by
15482 ;; zero don't affect the flags. We assume that shifts by constant
15483 ;; zero are optimized away.
15484 (define_insn "*<insn><mode>3_cmp"
15485 [(set (reg FLAGS_REG)
15488 (match_operand:SWI 1 "nonimmediate_operand" "0")
15489 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
15491 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
15492 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
15493 "(optimize_function_for_size_p (cfun)
15494 || !TARGET_PARTIAL_FLAG_REG_STALL
15495 || (operands[2] == const1_rtx
15497 && ix86_match_ccmode (insn, CCGOCmode)
15498 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
15500 if (operands[2] == const1_rtx
15501 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15502 return "<shift>{<imodesuffix>}\t%0";
15504 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
15506 [(set_attr "type" "ishift")
15507 (set (attr "length_immediate")
15509 (and (match_operand 2 "const1_operand")
15510 (ior (match_test "TARGET_SHIFT1")
15511 (match_test "optimize_function_for_size_p (cfun)")))
15513 (const_string "*")))
15514 (set_attr "mode" "<MODE>")])
15516 (define_insn "*<insn>si3_cmp_zext"
15517 [(set (reg FLAGS_REG)
15519 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
15520 (match_operand:QI 2 "const_1_to_31_operand"))
15522 (set (match_operand:DI 0 "register_operand" "=r")
15523 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
15525 && (optimize_function_for_size_p (cfun)
15526 || !TARGET_PARTIAL_FLAG_REG_STALL
15527 || (operands[2] == const1_rtx
15529 && ix86_match_ccmode (insn, CCGOCmode)
15530 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
15532 if (operands[2] == const1_rtx
15533 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15534 return "<shift>{l}\t%k0";
15536 return "<shift>{l}\t{%2, %k0|%k0, %2}";
15538 [(set_attr "type" "ishift")
15539 (set (attr "length_immediate")
15541 (and (match_operand 2 "const1_operand")
15542 (ior (match_test "TARGET_SHIFT1")
15543 (match_test "optimize_function_for_size_p (cfun)")))
15545 (const_string "*")))
15546 (set_attr "mode" "SI")])
15548 (define_insn "*<insn><mode>3_cconly"
15549 [(set (reg FLAGS_REG)
15552 (match_operand:SWI 1 "register_operand" "0")
15553 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
15555 (clobber (match_scratch:SWI 0 "=<r>"))]
15556 "(optimize_function_for_size_p (cfun)
15557 || !TARGET_PARTIAL_FLAG_REG_STALL
15558 || (operands[2] == const1_rtx
15560 && ix86_match_ccmode (insn, CCGOCmode)"
15562 if (operands[2] == const1_rtx
15563 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15564 return "<shift>{<imodesuffix>}\t%0";
15566 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
15568 [(set_attr "type" "ishift")
15569 (set (attr "length_immediate")
15571 (and (match_operand 2 "const1_operand")
15572 (ior (match_test "TARGET_SHIFT1")
15573 (match_test "optimize_function_for_size_p (cfun)")))
15575 (const_string "*")))
15576 (set_attr "mode" "<MODE>")])
15578 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
15579 (define_insn_and_split "*<insn>qi_ext<mode>_1"
15580 [(set (zero_extract:SWI248
15581 (match_operand 0 "int248_register_operand" "+Q,&Q")
15587 (match_operator:SWI248 3 "extract_operator"
15588 [(match_operand 1 "int248_register_operand" "0,!Q")
15591 (match_operand:QI 2 "nonmemory_operand" "cI,cI")) 0))
15592 (clobber (reg:CC FLAGS_REG))]
15595 if (which_alternative)
15598 if (operands[2] == const1_rtx
15599 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15600 return "<shift>{b}\t%h0";
15602 return "<shift>{b}\t{%2, %h0|%h0, %2}";
15605 && !(rtx_equal_p (operands[0], operands[1]))"
15606 [(set (zero_extract:SWI248
15607 (match_dup 0) (const_int 8) (const_int 8))
15610 [(set (zero_extract:SWI248
15611 (match_dup 0) (const_int 8) (const_int 8))
15616 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
15618 (clobber (reg:CC FLAGS_REG))])]
15620 [(set_attr "type" "ishift")
15621 (set (attr "length_immediate")
15623 (and (match_operand 2 "const1_operand")
15624 (ior (match_test "TARGET_SHIFT1")
15625 (match_test "optimize_function_for_size_p (cfun)")))
15627 (const_string "*")))
15628 (set_attr "mode" "QI")])
15630 (define_insn_and_split "*extend<dwi>2_doubleword_highpart"
15631 [(set (match_operand:<DWI> 0 "register_operand" "=r")
15633 (ashift:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")
15634 (match_operand:QI 2 "const_int_operand"))
15635 (match_operand:QI 3 "const_int_operand")))
15636 (clobber (reg:CC FLAGS_REG))]
15637 "INTVAL (operands[2]) == INTVAL (operands[3])
15638 && UINTVAL (operands[2]) < <MODE_SIZE> * BITS_PER_UNIT"
15640 "&& reload_completed"
15641 [(parallel [(set (match_dup 4)
15642 (ashift:DWIH (match_dup 4) (match_dup 2)))
15643 (clobber (reg:CC FLAGS_REG))])
15644 (parallel [(set (match_dup 4)
15645 (ashiftrt:DWIH (match_dup 4) (match_dup 2)))
15646 (clobber (reg:CC FLAGS_REG))])]
15647 "split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[4]);")
15649 (define_insn_and_split "*extendv2di2_highpart_stv"
15650 [(set (match_operand:V2DI 0 "register_operand" "=v")
15652 (ashift:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "vm")
15653 (match_operand:QI 2 "const_int_operand"))
15654 (match_operand:QI 3 "const_int_operand")))]
15655 "!TARGET_64BIT && TARGET_STV && TARGET_AVX512VL
15656 && INTVAL (operands[2]) == INTVAL (operands[3])
15657 && UINTVAL (operands[2]) < 32"
15659 "&& reload_completed"
15660 [(set (match_dup 0)
15661 (ashift:V2DI (match_dup 1) (match_dup 2)))
15663 (ashiftrt:V2DI (match_dup 0) (match_dup 2)))])
15665 ;; Rotate instructions
15667 (define_expand "<insn>ti3"
15668 [(set (match_operand:TI 0 "register_operand")
15669 (any_rotate:TI (match_operand:TI 1 "register_operand")
15670 (match_operand:QI 2 "nonmemory_operand")))]
15673 if (const_1_to_63_operand (operands[2], VOIDmode))
15674 emit_insn (gen_ix86_<insn>ti3_doubleword
15675 (operands[0], operands[1], operands[2]));
15676 else if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 64)
15678 operands[1] = force_reg (TImode, operands[1]);
15679 emit_insn (gen_<insn>64ti2_doubleword (operands[0], operands[1]));
15683 rtx amount = force_reg (QImode, operands[2]);
15684 rtx src_lo = gen_lowpart (DImode, operands[1]);
15685 rtx src_hi = gen_highpart (DImode, operands[1]);
15686 rtx tmp_lo = gen_reg_rtx (DImode);
15687 rtx tmp_hi = gen_reg_rtx (DImode);
15688 emit_move_insn (tmp_lo, src_lo);
15689 emit_move_insn (tmp_hi, src_hi);
15690 rtx (*shiftd) (rtx, rtx, rtx)
15691 = (<CODE> == ROTATE) ? gen_x86_64_shld : gen_x86_64_shrd;
15692 emit_insn (shiftd (tmp_lo, src_hi, amount));
15693 emit_insn (shiftd (tmp_hi, src_lo, amount));
15694 rtx dst_lo = gen_lowpart (DImode, operands[0]);
15695 rtx dst_hi = gen_highpart (DImode, operands[0]);
15696 emit_move_insn (dst_lo, tmp_lo);
15697 emit_move_insn (dst_hi, tmp_hi);
15698 emit_insn (gen_x86_shiftdi_adj_1 (dst_lo, dst_hi, amount, tmp_lo));
15703 (define_expand "<insn>di3"
15704 [(set (match_operand:DI 0 "shiftdi_operand")
15705 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
15706 (match_operand:QI 2 "nonmemory_operand")))]
15710 ix86_expand_binary_operator (<CODE>, DImode, operands);
15711 else if (const_1_to_31_operand (operands[2], VOIDmode))
15712 emit_insn (gen_ix86_<insn>di3_doubleword
15713 (operands[0], operands[1], operands[2]));
15714 else if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 32)
15716 operands[1] = force_reg (DImode, operands[1]);
15717 emit_insn (gen_<insn>32di2_doubleword (operands[0], operands[1]));
15725 (define_expand "<insn><mode>3"
15726 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
15727 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
15728 (match_operand:QI 2 "nonmemory_operand")))]
15730 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
15732 ;; Avoid useless masking of count operand.
15733 (define_insn_and_split "*<insn><mode>3_mask"
15734 [(set (match_operand:SWI 0 "nonimmediate_operand")
15736 (match_operand:SWI 1 "nonimmediate_operand")
15739 (match_operand 2 "int248_register_operand" "c")
15740 (match_operand 3 "const_int_operand")) 0)))
15741 (clobber (reg:CC FLAGS_REG))]
15742 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
15743 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15744 == GET_MODE_BITSIZE (<MODE>mode)-1
15745 && ix86_pre_reload_split ()"
15749 [(set (match_dup 0)
15750 (any_rotate:SWI (match_dup 1)
15752 (clobber (reg:CC FLAGS_REG))])]
15754 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
15755 operands[2] = gen_lowpart (QImode, operands[2]);
15759 [(set (match_operand:SWI 0 "register_operand")
15761 (match_operand:SWI 1 "const_int_operand")
15764 (match_operand 2 "int248_register_operand")
15765 (match_operand 3 "const_int_operand")) 0)))]
15766 "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode) - 1))
15767 == GET_MODE_BITSIZE (<MODE>mode) - 1"
15768 [(set (match_dup 4) (match_dup 1))
15770 (any_rotate:SWI (match_dup 4)
15771 (subreg:QI (match_dup 2) 0)))]
15772 "operands[4] = gen_reg_rtx (<MODE>mode);")
15774 (define_insn_and_split "*<insn><mode>3_mask_1"
15775 [(set (match_operand:SWI 0 "nonimmediate_operand")
15777 (match_operand:SWI 1 "nonimmediate_operand")
15779 (match_operand:QI 2 "register_operand" "c")
15780 (match_operand:QI 3 "const_int_operand"))))
15781 (clobber (reg:CC FLAGS_REG))]
15782 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
15783 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15784 == GET_MODE_BITSIZE (<MODE>mode)-1
15785 && ix86_pre_reload_split ()"
15789 [(set (match_dup 0)
15790 (any_rotate:SWI (match_dup 1)
15792 (clobber (reg:CC FLAGS_REG))])])
15795 [(set (match_operand:SWI 0 "register_operand")
15797 (match_operand:SWI 1 "const_int_operand")
15799 (match_operand:QI 2 "register_operand")
15800 (match_operand:QI 3 "const_int_operand"))))]
15801 "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode) - 1))
15802 == GET_MODE_BITSIZE (<MODE>mode) - 1"
15803 [(set (match_dup 4) (match_dup 1))
15805 (any_rotate:SWI (match_dup 4) (match_dup 2)))]
15806 "operands[4] = gen_reg_rtx (<MODE>mode);")
15808 ;; Implement rotation using two double-precision
15809 ;; shift instructions and a scratch register.
15811 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
15812 [(set (match_operand:<DWI> 0 "register_operand" "=r")
15813 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
15814 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
15815 (clobber (reg:CC FLAGS_REG))
15816 (clobber (match_scratch:DWIH 3 "=&r"))]
15820 [(set (match_dup 3) (match_dup 4))
15822 [(set (match_dup 4)
15823 (ior:DWIH (ashift:DWIH (match_dup 4)
15824 (and:QI (match_dup 2) (match_dup 6)))
15826 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
15827 (minus:QI (match_dup 7)
15828 (and:QI (match_dup 2)
15829 (match_dup 6)))) 0)))
15830 (clobber (reg:CC FLAGS_REG))])
15832 [(set (match_dup 5)
15833 (ior:DWIH (ashift:DWIH (match_dup 5)
15834 (and:QI (match_dup 2) (match_dup 6)))
15836 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 3))
15837 (minus:QI (match_dup 7)
15838 (and:QI (match_dup 2)
15839 (match_dup 6)))) 0)))
15840 (clobber (reg:CC FLAGS_REG))])]
15842 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
15843 operands[7] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
15845 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
15848 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
15849 [(set (match_operand:<DWI> 0 "register_operand" "=r")
15850 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
15851 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
15852 (clobber (reg:CC FLAGS_REG))
15853 (clobber (match_scratch:DWIH 3 "=&r"))]
15857 [(set (match_dup 3) (match_dup 4))
15859 [(set (match_dup 4)
15860 (ior:DWIH (lshiftrt:DWIH (match_dup 4)
15861 (and:QI (match_dup 2) (match_dup 6)))
15863 (ashift:<DWI> (zero_extend:<DWI> (match_dup 5))
15864 (minus:QI (match_dup 7)
15865 (and:QI (match_dup 2)
15866 (match_dup 6)))) 0)))
15867 (clobber (reg:CC FLAGS_REG))])
15869 [(set (match_dup 5)
15870 (ior:DWIH (lshiftrt:DWIH (match_dup 5)
15871 (and:QI (match_dup 2) (match_dup 6)))
15873 (ashift:<DWI> (zero_extend:<DWI> (match_dup 3))
15874 (minus:QI (match_dup 7)
15875 (and:QI (match_dup 2)
15876 (match_dup 6)))) 0)))
15877 (clobber (reg:CC FLAGS_REG))])]
15879 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
15880 operands[7] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
15882 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
15885 (define_insn_and_split "<insn>32di2_doubleword"
15886 [(set (match_operand:DI 0 "register_operand" "=r,r")
15887 (any_rotate:DI (match_operand:DI 1 "register_operand" "0,r")
15891 "&& reload_completed"
15892 [(set (match_dup 0) (match_dup 3))
15893 (set (match_dup 2) (match_dup 1))]
15895 split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);
15896 if (rtx_equal_p (operands[0], operands[1]))
15898 emit_insn (gen_swapsi (operands[0], operands[2]));
15903 (define_insn_and_split "<insn>64ti2_doubleword"
15904 [(set (match_operand:TI 0 "register_operand" "=r,r")
15905 (any_rotate:TI (match_operand:TI 1 "register_operand" "0,r")
15909 "&& reload_completed"
15910 [(set (match_dup 0) (match_dup 3))
15911 (set (match_dup 2) (match_dup 1))]
15913 split_double_mode (TImode, &operands[0], 2, &operands[0], &operands[2]);
15914 if (rtx_equal_p (operands[0], operands[1]))
15916 emit_insn (gen_swapdi (operands[0], operands[2]));
15921 (define_mode_attr rorx_immediate_operand
15922 [(SI "const_0_to_31_operand")
15923 (DI "const_0_to_63_operand")])
15925 (define_insn "*bmi2_rorx<mode>3_1"
15926 [(set (match_operand:SWI48 0 "register_operand" "=r")
15928 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
15929 (match_operand:QI 2 "<rorx_immediate_operand>" "<S>")))]
15930 "TARGET_BMI2 && !optimize_function_for_size_p (cfun)"
15931 "rorx\t{%2, %1, %0|%0, %1, %2}"
15932 [(set_attr "type" "rotatex")
15933 (set_attr "mode" "<MODE>")])
15935 (define_insn "*<insn><mode>3_1"
15936 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
15938 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
15939 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
15940 (clobber (reg:CC FLAGS_REG))]
15941 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
15943 switch (get_attr_type (insn))
15949 if (operands[2] == const1_rtx
15950 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15951 return "<rotate>{<imodesuffix>}\t%0";
15953 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
15956 [(set_attr "isa" "*,bmi2")
15957 (set_attr "type" "rotate,rotatex")
15958 (set (attr "preferred_for_size")
15959 (cond [(eq_attr "alternative" "0")
15960 (symbol_ref "true")]
15961 (symbol_ref "false")))
15962 (set (attr "length_immediate")
15964 (and (eq_attr "type" "rotate")
15965 (and (match_operand 2 "const1_operand")
15966 (ior (match_test "TARGET_SHIFT1")
15967 (match_test "optimize_function_for_size_p (cfun)"))))
15969 (const_string "*")))
15970 (set_attr "mode" "<MODE>")])
15972 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
15974 [(set (match_operand:SWI48 0 "register_operand")
15975 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
15976 (match_operand:QI 2 "const_int_operand")))
15977 (clobber (reg:CC FLAGS_REG))]
15978 "TARGET_BMI2 && reload_completed && !optimize_function_for_size_p (cfun)"
15979 [(set (match_dup 0)
15980 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
15982 int bitsize = GET_MODE_BITSIZE (<MODE>mode);
15984 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
15988 [(set (match_operand:SWI48 0 "register_operand")
15989 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
15990 (match_operand:QI 2 "const_int_operand")))
15991 (clobber (reg:CC FLAGS_REG))]
15992 "TARGET_BMI2 && reload_completed && !optimize_function_for_size_p (cfun)"
15993 [(set (match_dup 0)
15994 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
15996 (define_insn "*bmi2_rorxsi3_1_zext"
15997 [(set (match_operand:DI 0 "register_operand" "=r")
15999 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
16000 (match_operand:QI 2 "const_0_to_31_operand"))))]
16001 "TARGET_64BIT && TARGET_BMI2 && !optimize_function_for_size_p (cfun)"
16002 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
16003 [(set_attr "type" "rotatex")
16004 (set_attr "mode" "SI")])
16006 (define_insn "*<insn>si3_1_zext"
16007 [(set (match_operand:DI 0 "register_operand" "=r,r")
16009 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
16010 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
16011 (clobber (reg:CC FLAGS_REG))]
16012 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
16014 switch (get_attr_type (insn))
16020 if (operands[2] == const1_rtx
16021 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
16022 return "<rotate>{l}\t%k0";
16024 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
16027 [(set_attr "isa" "*,bmi2")
16028 (set_attr "type" "rotate,rotatex")
16029 (set (attr "preferred_for_size")
16030 (cond [(eq_attr "alternative" "0")
16031 (symbol_ref "true")]
16032 (symbol_ref "false")))
16033 (set (attr "length_immediate")
16035 (and (eq_attr "type" "rotate")
16036 (and (match_operand 2 "const1_operand")
16037 (ior (match_test "TARGET_SHIFT1")
16038 (match_test "optimize_function_for_size_p (cfun)"))))
16040 (const_string "*")))
16041 (set_attr "mode" "SI")])
16043 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
16045 [(set (match_operand:DI 0 "register_operand")
16047 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
16048 (match_operand:QI 2 "const_int_operand"))))
16049 (clobber (reg:CC FLAGS_REG))]
16050 "TARGET_64BIT && TARGET_BMI2 && reload_completed
16051 && !optimize_function_for_size_p (cfun)"
16052 [(set (match_dup 0)
16053 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
16055 int bitsize = GET_MODE_BITSIZE (SImode);
16057 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
16061 [(set (match_operand:DI 0 "register_operand")
16063 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
16064 (match_operand:QI 2 "const_int_operand"))))
16065 (clobber (reg:CC FLAGS_REG))]
16066 "TARGET_64BIT && TARGET_BMI2 && reload_completed
16067 && !optimize_function_for_size_p (cfun)"
16068 [(set (match_dup 0)
16069 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
16071 (define_insn "*<insn><mode>3_1"
16072 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
16073 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
16074 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
16075 (clobber (reg:CC FLAGS_REG))]
16076 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
16078 if (operands[2] == const1_rtx
16079 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
16080 return "<rotate>{<imodesuffix>}\t%0";
16082 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
16084 [(set_attr "type" "rotate")
16085 (set (attr "length_immediate")
16087 (and (match_operand 2 "const1_operand")
16088 (ior (match_test "TARGET_SHIFT1")
16089 (match_test "optimize_function_for_size_p (cfun)")))
16091 (const_string "*")))
16092 (set_attr "mode" "<MODE>")])
16094 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
16095 (define_insn_and_split "*<insn><mode>3_1_slp"
16096 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
16097 (any_rotate:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
16098 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
16099 (clobber (reg:CC FLAGS_REG))]
16100 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
16102 if (which_alternative)
16105 if (operands[2] == const1_rtx
16106 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
16107 return "<rotate>{<imodesuffix>}\t%0";
16109 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
16111 "&& reload_completed
16112 && !(rtx_equal_p (operands[0], operands[1]))"
16113 [(set (strict_low_part (match_dup 0)) (match_dup 1))
16115 [(set (strict_low_part (match_dup 0))
16116 (any_rotate:SWI12 (match_dup 0) (match_dup 2)))
16117 (clobber (reg:CC FLAGS_REG))])]
16119 [(set_attr "type" "rotate")
16120 (set (attr "length_immediate")
16122 (and (match_operand 2 "const1_operand")
16123 (ior (match_test "TARGET_SHIFT1")
16124 (match_test "optimize_function_for_size_p (cfun)")))
16126 (const_string "*")))
16127 (set_attr "mode" "<MODE>")])
16130 [(set (match_operand:HI 0 "QIreg_operand")
16131 (any_rotate:HI (match_dup 0) (const_int 8)))
16132 (clobber (reg:CC FLAGS_REG))]
16134 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
16135 [(parallel [(set (strict_low_part (match_dup 0))
16136 (bswap:HI (match_dup 0)))
16137 (clobber (reg:CC FLAGS_REG))])])
16139 ;; Rotations through carry flag
16140 (define_insn "rcrsi2"
16141 [(set (match_operand:SI 0 "register_operand" "=r")
16143 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
16145 (ashift:SI (ltu:SI (reg:CCC FLAGS_REG) (const_int 0))
16147 (clobber (reg:CC FLAGS_REG))]
16150 [(set_attr "type" "ishift1")
16151 (set_attr "memory" "none")
16152 (set_attr "length_immediate" "0")
16153 (set_attr "mode" "SI")])
16155 (define_insn "rcrdi2"
16156 [(set (match_operand:DI 0 "register_operand" "=r")
16158 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
16160 (ashift:DI (ltu:DI (reg:CCC FLAGS_REG) (const_int 0))
16162 (clobber (reg:CC FLAGS_REG))]
16165 [(set_attr "type" "ishift1")
16166 (set_attr "length_immediate" "0")
16167 (set_attr "mode" "DI")])
16169 ;; Versions of sar and shr that set the carry flag.
16170 (define_insn "<insn><mode>3_carry"
16171 [(set (reg:CCC FLAGS_REG)
16172 (unspec:CCC [(and:SWI48 (match_operand:SWI48 1 "register_operand" "0")
16174 (const_int 0)] UNSPEC_CC_NE))
16175 (set (match_operand:SWI48 0 "register_operand" "=r")
16176 (any_shiftrt:SWI48 (match_dup 1) (const_int 1)))]
16179 if (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
16180 return "<shift>{<imodesuffix>}\t%0";
16181 return "<shift>{<imodesuffix>}\t{1, %0|%0, 1}";
16183 [(set_attr "type" "ishift1")
16184 (set (attr "length_immediate")
16186 (ior (match_test "TARGET_SHIFT1")
16187 (match_test "optimize_function_for_size_p (cfun)"))
16189 (const_string "*")))
16190 (set_attr "mode" "<MODE>")])
16192 ;; Bit set / bit test instructions
16194 ;; %%% bts, btr, btc
16196 ;; These instructions are *slow* when applied to memory.
16198 (define_code_attr btsc [(ior "bts") (xor "btc")])
16200 (define_insn "*<btsc><mode>"
16201 [(set (match_operand:SWI48 0 "register_operand" "=r")
16203 (ashift:SWI48 (const_int 1)
16204 (match_operand:QI 2 "register_operand" "r"))
16205 (match_operand:SWI48 1 "register_operand" "0")))
16206 (clobber (reg:CC FLAGS_REG))]
16208 "<btsc>{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
16209 [(set_attr "type" "alu1")
16210 (set_attr "prefix_0f" "1")
16211 (set_attr "znver1_decode" "double")
16212 (set_attr "mode" "<MODE>")])
16214 ;; Avoid useless masking of count operand.
16215 (define_insn_and_split "*<btsc><mode>_mask"
16216 [(set (match_operand:SWI48 0 "register_operand")
16222 (match_operand 1 "int248_register_operand")
16223 (match_operand 2 "const_int_operand")) 0))
16224 (match_operand:SWI48 3 "register_operand")))
16225 (clobber (reg:CC FLAGS_REG))]
16227 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16228 == GET_MODE_BITSIZE (<MODE>mode)-1
16229 && ix86_pre_reload_split ()"
16233 [(set (match_dup 0)
16235 (ashift:SWI48 (const_int 1)
16238 (clobber (reg:CC FLAGS_REG))])]
16240 operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
16241 operands[1] = gen_lowpart (QImode, operands[1]);
16244 (define_insn_and_split "*<btsc><mode>_mask_1"
16245 [(set (match_operand:SWI48 0 "register_operand")
16250 (match_operand:QI 1 "register_operand")
16251 (match_operand:QI 2 "const_int_operand")))
16252 (match_operand:SWI48 3 "register_operand")))
16253 (clobber (reg:CC FLAGS_REG))]
16255 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16256 == GET_MODE_BITSIZE (<MODE>mode)-1
16257 && ix86_pre_reload_split ()"
16261 [(set (match_dup 0)
16263 (ashift:SWI48 (const_int 1)
16266 (clobber (reg:CC FLAGS_REG))])])
16268 (define_insn "*btr<mode>"
16269 [(set (match_operand:SWI48 0 "register_operand" "=r")
16271 (rotate:SWI48 (const_int -2)
16272 (match_operand:QI 2 "register_operand" "r"))
16273 (match_operand:SWI48 1 "register_operand" "0")))
16274 (clobber (reg:CC FLAGS_REG))]
16276 "btr{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
16277 [(set_attr "type" "alu1")
16278 (set_attr "prefix_0f" "1")
16279 (set_attr "znver1_decode" "double")
16280 (set_attr "mode" "<MODE>")])
16282 ;; Avoid useless masking of count operand.
16283 (define_insn_and_split "*btr<mode>_mask"
16284 [(set (match_operand:SWI48 0 "register_operand")
16290 (match_operand 1 "int248_register_operand")
16291 (match_operand 2 "const_int_operand")) 0))
16292 (match_operand:SWI48 3 "register_operand")))
16293 (clobber (reg:CC FLAGS_REG))]
16295 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16296 == GET_MODE_BITSIZE (<MODE>mode)-1
16297 && ix86_pre_reload_split ()"
16301 [(set (match_dup 0)
16303 (rotate:SWI48 (const_int -2)
16306 (clobber (reg:CC FLAGS_REG))])]
16308 operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
16309 operands[1] = gen_lowpart (QImode, operands[1]);
16312 (define_insn_and_split "*btr<mode>_mask_1"
16313 [(set (match_operand:SWI48 0 "register_operand")
16318 (match_operand:QI 1 "register_operand")
16319 (match_operand:QI 2 "const_int_operand")))
16320 (match_operand:SWI48 3 "register_operand")))
16321 (clobber (reg:CC FLAGS_REG))]
16323 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16324 == GET_MODE_BITSIZE (<MODE>mode)-1
16325 && ix86_pre_reload_split ()"
16329 [(set (match_dup 0)
16331 (rotate:SWI48 (const_int -2)
16334 (clobber (reg:CC FLAGS_REG))])])
16336 (define_insn_and_split "*btr<mode>_1"
16337 [(set (match_operand:SWI12 0 "register_operand")
16340 (rotate:SI (const_int -2)
16341 (match_operand:QI 2 "register_operand")) 0)
16342 (match_operand:SWI12 1 "nonimmediate_operand")))
16343 (clobber (reg:CC FLAGS_REG))]
16344 "TARGET_USE_BT && ix86_pre_reload_split ()"
16348 [(set (match_dup 0)
16349 (and:SI (rotate:SI (const_int -2) (match_dup 2))
16351 (clobber (reg:CC FLAGS_REG))])]
16353 operands[0] = lowpart_subreg (SImode, operands[0], <MODE>mode);
16354 operands[1] = force_reg (<MODE>mode, operands[1]);
16355 operands[1] = lowpart_subreg (SImode, operands[1], <MODE>mode);
16358 (define_insn_and_split "*btr<mode>_2"
16359 [(set (zero_extract:HI
16360 (match_operand:SWI12 0 "nonimmediate_operand")
16362 (match_operand:QI 1 "register_operand"))
16364 (clobber (reg:CC FLAGS_REG))]
16365 "TARGET_USE_BT && ix86_pre_reload_split ()"
16367 "&& MEM_P (operands[0])"
16368 [(set (match_dup 2) (match_dup 0))
16370 [(set (match_dup 3)
16371 (and:SI (rotate:SI (const_int -2) (match_dup 1))
16373 (clobber (reg:CC FLAGS_REG))])
16374 (set (match_dup 0) (match_dup 5))]
16376 operands[2] = gen_reg_rtx (<MODE>mode);
16377 operands[5] = gen_reg_rtx (<MODE>mode);
16378 operands[3] = lowpart_subreg (SImode, operands[5], <MODE>mode);
16379 operands[4] = lowpart_subreg (SImode, operands[2], <MODE>mode);
16383 [(set (zero_extract:HI
16384 (match_operand:SWI12 0 "register_operand")
16386 (match_operand:QI 1 "register_operand"))
16388 (clobber (reg:CC FLAGS_REG))]
16389 "TARGET_USE_BT && ix86_pre_reload_split ()"
16391 [(set (match_dup 0)
16392 (and:SI (rotate:SI (const_int -2) (match_dup 1))
16394 (clobber (reg:CC FLAGS_REG))])]
16396 operands[2] = lowpart_subreg (SImode, operands[0], <MODE>mode);
16397 operands[0] = lowpart_subreg (SImode, operands[0], <MODE>mode);
16400 ;; These instructions are never faster than the corresponding
16401 ;; and/ior/xor operations when using immediate operand, so with
16402 ;; 32-bit there's no point. But in 64-bit, we can't hold the
16403 ;; relevant immediates within the instruction itself, so operating
16404 ;; on bits in the high 32-bits of a register becomes easier.
16406 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
16407 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
16408 ;; negdf respectively, so they can never be disabled entirely.
16410 (define_insn "*btsq_imm"
16411 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
16413 (match_operand:QI 1 "const_0_to_63_operand"))
16415 (clobber (reg:CC FLAGS_REG))]
16416 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
16417 "bts{q}\t{%1, %0|%0, %1}"
16418 [(set_attr "type" "alu1")
16419 (set_attr "prefix_0f" "1")
16420 (set_attr "znver1_decode" "double")
16421 (set_attr "mode" "DI")])
16423 (define_insn "*btrq_imm"
16424 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
16426 (match_operand:QI 1 "const_0_to_63_operand"))
16428 (clobber (reg:CC FLAGS_REG))]
16429 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
16430 "btr{q}\t{%1, %0|%0, %1}"
16431 [(set_attr "type" "alu1")
16432 (set_attr "prefix_0f" "1")
16433 (set_attr "znver1_decode" "double")
16434 (set_attr "mode" "DI")])
16436 (define_insn "*btcq_imm"
16437 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
16439 (match_operand:QI 1 "const_0_to_63_operand"))
16440 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
16441 (clobber (reg:CC FLAGS_REG))]
16442 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
16443 "btc{q}\t{%1, %0|%0, %1}"
16444 [(set_attr "type" "alu1")
16445 (set_attr "prefix_0f" "1")
16446 (set_attr "znver1_decode" "double")
16447 (set_attr "mode" "DI")])
16449 ;; Allow Nocona to avoid these instructions if a register is available.
16452 [(match_scratch:DI 2 "r")
16453 (parallel [(set (zero_extract:DI
16454 (match_operand:DI 0 "nonimmediate_operand")
16456 (match_operand:QI 1 "const_0_to_63_operand"))
16458 (clobber (reg:CC FLAGS_REG))])]
16459 "TARGET_64BIT && !TARGET_USE_BT"
16460 [(parallel [(set (match_dup 0)
16461 (ior:DI (match_dup 0) (match_dup 3)))
16462 (clobber (reg:CC FLAGS_REG))])]
16464 int i = INTVAL (operands[1]);
16466 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
16468 if (!x86_64_immediate_operand (operands[3], DImode))
16470 emit_move_insn (operands[2], operands[3]);
16471 operands[3] = operands[2];
16476 [(match_scratch:DI 2 "r")
16477 (parallel [(set (zero_extract:DI
16478 (match_operand:DI 0 "nonimmediate_operand")
16480 (match_operand:QI 1 "const_0_to_63_operand"))
16482 (clobber (reg:CC FLAGS_REG))])]
16483 "TARGET_64BIT && !TARGET_USE_BT"
16484 [(parallel [(set (match_dup 0)
16485 (and:DI (match_dup 0) (match_dup 3)))
16486 (clobber (reg:CC FLAGS_REG))])]
16488 int i = INTVAL (operands[1]);
16490 operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
16492 if (!x86_64_immediate_operand (operands[3], DImode))
16494 emit_move_insn (operands[2], operands[3]);
16495 operands[3] = operands[2];
16500 [(match_scratch:DI 2 "r")
16501 (parallel [(set (zero_extract:DI
16502 (match_operand:DI 0 "nonimmediate_operand")
16504 (match_operand:QI 1 "const_0_to_63_operand"))
16505 (not:DI (zero_extract:DI
16506 (match_dup 0) (const_int 1) (match_dup 1))))
16507 (clobber (reg:CC FLAGS_REG))])]
16508 "TARGET_64BIT && !TARGET_USE_BT"
16509 [(parallel [(set (match_dup 0)
16510 (xor:DI (match_dup 0) (match_dup 3)))
16511 (clobber (reg:CC FLAGS_REG))])]
16513 int i = INTVAL (operands[1]);
16515 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
16517 if (!x86_64_immediate_operand (operands[3], DImode))
16519 emit_move_insn (operands[2], operands[3]);
16520 operands[3] = operands[2];
16526 (define_insn "*bt<mode>"
16527 [(set (reg:CCC FLAGS_REG)
16529 (zero_extract:SWI48
16530 (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
16532 (match_operand:QI 1 "nonmemory_operand" "q<S>,<S>"))
16536 switch (get_attr_mode (insn))
16539 return "bt{l}\t{%k1, %k0|%k0, %k1}";
16542 return "bt{q}\t{%q1, %0|%0, %q1}";
16545 gcc_unreachable ();
16548 [(set_attr "type" "alu1")
16549 (set_attr "prefix_0f" "1")
16552 (and (match_test "CONST_INT_P (operands[1])")
16553 (match_test "INTVAL (operands[1]) < 32"))
16554 (const_string "SI")
16555 (const_string "<MODE>")))])
16557 (define_insn_and_split "*bt<SWI48:mode>_mask"
16558 [(set (reg:CCC FLAGS_REG)
16560 (zero_extract:SWI48
16561 (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
16565 (match_operand:SWI248 1 "register_operand")
16566 (match_operand 2 "const_int_operand")) 0))
16569 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<SWI48:MODE>mode)-1))
16570 == GET_MODE_BITSIZE (<SWI48:MODE>mode)-1
16571 && ix86_pre_reload_split ()"
16574 [(set (reg:CCC FLAGS_REG)
16576 (zero_extract:SWI48 (match_dup 0) (const_int 1) (match_dup 1))
16578 "operands[1] = gen_lowpart (QImode, operands[1]);")
16580 (define_insn_and_split "*jcc_bt<mode>"
16582 (if_then_else (match_operator 0 "bt_comparison_operator"
16583 [(zero_extract:SWI48
16584 (match_operand:SWI48 1 "nonimmediate_operand")
16586 (match_operand:QI 2 "nonmemory_operand"))
16588 (label_ref (match_operand 3))
16590 (clobber (reg:CC FLAGS_REG))]
16591 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
16592 && (CONST_INT_P (operands[2])
16593 ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
16594 && INTVAL (operands[2])
16595 >= (optimize_function_for_size_p (cfun) ? 8 : 32))
16596 : !memory_operand (operands[1], <MODE>mode))
16597 && ix86_pre_reload_split ()"
16600 [(set (reg:CCC FLAGS_REG)
16602 (zero_extract:SWI48
16608 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16609 (label_ref (match_dup 3))
16612 operands[0] = shallow_copy_rtx (operands[0]);
16613 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16616 ;; Avoid useless masking of bit offset operand.
16617 (define_insn_and_split "*jcc_bt<mode>_mask"
16619 (if_then_else (match_operator 0 "bt_comparison_operator"
16620 [(zero_extract:SWI48
16621 (match_operand:SWI48 1 "register_operand")
16624 (match_operand:QI 2 "register_operand")
16625 (match_operand 3 "const_int_operand")))])
16626 (label_ref (match_operand 4))
16628 (clobber (reg:CC FLAGS_REG))]
16629 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
16630 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16631 == GET_MODE_BITSIZE (<MODE>mode)-1
16632 && ix86_pre_reload_split ()"
16635 [(set (reg:CCC FLAGS_REG)
16637 (zero_extract:SWI48
16643 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16644 (label_ref (match_dup 4))
16647 operands[0] = shallow_copy_rtx (operands[0]);
16648 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16651 ;; Avoid useless masking of bit offset operand.
16652 (define_insn_and_split "*jcc_bt<SWI48:mode>_mask_1"
16654 (if_then_else (match_operator 0 "bt_comparison_operator"
16655 [(zero_extract:SWI48
16656 (match_operand:SWI48 1 "register_operand")
16660 (match_operand:SWI248 2 "register_operand")
16661 (match_operand 3 "const_int_operand")) 0))])
16662 (label_ref (match_operand 4))
16664 (clobber (reg:CC FLAGS_REG))]
16665 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
16666 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<SWI48:MODE>mode)-1))
16667 == GET_MODE_BITSIZE (<SWI48:MODE>mode)-1
16668 && ix86_pre_reload_split ()"
16671 [(set (reg:CCC FLAGS_REG)
16673 (zero_extract:SWI48
16679 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16680 (label_ref (match_dup 4))
16683 operands[0] = shallow_copy_rtx (operands[0]);
16684 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16685 operands[2] = gen_lowpart (QImode, operands[2]);
16688 ;; Help combine recognize bt followed by cmov
16690 [(set (match_operand:SWI248 0 "register_operand")
16691 (if_then_else:SWI248
16692 (match_operator 5 "bt_comparison_operator"
16693 [(zero_extract:SWI48
16694 (match_operand:SWI48 1 "register_operand")
16696 (match_operand:QI 2 "register_operand"))
16698 (match_operand:SWI248 3 "nonimmediate_operand")
16699 (match_operand:SWI248 4 "nonimmediate_operand")))]
16700 "TARGET_USE_BT && TARGET_CMOVE
16701 && !(MEM_P (operands[3]) && MEM_P (operands[4]))
16702 && ix86_pre_reload_split ()"
16703 [(set (reg:CCC FLAGS_REG)
16705 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16708 (if_then_else:SWI248 (eq (reg:CCC FLAGS_REG) (const_int 0))
16712 if (GET_CODE (operands[5]) == EQ)
16713 std::swap (operands[3], operands[4]);
16716 ;; Help combine recognize bt followed by setc
16717 (define_insn_and_split "*bt<mode>_setcqi"
16718 [(set (subreg:SWI48 (match_operand:QI 0 "register_operand") 0)
16719 (zero_extract:SWI48
16720 (match_operand:SWI48 1 "register_operand")
16722 (match_operand:QI 2 "register_operand")))
16723 (clobber (reg:CC FLAGS_REG))]
16724 "TARGET_USE_BT && ix86_pre_reload_split ()"
16727 [(set (reg:CCC FLAGS_REG)
16729 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16732 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))])
16734 ;; Help combine recognize bt followed by setnc
16735 (define_insn_and_split "*bt<mode>_setncqi"
16736 [(set (match_operand:QI 0 "register_operand")
16740 (lshiftrt:SWI48 (match_operand:SWI48 1 "register_operand")
16741 (match_operand:QI 2 "register_operand")) 0))
16743 (clobber (reg:CC FLAGS_REG))]
16744 "TARGET_USE_BT && ix86_pre_reload_split ()"
16747 [(set (reg:CCC FLAGS_REG)
16749 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16752 (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))])
16754 (define_insn_and_split "*bt<mode>_setnc<mode>"
16755 [(set (match_operand:SWI48 0 "register_operand")
16758 (lshiftrt:SWI48 (match_operand:SWI48 1 "register_operand")
16759 (match_operand:QI 2 "register_operand")))
16761 (clobber (reg:CC FLAGS_REG))]
16762 "TARGET_USE_BT && ix86_pre_reload_split ()"
16765 [(set (reg:CCC FLAGS_REG)
16767 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16770 (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))
16771 (set (match_dup 0) (zero_extend:SWI48 (match_dup 3)))]
16772 "operands[3] = gen_reg_rtx (QImode);")
16774 ;; Help combine recognize bt followed by setnc (PR target/110588)
16775 (define_insn_and_split "*bt<mode>_setncqi_2"
16776 [(set (match_operand:QI 0 "register_operand")
16778 (zero_extract:SWI48
16779 (match_operand:SWI48 1 "register_operand")
16781 (match_operand:QI 2 "register_operand"))
16783 (clobber (reg:CC FLAGS_REG))]
16784 "TARGET_USE_BT && ix86_pre_reload_split ()"
16787 [(set (reg:CCC FLAGS_REG)
16789 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16792 (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))])
16794 ;; Help combine recognize bt followed by setc
16795 (define_insn_and_split "*bt<mode>_setc<mode>_mask"
16796 [(set (match_operand:SWI48 0 "register_operand")
16797 (zero_extract:SWI48
16798 (match_operand:SWI48 1 "register_operand")
16802 (match_operand:SWI48 2 "register_operand")
16803 (match_operand 3 "const_int_operand")) 0)))
16804 (clobber (reg:CC FLAGS_REG))]
16806 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16807 == GET_MODE_BITSIZE (<MODE>mode)-1
16808 && ix86_pre_reload_split ()"
16811 [(set (reg:CCC FLAGS_REG)
16813 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16816 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))
16817 (set (match_dup 0) (zero_extend:SWI48 (match_dup 3)))]
16819 operands[2] = gen_lowpart (QImode, operands[2]);
16820 operands[3] = gen_reg_rtx (QImode);
16823 ;; Store-flag instructions.
16826 [(set (match_operand:QI 0 "nonimmediate_operand")
16827 (match_operator:QI 1 "add_comparison_operator"
16828 [(not:SWI (match_operand:SWI 2 "register_operand"))
16829 (match_operand:SWI 3 "nonimmediate_operand")]))]
16831 [(set (reg:CCC FLAGS_REG)
16833 (plus:SWI (match_dup 2) (match_dup 3))
16836 (match_op_dup 1 [(reg:CCC FLAGS_REG) (const_int 0)]))])
16839 [(set (match_operand:QI 0 "nonimmediate_operand")
16840 (match_operator:QI 1 "shr_comparison_operator"
16841 [(match_operand:DI 2 "register_operand")
16842 (match_operand 3 "const_int_operand")]))]
16844 && IN_RANGE (exact_log2 (UINTVAL (operands[3]) + 1), 32, 63)"
16845 [(set (reg:CCZ FLAGS_REG)
16847 (lshiftrt:DI (match_dup 2) (match_dup 4))
16850 (match_op_dup 1 [(reg:CCZ FLAGS_REG) (const_int 0)]))]
16852 enum rtx_code new_code;
16854 operands[1] = shallow_copy_rtx (operands[1]);
16855 switch (GET_CODE (operands[1]))
16857 case GTU: new_code = NE; break;
16858 case LEU: new_code = EQ; break;
16859 default: gcc_unreachable ();
16861 PUT_CODE (operands[1], new_code);
16863 operands[4] = GEN_INT (exact_log2 (UINTVAL (operands[3]) + 1));
16866 ;; For all sCOND expanders, also expand the compare or test insn that
16867 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
16869 (define_insn_and_split "*setcc_di_1"
16870 [(set (match_operand:DI 0 "register_operand" "=q")
16871 (match_operator:DI 1 "ix86_comparison_operator"
16872 [(reg FLAGS_REG) (const_int 0)]))]
16873 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
16875 "&& reload_completed"
16876 [(set (match_dup 2) (match_dup 1))
16877 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
16879 operands[1] = shallow_copy_rtx (operands[1]);
16880 PUT_MODE (operands[1], QImode);
16881 operands[2] = gen_lowpart (QImode, operands[0]);
16884 (define_insn_and_split "*setcc_<mode>_1_and"
16885 [(set (match_operand:SWI24 0 "register_operand" "=q")
16886 (match_operator:SWI24 1 "ix86_comparison_operator"
16887 [(reg FLAGS_REG) (const_int 0)]))
16888 (clobber (reg:CC FLAGS_REG))]
16889 "!TARGET_PARTIAL_REG_STALL
16890 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
16892 "&& reload_completed"
16893 [(set (match_dup 2) (match_dup 1))
16894 (parallel [(set (match_dup 0) (zero_extend:SWI24 (match_dup 2)))
16895 (clobber (reg:CC FLAGS_REG))])]
16897 operands[1] = shallow_copy_rtx (operands[1]);
16898 PUT_MODE (operands[1], QImode);
16899 operands[2] = gen_lowpart (QImode, operands[0]);
16902 (define_insn_and_split "*setcc_<mode>_1_movzbl"
16903 [(set (match_operand:SWI24 0 "register_operand" "=q")
16904 (match_operator:SWI24 1 "ix86_comparison_operator"
16905 [(reg FLAGS_REG) (const_int 0)]))]
16906 "!TARGET_PARTIAL_REG_STALL
16907 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
16909 "&& reload_completed"
16910 [(set (match_dup 2) (match_dup 1))
16911 (set (match_dup 0) (zero_extend:SWI24 (match_dup 2)))]
16913 operands[1] = shallow_copy_rtx (operands[1]);
16914 PUT_MODE (operands[1], QImode);
16915 operands[2] = gen_lowpart (QImode, operands[0]);
16918 (define_insn "*setcc_qi"
16919 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
16920 (match_operator:QI 1 "ix86_comparison_operator"
16921 [(reg FLAGS_REG) (const_int 0)]))]
16924 [(set_attr "type" "setcc")
16925 (set_attr "mode" "QI")])
16927 (define_insn "*setcc_qi_slp"
16928 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+q"))
16929 (match_operator:QI 1 "ix86_comparison_operator"
16930 [(reg FLAGS_REG) (const_int 0)]))]
16933 [(set_attr "type" "setcc")
16934 (set_attr "mode" "QI")])
16936 ;; In general it is not safe to assume too much about CCmode registers,
16937 ;; so simplify-rtx stops when it sees a second one. Under certain
16938 ;; conditions this is safe on x86, so help combine not create
16945 [(set (match_operand:QI 0 "nonimmediate_operand")
16946 (ne:QI (match_operator 1 "ix86_comparison_operator"
16947 [(reg FLAGS_REG) (const_int 0)])
16950 [(set (match_dup 0) (match_dup 1))]
16952 operands[1] = shallow_copy_rtx (operands[1]);
16953 PUT_MODE (operands[1], QImode);
16957 [(set (strict_low_part (match_operand:QI 0 "register_operand"))
16958 (ne:QI (match_operator 1 "ix86_comparison_operator"
16959 [(reg FLAGS_REG) (const_int 0)])
16962 [(set (match_dup 0) (match_dup 1))]
16964 operands[1] = shallow_copy_rtx (operands[1]);
16965 PUT_MODE (operands[1], QImode);
16969 [(set (match_operand:QI 0 "nonimmediate_operand")
16970 (eq:QI (match_operator 1 "ix86_comparison_operator"
16971 [(reg FLAGS_REG) (const_int 0)])
16974 [(set (match_dup 0) (match_dup 1))]
16976 operands[1] = shallow_copy_rtx (operands[1]);
16977 PUT_MODE (operands[1], QImode);
16978 PUT_CODE (operands[1],
16979 ix86_reverse_condition (GET_CODE (operands[1]),
16980 GET_MODE (XEXP (operands[1], 0))));
16982 /* Make sure that (a) the CCmode we have for the flags is strong
16983 enough for the reversed compare or (b) we have a valid FP compare. */
16984 if (! ix86_comparison_operator (operands[1], VOIDmode))
16989 [(set (strict_low_part (match_operand:QI 0 "register_operand"))
16990 (eq:QI (match_operator 1 "ix86_comparison_operator"
16991 [(reg FLAGS_REG) (const_int 0)])
16994 [(set (match_dup 0) (match_dup 1))]
16996 operands[1] = shallow_copy_rtx (operands[1]);
16997 PUT_MODE (operands[1], QImode);
16998 PUT_CODE (operands[1],
16999 ix86_reverse_condition (GET_CODE (operands[1]),
17000 GET_MODE (XEXP (operands[1], 0))));
17002 /* Make sure that (a) the CCmode we have for the flags is strong
17003 enough for the reversed compare or (b) we have a valid FP compare. */
17004 if (! ix86_comparison_operator (operands[1], VOIDmode))
17008 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
17009 ;; subsequent logical operations are used to imitate conditional moves.
17010 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
17013 (define_insn "setcc_<mode>_sse"
17014 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
17015 (match_operator:MODEF 3 "sse_comparison_operator"
17016 [(match_operand:MODEF 1 "register_operand" "0,x")
17017 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xjm")]))]
17018 "SSE_FLOAT_MODE_P (<MODE>mode)"
17020 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
17021 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17022 [(set_attr "isa" "noavx,avx")
17023 (set_attr "addr" "*,gpr16")
17024 (set_attr "type" "ssecmp")
17025 (set_attr "length_immediate" "1")
17026 (set_attr "prefix" "orig,vex")
17027 (set_attr "mode" "<MODE>")])
17029 (define_insn "setcc_hf_mask"
17030 [(set (match_operand:QI 0 "register_operand" "=k")
17032 [(match_operand:HF 1 "register_operand" "v")
17033 (match_operand:HF 2 "nonimmediate_operand" "vm")
17034 (match_operand:SI 3 "const_0_to_31_operand")]
17036 "TARGET_AVX512FP16"
17037 "vcmpsh\t{%3, %2, %1, %0|%0, %1, %2, %3}"
17038 [(set_attr "type" "ssecmp")
17039 (set_attr "prefix" "evex")
17040 (set_attr "mode" "HF")])
17043 ;; Basic conditional jump instructions.
17048 (match_operator 1 "add_comparison_operator"
17049 [(not:SWI (match_operand:SWI 2 "register_operand"))
17050 (match_operand:SWI 3 "nonimmediate_operand")])
17051 (label_ref (match_operand 0))
17054 [(set (reg:CCC FLAGS_REG)
17056 (plus:SWI (match_dup 2) (match_dup 3))
17059 (if_then_else (match_op_dup 1 [(reg:CCC FLAGS_REG) (const_int 0)])
17060 (label_ref (match_operand 0))
17066 (match_operator 1 "shr_comparison_operator"
17067 [(match_operand:DI 2 "register_operand")
17068 (match_operand 3 "const_int_operand")])
17069 (label_ref (match_operand 0))
17072 && IN_RANGE (exact_log2 (UINTVAL (operands[3]) + 1), 32, 63)"
17073 [(set (reg:CCZ FLAGS_REG)
17075 (lshiftrt:DI (match_dup 2) (match_dup 4))
17078 (if_then_else (match_op_dup 1 [(reg:CCZ FLAGS_REG) (const_int 0)])
17079 (label_ref (match_operand 0))
17082 enum rtx_code new_code;
17084 operands[1] = shallow_copy_rtx (operands[1]);
17085 switch (GET_CODE (operands[1]))
17087 case GTU: new_code = NE; break;
17088 case LEU: new_code = EQ; break;
17089 default: gcc_unreachable ();
17091 PUT_CODE (operands[1], new_code);
17093 operands[4] = GEN_INT (exact_log2 (UINTVAL (operands[3]) + 1));
17096 ;; We ignore the overflow flag for signed branch instructions.
17098 (define_insn "*jcc"
17100 (if_then_else (match_operator 1 "ix86_comparison_operator"
17101 [(reg FLAGS_REG) (const_int 0)])
17102 (label_ref (match_operand 0))
17106 [(set_attr "type" "ibr")
17107 (set_attr "modrm" "0")
17108 (set (attr "length")
17110 (and (ge (minus (match_dup 0) (pc))
17112 (lt (minus (match_dup 0) (pc))
17117 ;; In general it is not safe to assume too much about CCmode registers,
17118 ;; so simplify-rtx stops when it sees a second one. Under certain
17119 ;; conditions this is safe on x86, so help combine not create
17127 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
17128 [(reg FLAGS_REG) (const_int 0)])
17130 (label_ref (match_operand 1))
17134 (if_then_else (match_dup 0)
17135 (label_ref (match_dup 1))
17138 operands[0] = shallow_copy_rtx (operands[0]);
17139 PUT_MODE (operands[0], VOIDmode);
17144 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
17145 [(reg FLAGS_REG) (const_int 0)])
17147 (label_ref (match_operand 1))
17151 (if_then_else (match_dup 0)
17152 (label_ref (match_dup 1))
17155 operands[0] = shallow_copy_rtx (operands[0]);
17156 PUT_MODE (operands[0], VOIDmode);
17157 PUT_CODE (operands[0],
17158 ix86_reverse_condition (GET_CODE (operands[0]),
17159 GET_MODE (XEXP (operands[0], 0))));
17161 /* Make sure that (a) the CCmode we have for the flags is strong
17162 enough for the reversed compare or (b) we have a valid FP compare. */
17163 if (! ix86_comparison_operator (operands[0], VOIDmode))
17167 ;; Unconditional and other jump instructions
17169 (define_insn "jump"
17171 (label_ref (match_operand 0)))]
17174 [(set_attr "type" "ibr")
17175 (set_attr "modrm" "0")
17176 (set (attr "length")
17178 (and (ge (minus (match_dup 0) (pc))
17180 (lt (minus (match_dup 0) (pc))
17185 (define_expand "indirect_jump"
17186 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
17189 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
17190 operands[0] = convert_memory_address (word_mode, operands[0]);
17191 cfun->machine->has_local_indirect_jump = true;
17194 (define_insn "*indirect_jump"
17195 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
17197 "* return ix86_output_indirect_jmp (operands[0]);"
17198 [(set (attr "type")
17199 (if_then_else (match_test "(cfun->machine->indirect_branch_type
17200 != indirect_branch_keep)")
17201 (const_string "multi")
17202 (const_string "ibr")))
17203 (set_attr "length_immediate" "0")])
17205 (define_expand "tablejump"
17206 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
17207 (use (label_ref (match_operand 1)))])]
17210 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
17211 relative. Convert the relative address to an absolute address. */
17215 enum rtx_code code;
17217 /* We can't use @GOTOFF for text labels on VxWorks;
17218 see gotoff_operand. */
17219 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
17223 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
17225 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
17229 op1 = pic_offset_table_rtx;
17234 op0 = pic_offset_table_rtx;
17238 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
17242 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
17243 operands[0] = convert_memory_address (word_mode, operands[0]);
17244 cfun->machine->has_local_indirect_jump = true;
17247 (define_insn "*tablejump_1"
17248 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
17249 (use (label_ref (match_operand 1)))]
17251 "* return ix86_output_indirect_jmp (operands[0]);"
17252 [(set (attr "type")
17253 (if_then_else (match_test "(cfun->machine->indirect_branch_type
17254 != indirect_branch_keep)")
17255 (const_string "multi")
17256 (const_string "ibr")))
17257 (set_attr "length_immediate" "0")])
17259 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
17262 [(set (match_operand 4 "flags_reg_operand") (match_operand 0))
17263 (set (match_operand:QI 1 "register_operand")
17264 (match_operator:QI 2 "ix86_comparison_operator"
17265 [(reg FLAGS_REG) (const_int 0)]))
17266 (set (match_operand 3 "any_QIreg_operand")
17267 (zero_extend (match_dup 1)))]
17268 "(peep2_reg_dead_p (3, operands[1])
17269 || operands_match_p (operands[1], operands[3]))
17270 && ! reg_overlap_mentioned_p (operands[3], operands[0])
17271 && peep2_regno_dead_p (0, FLAGS_REG)"
17272 [(set (match_dup 4) (match_dup 0))
17273 (set (strict_low_part (match_dup 5))
17276 operands[5] = gen_lowpart (QImode, operands[3]);
17277 ix86_expand_clear (operands[3]);
17281 [(parallel [(set (match_operand 5 "flags_reg_operand") (match_operand 0))
17282 (match_operand 4)])
17283 (set (match_operand:QI 1 "register_operand")
17284 (match_operator:QI 2 "ix86_comparison_operator"
17285 [(reg FLAGS_REG) (const_int 0)]))
17286 (set (match_operand 3 "any_QIreg_operand")
17287 (zero_extend (match_dup 1)))]
17288 "(peep2_reg_dead_p (3, operands[1])
17289 || operands_match_p (operands[1], operands[3]))
17290 && ! reg_overlap_mentioned_p (operands[3], operands[0])
17291 && ! reg_overlap_mentioned_p (operands[3], operands[4])
17292 && ! reg_set_p (operands[3], operands[4])
17293 && peep2_regno_dead_p (0, FLAGS_REG)"
17294 [(parallel [(set (match_dup 5) (match_dup 0))
17296 (set (strict_low_part (match_dup 6))
17299 operands[6] = gen_lowpart (QImode, operands[3]);
17300 ix86_expand_clear (operands[3]);
17304 [(set (match_operand 6 "flags_reg_operand") (match_operand 0))
17305 (parallel [(set (match_operand 7 "flags_reg_operand") (match_operand 1))
17306 (match_operand 5)])
17307 (set (match_operand:QI 2 "register_operand")
17308 (match_operator:QI 3 "ix86_comparison_operator"
17309 [(reg FLAGS_REG) (const_int 0)]))
17310 (set (match_operand 4 "any_QIreg_operand")
17311 (zero_extend (match_dup 2)))]
17312 "(peep2_reg_dead_p (4, operands[2])
17313 || operands_match_p (operands[2], operands[4]))
17314 && ! reg_overlap_mentioned_p (operands[4], operands[0])
17315 && ! reg_overlap_mentioned_p (operands[4], operands[1])
17316 && ! reg_overlap_mentioned_p (operands[4], operands[5])
17317 && ! reg_set_p (operands[4], operands[5])
17318 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
17319 && peep2_regno_dead_p (0, FLAGS_REG)"
17320 [(set (match_dup 6) (match_dup 0))
17321 (parallel [(set (match_dup 7) (match_dup 1))
17323 (set (strict_low_part (match_dup 8))
17326 operands[8] = gen_lowpart (QImode, operands[4]);
17327 ix86_expand_clear (operands[4]);
17330 ;; Similar, but match zero extend with andsi3.
17333 [(set (match_operand 4 "flags_reg_operand") (match_operand 0))
17334 (set (match_operand:QI 1 "register_operand")
17335 (match_operator:QI 2 "ix86_comparison_operator"
17336 [(reg FLAGS_REG) (const_int 0)]))
17337 (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
17338 (and:SI (match_dup 3) (const_int 255)))
17339 (clobber (reg:CC FLAGS_REG))])]
17340 "REGNO (operands[1]) == REGNO (operands[3])
17341 && ! reg_overlap_mentioned_p (operands[3], operands[0])
17342 && peep2_regno_dead_p (0, FLAGS_REG)"
17343 [(set (match_dup 4) (match_dup 0))
17344 (set (strict_low_part (match_dup 5))
17347 operands[5] = gen_lowpart (QImode, operands[3]);
17348 ix86_expand_clear (operands[3]);
17352 [(parallel [(set (match_operand 5 "flags_reg_operand") (match_operand 0))
17353 (match_operand 4)])
17354 (set (match_operand:QI 1 "register_operand")
17355 (match_operator:QI 2 "ix86_comparison_operator"
17356 [(reg FLAGS_REG) (const_int 0)]))
17357 (parallel [(set (match_operand 3 "any_QIreg_operand")
17358 (zero_extend (match_dup 1)))
17359 (clobber (reg:CC FLAGS_REG))])]
17360 "(peep2_reg_dead_p (3, operands[1])
17361 || operands_match_p (operands[1], operands[3]))
17362 && ! reg_overlap_mentioned_p (operands[3], operands[0])
17363 && ! reg_overlap_mentioned_p (operands[3], operands[4])
17364 && ! reg_set_p (operands[3], operands[4])
17365 && peep2_regno_dead_p (0, FLAGS_REG)"
17366 [(parallel [(set (match_dup 5) (match_dup 0))
17368 (set (strict_low_part (match_dup 6))
17371 operands[6] = gen_lowpart (QImode, operands[3]);
17372 ix86_expand_clear (operands[3]);
17376 [(set (match_operand 6 "flags_reg_operand") (match_operand 0))
17377 (parallel [(set (match_operand 7 "flags_reg_operand") (match_operand 1))
17378 (match_operand 5)])
17379 (set (match_operand:QI 2 "register_operand")
17380 (match_operator:QI 3 "ix86_comparison_operator"
17381 [(reg FLAGS_REG) (const_int 0)]))
17382 (parallel [(set (match_operand 4 "any_QIreg_operand")
17383 (zero_extend (match_dup 2)))
17384 (clobber (reg:CC FLAGS_REG))])]
17385 "(peep2_reg_dead_p (4, operands[2])
17386 || operands_match_p (operands[2], operands[4]))
17387 && ! reg_overlap_mentioned_p (operands[4], operands[0])
17388 && ! reg_overlap_mentioned_p (operands[4], operands[1])
17389 && ! reg_overlap_mentioned_p (operands[4], operands[5])
17390 && ! reg_set_p (operands[4], operands[5])
17391 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
17392 && peep2_regno_dead_p (0, FLAGS_REG)"
17393 [(set (match_dup 6) (match_dup 0))
17394 (parallel [(set (match_dup 7) (match_dup 1))
17396 (set (strict_low_part (match_dup 8))
17399 operands[8] = gen_lowpart (QImode, operands[4]);
17400 ix86_expand_clear (operands[4]);
17403 ;; Call instructions.
17405 ;; The predicates normally associated with named expanders are not properly
17406 ;; checked for calls. This is a bug in the generic code, but it isn't that
17407 ;; easy to fix. Ignore it for now and be prepared to fix things up.
17409 ;; P6 processors will jump to the address after the decrement when %esp
17410 ;; is used as a call operand, so they will execute return address as a code.
17411 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
17413 ;; Register constraint for call instruction.
17414 (define_mode_attr c [(SI "l") (DI "r")])
17416 ;; Call subroutine returning no value.
17418 (define_expand "call"
17419 [(call (match_operand:QI 0)
17421 (use (match_operand 2))]
17424 ix86_expand_call (NULL, operands[0], operands[1],
17425 operands[2], NULL, false);
17429 (define_expand "sibcall"
17430 [(call (match_operand:QI 0)
17432 (use (match_operand 2))]
17435 ix86_expand_call (NULL, operands[0], operands[1],
17436 operands[2], NULL, true);
17440 (define_insn "*call"
17441 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
17442 (match_operand 1))]
17443 "!SIBLING_CALL_P (insn)"
17444 "* return ix86_output_call_insn (insn, operands[0]);"
17445 [(set_attr "type" "call")])
17447 ;; This covers both call and sibcall since only GOT slot is allowed.
17448 (define_insn "*call_got_x32"
17449 [(call (mem:QI (zero_extend:DI
17450 (match_operand:SI 0 "GOT_memory_operand" "Bg")))
17451 (match_operand 1))]
17454 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
17455 return ix86_output_call_insn (insn, fnaddr);
17457 [(set_attr "type" "call")])
17459 ;; Since sibcall never returns, we can only use call-clobbered register
17461 (define_insn "*sibcall_GOT_32"
17464 (match_operand:SI 0 "register_no_elim_operand" "U")
17465 (match_operand:SI 1 "GOT32_symbol_operand"))))
17466 (match_operand 2))]
17469 && !TARGET_INDIRECT_BRANCH_REGISTER
17470 && SIBLING_CALL_P (insn)"
17472 rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
17473 fnaddr = gen_const_mem (SImode, fnaddr);
17474 return ix86_output_call_insn (insn, fnaddr);
17476 [(set_attr "type" "call")])
17478 (define_insn "*sibcall"
17479 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
17480 (match_operand 1))]
17481 "SIBLING_CALL_P (insn)"
17482 "* return ix86_output_call_insn (insn, operands[0]);"
17483 [(set_attr "type" "call")])
17485 (define_insn "*sibcall_memory"
17486 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
17488 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17489 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
17490 "* return ix86_output_call_insn (insn, operands[0]);"
17491 [(set_attr "type" "call")])
17494 [(set (match_operand:W 0 "register_operand")
17495 (match_operand:W 1 "memory_operand"))
17496 (call (mem:QI (match_dup 0))
17497 (match_operand 3))]
17499 && !TARGET_INDIRECT_BRANCH_REGISTER
17500 && SIBLING_CALL_P (peep2_next_insn (1))
17501 && !reg_mentioned_p (operands[0],
17502 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17503 [(parallel [(call (mem:QI (match_dup 1))
17505 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17508 [(set (match_operand:W 0 "register_operand")
17509 (match_operand:W 1 "memory_operand"))
17510 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17511 (call (mem:QI (match_dup 0))
17512 (match_operand 3))]
17514 && !TARGET_INDIRECT_BRANCH_REGISTER
17515 && SIBLING_CALL_P (peep2_next_insn (2))
17516 && !reg_mentioned_p (operands[0],
17517 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17518 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17519 (parallel [(call (mem:QI (match_dup 1))
17521 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17523 (define_expand "call_pop"
17524 [(parallel [(call (match_operand:QI 0)
17525 (match_operand:SI 1))
17526 (set (reg:SI SP_REG)
17527 (plus:SI (reg:SI SP_REG)
17528 (match_operand:SI 3)))])]
17531 ix86_expand_call (NULL, operands[0], operands[1],
17532 operands[2], operands[3], false);
17536 (define_insn "*call_pop"
17537 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz"))
17539 (set (reg:SI SP_REG)
17540 (plus:SI (reg:SI SP_REG)
17541 (match_operand:SI 2 "immediate_operand" "i")))]
17542 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17543 "* return ix86_output_call_insn (insn, operands[0]);"
17544 [(set_attr "type" "call")])
17546 (define_insn "*sibcall_pop"
17547 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
17549 (set (reg:SI SP_REG)
17550 (plus:SI (reg:SI SP_REG)
17551 (match_operand:SI 2 "immediate_operand" "i")))]
17552 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17553 "* return ix86_output_call_insn (insn, operands[0]);"
17554 [(set_attr "type" "call")])
17556 (define_insn "*sibcall_pop_memory"
17557 [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs"))
17559 (set (reg:SI SP_REG)
17560 (plus:SI (reg:SI SP_REG)
17561 (match_operand:SI 2 "immediate_operand" "i")))
17562 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17564 "* return ix86_output_call_insn (insn, operands[0]);"
17565 [(set_attr "type" "call")])
17568 [(set (match_operand:SI 0 "register_operand")
17569 (match_operand:SI 1 "memory_operand"))
17570 (parallel [(call (mem:QI (match_dup 0))
17572 (set (reg:SI SP_REG)
17573 (plus:SI (reg:SI SP_REG)
17574 (match_operand:SI 4 "immediate_operand")))])]
17575 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
17576 && !reg_mentioned_p (operands[0],
17577 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17578 [(parallel [(call (mem:QI (match_dup 1))
17580 (set (reg:SI SP_REG)
17581 (plus:SI (reg:SI SP_REG)
17583 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17586 [(set (match_operand:SI 0 "register_operand")
17587 (match_operand:SI 1 "memory_operand"))
17588 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17589 (parallel [(call (mem:QI (match_dup 0))
17591 (set (reg:SI SP_REG)
17592 (plus:SI (reg:SI SP_REG)
17593 (match_operand:SI 4 "immediate_operand")))])]
17594 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
17595 && !reg_mentioned_p (operands[0],
17596 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17597 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17598 (parallel [(call (mem:QI (match_dup 1))
17600 (set (reg:SI SP_REG)
17601 (plus:SI (reg:SI SP_REG)
17603 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17605 ;; Combining simple memory jump instruction
17608 [(set (match_operand:W 0 "register_operand")
17609 (match_operand:W 1 "memory_operand"))
17610 (set (pc) (match_dup 0))]
17612 && !TARGET_INDIRECT_BRANCH_REGISTER
17613 && peep2_reg_dead_p (2, operands[0])"
17614 [(set (pc) (match_dup 1))])
17616 ;; Call subroutine, returning value in operand 0
17618 (define_expand "call_value"
17619 [(set (match_operand 0)
17620 (call (match_operand:QI 1)
17621 (match_operand 2)))
17622 (use (match_operand 3))]
17625 ix86_expand_call (operands[0], operands[1], operands[2],
17626 operands[3], NULL, false);
17630 (define_expand "sibcall_value"
17631 [(set (match_operand 0)
17632 (call (match_operand:QI 1)
17633 (match_operand 2)))
17634 (use (match_operand 3))]
17637 ix86_expand_call (operands[0], operands[1], operands[2],
17638 operands[3], NULL, true);
17642 (define_insn "*call_value"
17643 [(set (match_operand 0)
17644 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
17645 (match_operand 2)))]
17646 "!SIBLING_CALL_P (insn)"
17647 "* return ix86_output_call_insn (insn, operands[1]);"
17648 [(set_attr "type" "callv")])
17650 ;; This covers both call and sibcall since only GOT slot is allowed.
17651 (define_insn "*call_value_got_x32"
17652 [(set (match_operand 0)
17655 (match_operand:SI 1 "GOT_memory_operand" "Bg")))
17656 (match_operand 2)))]
17659 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
17660 return ix86_output_call_insn (insn, fnaddr);
17662 [(set_attr "type" "callv")])
17664 ;; Since sibcall never returns, we can only use call-clobbered register
17666 (define_insn "*sibcall_value_GOT_32"
17667 [(set (match_operand 0)
17670 (match_operand:SI 1 "register_no_elim_operand" "U")
17671 (match_operand:SI 2 "GOT32_symbol_operand"))))
17672 (match_operand 3)))]
17675 && !TARGET_INDIRECT_BRANCH_REGISTER
17676 && SIBLING_CALL_P (insn)"
17678 rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
17679 fnaddr = gen_const_mem (SImode, fnaddr);
17680 return ix86_output_call_insn (insn, fnaddr);
17682 [(set_attr "type" "callv")])
17684 (define_insn "*sibcall_value"
17685 [(set (match_operand 0)
17686 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
17687 (match_operand 2)))]
17688 "SIBLING_CALL_P (insn)"
17689 "* return ix86_output_call_insn (insn, operands[1]);"
17690 [(set_attr "type" "callv")])
17692 (define_insn "*sibcall_value_memory"
17693 [(set (match_operand 0)
17694 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
17695 (match_operand 2)))
17696 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17697 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
17698 "* return ix86_output_call_insn (insn, operands[1]);"
17699 [(set_attr "type" "callv")])
17702 [(set (match_operand:W 0 "register_operand")
17703 (match_operand:W 1 "memory_operand"))
17704 (set (match_operand 2)
17705 (call (mem:QI (match_dup 0))
17706 (match_operand 3)))]
17708 && !TARGET_INDIRECT_BRANCH_REGISTER
17709 && SIBLING_CALL_P (peep2_next_insn (1))
17710 && !reg_mentioned_p (operands[0],
17711 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17712 [(parallel [(set (match_dup 2)
17713 (call (mem:QI (match_dup 1))
17715 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17718 [(set (match_operand:W 0 "register_operand")
17719 (match_operand:W 1 "memory_operand"))
17720 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17721 (set (match_operand 2)
17722 (call (mem:QI (match_dup 0))
17723 (match_operand 3)))]
17725 && !TARGET_INDIRECT_BRANCH_REGISTER
17726 && SIBLING_CALL_P (peep2_next_insn (2))
17727 && !reg_mentioned_p (operands[0],
17728 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17729 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17730 (parallel [(set (match_dup 2)
17731 (call (mem:QI (match_dup 1))
17733 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17735 (define_expand "call_value_pop"
17736 [(parallel [(set (match_operand 0)
17737 (call (match_operand:QI 1)
17738 (match_operand:SI 2)))
17739 (set (reg:SI SP_REG)
17740 (plus:SI (reg:SI SP_REG)
17741 (match_operand:SI 4)))])]
17744 ix86_expand_call (operands[0], operands[1], operands[2],
17745 operands[3], operands[4], false);
17749 (define_insn "*call_value_pop"
17750 [(set (match_operand 0)
17751 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz"))
17752 (match_operand 2)))
17753 (set (reg:SI SP_REG)
17754 (plus:SI (reg:SI SP_REG)
17755 (match_operand:SI 3 "immediate_operand" "i")))]
17756 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17757 "* return ix86_output_call_insn (insn, operands[1]);"
17758 [(set_attr "type" "callv")])
17760 (define_insn "*sibcall_value_pop"
17761 [(set (match_operand 0)
17762 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
17763 (match_operand 2)))
17764 (set (reg:SI SP_REG)
17765 (plus:SI (reg:SI SP_REG)
17766 (match_operand:SI 3 "immediate_operand" "i")))]
17767 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17768 "* return ix86_output_call_insn (insn, operands[1]);"
17769 [(set_attr "type" "callv")])
17771 (define_insn "*sibcall_value_pop_memory"
17772 [(set (match_operand 0)
17773 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
17774 (match_operand 2)))
17775 (set (reg:SI SP_REG)
17776 (plus:SI (reg:SI SP_REG)
17777 (match_operand:SI 3 "immediate_operand" "i")))
17778 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17780 "* return ix86_output_call_insn (insn, operands[1]);"
17781 [(set_attr "type" "callv")])
17784 [(set (match_operand:SI 0 "register_operand")
17785 (match_operand:SI 1 "memory_operand"))
17786 (parallel [(set (match_operand 2)
17787 (call (mem:QI (match_dup 0))
17788 (match_operand 3)))
17789 (set (reg:SI SP_REG)
17790 (plus:SI (reg:SI SP_REG)
17791 (match_operand:SI 4 "immediate_operand")))])]
17792 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
17793 && !reg_mentioned_p (operands[0],
17794 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17795 [(parallel [(set (match_dup 2)
17796 (call (mem:QI (match_dup 1))
17798 (set (reg:SI SP_REG)
17799 (plus:SI (reg:SI SP_REG)
17801 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17804 [(set (match_operand:SI 0 "register_operand")
17805 (match_operand:SI 1 "memory_operand"))
17806 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17807 (parallel [(set (match_operand 2)
17808 (call (mem:QI (match_dup 0))
17809 (match_operand 3)))
17810 (set (reg:SI SP_REG)
17811 (plus:SI (reg:SI SP_REG)
17812 (match_operand:SI 4 "immediate_operand")))])]
17813 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
17814 && !reg_mentioned_p (operands[0],
17815 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17816 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17817 (parallel [(set (match_dup 2)
17818 (call (mem:QI (match_dup 1))
17820 (set (reg:SI SP_REG)
17821 (plus:SI (reg:SI SP_REG)
17823 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17825 ;; Call subroutine returning any type.
17827 (define_expand "untyped_call"
17828 [(parallel [(call (match_operand 0)
17831 (match_operand 2)])]
17836 /* In order to give reg-stack an easier job in validating two
17837 coprocessor registers as containing a possible return value,
17838 simply pretend the untyped call returns a complex long double
17841 We can't use SSE_REGPARM_MAX here since callee is unprototyped
17842 and should have the default ABI. */
17844 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
17845 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
17846 operands[0], const0_rtx,
17847 GEN_INT ((TARGET_64BIT
17848 ? (ix86_abi == SYSV_ABI
17849 ? X86_64_SSE_REGPARM_MAX
17850 : X86_64_MS_SSE_REGPARM_MAX)
17851 : X86_32_SSE_REGPARM_MAX)
17855 for (i = 0; i < XVECLEN (operands[2], 0); i++)
17857 rtx set = XVECEXP (operands[2], 0, i);
17858 emit_move_insn (SET_DEST (set), SET_SRC (set));
17861 /* The optimizer does not know that the call sets the function value
17862 registers we stored in the result block. We avoid problems by
17863 claiming that all hard registers are used and clobbered at this
17865 emit_insn (gen_blockage ());
17870 ;; Prologue and epilogue instructions
17872 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
17873 ;; all of memory. This blocks insns from being moved across this point.
17875 (define_insn "blockage"
17876 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
17879 [(set_attr "length" "0")])
17881 ;; Do not schedule instructions accessing memory across this point.
17883 (define_expand "memory_blockage"
17884 [(set (match_dup 0)
17885 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
17888 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
17889 MEM_VOLATILE_P (operands[0]) = 1;
17892 (define_insn "*memory_blockage"
17893 [(set (match_operand:BLK 0)
17894 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
17897 [(set_attr "length" "0")])
17899 ;; As USE insns aren't meaningful after reload, this is used instead
17900 ;; to prevent deleting instructions setting registers for PIC code
17901 (define_insn "prologue_use"
17902 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
17905 [(set_attr "length" "0")])
17907 ;; Insn emitted into the body of a function to return from a function.
17908 ;; This is only done if the function's epilogue is known to be simple.
17909 ;; See comments for ix86_can_use_return_insn_p in i386.cc.
17911 (define_expand "return"
17913 "ix86_can_use_return_insn_p ()"
17915 if (crtl->args.pops_args)
17917 rtx popc = GEN_INT (crtl->args.pops_args);
17918 emit_jump_insn (gen_simple_return_pop_internal (popc));
17923 ;; We need to disable this for TARGET_SEH, as otherwise
17924 ;; shrink-wrapped prologue gets enabled too. This might exceed
17925 ;; the maximum size of prologue in unwind information.
17926 ;; Also disallow shrink-wrapping if using stack slot to pass the
17927 ;; static chain pointer - the first instruction has to be pushl %esi
17928 ;; and it can't be moved around, as we use alternate entry points
17930 ;; Also disallow for ms_hook_prologue functions which have frame
17931 ;; pointer set up in function label which is correctly handled in
17932 ;; ix86_expand_{prologue|epligoue}() only.
17934 (define_expand "simple_return"
17936 "!TARGET_SEH && !ix86_static_chain_on_stack && !ix86_function_ms_hook_prologue (cfun->decl)"
17938 if (crtl->args.pops_args)
17940 rtx popc = GEN_INT (crtl->args.pops_args);
17941 emit_jump_insn (gen_simple_return_pop_internal (popc));
17946 (define_insn "simple_return_internal"
17949 "* return ix86_output_function_return (false);"
17950 [(set_attr "length" "1")
17951 (set_attr "atom_unit" "jeu")
17952 (set_attr "length_immediate" "0")
17953 (set_attr "modrm" "0")])
17955 (define_insn "interrupt_return"
17957 (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
17960 return TARGET_64BIT ? (TARGET_UINTR ? "uiret" : "iretq") : "iret";
17963 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
17964 ;; instruction Athlon and K8 have.
17966 (define_insn "simple_return_internal_long"
17968 (unspec [(const_int 0)] UNSPEC_REP)]
17970 "* return ix86_output_function_return (true);"
17971 [(set_attr "length" "2")
17972 (set_attr "atom_unit" "jeu")
17973 (set_attr "length_immediate" "0")
17974 (set_attr "prefix_rep" "1")
17975 (set_attr "modrm" "0")])
17977 (define_insn_and_split "simple_return_pop_internal"
17979 (use (match_operand:SI 0 "const_int_operand"))]
17982 "&& cfun->machine->function_return_type != indirect_branch_keep"
17984 "ix86_split_simple_return_pop_internal (operands[0]); DONE;"
17985 [(set_attr "length" "3")
17986 (set_attr "atom_unit" "jeu")
17987 (set_attr "length_immediate" "2")
17988 (set_attr "modrm" "0")])
17990 (define_expand "simple_return_indirect_internal"
17993 (use (match_operand 0 "register_operand"))])])
17995 (define_insn "*simple_return_indirect_internal<mode>"
17997 (use (match_operand:W 0 "register_operand" "r"))]
17999 "* return ix86_output_indirect_function_return (operands[0]);"
18000 [(set (attr "type")
18001 (if_then_else (match_test "(cfun->machine->indirect_branch_type
18002 != indirect_branch_keep)")
18003 (const_string "multi")
18004 (const_string "ibr")))
18005 (set_attr "length_immediate" "0")])
18011 [(set_attr "length" "1")
18012 (set_attr "length_immediate" "0")
18013 (set_attr "modrm" "0")])
18015 ;; Generate nops. Operand 0 is the number of nops, up to 8.
18016 (define_insn "nops"
18017 [(unspec_volatile [(match_operand 0 "const_int_operand")]
18021 int num = INTVAL (operands[0]);
18023 gcc_assert (IN_RANGE (num, 1, 8));
18026 fputs ("\tnop\n", asm_out_file);
18030 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
18031 (set_attr "length_immediate" "0")
18032 (set_attr "modrm" "0")])
18034 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
18035 ;; branch prediction penalty for the third jump in a 16-byte
18039 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
18042 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
18043 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
18045 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
18046 The align insn is used to avoid 3 jump instructions in the row to improve
18047 branch prediction and the benefits hardly outweigh the cost of extra 8
18048 nops on the average inserted by full alignment pseudo operation. */
18052 [(set_attr "length" "16")])
18054 (define_expand "prologue"
18057 "ix86_expand_prologue (); DONE;")
18059 (define_expand "set_got"
18061 [(set (match_operand:SI 0 "register_operand")
18062 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
18063 (clobber (reg:CC FLAGS_REG))])]
18066 if (flag_pic && !TARGET_VXWORKS_RTP)
18067 ix86_pc_thunk_call_expanded = true;
18070 (define_insn "*set_got"
18071 [(set (match_operand:SI 0 "register_operand" "=r")
18072 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
18073 (clobber (reg:CC FLAGS_REG))]
18075 "* return output_set_got (operands[0], NULL_RTX);"
18076 [(set_attr "type" "multi")
18077 (set_attr "length" "12")])
18079 (define_expand "set_got_labelled"
18081 [(set (match_operand:SI 0 "register_operand")
18082 (unspec:SI [(label_ref (match_operand 1))]
18084 (clobber (reg:CC FLAGS_REG))])]
18087 if (flag_pic && !TARGET_VXWORKS_RTP)
18088 ix86_pc_thunk_call_expanded = true;
18091 (define_insn "*set_got_labelled"
18092 [(set (match_operand:SI 0 "register_operand" "=r")
18093 (unspec:SI [(label_ref (match_operand 1))]
18095 (clobber (reg:CC FLAGS_REG))]
18097 "* return output_set_got (operands[0], operands[1]);"
18098 [(set_attr "type" "multi")
18099 (set_attr "length" "12")])
18101 (define_insn "set_got_rex64"
18102 [(set (match_operand:DI 0 "register_operand" "=r")
18103 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
18105 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
18106 [(set_attr "type" "lea")
18107 (set_attr "length_address" "4")
18108 (set_attr "mode" "DI")])
18110 (define_insn "set_rip_rex64"
18111 [(set (match_operand:DI 0 "register_operand" "=r")
18112 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
18114 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
18115 [(set_attr "type" "lea")
18116 (set_attr "length_address" "4")
18117 (set_attr "mode" "DI")])
18119 (define_insn "set_got_offset_rex64"
18120 [(set (match_operand:DI 0 "register_operand" "=r")
18122 [(label_ref (match_operand 1))]
18123 UNSPEC_SET_GOT_OFFSET))]
18125 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
18126 [(set_attr "type" "imov")
18127 (set_attr "length_immediate" "0")
18128 (set_attr "length_address" "8")
18129 (set_attr "mode" "DI")])
18131 (define_expand "epilogue"
18134 "ix86_expand_epilogue (1); DONE;")
18136 (define_expand "sibcall_epilogue"
18139 "ix86_expand_epilogue (0); DONE;")
18141 (define_expand "eh_return"
18142 [(use (match_operand 0 "register_operand"))]
18145 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
18147 /* Tricky bit: we write the address of the handler to which we will
18148 be returning into someone else's stack frame, one word below the
18149 stack address we wish to restore. */
18150 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
18151 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
18152 /* Return address is always in word_mode. */
18153 tmp = gen_rtx_MEM (word_mode, tmp);
18154 if (GET_MODE (ra) != word_mode)
18155 ra = convert_to_mode (word_mode, ra, 1);
18156 emit_move_insn (tmp, ra);
18158 emit_jump_insn (gen_eh_return_internal ());
18163 (define_insn_and_split "eh_return_internal"
18167 "epilogue_completed"
18169 "ix86_expand_epilogue (2); DONE;")
18171 (define_expand "@leave_<mode>"
18173 [(set (reg:W SP_REG) (plus:W (reg:W BP_REG) (match_dup 0)))
18174 (set (reg:W BP_REG) (mem:W (reg:W BP_REG)))
18175 (clobber (mem:BLK (scratch)))])]
18177 "operands[0] = GEN_INT (<MODE_SIZE>);")
18179 (define_insn "*leave"
18180 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
18181 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
18182 (clobber (mem:BLK (scratch)))]
18185 [(set_attr "type" "leave")])
18187 (define_insn "*leave_rex64"
18188 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
18189 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
18190 (clobber (mem:BLK (scratch)))]
18193 [(set_attr "type" "leave")])
18195 ;; Handle -fsplit-stack.
18197 (define_expand "split_stack_prologue"
18201 ix86_expand_split_stack_prologue ();
18205 ;; In order to support the call/return predictor, we use a return
18206 ;; instruction which the middle-end doesn't see.
18207 (define_insn "split_stack_return"
18208 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
18209 UNSPECV_SPLIT_STACK_RETURN)]
18212 if (operands[0] == const0_rtx)
18217 [(set_attr "atom_unit" "jeu")
18218 (set_attr "modrm" "0")
18219 (set (attr "length")
18220 (if_then_else (match_operand:SI 0 "const0_operand")
18223 (set (attr "length_immediate")
18224 (if_then_else (match_operand:SI 0 "const0_operand")
18228 ;; If there are operand 0 bytes available on the stack, jump to
18231 (define_expand "split_stack_space_check"
18232 [(set (pc) (if_then_else
18233 (ltu (minus (reg SP_REG)
18234 (match_operand 0 "register_operand"))
18236 (label_ref (match_operand 1))
18240 rtx reg = gen_reg_rtx (Pmode);
18242 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, operands[0]));
18244 operands[2] = ix86_split_stack_guard ();
18245 ix86_expand_branch (GEU, reg, operands[2], operands[1]);
18250 ;; Bit manipulation instructions.
18252 (define_expand "ffs<mode>2"
18253 [(set (match_dup 2) (const_int -1))
18254 (parallel [(set (match_dup 3) (match_dup 4))
18255 (set (match_operand:SWI48 0 "register_operand")
18257 (match_operand:SWI48 1 "nonimmediate_operand")))])
18258 (set (match_dup 0) (if_then_else:SWI48
18259 (eq (match_dup 3) (const_int 0))
18262 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
18263 (clobber (reg:CC FLAGS_REG))])]
18266 machine_mode flags_mode;
18268 if (<MODE>mode == SImode && !TARGET_CMOVE)
18270 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
18274 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
18276 operands[2] = gen_reg_rtx (<MODE>mode);
18277 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
18278 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
18281 (define_insn_and_split "ffssi2_no_cmove"
18282 [(set (match_operand:SI 0 "register_operand" "=r")
18283 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
18284 (clobber (match_scratch:SI 2 "=&q"))
18285 (clobber (reg:CC FLAGS_REG))]
18288 "&& reload_completed"
18289 [(parallel [(set (match_dup 4) (match_dup 5))
18290 (set (match_dup 0) (ctz:SI (match_dup 1)))])
18291 (set (strict_low_part (match_dup 3))
18292 (eq:QI (match_dup 4) (const_int 0)))
18293 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
18294 (clobber (reg:CC FLAGS_REG))])
18295 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
18296 (clobber (reg:CC FLAGS_REG))])
18297 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
18298 (clobber (reg:CC FLAGS_REG))])]
18300 machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
18302 operands[3] = gen_lowpart (QImode, operands[2]);
18303 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
18304 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
18306 ix86_expand_clear (operands[2]);
18309 (define_insn_and_split "*tzcnt<mode>_1"
18310 [(set (reg:CCC FLAGS_REG)
18311 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18313 (set (match_operand:SWI48 0 "register_operand" "=r")
18314 (ctz:SWI48 (match_dup 1)))]
18316 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
18317 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18318 && optimize_function_for_speed_p (cfun)
18319 && !reg_mentioned_p (operands[0], operands[1])"
18321 [(set (reg:CCC FLAGS_REG)
18322 (compare:CCC (match_dup 1) (const_int 0)))
18324 (ctz:SWI48 (match_dup 1)))
18325 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
18326 "ix86_expand_clear (operands[0]);"
18327 [(set_attr "type" "alu1")
18328 (set_attr "prefix_0f" "1")
18329 (set_attr "prefix_rep" "1")
18330 (set_attr "btver2_decode" "double")
18331 (set_attr "mode" "<MODE>")])
18333 ; False dependency happens when destination is only updated by tzcnt,
18334 ; lzcnt or popcnt. There is no false dependency when destination is
18335 ; also used in source.
18336 (define_insn "*tzcnt<mode>_1_falsedep"
18337 [(set (reg:CCC FLAGS_REG)
18338 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18340 (set (match_operand:SWI48 0 "register_operand" "=r")
18341 (ctz:SWI48 (match_dup 1)))
18342 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18343 UNSPEC_INSN_FALSE_DEP)]
18345 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
18346 [(set_attr "type" "alu1")
18347 (set_attr "prefix_0f" "1")
18348 (set_attr "prefix_rep" "1")
18349 (set_attr "btver2_decode" "double")
18350 (set_attr "mode" "<MODE>")])
18352 (define_insn "*bsf<mode>_1"
18353 [(set (reg:CCZ FLAGS_REG)
18354 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18356 (set (match_operand:SWI48 0 "register_operand" "=r")
18357 (ctz:SWI48 (match_dup 1)))]
18359 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
18360 [(set_attr "type" "alu1")
18361 (set_attr "prefix_0f" "1")
18362 (set_attr "btver2_decode" "double")
18363 (set_attr "znver1_decode" "vector")
18364 (set_attr "mode" "<MODE>")])
18366 (define_insn_and_split "ctz<mode>2"
18367 [(set (match_operand:SWI48 0 "register_operand" "=r")
18369 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18370 (clobber (reg:CC FLAGS_REG))]
18374 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
18375 else if (optimize_function_for_size_p (cfun))
18377 else if (TARGET_CPU_P (GENERIC))
18378 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
18379 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
18381 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
18383 "(TARGET_BMI || TARGET_CPU_P (GENERIC))
18384 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18385 && optimize_function_for_speed_p (cfun)
18386 && !reg_mentioned_p (operands[0], operands[1])"
18388 [(set (match_dup 0)
18389 (ctz:SWI48 (match_dup 1)))
18390 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18391 (clobber (reg:CC FLAGS_REG))])]
18392 "ix86_expand_clear (operands[0]);"
18393 [(set_attr "type" "alu1")
18394 (set_attr "prefix_0f" "1")
18395 (set (attr "prefix_rep")
18397 (ior (match_test "TARGET_BMI")
18398 (and (not (match_test "optimize_function_for_size_p (cfun)"))
18399 (match_test "TARGET_CPU_P (GENERIC)")))
18401 (const_string "0")))
18402 (set_attr "mode" "<MODE>")])
18404 ; False dependency happens when destination is only updated by tzcnt,
18405 ; lzcnt or popcnt. There is no false dependency when destination is
18406 ; also used in source.
18407 (define_insn "*ctz<mode>2_falsedep"
18408 [(set (match_operand:SWI48 0 "register_operand" "=r")
18410 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18411 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18412 UNSPEC_INSN_FALSE_DEP)
18413 (clobber (reg:CC FLAGS_REG))]
18417 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
18418 else if (TARGET_CPU_P (GENERIC))
18419 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
18420 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
18422 gcc_unreachable ();
18424 [(set_attr "type" "alu1")
18425 (set_attr "prefix_0f" "1")
18426 (set_attr "prefix_rep" "1")
18427 (set_attr "mode" "<MODE>")])
18429 (define_insn_and_split "*ctzsi2_zext"
18430 [(set (match_operand:DI 0 "register_operand" "=r")
18434 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
18436 (clobber (reg:CC FLAGS_REG))]
18437 "TARGET_BMI && TARGET_64BIT"
18438 "tzcnt{l}\t{%1, %k0|%k0, %1}"
18439 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18440 && optimize_function_for_speed_p (cfun)
18441 && !reg_mentioned_p (operands[0], operands[1])"
18443 [(set (match_dup 0)
18444 (and:DI (subreg:DI (ctz:SI (match_dup 1)) 0) (const_int 63)))
18445 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18446 (clobber (reg:CC FLAGS_REG))])]
18447 "ix86_expand_clear (operands[0]);"
18448 [(set_attr "type" "alu1")
18449 (set_attr "prefix_0f" "1")
18450 (set_attr "prefix_rep" "1")
18451 (set_attr "mode" "SI")])
18453 ; False dependency happens when destination is only updated by tzcnt,
18454 ; lzcnt or popcnt. There is no false dependency when destination is
18455 ; also used in source.
18456 (define_insn "*ctzsi2_zext_falsedep"
18457 [(set (match_operand:DI 0 "register_operand" "=r")
18461 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
18463 (unspec [(match_operand:DI 2 "register_operand" "0")]
18464 UNSPEC_INSN_FALSE_DEP)
18465 (clobber (reg:CC FLAGS_REG))]
18466 "TARGET_BMI && TARGET_64BIT"
18467 "tzcnt{l}\t{%1, %k0|%k0, %1}"
18468 [(set_attr "type" "alu1")
18469 (set_attr "prefix_0f" "1")
18470 (set_attr "prefix_rep" "1")
18471 (set_attr "mode" "SI")])
18473 (define_insn_and_split "*ctzsidi2_<s>ext"
18474 [(set (match_operand:DI 0 "register_operand" "=r")
18477 (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18478 (clobber (reg:CC FLAGS_REG))]
18482 return "tzcnt{l}\t{%1, %k0|%k0, %1}";
18483 else if (TARGET_CPU_P (GENERIC)
18484 && !optimize_function_for_size_p (cfun))
18485 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
18486 return "rep%; bsf{l}\t{%1, %k0|%k0, %1}";
18487 return "bsf{l}\t{%1, %k0|%k0, %1}";
18489 "(TARGET_BMI || TARGET_CPU_P (GENERIC))
18490 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18491 && optimize_function_for_speed_p (cfun)
18492 && !reg_mentioned_p (operands[0], operands[1])"
18494 [(set (match_dup 0)
18495 (any_extend:DI (ctz:SI (match_dup 1))))
18496 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18497 (clobber (reg:CC FLAGS_REG))])]
18498 "ix86_expand_clear (operands[0]);"
18499 [(set_attr "type" "alu1")
18500 (set_attr "prefix_0f" "1")
18501 (set (attr "prefix_rep")
18503 (ior (match_test "TARGET_BMI")
18504 (and (not (match_test "optimize_function_for_size_p (cfun)"))
18505 (match_test "TARGET_CPU_P (GENERIC)")))
18507 (const_string "0")))
18508 (set_attr "mode" "SI")])
18510 (define_insn "*ctzsidi2_<s>ext_falsedep"
18511 [(set (match_operand:DI 0 "register_operand" "=r")
18514 (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18515 (unspec [(match_operand:DI 2 "register_operand" "0")]
18516 UNSPEC_INSN_FALSE_DEP)
18517 (clobber (reg:CC FLAGS_REG))]
18521 return "tzcnt{l}\t{%1, %k0|%k0, %1}";
18522 else if (TARGET_CPU_P (GENERIC))
18523 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
18524 return "rep%; bsf{l}\t{%1, %k0|%k0, %1}";
18526 gcc_unreachable ();
18528 [(set_attr "type" "alu1")
18529 (set_attr "prefix_0f" "1")
18530 (set_attr "prefix_rep" "1")
18531 (set_attr "mode" "SI")])
18533 (define_insn "bsr_rex64"
18534 [(set (reg:CCZ FLAGS_REG)
18535 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
18537 (set (match_operand:DI 0 "register_operand" "=r")
18538 (minus:DI (const_int 63)
18539 (clz:DI (match_dup 1))))]
18541 "bsr{q}\t{%1, %0|%0, %1}"
18542 [(set_attr "type" "alu1")
18543 (set_attr "prefix_0f" "1")
18544 (set_attr "znver1_decode" "vector")
18545 (set_attr "mode" "DI")])
18547 (define_insn "bsr_rex64_1"
18548 [(set (match_operand:DI 0 "register_operand" "=r")
18549 (minus:DI (const_int 63)
18550 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
18551 (clobber (reg:CC FLAGS_REG))]
18552 "!TARGET_LZCNT && TARGET_64BIT"
18553 "bsr{q}\t{%1, %0|%0, %1}"
18554 [(set_attr "type" "alu1")
18555 (set_attr "prefix_0f" "1")
18556 (set_attr "znver1_decode" "vector")
18557 (set_attr "mode" "DI")])
18559 (define_insn "bsr_rex64_1_zext"
18560 [(set (match_operand:DI 0 "register_operand" "=r")
18562 (minus:SI (const_int 63)
18564 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
18566 (clobber (reg:CC FLAGS_REG))]
18567 "!TARGET_LZCNT && TARGET_64BIT"
18568 "bsr{q}\t{%1, %0|%0, %1}"
18569 [(set_attr "type" "alu1")
18570 (set_attr "prefix_0f" "1")
18571 (set_attr "znver1_decode" "vector")
18572 (set_attr "mode" "DI")])
18575 [(set (reg:CCZ FLAGS_REG)
18576 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
18578 (set (match_operand:SI 0 "register_operand" "=r")
18579 (minus:SI (const_int 31)
18580 (clz:SI (match_dup 1))))]
18582 "bsr{l}\t{%1, %0|%0, %1}"
18583 [(set_attr "type" "alu1")
18584 (set_attr "prefix_0f" "1")
18585 (set_attr "znver1_decode" "vector")
18586 (set_attr "mode" "SI")])
18588 (define_insn "bsr_1"
18589 [(set (match_operand:SI 0 "register_operand" "=r")
18590 (minus:SI (const_int 31)
18591 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18592 (clobber (reg:CC FLAGS_REG))]
18594 "bsr{l}\t{%1, %0|%0, %1}"
18595 [(set_attr "type" "alu1")
18596 (set_attr "prefix_0f" "1")
18597 (set_attr "znver1_decode" "vector")
18598 (set_attr "mode" "SI")])
18600 (define_insn "bsr_zext_1"
18601 [(set (match_operand:DI 0 "register_operand" "=r")
18605 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))))
18606 (clobber (reg:CC FLAGS_REG))]
18607 "!TARGET_LZCNT && TARGET_64BIT"
18608 "bsr{l}\t{%1, %k0|%k0, %1}"
18609 [(set_attr "type" "alu1")
18610 (set_attr "prefix_0f" "1")
18611 (set_attr "znver1_decode" "vector")
18612 (set_attr "mode" "SI")])
18614 ; As bsr is undefined behavior on zero and for other input
18615 ; values it is in range 0 to 63, we can optimize away sign-extends.
18616 (define_insn_and_split "*bsr_rex64_2"
18617 [(set (match_operand:DI 0 "register_operand")
18622 (subreg:SI (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
18625 (clobber (reg:CC FLAGS_REG))]
18626 "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
18629 [(parallel [(set (reg:CCZ FLAGS_REG)
18630 (compare:CCZ (match_dup 1) (const_int 0)))
18632 (minus:DI (const_int 63) (clz:DI (match_dup 1))))])
18633 (parallel [(set (match_dup 0)
18634 (zero_extend:DI (xor:SI (match_dup 3) (const_int 63))))
18635 (clobber (reg:CC FLAGS_REG))])]
18637 operands[2] = gen_reg_rtx (DImode);
18638 operands[3] = lowpart_subreg (SImode, operands[2], DImode);
18641 (define_insn_and_split "*bsr_2"
18642 [(set (match_operand:DI 0 "register_operand")
18647 (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
18649 (clobber (reg:CC FLAGS_REG))]
18650 "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
18653 [(parallel [(set (reg:CCZ FLAGS_REG)
18654 (compare:CCZ (match_dup 1) (const_int 0)))
18656 (minus:SI (const_int 31) (clz:SI (match_dup 1))))])
18657 (parallel [(set (match_dup 0)
18658 (zero_extend:DI (xor:SI (match_dup 2) (const_int 31))))
18659 (clobber (reg:CC FLAGS_REG))])]
18660 "operands[2] = gen_reg_rtx (SImode);")
18662 ; Splitters to optimize 64 - __builtin_clzl (x) or 32 - __builtin_clz (x).
18663 ; Again, as for !TARGET_LZCNT CLZ is UB at zero, CLZ is guaranteed to be
18664 ; in [0, 63] or [0, 31] range.
18666 [(set (match_operand:SI 0 "register_operand")
18668 (match_operand:SI 2 "const_int_operand")
18670 (minus:SI (const_int 63)
18672 (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
18675 "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
18676 [(set (match_dup 3)
18677 (minus:DI (const_int 63) (clz:DI (match_dup 1))))
18679 (plus:SI (match_dup 5) (match_dup 4)))]
18681 operands[3] = gen_reg_rtx (DImode);
18682 operands[5] = lowpart_subreg (SImode, operands[3], DImode);
18683 if (INTVAL (operands[2]) == 63)
18685 emit_insn (gen_bsr_rex64_1_zext (operands[3], operands[1]));
18686 emit_move_insn (operands[0], operands[5]);
18689 operands[4] = gen_int_mode (UINTVAL (operands[2]) - 63, SImode);
18693 [(set (match_operand:SI 0 "register_operand")
18695 (match_operand:SI 2 "const_int_operand")
18697 (minus:SI (const_int 31)
18698 (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
18700 "!TARGET_LZCNT && ix86_pre_reload_split ()"
18701 [(set (match_dup 3)
18702 (minus:SI (const_int 31) (clz:SI (match_dup 1))))
18704 (plus:SI (match_dup 3) (match_dup 4)))]
18706 if (INTVAL (operands[2]) == 31)
18708 emit_insn (gen_bsr_1 (operands[0], operands[1]));
18711 operands[3] = gen_reg_rtx (SImode);
18712 operands[4] = gen_int_mode (UINTVAL (operands[2]) - 31, SImode);
18716 [(set (match_operand:DI 0 "register_operand")
18718 (match_operand:DI 2 "const_int_operand")
18721 (minus:SI (const_int 63)
18723 (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
18728 && ix86_pre_reload_split ()
18729 && ((unsigned HOST_WIDE_INT)
18730 trunc_int_for_mode (UINTVAL (operands[2]) - 63, SImode)
18731 == UINTVAL (operands[2]) - 63)"
18732 [(set (match_dup 3)
18733 (minus:DI (const_int 63) (clz:DI (match_dup 1))))
18735 (plus:DI (match_dup 3) (match_dup 4)))]
18737 if (INTVAL (operands[2]) == 63)
18739 emit_insn (gen_bsr_rex64_1 (operands[0], operands[1]));
18742 operands[3] = gen_reg_rtx (DImode);
18743 operands[4] = GEN_INT (UINTVAL (operands[2]) - 63);
18747 [(set (match_operand:DI 0 "register_operand")
18749 (match_operand:DI 2 "const_int_operand")
18752 (minus:SI (const_int 31)
18753 (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
18754 (const_int 31)))))]
18757 && ix86_pre_reload_split ()
18758 && ((unsigned HOST_WIDE_INT)
18759 trunc_int_for_mode (UINTVAL (operands[2]) - 31, SImode)
18760 == UINTVAL (operands[2]) - 31)"
18761 [(set (match_dup 3)
18762 (zero_extend:DI (minus:SI (const_int 31) (clz:SI (match_dup 1)))))
18764 (plus:DI (match_dup 3) (match_dup 4)))]
18766 if (INTVAL (operands[2]) == 31)
18768 emit_insn (gen_bsr_zext_1 (operands[0], operands[1]));
18771 operands[3] = gen_reg_rtx (DImode);
18772 operands[4] = GEN_INT (UINTVAL (operands[2]) - 31);
18775 (define_expand "clz<mode>2"
18777 [(set (reg:CCZ FLAGS_REG)
18778 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18780 (set (match_dup 3) (minus:SWI48
18782 (clz:SWI48 (match_dup 1))))])
18784 [(set (match_operand:SWI48 0 "register_operand")
18785 (xor:SWI48 (match_dup 3) (match_dup 2)))
18786 (clobber (reg:CC FLAGS_REG))])]
18791 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
18794 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
18795 operands[3] = gen_reg_rtx (<MODE>mode);
18798 (define_insn_and_split "clz<mode>2_lzcnt"
18799 [(set (match_operand:SWI48 0 "register_operand" "=r")
18801 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18802 (clobber (reg:CC FLAGS_REG))]
18804 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
18805 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18806 && optimize_function_for_speed_p (cfun)
18807 && !reg_mentioned_p (operands[0], operands[1])"
18809 [(set (match_dup 0)
18810 (clz:SWI48 (match_dup 1)))
18811 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18812 (clobber (reg:CC FLAGS_REG))])]
18813 "ix86_expand_clear (operands[0]);"
18814 [(set_attr "prefix_rep" "1")
18815 (set_attr "type" "bitmanip")
18816 (set_attr "mode" "<MODE>")])
18818 ; False dependency happens when destination is only updated by tzcnt,
18819 ; lzcnt or popcnt. There is no false dependency when destination is
18820 ; also used in source.
18821 (define_insn "*clz<mode>2_lzcnt_falsedep"
18822 [(set (match_operand:SWI48 0 "register_operand" "=r")
18824 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18825 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18826 UNSPEC_INSN_FALSE_DEP)
18827 (clobber (reg:CC FLAGS_REG))]
18829 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
18830 [(set_attr "prefix_rep" "1")
18831 (set_attr "type" "bitmanip")
18832 (set_attr "mode" "<MODE>")])
18834 (define_insn_and_split "*clzsi2_lzcnt_zext"
18835 [(set (match_operand:DI 0 "register_operand" "=r")
18839 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
18841 (clobber (reg:CC FLAGS_REG))]
18842 "TARGET_LZCNT && TARGET_64BIT"
18843 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18844 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18845 && optimize_function_for_speed_p (cfun)
18846 && !reg_mentioned_p (operands[0], operands[1])"
18848 [(set (match_dup 0)
18849 (and:DI (subreg:DI (clz:SI (match_dup 1)) 0) (const_int 63)))
18850 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18851 (clobber (reg:CC FLAGS_REG))])]
18852 "ix86_expand_clear (operands[0]);"
18853 [(set_attr "prefix_rep" "1")
18854 (set_attr "type" "bitmanip")
18855 (set_attr "mode" "SI")])
18857 ; False dependency happens when destination is only updated by tzcnt,
18858 ; lzcnt or popcnt. There is no false dependency when destination is
18859 ; also used in source.
18860 (define_insn "*clzsi2_lzcnt_zext_falsedep"
18861 [(set (match_operand:DI 0 "register_operand" "=r")
18865 (match_operand:SWI48 1 "nonimmediate_operand" "rm")) 0)
18867 (unspec [(match_operand:DI 2 "register_operand" "0")]
18868 UNSPEC_INSN_FALSE_DEP)
18869 (clobber (reg:CC FLAGS_REG))]
18871 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18872 [(set_attr "prefix_rep" "1")
18873 (set_attr "type" "bitmanip")
18874 (set_attr "mode" "SI")])
18876 (define_insn_and_split "*clzsi2_lzcnt_zext_2"
18877 [(set (match_operand:DI 0 "register_operand" "=r")
18879 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18880 (clobber (reg:CC FLAGS_REG))]
18881 "TARGET_LZCNT && TARGET_64BIT"
18882 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18883 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18884 && optimize_function_for_speed_p (cfun)
18885 && !reg_mentioned_p (operands[0], operands[1])"
18887 [(set (match_dup 0)
18888 (zero_extend:DI (clz:SI (match_dup 1))))
18889 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18890 (clobber (reg:CC FLAGS_REG))])]
18891 "ix86_expand_clear (operands[0]);"
18892 [(set_attr "prefix_rep" "1")
18893 (set_attr "type" "bitmanip")
18894 (set_attr "mode" "SI")])
18896 ; False dependency happens when destination is only updated by tzcnt,
18897 ; lzcnt or popcnt. There is no false dependency when destination is
18898 ; also used in source.
18899 (define_insn "*clzsi2_lzcnt_zext_2_falsedep"
18900 [(set (match_operand:DI 0 "register_operand" "=r")
18902 (clz:SI (match_operand:SWI48 1 "nonimmediate_operand" "rm"))))
18903 (unspec [(match_operand:DI 2 "register_operand" "0")]
18904 UNSPEC_INSN_FALSE_DEP)
18905 (clobber (reg:CC FLAGS_REG))]
18907 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18908 [(set_attr "prefix_rep" "1")
18909 (set_attr "type" "bitmanip")
18910 (set_attr "mode" "SI")])
18912 (define_int_iterator LT_ZCNT
18913 [(UNSPEC_TZCNT "TARGET_BMI")
18914 (UNSPEC_LZCNT "TARGET_LZCNT")])
18916 (define_int_attr lt_zcnt
18917 [(UNSPEC_TZCNT "tzcnt")
18918 (UNSPEC_LZCNT "lzcnt")])
18920 (define_int_attr lt_zcnt_type
18921 [(UNSPEC_TZCNT "alu1")
18922 (UNSPEC_LZCNT "bitmanip")])
18924 ;; Version of lzcnt/tzcnt that is expanded from intrinsics. This version
18925 ;; provides operand size as output when source operand is zero.
18927 (define_insn_and_split "<lt_zcnt>_<mode>"
18928 [(set (match_operand:SWI48 0 "register_operand" "=r")
18930 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
18931 (clobber (reg:CC FLAGS_REG))]
18933 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
18934 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18935 && optimize_function_for_speed_p (cfun)
18936 && !reg_mentioned_p (operands[0], operands[1])"
18938 [(set (match_dup 0)
18939 (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
18940 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18941 (clobber (reg:CC FLAGS_REG))])]
18942 "ix86_expand_clear (operands[0]);"
18943 [(set_attr "type" "<lt_zcnt_type>")
18944 (set_attr "prefix_0f" "1")
18945 (set_attr "prefix_rep" "1")
18946 (set_attr "mode" "<MODE>")])
18948 ; False dependency happens when destination is only updated by tzcnt,
18949 ; lzcnt or popcnt. There is no false dependency when destination is
18950 ; also used in source.
18951 (define_insn "*<lt_zcnt>_<mode>_falsedep"
18952 [(set (match_operand:SWI48 0 "register_operand" "=r")
18954 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
18955 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18956 UNSPEC_INSN_FALSE_DEP)
18957 (clobber (reg:CC FLAGS_REG))]
18959 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
18960 [(set_attr "type" "<lt_zcnt_type>")
18961 (set_attr "prefix_0f" "1")
18962 (set_attr "prefix_rep" "1")
18963 (set_attr "mode" "<MODE>")])
18965 (define_insn "<lt_zcnt>_hi"
18966 [(set (match_operand:HI 0 "register_operand" "=r")
18968 [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT))
18969 (clobber (reg:CC FLAGS_REG))]
18971 "<lt_zcnt>{w}\t{%1, %0|%0, %1}"
18972 [(set_attr "type" "<lt_zcnt_type>")
18973 (set_attr "prefix_0f" "1")
18974 (set_attr "prefix_rep" "1")
18975 (set_attr "mode" "HI")])
18977 ;; BMI instructions.
18979 (define_insn "bmi_bextr_<mode>"
18980 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
18981 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
18982 (match_operand:SWI48 2 "register_operand" "r,r")]
18984 (clobber (reg:CC FLAGS_REG))]
18986 "bextr\t{%2, %1, %0|%0, %1, %2}"
18987 [(set_attr "type" "bitmanip")
18988 (set_attr "btver2_decode" "direct, double")
18989 (set_attr "mode" "<MODE>")])
18991 (define_insn "*bmi_bextr_<mode>_ccz"
18992 [(set (reg:CCZ FLAGS_REG)
18994 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
18995 (match_operand:SWI48 2 "register_operand" "r,r")]
18998 (clobber (match_scratch:SWI48 0 "=r,r"))]
19000 "bextr\t{%2, %1, %0|%0, %1, %2}"
19001 [(set_attr "type" "bitmanip")
19002 (set_attr "btver2_decode" "direct, double")
19003 (set_attr "mode" "<MODE>")])
19005 (define_insn "*bmi_blsi_<mode>"
19006 [(set (match_operand:SWI48 0 "register_operand" "=r")
19009 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
19011 (clobber (reg:CC FLAGS_REG))]
19013 "blsi\t{%1, %0|%0, %1}"
19014 [(set_attr "type" "bitmanip")
19015 (set_attr "btver2_decode" "double")
19016 (set_attr "mode" "<MODE>")])
19018 (define_insn "*bmi_blsi_<mode>_cmp"
19019 [(set (reg FLAGS_REG)
19022 (neg:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
19025 (set (match_operand:SWI48 0 "register_operand" "=r")
19026 (and:SWI48 (neg:SWI48 (match_dup 1)) (match_dup 1)))]
19027 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
19028 "blsi\t{%1, %0|%0, %1}"
19029 [(set_attr "type" "bitmanip")
19030 (set_attr "btver2_decode" "double")
19031 (set_attr "mode" "<MODE>")])
19033 (define_insn "*bmi_blsi_<mode>_ccno"
19034 [(set (reg FLAGS_REG)
19037 (neg:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
19040 (clobber (match_scratch:SWI48 0 "=r"))]
19041 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
19042 "blsi\t{%1, %0|%0, %1}"
19043 [(set_attr "type" "bitmanip")
19044 (set_attr "btver2_decode" "double")
19045 (set_attr "mode" "<MODE>")])
19047 (define_insn "*bmi_blsmsk_<mode>"
19048 [(set (match_operand:SWI48 0 "register_operand" "=r")
19051 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19054 (clobber (reg:CC FLAGS_REG))]
19056 "blsmsk\t{%1, %0|%0, %1}"
19057 [(set_attr "type" "bitmanip")
19058 (set_attr "btver2_decode" "double")
19059 (set_attr "mode" "<MODE>")])
19061 (define_insn "*bmi_blsr_<mode>"
19062 [(set (match_operand:SWI48 0 "register_operand" "=r")
19065 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19068 (clobber (reg:CC FLAGS_REG))]
19070 "blsr\t{%1, %0|%0, %1}"
19071 [(set_attr "type" "bitmanip")
19072 (set_attr "btver2_decode" "double")
19073 (set_attr "mode" "<MODE>")])
19075 (define_insn "*bmi_blsr_<mode>_cmp"
19076 [(set (reg:CCZ FLAGS_REG)
19080 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19084 (set (match_operand:SWI48 0 "register_operand" "=r")
19091 "blsr\t{%1, %0|%0, %1}"
19092 [(set_attr "type" "bitmanip")
19093 (set_attr "btver2_decode" "double")
19094 (set_attr "mode" "<MODE>")])
19096 (define_insn "*bmi_blsr_<mode>_ccz"
19097 [(set (reg:CCZ FLAGS_REG)
19101 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19105 (clobber (match_scratch:SWI48 0 "=r"))]
19107 "blsr\t{%1, %0|%0, %1}"
19108 [(set_attr "type" "bitmanip")
19109 (set_attr "btver2_decode" "double")
19110 (set_attr "mode" "<MODE>")])
19112 ;; BMI2 instructions.
19113 (define_expand "bmi2_bzhi_<mode>3"
19115 [(set (match_operand:SWI48 0 "register_operand")
19116 (if_then_else:SWI48
19117 (ne:QI (match_operand:QI 2 "register_operand")
19119 (zero_extract:SWI48
19120 (match_operand:SWI48 1 "nonimmediate_operand")
19121 (umin:QI (match_dup 2) (match_dup 3))
19124 (clobber (reg:CC FLAGS_REG))])]
19127 operands[2] = gen_lowpart (QImode, operands[2]);
19128 operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
19131 (define_insn "*bmi2_bzhi_<mode>3"
19132 [(set (match_operand:SWI48 0 "register_operand" "=r")
19133 (if_then_else:SWI48
19134 (ne:QI (match_operand:QI 2 "register_operand" "q")
19136 (zero_extract:SWI48
19137 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19138 (umin:QI (match_dup 2)
19139 (match_operand:QI 3 "const_int_operand"))
19142 (clobber (reg:CC FLAGS_REG))]
19143 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
19144 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
19145 [(set_attr "type" "bitmanip")
19146 (set_attr "prefix" "vex")
19147 (set_attr "mode" "<MODE>")])
19149 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
19150 [(set (reg:CCZ FLAGS_REG)
19152 (if_then_else:SWI48
19153 (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0))
19154 (zero_extract:SWI48
19155 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19156 (umin:QI (match_dup 2)
19157 (match_operand:QI 3 "const_int_operand"))
19161 (clobber (match_scratch:SWI48 0 "=r"))]
19162 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
19163 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
19164 [(set_attr "type" "bitmanip")
19165 (set_attr "prefix" "vex")
19166 (set_attr "mode" "<MODE>")])
19168 (define_insn "*bmi2_bzhi_<mode>3_2"
19169 [(set (match_operand:SWI48 0 "register_operand" "=r")
19172 (ashift:SWI48 (const_int 1)
19173 (match_operand:QI 2 "register_operand" "r"))
19175 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
19176 (clobber (reg:CC FLAGS_REG))]
19178 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
19179 [(set_attr "type" "bitmanip")
19180 (set_attr "prefix" "vex")
19181 (set_attr "mode" "<MODE>")])
19183 (define_insn "*bmi2_bzhi_<mode>3_3"
19184 [(set (match_operand:SWI48 0 "register_operand" "=r")
19187 (ashift:SWI48 (const_int -1)
19188 (match_operand:QI 2 "register_operand" "r")))
19189 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
19190 (clobber (reg:CC FLAGS_REG))]
19192 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
19193 [(set_attr "type" "bitmanip")
19194 (set_attr "prefix" "vex")
19195 (set_attr "mode" "<MODE>")])
19197 (define_insn "*bmi2_bzhi_zero_extendsidi_4"
19198 [(set (match_operand:DI 0 "register_operand" "=r")
19202 (ashift:SI (const_int 1)
19203 (match_operand:QI 2 "register_operand" "r"))
19205 (match_operand:SI 1 "nonimmediate_operand" "rm"))))
19206 (clobber (reg:CC FLAGS_REG))]
19207 "TARGET_64BIT && TARGET_BMI2"
19208 "bzhi\t{%q2, %q1, %q0|%q0, %q1, %q2}"
19209 [(set_attr "type" "bitmanip")
19210 (set_attr "prefix" "vex")
19211 (set_attr "mode" "DI")])
19213 (define_insn "*bmi2_bzhi_zero_extendsidi_5"
19214 [(set (match_operand:DI 0 "register_operand" "=r")
19218 (ashift:SI (const_int 1)
19219 (match_operand:QI 2 "register_operand" "r"))
19221 (match_operand:DI 1 "nonimmediate_operand" "rm")))
19222 (clobber (reg:CC FLAGS_REG))]
19223 "TARGET_64BIT && TARGET_BMI2"
19224 "bzhi\t{%q2, %q1, %q0|%q0, %q1, %q2}"
19225 [(set_attr "type" "bitmanip")
19226 (set_attr "prefix" "vex")
19227 (set_attr "mode" "DI")])
19229 (define_insn "bmi2_pdep_<mode>3"
19230 [(set (match_operand:SWI48 0 "register_operand" "=r")
19231 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
19232 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
19235 "pdep\t{%2, %1, %0|%0, %1, %2}"
19236 [(set_attr "type" "bitmanip")
19237 (set_attr "prefix" "vex")
19238 (set_attr "mode" "<MODE>")])
19240 (define_insn "bmi2_pext_<mode>3"
19241 [(set (match_operand:SWI48 0 "register_operand" "=r")
19242 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
19243 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
19246 "pext\t{%2, %1, %0|%0, %1, %2}"
19247 [(set_attr "type" "bitmanip")
19248 (set_attr "prefix" "vex")
19249 (set_attr "mode" "<MODE>")])
19251 ;; TBM instructions.
19252 (define_insn "@tbm_bextri_<mode>"
19253 [(set (match_operand:SWI48 0 "register_operand" "=r")
19254 (zero_extract:SWI48
19255 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19256 (match_operand:QI 2 "const_0_to_255_operand")
19257 (match_operand:QI 3 "const_0_to_255_operand")))
19258 (clobber (reg:CC FLAGS_REG))]
19261 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
19262 return "bextr\t{%2, %1, %0|%0, %1, %2}";
19264 [(set_attr "type" "bitmanip")
19265 (set_attr "mode" "<MODE>")])
19267 (define_insn "*tbm_blcfill_<mode>"
19268 [(set (match_operand:SWI48 0 "register_operand" "=r")
19271 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19274 (clobber (reg:CC FLAGS_REG))]
19276 "blcfill\t{%1, %0|%0, %1}"
19277 [(set_attr "type" "bitmanip")
19278 (set_attr "mode" "<MODE>")])
19280 (define_insn "*tbm_blci_<mode>"
19281 [(set (match_operand:SWI48 0 "register_operand" "=r")
19285 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19288 (clobber (reg:CC FLAGS_REG))]
19290 "blci\t{%1, %0|%0, %1}"
19291 [(set_attr "type" "bitmanip")
19292 (set_attr "mode" "<MODE>")])
19294 (define_insn "*tbm_blcic_<mode>"
19295 [(set (match_operand:SWI48 0 "register_operand" "=r")
19298 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19302 (clobber (reg:CC FLAGS_REG))]
19304 "blcic\t{%1, %0|%0, %1}"
19305 [(set_attr "type" "bitmanip")
19306 (set_attr "mode" "<MODE>")])
19308 (define_insn "*tbm_blcmsk_<mode>"
19309 [(set (match_operand:SWI48 0 "register_operand" "=r")
19312 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19315 (clobber (reg:CC FLAGS_REG))]
19317 "blcmsk\t{%1, %0|%0, %1}"
19318 [(set_attr "type" "bitmanip")
19319 (set_attr "mode" "<MODE>")])
19321 (define_insn "*tbm_blcs_<mode>"
19322 [(set (match_operand:SWI48 0 "register_operand" "=r")
19325 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19328 (clobber (reg:CC FLAGS_REG))]
19330 "blcs\t{%1, %0|%0, %1}"
19331 [(set_attr "type" "bitmanip")
19332 (set_attr "mode" "<MODE>")])
19334 (define_insn "*tbm_blsfill_<mode>"
19335 [(set (match_operand:SWI48 0 "register_operand" "=r")
19338 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19341 (clobber (reg:CC FLAGS_REG))]
19343 "blsfill\t{%1, %0|%0, %1}"
19344 [(set_attr "type" "bitmanip")
19345 (set_attr "mode" "<MODE>")])
19347 (define_insn "*tbm_blsic_<mode>"
19348 [(set (match_operand:SWI48 0 "register_operand" "=r")
19351 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19355 (clobber (reg:CC FLAGS_REG))]
19357 "blsic\t{%1, %0|%0, %1}"
19358 [(set_attr "type" "bitmanip")
19359 (set_attr "mode" "<MODE>")])
19361 (define_insn "*tbm_t1mskc_<mode>"
19362 [(set (match_operand:SWI48 0 "register_operand" "=r")
19365 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19369 (clobber (reg:CC FLAGS_REG))]
19371 "t1mskc\t{%1, %0|%0, %1}"
19372 [(set_attr "type" "bitmanip")
19373 (set_attr "mode" "<MODE>")])
19375 (define_insn "*tbm_tzmsk_<mode>"
19376 [(set (match_operand:SWI48 0 "register_operand" "=r")
19379 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19383 (clobber (reg:CC FLAGS_REG))]
19385 "tzmsk\t{%1, %0|%0, %1}"
19386 [(set_attr "type" "bitmanip")
19387 (set_attr "mode" "<MODE>")])
19389 (define_insn_and_split "popcount<mode>2"
19390 [(set (match_operand:SWI48 0 "register_operand" "=r")
19392 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
19393 (clobber (reg:CC FLAGS_REG))]
19397 return "popcnt\t{%1, %0|%0, %1}";
19399 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
19402 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
19403 && optimize_function_for_speed_p (cfun)
19404 && !reg_mentioned_p (operands[0], operands[1])"
19406 [(set (match_dup 0)
19407 (popcount:SWI48 (match_dup 1)))
19408 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
19409 (clobber (reg:CC FLAGS_REG))])]
19410 "ix86_expand_clear (operands[0]);"
19411 [(set_attr "prefix_rep" "1")
19412 (set_attr "type" "bitmanip")
19413 (set_attr "mode" "<MODE>")])
19415 ; False dependency happens when destination is only updated by tzcnt,
19416 ; lzcnt or popcnt. There is no false dependency when destination is
19417 ; also used in source.
19418 (define_insn "*popcount<mode>2_falsedep"
19419 [(set (match_operand:SWI48 0 "register_operand" "=r")
19421 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
19422 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
19423 UNSPEC_INSN_FALSE_DEP)
19424 (clobber (reg:CC FLAGS_REG))]
19428 return "popcnt\t{%1, %0|%0, %1}";
19430 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
19433 [(set_attr "prefix_rep" "1")
19434 (set_attr "type" "bitmanip")
19435 (set_attr "mode" "<MODE>")])
19437 (define_insn_and_split "*popcountsi2_zext"
19438 [(set (match_operand:DI 0 "register_operand" "=r")
19442 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
19444 (clobber (reg:CC FLAGS_REG))]
19445 "TARGET_POPCNT && TARGET_64BIT"
19448 return "popcnt\t{%1, %k0|%k0, %1}";
19450 return "popcnt{l}\t{%1, %k0|%k0, %1}";
19453 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
19454 && optimize_function_for_speed_p (cfun)
19455 && !reg_mentioned_p (operands[0], operands[1])"
19457 [(set (match_dup 0)
19458 (and:DI (subreg:DI (popcount:SI (match_dup 1)) 0) (const_int 63)))
19459 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
19460 (clobber (reg:CC FLAGS_REG))])]
19461 "ix86_expand_clear (operands[0]);"
19462 [(set_attr "prefix_rep" "1")
19463 (set_attr "type" "bitmanip")
19464 (set_attr "mode" "SI")])
19466 ; False dependency happens when destination is only updated by tzcnt,
19467 ; lzcnt or popcnt. There is no false dependency when destination is
19468 ; also used in source.
19469 (define_insn "*popcountsi2_zext_falsedep"
19470 [(set (match_operand:DI 0 "register_operand" "=r")
19474 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
19476 (unspec [(match_operand:DI 2 "register_operand" "0")]
19477 UNSPEC_INSN_FALSE_DEP)
19478 (clobber (reg:CC FLAGS_REG))]
19479 "TARGET_POPCNT && TARGET_64BIT"
19482 return "popcnt\t{%1, %k0|%k0, %1}";
19484 return "popcnt{l}\t{%1, %k0|%k0, %1}";
19487 [(set_attr "prefix_rep" "1")
19488 (set_attr "type" "bitmanip")
19489 (set_attr "mode" "SI")])
19491 (define_insn_and_split "*popcountsi2_zext_2"
19492 [(set (match_operand:DI 0 "register_operand" "=r")
19494 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
19495 (clobber (reg:CC FLAGS_REG))]
19496 "TARGET_POPCNT && TARGET_64BIT"
19499 return "popcnt\t{%1, %k0|%k0, %1}";
19501 return "popcnt{l}\t{%1, %k0|%k0, %1}";
19504 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
19505 && optimize_function_for_speed_p (cfun)
19506 && !reg_mentioned_p (operands[0], operands[1])"
19508 [(set (match_dup 0)
19509 (zero_extend:DI (popcount:SI (match_dup 1))))
19510 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
19511 (clobber (reg:CC FLAGS_REG))])]
19512 "ix86_expand_clear (operands[0]);"
19513 [(set_attr "prefix_rep" "1")
19514 (set_attr "type" "bitmanip")
19515 (set_attr "mode" "SI")])
19517 ; False dependency happens when destination is only updated by tzcnt,
19518 ; lzcnt or popcnt. There is no false dependency when destination is
19519 ; also used in source.
19520 (define_insn "*popcountsi2_zext_2_falsedep"
19521 [(set (match_operand:DI 0 "register_operand" "=r")
19523 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
19524 (unspec [(match_operand:DI 2 "register_operand" "0")]
19525 UNSPEC_INSN_FALSE_DEP)
19526 (clobber (reg:CC FLAGS_REG))]
19527 "TARGET_POPCNT && TARGET_64BIT"
19530 return "popcnt\t{%1, %k0|%k0, %1}";
19532 return "popcnt{l}\t{%1, %k0|%k0, %1}";
19535 [(set_attr "prefix_rep" "1")
19536 (set_attr "type" "bitmanip")
19537 (set_attr "mode" "SI")])
19539 (define_insn_and_split "*popcounthi2_1"
19540 [(set (match_operand:SI 0 "register_operand")
19542 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
19543 (clobber (reg:CC FLAGS_REG))]
19545 && ix86_pre_reload_split ()"
19550 rtx tmp = gen_reg_rtx (HImode);
19552 emit_insn (gen_popcounthi2 (tmp, operands[1]));
19553 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
19557 (define_insn_and_split "*popcounthi2_2"
19558 [(set (match_operand:SI 0 "register_operand")
19560 (popcount:HI (match_operand:HI 1 "nonimmediate_operand"))))
19561 (clobber (reg:CC FLAGS_REG))]
19563 && ix86_pre_reload_split ()"
19568 rtx tmp = gen_reg_rtx (HImode);
19570 emit_insn (gen_popcounthi2 (tmp, operands[1]));
19571 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
19575 (define_insn "popcounthi2"
19576 [(set (match_operand:HI 0 "register_operand" "=r")
19578 (match_operand:HI 1 "nonimmediate_operand" "rm")))
19579 (clobber (reg:CC FLAGS_REG))]
19583 return "popcnt\t{%1, %0|%0, %1}";
19585 return "popcnt{w}\t{%1, %0|%0, %1}";
19588 [(set_attr "prefix_rep" "1")
19589 (set_attr "type" "bitmanip")
19590 (set_attr "mode" "HI")])
19592 (define_expand "bswapdi2"
19593 [(set (match_operand:DI 0 "register_operand")
19594 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
19598 operands[1] = force_reg (DImode, operands[1]);
19601 (define_expand "bswapsi2"
19602 [(set (match_operand:SI 0 "register_operand")
19603 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
19608 else if (TARGET_BSWAP)
19609 operands[1] = force_reg (SImode, operands[1]);
19612 rtx x = operands[0];
19614 emit_move_insn (x, operands[1]);
19615 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
19616 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
19617 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
19622 (define_insn "*bswap<mode>2_movbe"
19623 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
19624 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
19626 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
19629 movbe{<imodesuffix>}\t{%1, %0|%0, %1}
19630 movbe{<imodesuffix>}\t{%1, %0|%0, %1}"
19631 [(set_attr "type" "bitmanip,imov,imov")
19632 (set_attr "modrm" "0,1,1")
19633 (set_attr "prefix_0f" "*,1,1")
19634 (set_attr "prefix_extra" "*,1,1")
19635 (set_attr "mode" "<MODE>")])
19637 (define_insn "*bswap<mode>2"
19638 [(set (match_operand:SWI48 0 "register_operand" "=r")
19639 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
19642 [(set_attr "type" "bitmanip")
19643 (set_attr "modrm" "0")
19644 (set_attr "mode" "<MODE>")])
19646 (define_expand "bswaphi2"
19647 [(set (match_operand:HI 0 "register_operand")
19648 (bswap:HI (match_operand:HI 1 "nonimmediate_operand")))]
19651 (define_insn "*bswaphi2_movbe"
19652 [(set (match_operand:HI 0 "nonimmediate_operand" "=Q,r,m")
19653 (bswap:HI (match_operand:HI 1 "nonimmediate_operand" "0,m,r")))]
19655 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
19657 xchg{b}\t{%h0, %b0|%b0, %h0}
19658 movbe{w}\t{%1, %0|%0, %1}
19659 movbe{w}\t{%1, %0|%0, %1}"
19660 [(set_attr "type" "imov")
19661 (set_attr "modrm" "*,1,1")
19662 (set_attr "prefix_0f" "*,1,1")
19663 (set_attr "prefix_extra" "*,1,1")
19664 (set_attr "pent_pair" "np,*,*")
19665 (set_attr "athlon_decode" "vector,*,*")
19666 (set_attr "amdfam10_decode" "double,*,*")
19667 (set_attr "bdver1_decode" "double,*,*")
19668 (set_attr "mode" "QI,HI,HI")])
19671 [(set (match_operand:HI 0 "general_reg_operand")
19672 (bswap:HI (match_dup 0)))]
19674 && !(TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))
19675 && peep2_regno_dead_p (0, FLAGS_REG)"
19676 [(parallel [(set (match_dup 0) (rotate:HI (match_dup 0) (const_int 8)))
19677 (clobber (reg:CC FLAGS_REG))])])
19679 (define_insn "bswaphi_lowpart"
19680 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
19681 (bswap:HI (match_dup 0)))
19682 (clobber (reg:CC FLAGS_REG))]
19685 xchg{b}\t{%h0, %b0|%b0, %h0}
19686 rol{w}\t{$8, %0|%0, 8}"
19687 [(set (attr "preferred_for_size")
19688 (cond [(eq_attr "alternative" "0")
19689 (symbol_ref "true")]
19690 (symbol_ref "false")))
19691 (set (attr "preferred_for_speed")
19692 (cond [(eq_attr "alternative" "0")
19693 (symbol_ref "TARGET_USE_XCHGB")]
19694 (symbol_ref "!TARGET_USE_XCHGB")))
19695 (set_attr "length" "2,4")
19696 (set_attr "mode" "QI,HI")])
19698 (define_expand "paritydi2"
19699 [(set (match_operand:DI 0 "register_operand")
19700 (parity:DI (match_operand:DI 1 "register_operand")))]
19703 rtx scratch = gen_reg_rtx (QImode);
19704 rtx hipart1 = gen_reg_rtx (SImode);
19705 rtx lopart1 = gen_reg_rtx (SImode);
19706 rtx xor1 = gen_reg_rtx (SImode);
19707 rtx shift2 = gen_reg_rtx (SImode);
19708 rtx hipart2 = gen_reg_rtx (HImode);
19709 rtx lopart2 = gen_reg_rtx (HImode);
19710 rtx xor2 = gen_reg_rtx (HImode);
19714 rtx shift1 = gen_reg_rtx (DImode);
19715 emit_insn (gen_lshrdi3 (shift1, operands[1], GEN_INT (32)));
19716 emit_move_insn (hipart1, gen_lowpart (SImode, shift1));
19719 emit_move_insn (hipart1, gen_highpart (SImode, operands[1]));
19721 emit_move_insn (lopart1, gen_lowpart (SImode, operands[1]));
19722 emit_insn (gen_xorsi3 (xor1, hipart1, lopart1));
19724 emit_insn (gen_lshrsi3 (shift2, xor1, GEN_INT (16)));
19725 emit_move_insn (hipart2, gen_lowpart (HImode, shift2));
19726 emit_move_insn (lopart2, gen_lowpart (HImode, xor1));
19727 emit_insn (gen_xorhi3 (xor2, hipart2, lopart2));
19729 emit_insn (gen_parityhi2_cmp (xor2));
19731 ix86_expand_setcc (scratch, ORDERED,
19732 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19735 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
19738 rtx tmp = gen_reg_rtx (SImode);
19740 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
19741 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
19746 (define_expand "paritysi2"
19747 [(set (match_operand:SI 0 "register_operand")
19748 (parity:SI (match_operand:SI 1 "register_operand")))]
19751 rtx scratch = gen_reg_rtx (QImode);
19752 rtx shift = gen_reg_rtx (SImode);
19753 rtx hipart = gen_reg_rtx (HImode);
19754 rtx lopart = gen_reg_rtx (HImode);
19755 rtx tmp = gen_reg_rtx (HImode);
19757 emit_insn (gen_lshrsi3 (shift, operands[1], GEN_INT (16)));
19758 emit_move_insn (hipart, gen_lowpart (HImode, shift));
19759 emit_move_insn (lopart, gen_lowpart (HImode, operands[1]));
19760 emit_insn (gen_xorhi3 (tmp, hipart, lopart));
19762 emit_insn (gen_parityhi2_cmp (tmp));
19764 ix86_expand_setcc (scratch, ORDERED,
19765 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19767 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
19771 (define_expand "parityhi2"
19772 [(set (match_operand:HI 0 "register_operand")
19773 (parity:HI (match_operand:HI 1 "register_operand")))]
19776 rtx scratch = gen_reg_rtx (QImode);
19778 emit_insn (gen_parityhi2_cmp (operands[1]));
19780 ix86_expand_setcc (scratch, ORDERED,
19781 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19783 emit_insn (gen_zero_extendqihi2 (operands[0], scratch));
19787 (define_expand "parityqi2"
19788 [(set (match_operand:QI 0 "register_operand")
19789 (parity:QI (match_operand:QI 1 "register_operand")))]
19792 emit_insn (gen_parityqi2_cmp (operands[1]));
19794 ix86_expand_setcc (operands[0], ORDERED,
19795 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19799 (define_insn "parityhi2_cmp"
19800 [(set (reg:CC FLAGS_REG)
19801 (unspec:CC [(match_operand:HI 0 "register_operand" "+Q")]
19803 (clobber (match_dup 0))]
19805 "xor{b}\t{%h0, %b0|%b0, %h0}"
19806 [(set_attr "length" "2")
19807 (set_attr "mode" "QI")])
19809 (define_insn "parityqi2_cmp"
19810 [(set (reg:CC FLAGS_REG)
19811 (unspec:CC [(match_operand:QI 0 "register_operand" "q")]
19815 [(set_attr "mode" "QI")])
19817 ;; Replace zero_extend:HI followed by parityhi2_cmp with parityqi2_cmp
19819 [(set (match_operand:HI 0 "register_operand")
19820 (zero_extend:HI (match_operand:QI 1 "general_reg_operand")))
19821 (parallel [(set (reg:CC FLAGS_REG)
19822 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
19823 (clobber (match_dup 0))])]
19825 [(set (reg:CC FLAGS_REG)
19826 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))])
19828 ;; Eliminate QImode popcount&1 using parity flag
19830 [(set (match_operand:SI 0 "register_operand")
19831 (zero_extend:SI (match_operand:QI 1 "general_reg_operand")))
19832 (parallel [(set (match_operand:SI 2 "register_operand")
19833 (popcount:SI (match_dup 0)))
19834 (clobber (reg:CC FLAGS_REG))])
19835 (set (reg:CCZ FLAGS_REG)
19836 (compare:CCZ (and:QI (match_operand:QI 3 "register_operand")
19839 (set (pc) (if_then_else (match_operator 4 "bt_comparison_operator"
19840 [(reg:CCZ FLAGS_REG)
19842 (label_ref (match_operand 5))
19844 "REGNO (operands[2]) == REGNO (operands[3])
19845 && peep2_reg_dead_p (3, operands[0])
19846 && peep2_reg_dead_p (3, operands[2])
19847 && peep2_regno_dead_p (4, FLAGS_REG)"
19848 [(set (reg:CC FLAGS_REG)
19849 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
19850 (set (pc) (if_then_else (match_op_dup 4 [(reg:CC FLAGS_REG)
19852 (label_ref (match_dup 5))
19855 operands[4] = shallow_copy_rtx (operands[4]);
19856 PUT_CODE (operands[4], GET_CODE (operands[4]) == EQ ? UNORDERED : ORDERED);
19859 ;; Eliminate HImode popcount&1 using parity flag
19861 [(match_scratch:HI 0 "Q")
19862 (parallel [(set (match_operand:HI 1 "register_operand")
19864 (match_operand:HI 2 "nonimmediate_operand")))
19865 (clobber (reg:CC FLAGS_REG))])
19866 (set (match_operand 3 "register_operand")
19867 (zero_extend (match_dup 1)))
19868 (set (reg:CCZ FLAGS_REG)
19869 (compare:CCZ (and:QI (match_operand:QI 4 "register_operand")
19872 (set (pc) (if_then_else (match_operator 5 "bt_comparison_operator"
19873 [(reg:CCZ FLAGS_REG)
19875 (label_ref (match_operand 6))
19877 "REGNO (operands[3]) == REGNO (operands[4])
19878 && peep2_reg_dead_p (3, operands[1])
19879 && peep2_reg_dead_p (3, operands[3])
19880 && peep2_regno_dead_p (4, FLAGS_REG)"
19881 [(set (match_dup 0) (match_dup 2))
19882 (parallel [(set (reg:CC FLAGS_REG)
19883 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
19884 (clobber (match_dup 0))])
19885 (set (pc) (if_then_else (match_op_dup 5 [(reg:CC FLAGS_REG)
19887 (label_ref (match_dup 6))
19890 operands[5] = shallow_copy_rtx (operands[5]);
19891 PUT_CODE (operands[5], GET_CODE (operands[5]) == EQ ? UNORDERED : ORDERED);
19894 ;; Eliminate HImode popcount&1 using parity flag (variant 2)
19896 [(match_scratch:HI 0 "Q")
19897 (parallel [(set (match_operand:HI 1 "register_operand")
19899 (match_operand:HI 2 "nonimmediate_operand")))
19900 (clobber (reg:CC FLAGS_REG))])
19901 (set (reg:CCZ FLAGS_REG)
19902 (compare:CCZ (and:QI (match_operand:QI 3 "register_operand")
19905 (set (pc) (if_then_else (match_operator 4 "bt_comparison_operator"
19906 [(reg:CCZ FLAGS_REG)
19908 (label_ref (match_operand 5))
19910 "REGNO (operands[1]) == REGNO (operands[3])
19911 && peep2_reg_dead_p (2, operands[1])
19912 && peep2_reg_dead_p (2, operands[3])
19913 && peep2_regno_dead_p (3, FLAGS_REG)"
19914 [(set (match_dup 0) (match_dup 2))
19915 (parallel [(set (reg:CC FLAGS_REG)
19916 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
19917 (clobber (match_dup 0))])
19918 (set (pc) (if_then_else (match_op_dup 4 [(reg:CC FLAGS_REG)
19920 (label_ref (match_dup 5))
19923 operands[4] = shallow_copy_rtx (operands[4]);
19924 PUT_CODE (operands[4], GET_CODE (operands[4]) == EQ ? UNORDERED : ORDERED);
19928 ;; Thread-local storage patterns for ELF.
19930 ;; Note that these code sequences must appear exactly as shown
19931 ;; in order to allow linker relaxation.
19933 (define_insn "*tls_global_dynamic_32_gnu"
19934 [(set (match_operand:SI 0 "register_operand" "=a")
19936 [(match_operand:SI 1 "register_operand" "Yb")
19937 (match_operand 2 "tls_symbolic_operand")
19938 (match_operand 3 "constant_call_address_operand" "Bz")
19941 (clobber (match_scratch:SI 4 "=d"))
19942 (clobber (match_scratch:SI 5 "=c"))
19943 (clobber (reg:CC FLAGS_REG))]
19944 "!TARGET_64BIT && TARGET_GNU_TLS"
19946 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19948 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
19951 ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
19952 if (TARGET_SUN_TLS)
19953 #ifdef HAVE_AS_IX86_TLSGDPLT
19954 return "call\t%a2@tlsgdplt";
19956 return "call\t%p3@plt";
19958 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19959 return "call\t%P3";
19960 return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
19962 [(set_attr "type" "multi")
19963 (set_attr "length" "12")])
19965 (define_expand "tls_global_dynamic_32"
19967 [(set (match_operand:SI 0 "register_operand")
19968 (unspec:SI [(match_operand:SI 2 "register_operand")
19969 (match_operand 1 "tls_symbolic_operand")
19970 (match_operand 3 "constant_call_address_operand")
19973 (clobber (scratch:SI))
19974 (clobber (scratch:SI))
19975 (clobber (reg:CC FLAGS_REG))])]
19977 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
19979 (define_insn "*tls_global_dynamic_64_<mode>"
19980 [(set (match_operand:P 0 "register_operand" "=a")
19982 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
19983 (match_operand 3)))
19984 (unspec:P [(match_operand 1 "tls_symbolic_operand")
19990 /* The .loc directive has effect for 'the immediately following assembly
19991 instruction'. So for a sequence:
19995 the 'immediately following assembly instruction' is insn1.
19996 We want to emit an insn prefix here, but if we use .byte (as shown in
19997 'ELF Handling For Thread-Local Storage'), a preceding .loc will point
19998 inside the insn sequence, rather than to the start. After relaxation
19999 of the sequence by the linker, the .loc might point inside an insn.
20000 Use data16 prefix instead, which doesn't have this problem. */
20001 fputs ("\tdata16", asm_out_file);
20003 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
20004 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
20005 fputs (ASM_SHORT "0x6666\n", asm_out_file);
20007 fputs (ASM_BYTE "0x66\n", asm_out_file);
20008 fputs ("\trex64\n", asm_out_file);
20009 if (TARGET_SUN_TLS)
20010 return "call\t%p2@plt";
20011 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
20012 return "call\t%P2";
20013 return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
20015 [(set_attr "type" "multi")
20016 (set (attr "length")
20017 (symbol_ref "TARGET_X32 ? 15 : 16"))])
20019 (define_insn "*tls_global_dynamic_64_largepic"
20020 [(set (match_operand:DI 0 "register_operand" "=a")
20022 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
20023 (match_operand:DI 3 "immediate_operand" "i")))
20024 (match_operand 4)))
20025 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
20028 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
20029 && GET_CODE (operands[3]) == CONST
20030 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
20031 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
20034 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
20035 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
20036 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
20037 return "call\t{*%%rax|rax}";
20039 [(set_attr "type" "multi")
20040 (set_attr "length" "22")])
20042 (define_expand "@tls_global_dynamic_64_<mode>"
20044 [(set (match_operand:P 0 "register_operand")
20046 (mem:QI (match_operand 2))
20048 (unspec:P [(match_operand 1 "tls_symbolic_operand")
20052 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
20054 (define_insn "*tls_local_dynamic_base_32_gnu"
20055 [(set (match_operand:SI 0 "register_operand" "=a")
20057 [(match_operand:SI 1 "register_operand" "Yb")
20058 (match_operand 2 "constant_call_address_operand" "Bz")
20060 UNSPEC_TLS_LD_BASE))
20061 (clobber (match_scratch:SI 3 "=d"))
20062 (clobber (match_scratch:SI 4 "=c"))
20063 (clobber (reg:CC FLAGS_REG))]
20064 "!TARGET_64BIT && TARGET_GNU_TLS"
20067 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
20068 if (TARGET_SUN_TLS)
20070 if (HAVE_AS_IX86_TLSLDMPLT)
20071 return "call\t%&@tlsldmplt";
20073 return "call\t%p2@plt";
20075 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
20076 return "call\t%P2";
20077 return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
20079 [(set_attr "type" "multi")
20080 (set_attr "length" "11")])
20082 (define_expand "tls_local_dynamic_base_32"
20084 [(set (match_operand:SI 0 "register_operand")
20086 [(match_operand:SI 1 "register_operand")
20087 (match_operand 2 "constant_call_address_operand")
20089 UNSPEC_TLS_LD_BASE))
20090 (clobber (scratch:SI))
20091 (clobber (scratch:SI))
20092 (clobber (reg:CC FLAGS_REG))])]
20094 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
20096 (define_insn "*tls_local_dynamic_base_64_<mode>"
20097 [(set (match_operand:P 0 "register_operand" "=a")
20099 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
20100 (match_operand 2)))
20101 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
20105 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
20106 if (TARGET_SUN_TLS)
20107 return "call\t%p1@plt";
20108 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
20109 return "call\t%P1";
20110 return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
20112 [(set_attr "type" "multi")
20113 (set_attr "length" "12")])
20115 (define_insn "*tls_local_dynamic_base_64_largepic"
20116 [(set (match_operand:DI 0 "register_operand" "=a")
20118 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
20119 (match_operand:DI 2 "immediate_operand" "i")))
20120 (match_operand 3)))
20121 (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
20122 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
20123 && GET_CODE (operands[2]) == CONST
20124 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
20125 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
20128 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
20129 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
20130 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
20131 return "call\t{*%%rax|rax}";
20133 [(set_attr "type" "multi")
20134 (set_attr "length" "22")])
20136 (define_expand "@tls_local_dynamic_base_64_<mode>"
20138 [(set (match_operand:P 0 "register_operand")
20140 (mem:QI (match_operand 1))
20142 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
20144 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
20146 ;; Local dynamic of a single variable is a lose. Show combine how
20147 ;; to convert that back to global dynamic.
20149 (define_insn_and_split "*tls_local_dynamic_32_once"
20150 [(set (match_operand:SI 0 "register_operand" "=a")
20152 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
20153 (match_operand 2 "constant_call_address_operand" "Bz")
20155 UNSPEC_TLS_LD_BASE)
20156 (const:SI (unspec:SI
20157 [(match_operand 3 "tls_symbolic_operand")]
20159 (clobber (match_scratch:SI 4 "=d"))
20160 (clobber (match_scratch:SI 5 "=c"))
20161 (clobber (reg:CC FLAGS_REG))]
20166 [(set (match_dup 0)
20167 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
20170 (clobber (match_dup 4))
20171 (clobber (match_dup 5))
20172 (clobber (reg:CC FLAGS_REG))])])
20174 ;; Load and add the thread base pointer from %<tp_seg>:0.
20175 (define_expand "get_thread_pointer<mode>"
20176 [(set (match_operand:PTR 0 "register_operand")
20177 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
20180 /* targetm is not visible in the scope of the condition. */
20181 if (!targetm.have_tls)
20182 error ("%<__builtin_thread_pointer%> is not supported on this target");
20185 (define_insn_and_split "*load_tp_<mode>"
20186 [(set (match_operand:PTR 0 "register_operand" "=r")
20187 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
20191 [(set (match_dup 0)
20194 addr_space_t as = DEFAULT_TLS_SEG_REG;
20196 operands[1] = gen_const_mem (<MODE>mode, const0_rtx);
20197 set_mem_addr_space (operands[1], as);
20200 (define_insn_and_split "*load_tp_x32_zext"
20201 [(set (match_operand:DI 0 "register_operand" "=r")
20203 (unspec:SI [(const_int 0)] UNSPEC_TP)))]
20207 [(set (match_dup 0)
20208 (zero_extend:DI (match_dup 1)))]
20210 addr_space_t as = DEFAULT_TLS_SEG_REG;
20212 operands[1] = gen_const_mem (SImode, const0_rtx);
20213 set_mem_addr_space (operands[1], as);
20216 (define_insn_and_split "*add_tp_<mode>"
20217 [(set (match_operand:PTR 0 "register_operand" "=r")
20219 (unspec:PTR [(const_int 0)] UNSPEC_TP)
20220 (match_operand:PTR 1 "register_operand" "0")))
20221 (clobber (reg:CC FLAGS_REG))]
20226 [(set (match_dup 0)
20227 (plus:PTR (match_dup 1) (match_dup 2)))
20228 (clobber (reg:CC FLAGS_REG))])]
20230 addr_space_t as = DEFAULT_TLS_SEG_REG;
20232 operands[2] = gen_const_mem (<MODE>mode, const0_rtx);
20233 set_mem_addr_space (operands[2], as);
20236 (define_insn_and_split "*add_tp_x32_zext"
20237 [(set (match_operand:DI 0 "register_operand" "=r")
20239 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
20240 (match_operand:SI 1 "register_operand" "0"))))
20241 (clobber (reg:CC FLAGS_REG))]
20246 [(set (match_dup 0)
20248 (plus:SI (match_dup 1) (match_dup 2))))
20249 (clobber (reg:CC FLAGS_REG))])]
20251 addr_space_t as = DEFAULT_TLS_SEG_REG;
20253 operands[2] = gen_const_mem (SImode, const0_rtx);
20254 set_mem_addr_space (operands[2], as);
20257 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
20258 ;; %rax as destination of the initial executable code sequence.
20259 (define_insn "tls_initial_exec_64_sun"
20260 [(set (match_operand:DI 0 "register_operand" "=a")
20262 [(match_operand 1 "tls_symbolic_operand")]
20263 UNSPEC_TLS_IE_SUN))
20264 (clobber (reg:CC FLAGS_REG))]
20265 "TARGET_64BIT && TARGET_SUN_TLS"
20268 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
20269 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
20271 [(set_attr "type" "multi")])
20273 ;; GNU2 TLS patterns can be split.
20275 (define_expand "tls_dynamic_gnu2_32"
20276 [(set (match_dup 3)
20277 (plus:SI (match_operand:SI 2 "register_operand")
20279 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
20282 [(set (match_operand:SI 0 "register_operand")
20283 (unspec:SI [(match_dup 1) (match_dup 3)
20284 (match_dup 2) (reg:SI SP_REG)]
20286 (clobber (reg:CC FLAGS_REG))])]
20287 "!TARGET_64BIT && TARGET_GNU2_TLS"
20289 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
20290 ix86_tls_descriptor_calls_expanded_in_cfun = true;
20293 (define_insn "*tls_dynamic_gnu2_lea_32"
20294 [(set (match_operand:SI 0 "register_operand" "=r")
20295 (plus:SI (match_operand:SI 1 "register_operand" "b")
20297 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
20298 UNSPEC_TLSDESC))))]
20299 "!TARGET_64BIT && TARGET_GNU2_TLS"
20300 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
20301 [(set_attr "type" "lea")
20302 (set_attr "mode" "SI")
20303 (set_attr "length" "6")
20304 (set_attr "length_address" "4")])
20306 (define_insn "*tls_dynamic_gnu2_call_32"
20307 [(set (match_operand:SI 0 "register_operand" "=a")
20308 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
20309 (match_operand:SI 2 "register_operand" "0")
20310 ;; we have to make sure %ebx still points to the GOT
20311 (match_operand:SI 3 "register_operand" "b")
20314 (clobber (reg:CC FLAGS_REG))]
20315 "!TARGET_64BIT && TARGET_GNU2_TLS"
20316 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
20317 [(set_attr "type" "call")
20318 (set_attr "length" "2")
20319 (set_attr "length_address" "0")])
20321 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
20322 [(set (match_operand:SI 0 "register_operand" "=&a")
20324 (unspec:SI [(match_operand 3 "tls_modbase_operand")
20325 (match_operand:SI 4)
20326 (match_operand:SI 2 "register_operand" "b")
20329 (const:SI (unspec:SI
20330 [(match_operand 1 "tls_symbolic_operand")]
20332 (clobber (reg:CC FLAGS_REG))]
20333 "!TARGET_64BIT && TARGET_GNU2_TLS"
20336 [(set (match_dup 0) (match_dup 5))]
20338 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
20339 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
20342 (define_expand "@tls_dynamic_gnu2_64_<mode>"
20343 [(set (match_dup 2)
20344 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")]
20347 [(set (match_operand:PTR 0 "register_operand")
20348 (unspec:PTR [(match_dup 1) (match_dup 2) (reg:PTR SP_REG)]
20350 (clobber (reg:CC FLAGS_REG))])]
20351 "TARGET_64BIT && TARGET_GNU2_TLS"
20353 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (ptr_mode) : operands[0];
20354 ix86_tls_descriptor_calls_expanded_in_cfun = true;
20357 (define_insn "*tls_dynamic_gnu2_lea_64_<mode>"
20358 [(set (match_operand:PTR 0 "register_operand" "=r")
20359 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")]
20361 "TARGET_64BIT && TARGET_GNU2_TLS"
20362 "lea%z0\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
20363 [(set_attr "type" "lea")
20364 (set_attr "mode" "<MODE>")
20365 (set_attr "length" "7")
20366 (set_attr "length_address" "4")])
20368 (define_insn "*tls_dynamic_gnu2_call_64_<mode>"
20369 [(set (match_operand:PTR 0 "register_operand" "=a")
20370 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")
20371 (match_operand:PTR 2 "register_operand" "0")
20374 (clobber (reg:CC FLAGS_REG))]
20375 "TARGET_64BIT && TARGET_GNU2_TLS"
20376 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
20377 [(set_attr "type" "call")
20378 (set_attr "length" "2")
20379 (set_attr "length_address" "0")])
20381 (define_insn_and_split "*tls_dynamic_gnu2_combine_64_<mode>"
20382 [(set (match_operand:PTR 0 "register_operand" "=&a")
20384 (unspec:PTR [(match_operand 2 "tls_modbase_operand")
20385 (match_operand:PTR 3)
20388 (const:PTR (unspec:PTR
20389 [(match_operand 1 "tls_symbolic_operand")]
20391 (clobber (reg:CC FLAGS_REG))]
20392 "TARGET_64BIT && TARGET_GNU2_TLS"
20395 [(set (match_dup 0) (match_dup 4))]
20397 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (ptr_mode) : operands[0];
20398 emit_insn (gen_tls_dynamic_gnu2_64 (ptr_mode, operands[4], operands[1]));
20402 [(match_operand 0 "tls_address_pattern")]
20403 "TARGET_TLS_DIRECT_SEG_REFS"
20405 "operands[0] = ix86_rewrite_tls_address (operands[0]);")
20408 ;; These patterns match the binary 387 instructions for addM3, subM3,
20409 ;; mulM3 and divM3. There are three patterns for each of DFmode and
20410 ;; SFmode. The first is the normal insn, the second the same insn but
20411 ;; with one operand a conversion, and the third the same insn but with
20412 ;; the other operand a conversion. The conversion may be SFmode or
20413 ;; SImode if the target mode DFmode, but only SImode if the target mode
20416 ;; Gcc is slightly more smart about handling normal two address instructions
20417 ;; so use special patterns for add and mull.
20419 (define_insn "*fop_xf_comm_i387"
20420 [(set (match_operand:XF 0 "register_operand" "=f")
20421 (match_operator:XF 3 "binary_fp_operator"
20422 [(match_operand:XF 1 "register_operand" "%0")
20423 (match_operand:XF 2 "register_operand" "f")]))]
20425 && COMMUTATIVE_ARITH_P (operands[3])"
20426 "* return output_387_binary_op (insn, operands);"
20427 [(set (attr "type")
20428 (if_then_else (match_operand:XF 3 "mult_operator")
20429 (const_string "fmul")
20430 (const_string "fop")))
20431 (set_attr "mode" "XF")])
20433 (define_insn "*fop_<mode>_comm"
20434 [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
20435 (match_operator:MODEF 3 "binary_fp_operator"
20436 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
20437 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
20438 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20439 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
20440 && COMMUTATIVE_ARITH_P (operands[3])
20441 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
20442 "* return output_387_binary_op (insn, operands);"
20443 [(set (attr "type")
20444 (if_then_else (eq_attr "alternative" "1,2")
20445 (if_then_else (match_operand:MODEF 3 "mult_operator")
20446 (const_string "ssemul")
20447 (const_string "sseadd"))
20448 (if_then_else (match_operand:MODEF 3 "mult_operator")
20449 (const_string "fmul")
20450 (const_string "fop"))))
20451 (set_attr "isa" "*,noavx,avx")
20452 (set_attr "prefix" "orig,orig,vex")
20453 (set_attr "mode" "<MODE>")
20454 (set (attr "enabled")
20456 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
20458 (eq_attr "alternative" "0")
20459 (symbol_ref "TARGET_MIX_SSE_I387
20460 && X87_ENABLE_ARITH (<MODE>mode)")
20461 (const_string "*"))
20463 (eq_attr "alternative" "0")
20464 (symbol_ref "true")
20465 (symbol_ref "false"))))])
20467 (define_insn "*<insn>hf"
20468 [(set (match_operand:HF 0 "register_operand" "=v")
20469 (plusminusmultdiv:HF
20470 (match_operand:HF 1 "nonimmediate_operand" "<comm>v")
20471 (match_operand:HF 2 "nonimmediate_operand" "vm")))]
20473 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
20474 "v<insn>sh\t{%2, %1, %0|%0, %1, %2}"
20475 [(set_attr "prefix" "evex")
20476 (set_attr "mode" "HF")])
20478 (define_insn "*rcpsf2_sse"
20479 [(set (match_operand:SF 0 "register_operand" "=x,x,x,x")
20480 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m,ja")]
20482 "TARGET_SSE && TARGET_SSE_MATH"
20484 %vrcpss\t{%d1, %0|%0, %d1}
20485 %vrcpss\t{%d1, %0|%0, %d1}
20486 rcpss\t{%1, %d0|%d0, %1}
20487 vrcpss\t{%1, %d0|%d0, %1}"
20488 [(set_attr "isa" "*,*,noavx,avx")
20489 (set_attr "addr" "*,*,*,gpr16")
20490 (set_attr "type" "sse")
20491 (set_attr "atom_sse_attr" "rcp")
20492 (set_attr "btver2_sse_attr" "rcp")
20493 (set_attr "prefix" "maybe_vex")
20494 (set_attr "mode" "SF")
20495 (set_attr "avx_partial_xmm_update" "false,false,true,true")
20496 (set (attr "preferred_for_speed")
20497 (cond [(match_test "TARGET_AVX")
20498 (symbol_ref "true")
20499 (eq_attr "alternative" "1,2,3")
20500 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
20502 (symbol_ref "true")))])
20504 (define_insn "rcphf2"
20505 [(set (match_operand:HF 0 "register_operand" "=v,v")
20506 (unspec:HF [(match_operand:HF 1 "nonimmediate_operand" "v,m")]
20508 "TARGET_AVX512FP16"
20510 vrcpsh\t{%d1, %0|%0, %d1}
20511 vrcpsh\t{%1, %d0|%d0, %1}"
20512 [(set_attr "type" "sse")
20513 (set_attr "prefix" "evex")
20514 (set_attr "mode" "HF")
20515 (set_attr "avx_partial_xmm_update" "false,true")])
20517 (define_insn "*fop_xf_1_i387"
20518 [(set (match_operand:XF 0 "register_operand" "=f,f")
20519 (match_operator:XF 3 "binary_fp_operator"
20520 [(match_operand:XF 1 "register_operand" "0,f")
20521 (match_operand:XF 2 "register_operand" "f,0")]))]
20523 && !COMMUTATIVE_ARITH_P (operands[3])"
20524 "* return output_387_binary_op (insn, operands);"
20525 [(set (attr "type")
20526 (if_then_else (match_operand:XF 3 "div_operator")
20527 (const_string "fdiv")
20528 (const_string "fop")))
20529 (set_attr "mode" "XF")])
20531 (define_insn "*fop_<mode>_1"
20532 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
20533 (match_operator:MODEF 3 "binary_fp_operator"
20534 [(match_operand:MODEF 1
20535 "x87nonimm_ssenomem_operand" "0,fm,0,v")
20536 (match_operand:MODEF 2
20537 "nonimmediate_operand" "fm,0,xm,vm")]))]
20538 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20539 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
20540 && !COMMUTATIVE_ARITH_P (operands[3])
20541 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
20542 "* return output_387_binary_op (insn, operands);"
20543 [(set (attr "type")
20544 (if_then_else (eq_attr "alternative" "2,3")
20545 (if_then_else (match_operand:MODEF 3 "div_operator")
20546 (const_string "ssediv")
20547 (const_string "sseadd"))
20548 (if_then_else (match_operand:MODEF 3 "div_operator")
20549 (const_string "fdiv")
20550 (const_string "fop"))))
20551 (set_attr "isa" "*,*,noavx,avx")
20552 (set_attr "prefix" "orig,orig,orig,vex")
20553 (set_attr "mode" "<MODE>")
20554 (set (attr "enabled")
20556 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
20558 (eq_attr "alternative" "0,1")
20559 (symbol_ref "TARGET_MIX_SSE_I387
20560 && X87_ENABLE_ARITH (<MODE>mode)")
20561 (const_string "*"))
20563 (eq_attr "alternative" "0,1")
20564 (symbol_ref "true")
20565 (symbol_ref "false"))))])
20567 (define_insn "*fop_<X87MODEF:mode>_2_i387"
20568 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
20569 (match_operator:X87MODEF 3 "binary_fp_operator"
20571 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
20572 (match_operand:X87MODEF 2 "register_operand" "0")]))]
20573 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
20574 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
20575 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
20576 || optimize_function_for_size_p (cfun))"
20577 "* return output_387_binary_op (insn, operands);"
20578 [(set (attr "type")
20579 (cond [(match_operand:X87MODEF 3 "mult_operator")
20580 (const_string "fmul")
20581 (match_operand:X87MODEF 3 "div_operator")
20582 (const_string "fdiv")
20584 (const_string "fop")))
20585 (set_attr "fp_int_src" "true")
20586 (set_attr "mode" "<SWI24:MODE>")])
20588 (define_insn "*fop_<X87MODEF:mode>_3_i387"
20589 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
20590 (match_operator:X87MODEF 3 "binary_fp_operator"
20591 [(match_operand:X87MODEF 1 "register_operand" "0")
20593 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
20594 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
20595 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
20596 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
20597 || optimize_function_for_size_p (cfun))"
20598 "* return output_387_binary_op (insn, operands);"
20599 [(set (attr "type")
20600 (cond [(match_operand:X87MODEF 3 "mult_operator")
20601 (const_string "fmul")
20602 (match_operand:X87MODEF 3 "div_operator")
20603 (const_string "fdiv")
20605 (const_string "fop")))
20606 (set_attr "fp_int_src" "true")
20607 (set_attr "mode" "<SWI24:MODE>")])
20609 (define_insn "*fop_xf_4_i387"
20610 [(set (match_operand:XF 0 "register_operand" "=f,f")
20611 (match_operator:XF 3 "binary_fp_operator"
20613 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
20614 (match_operand:XF 2 "register_operand" "0,f")]))]
20616 "* return output_387_binary_op (insn, operands);"
20617 [(set (attr "type")
20618 (cond [(match_operand:XF 3 "mult_operator")
20619 (const_string "fmul")
20620 (match_operand:XF 3 "div_operator")
20621 (const_string "fdiv")
20623 (const_string "fop")))
20624 (set_attr "mode" "<MODE>")])
20626 (define_insn "*fop_df_4_i387"
20627 [(set (match_operand:DF 0 "register_operand" "=f,f")
20628 (match_operator:DF 3 "binary_fp_operator"
20630 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
20631 (match_operand:DF 2 "register_operand" "0,f")]))]
20632 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
20633 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
20634 "* return output_387_binary_op (insn, operands);"
20635 [(set (attr "type")
20636 (cond [(match_operand:DF 3 "mult_operator")
20637 (const_string "fmul")
20638 (match_operand:DF 3 "div_operator")
20639 (const_string "fdiv")
20641 (const_string "fop")))
20642 (set_attr "mode" "SF")])
20644 (define_insn "*fop_xf_5_i387"
20645 [(set (match_operand:XF 0 "register_operand" "=f,f")
20646 (match_operator:XF 3 "binary_fp_operator"
20647 [(match_operand:XF 1 "register_operand" "0,f")
20649 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
20651 "* return output_387_binary_op (insn, operands);"
20652 [(set (attr "type")
20653 (cond [(match_operand:XF 3 "mult_operator")
20654 (const_string "fmul")
20655 (match_operand:XF 3 "div_operator")
20656 (const_string "fdiv")
20658 (const_string "fop")))
20659 (set_attr "mode" "<MODE>")])
20661 (define_insn "*fop_df_5_i387"
20662 [(set (match_operand:DF 0 "register_operand" "=f,f")
20663 (match_operator:DF 3 "binary_fp_operator"
20664 [(match_operand:DF 1 "register_operand" "0,f")
20666 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
20667 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
20668 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
20669 "* return output_387_binary_op (insn, operands);"
20670 [(set (attr "type")
20671 (cond [(match_operand:DF 3 "mult_operator")
20672 (const_string "fmul")
20673 (match_operand:DF 3 "div_operator")
20674 (const_string "fdiv")
20676 (const_string "fop")))
20677 (set_attr "mode" "SF")])
20679 (define_insn "*fop_xf_6_i387"
20680 [(set (match_operand:XF 0 "register_operand" "=f,f")
20681 (match_operator:XF 3 "binary_fp_operator"
20683 (match_operand:MODEF 1 "register_operand" "0,f"))
20685 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
20687 "* return output_387_binary_op (insn, operands);"
20688 [(set (attr "type")
20689 (cond [(match_operand:XF 3 "mult_operator")
20690 (const_string "fmul")
20691 (match_operand:XF 3 "div_operator")
20692 (const_string "fdiv")
20694 (const_string "fop")))
20695 (set_attr "mode" "<MODE>")])
20697 (define_insn "*fop_df_6_i387"
20698 [(set (match_operand:DF 0 "register_operand" "=f,f")
20699 (match_operator:DF 3 "binary_fp_operator"
20701 (match_operand:SF 1 "register_operand" "0,f"))
20703 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
20704 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
20705 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
20706 "* return output_387_binary_op (insn, operands);"
20707 [(set (attr "type")
20708 (cond [(match_operand:DF 3 "mult_operator")
20709 (const_string "fmul")
20710 (match_operand:DF 3 "div_operator")
20711 (const_string "fdiv")
20713 (const_string "fop")))
20714 (set_attr "mode" "SF")])
20716 ;; FPU special functions.
20718 ;; This pattern implements a no-op XFmode truncation for
20719 ;; all fancy i386 XFmode math functions.
20721 (define_insn "truncxf<mode>2_i387_noop_unspec"
20722 [(set (match_operand:MODEF 0 "nonimmediate_operand" "=mf")
20723 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
20724 UNSPEC_TRUNC_NOOP))]
20725 "TARGET_USE_FANCY_MATH_387"
20726 "* return output_387_reg_move (insn, operands);"
20727 [(set_attr "type" "fmov")
20728 (set_attr "mode" "<MODE>")])
20730 (define_insn "sqrtxf2"
20731 [(set (match_operand:XF 0 "register_operand" "=f")
20732 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
20733 "TARGET_USE_FANCY_MATH_387"
20735 [(set_attr "type" "fpspc")
20736 (set_attr "mode" "XF")
20737 (set_attr "athlon_decode" "direct")
20738 (set_attr "amdfam10_decode" "direct")
20739 (set_attr "bdver1_decode" "direct")])
20741 (define_insn "*rsqrtsf2_sse"
20742 [(set (match_operand:SF 0 "register_operand" "=x,x,x,x")
20743 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m,ja")]
20745 "TARGET_SSE && TARGET_SSE_MATH"
20747 %vrsqrtss\t{%d1, %0|%0, %d1}
20748 %vrsqrtss\t{%d1, %0|%0, %d1}
20749 rsqrtss\t{%1, %d0|%d0, %1}
20750 vrsqrtss\t{%1, %d0|%d0, %1}"
20751 [(set_attr "isa" "*,*,noavx,avx")
20752 (set_attr "addr" "*,*,*,gpr16")
20753 (set_attr "type" "sse")
20754 (set_attr "atom_sse_attr" "rcp")
20755 (set_attr "btver2_sse_attr" "rcp")
20756 (set_attr "prefix" "maybe_vex")
20757 (set_attr "mode" "SF")
20758 (set_attr "avx_partial_xmm_update" "false,false,true,true")
20759 (set (attr "preferred_for_speed")
20760 (cond [(match_test "TARGET_AVX")
20761 (symbol_ref "true")
20762 (eq_attr "alternative" "1,2,3")
20763 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
20765 (symbol_ref "true")))])
20767 (define_expand "rsqrtsf2"
20768 [(set (match_operand:SF 0 "register_operand")
20769 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
20771 "TARGET_SSE && TARGET_SSE_MATH"
20773 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
20777 (define_insn "rsqrthf2"
20778 [(set (match_operand:HF 0 "register_operand" "=v,v")
20779 (unspec:HF [(match_operand:HF 1 "nonimmediate_operand" "v,m")]
20781 "TARGET_AVX512FP16"
20783 vrsqrtsh\t{%d1, %0|%0, %d1}
20784 vrsqrtsh\t{%1, %d0|%d0, %1}"
20785 [(set_attr "type" "sse")
20786 (set_attr "prefix" "evex")
20787 (set_attr "avx_partial_xmm_update" "false,true")
20788 (set_attr "mode" "HF")])
20790 (define_insn "sqrthf2"
20791 [(set (match_operand:HF 0 "register_operand" "=v,v")
20793 (match_operand:HF 1 "nonimmediate_operand" "v,m")))]
20794 "TARGET_AVX512FP16"
20796 vsqrtsh\t{%d1, %0|%0, %d1}
20797 vsqrtsh\t{%1, %d0|%d0, %1}"
20798 [(set_attr "type" "sse")
20799 (set_attr "prefix" "evex")
20800 (set_attr "avx_partial_xmm_update" "false,true")
20801 (set_attr "mode" "HF")])
20803 (define_insn "*sqrt<mode>2_sse"
20804 [(set (match_operand:MODEF 0 "register_operand" "=v,v,v")
20806 (match_operand:MODEF 1 "nonimmediate_operand" "0,v,m")))]
20807 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20809 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
20810 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
20811 %vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
20812 [(set_attr "type" "sse")
20813 (set_attr "atom_sse_attr" "sqrt")
20814 (set_attr "btver2_sse_attr" "sqrt")
20815 (set_attr "prefix" "maybe_vex")
20816 (set_attr "avx_partial_xmm_update" "false,false,true")
20817 (set_attr "mode" "<MODE>")
20818 (set (attr "preferred_for_speed")
20819 (cond [(match_test "TARGET_AVX")
20820 (symbol_ref "true")
20821 (eq_attr "alternative" "1,2")
20822 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
20824 (symbol_ref "true")))])
20826 (define_expand "sqrt<mode>2"
20827 [(set (match_operand:MODEF 0 "register_operand")
20829 (match_operand:MODEF 1 "nonimmediate_operand")))]
20830 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
20831 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
20833 if (<MODE>mode == SFmode
20834 && TARGET_SSE && TARGET_SSE_MATH
20835 && TARGET_RECIP_SQRT
20836 && !optimize_function_for_size_p (cfun)
20837 && flag_finite_math_only && !flag_trapping_math
20838 && flag_unsafe_math_optimizations)
20840 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
20844 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
20846 rtx op0 = gen_reg_rtx (XFmode);
20847 rtx op1 = gen_reg_rtx (XFmode);
20849 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20850 emit_insn (gen_sqrtxf2 (op0, op1));
20851 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
20856 (define_expand "hypot<mode>3"
20857 [(use (match_operand:MODEF 0 "register_operand"))
20858 (use (match_operand:MODEF 1 "general_operand"))
20859 (use (match_operand:MODEF 2 "general_operand"))]
20860 "TARGET_USE_FANCY_MATH_387
20861 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20862 || TARGET_MIX_SSE_I387)
20863 && flag_finite_math_only
20864 && flag_unsafe_math_optimizations"
20866 rtx op0 = gen_reg_rtx (XFmode);
20867 rtx op1 = gen_reg_rtx (XFmode);
20868 rtx op2 = gen_reg_rtx (XFmode);
20870 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20871 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20873 emit_insn (gen_mulxf3 (op1, op1, op1));
20874 emit_insn (gen_mulxf3 (op2, op2, op2));
20875 emit_insn (gen_addxf3 (op0, op2, op1));
20876 emit_insn (gen_sqrtxf2 (op0, op0));
20878 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20882 (define_insn "x86_fnstsw_1"
20883 [(set (match_operand:HI 0 "register_operand" "=a")
20884 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
20887 [(set_attr "length" "2")
20888 (set_attr "mode" "SI")
20889 (set_attr "unit" "i387")])
20891 (define_insn "fpremxf4_i387"
20892 [(set (match_operand:XF 0 "register_operand" "=f")
20893 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
20894 (match_operand:XF 3 "register_operand" "1")]
20896 (set (match_operand:XF 1 "register_operand" "=f")
20897 (unspec:XF [(match_dup 2) (match_dup 3)]
20899 (set (reg:CCFP FPSR_REG)
20900 (unspec:CCFP [(match_dup 2) (match_dup 3)]
20902 "TARGET_USE_FANCY_MATH_387"
20904 [(set_attr "type" "fpspc")
20905 (set_attr "znver1_decode" "vector")
20906 (set_attr "mode" "XF")])
20908 (define_expand "fmodxf3"
20909 [(use (match_operand:XF 0 "register_operand"))
20910 (use (match_operand:XF 1 "general_operand"))
20911 (use (match_operand:XF 2 "general_operand"))]
20912 "TARGET_USE_FANCY_MATH_387"
20914 rtx_code_label *label = gen_label_rtx ();
20916 rtx op1 = gen_reg_rtx (XFmode);
20917 rtx op2 = gen_reg_rtx (XFmode);
20919 emit_move_insn (op2, operands[2]);
20920 emit_move_insn (op1, operands[1]);
20922 emit_label (label);
20923 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
20924 ix86_emit_fp_unordered_jump (label);
20925 LABEL_NUSES (label) = 1;
20927 emit_move_insn (operands[0], op1);
20931 (define_expand "fmod<mode>3"
20932 [(use (match_operand:MODEF 0 "register_operand"))
20933 (use (match_operand:MODEF 1 "general_operand"))
20934 (use (match_operand:MODEF 2 "general_operand"))]
20935 "TARGET_USE_FANCY_MATH_387"
20937 rtx (*gen_truncxf) (rtx, rtx);
20939 rtx_code_label *label = gen_label_rtx ();
20941 rtx op1 = gen_reg_rtx (XFmode);
20942 rtx op2 = gen_reg_rtx (XFmode);
20944 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20945 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20947 emit_label (label);
20948 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
20949 ix86_emit_fp_unordered_jump (label);
20950 LABEL_NUSES (label) = 1;
20952 /* Truncate the result properly for strict SSE math. */
20953 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
20954 && !TARGET_MIX_SSE_I387)
20955 gen_truncxf = gen_truncxf<mode>2;
20957 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
20959 emit_insn (gen_truncxf (operands[0], op1));
20963 (define_insn "fprem1xf4_i387"
20964 [(set (match_operand:XF 0 "register_operand" "=f")
20965 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
20966 (match_operand:XF 3 "register_operand" "1")]
20968 (set (match_operand:XF 1 "register_operand" "=f")
20969 (unspec:XF [(match_dup 2) (match_dup 3)]
20971 (set (reg:CCFP FPSR_REG)
20972 (unspec:CCFP [(match_dup 2) (match_dup 3)]
20974 "TARGET_USE_FANCY_MATH_387"
20976 [(set_attr "type" "fpspc")
20977 (set_attr "znver1_decode" "vector")
20978 (set_attr "mode" "XF")])
20980 (define_expand "remainderxf3"
20981 [(use (match_operand:XF 0 "register_operand"))
20982 (use (match_operand:XF 1 "general_operand"))
20983 (use (match_operand:XF 2 "general_operand"))]
20984 "TARGET_USE_FANCY_MATH_387"
20986 rtx_code_label *label = gen_label_rtx ();
20988 rtx op1 = gen_reg_rtx (XFmode);
20989 rtx op2 = gen_reg_rtx (XFmode);
20991 emit_move_insn (op2, operands[2]);
20992 emit_move_insn (op1, operands[1]);
20994 emit_label (label);
20995 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
20996 ix86_emit_fp_unordered_jump (label);
20997 LABEL_NUSES (label) = 1;
20999 emit_move_insn (operands[0], op1);
21003 (define_expand "remainder<mode>3"
21004 [(use (match_operand:MODEF 0 "register_operand"))
21005 (use (match_operand:MODEF 1 "general_operand"))
21006 (use (match_operand:MODEF 2 "general_operand"))]
21007 "TARGET_USE_FANCY_MATH_387"
21009 rtx (*gen_truncxf) (rtx, rtx);
21011 rtx_code_label *label = gen_label_rtx ();
21013 rtx op1 = gen_reg_rtx (XFmode);
21014 rtx op2 = gen_reg_rtx (XFmode);
21016 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
21017 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21019 emit_label (label);
21021 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
21022 ix86_emit_fp_unordered_jump (label);
21023 LABEL_NUSES (label) = 1;
21025 /* Truncate the result properly for strict SSE math. */
21026 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
21027 && !TARGET_MIX_SSE_I387)
21028 gen_truncxf = gen_truncxf<mode>2;
21030 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
21032 emit_insn (gen_truncxf (operands[0], op1));
21036 (define_int_iterator SINCOS
21040 (define_int_attr sincos
21041 [(UNSPEC_SIN "sin")
21042 (UNSPEC_COS "cos")])
21044 (define_insn "<sincos>xf2"
21045 [(set (match_operand:XF 0 "register_operand" "=f")
21046 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
21048 "TARGET_USE_FANCY_MATH_387
21049 && flag_unsafe_math_optimizations"
21051 [(set_attr "type" "fpspc")
21052 (set_attr "znver1_decode" "vector")
21053 (set_attr "mode" "XF")])
21055 (define_expand "<sincos><mode>2"
21056 [(set (match_operand:MODEF 0 "register_operand")
21057 (unspec:MODEF [(match_operand:MODEF 1 "general_operand")]
21059 "TARGET_USE_FANCY_MATH_387
21060 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21061 || TARGET_MIX_SSE_I387)
21062 && flag_unsafe_math_optimizations"
21064 rtx op0 = gen_reg_rtx (XFmode);
21065 rtx op1 = gen_reg_rtx (XFmode);
21067 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21068 emit_insn (gen_<sincos>xf2 (op0, op1));
21069 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21073 (define_insn "sincosxf3"
21074 [(set (match_operand:XF 0 "register_operand" "=f")
21075 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
21076 UNSPEC_SINCOS_COS))
21077 (set (match_operand:XF 1 "register_operand" "=f")
21078 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
21079 "TARGET_USE_FANCY_MATH_387
21080 && flag_unsafe_math_optimizations"
21082 [(set_attr "type" "fpspc")
21083 (set_attr "znver1_decode" "vector")
21084 (set_attr "mode" "XF")])
21086 (define_expand "sincos<mode>3"
21087 [(use (match_operand:MODEF 0 "register_operand"))
21088 (use (match_operand:MODEF 1 "register_operand"))
21089 (use (match_operand:MODEF 2 "general_operand"))]
21090 "TARGET_USE_FANCY_MATH_387
21091 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21092 || TARGET_MIX_SSE_I387)
21093 && flag_unsafe_math_optimizations"
21095 rtx op0 = gen_reg_rtx (XFmode);
21096 rtx op1 = gen_reg_rtx (XFmode);
21097 rtx op2 = gen_reg_rtx (XFmode);
21099 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
21100 emit_insn (gen_sincosxf3 (op0, op1, op2));
21101 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21102 emit_insn (gen_truncxf<mode>2 (operands[1], op1));
21106 (define_insn "fptanxf4_i387"
21107 [(set (match_operand:SF 0 "register_operand" "=f")
21108 (match_operand:SF 3 "const1_operand"))
21109 (set (match_operand:XF 1 "register_operand" "=f")
21110 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
21112 "TARGET_USE_FANCY_MATH_387
21113 && flag_unsafe_math_optimizations"
21115 [(set_attr "type" "fpspc")
21116 (set_attr "znver1_decode" "vector")
21117 (set_attr "mode" "XF")])
21119 (define_expand "tanxf2"
21120 [(use (match_operand:XF 0 "register_operand"))
21121 (use (match_operand:XF 1 "register_operand"))]
21122 "TARGET_USE_FANCY_MATH_387
21123 && flag_unsafe_math_optimizations"
21125 rtx one = gen_reg_rtx (SFmode);
21126 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1],
21127 CONST1_RTX (SFmode)));
21131 (define_expand "tan<mode>2"
21132 [(use (match_operand:MODEF 0 "register_operand"))
21133 (use (match_operand:MODEF 1 "general_operand"))]
21134 "TARGET_USE_FANCY_MATH_387
21135 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21136 || TARGET_MIX_SSE_I387)
21137 && flag_unsafe_math_optimizations"
21139 rtx op0 = gen_reg_rtx (XFmode);
21140 rtx op1 = gen_reg_rtx (XFmode);
21142 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21143 emit_insn (gen_tanxf2 (op0, op1));
21144 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21148 (define_insn "atan2xf3"
21149 [(set (match_operand:XF 0 "register_operand" "=f")
21150 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
21151 (match_operand:XF 1 "register_operand" "f")]
21153 (clobber (match_scratch:XF 3 "=1"))]
21154 "TARGET_USE_FANCY_MATH_387
21155 && flag_unsafe_math_optimizations"
21157 [(set_attr "type" "fpspc")
21158 (set_attr "znver1_decode" "vector")
21159 (set_attr "mode" "XF")])
21161 (define_expand "atan2<mode>3"
21162 [(use (match_operand:MODEF 0 "register_operand"))
21163 (use (match_operand:MODEF 1 "general_operand"))
21164 (use (match_operand:MODEF 2 "general_operand"))]
21165 "TARGET_USE_FANCY_MATH_387
21166 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21167 || TARGET_MIX_SSE_I387)
21168 && flag_unsafe_math_optimizations"
21170 rtx op0 = gen_reg_rtx (XFmode);
21171 rtx op1 = gen_reg_rtx (XFmode);
21172 rtx op2 = gen_reg_rtx (XFmode);
21174 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
21175 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21177 emit_insn (gen_atan2xf3 (op0, op1, op2));
21178 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21182 (define_expand "atanxf2"
21183 [(parallel [(set (match_operand:XF 0 "register_operand")
21184 (unspec:XF [(match_dup 2)
21185 (match_operand:XF 1 "register_operand")]
21187 (clobber (scratch:XF))])]
21188 "TARGET_USE_FANCY_MATH_387
21189 && flag_unsafe_math_optimizations"
21190 "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
21192 (define_expand "atan<mode>2"
21193 [(use (match_operand:MODEF 0 "register_operand"))
21194 (use (match_operand:MODEF 1 "general_operand"))]
21195 "TARGET_USE_FANCY_MATH_387
21196 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21197 || TARGET_MIX_SSE_I387)
21198 && flag_unsafe_math_optimizations"
21200 rtx op0 = gen_reg_rtx (XFmode);
21201 rtx op1 = gen_reg_rtx (XFmode);
21203 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21204 emit_insn (gen_atanxf2 (op0, op1));
21205 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21209 (define_expand "asinxf2"
21210 [(set (match_dup 2)
21211 (mult:XF (match_operand:XF 1 "register_operand")
21213 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
21214 (set (match_dup 5) (sqrt:XF (match_dup 4)))
21215 (parallel [(set (match_operand:XF 0 "register_operand")
21216 (unspec:XF [(match_dup 5) (match_dup 1)]
21218 (clobber (scratch:XF))])]
21219 "TARGET_USE_FANCY_MATH_387
21220 && flag_unsafe_math_optimizations"
21224 for (i = 2; i < 6; i++)
21225 operands[i] = gen_reg_rtx (XFmode);
21227 emit_move_insn (operands[3], CONST1_RTX (XFmode));
21230 (define_expand "asin<mode>2"
21231 [(use (match_operand:MODEF 0 "register_operand"))
21232 (use (match_operand:MODEF 1 "general_operand"))]
21233 "TARGET_USE_FANCY_MATH_387
21234 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21235 || TARGET_MIX_SSE_I387)
21236 && flag_unsafe_math_optimizations"
21238 rtx op0 = gen_reg_rtx (XFmode);
21239 rtx op1 = gen_reg_rtx (XFmode);
21241 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21242 emit_insn (gen_asinxf2 (op0, op1));
21243 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21247 (define_expand "acosxf2"
21248 [(set (match_dup 2)
21249 (mult:XF (match_operand:XF 1 "register_operand")
21251 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
21252 (set (match_dup 5) (sqrt:XF (match_dup 4)))
21253 (parallel [(set (match_operand:XF 0 "register_operand")
21254 (unspec:XF [(match_dup 1) (match_dup 5)]
21256 (clobber (scratch:XF))])]
21257 "TARGET_USE_FANCY_MATH_387
21258 && flag_unsafe_math_optimizations"
21262 for (i = 2; i < 6; i++)
21263 operands[i] = gen_reg_rtx (XFmode);
21265 emit_move_insn (operands[3], CONST1_RTX (XFmode));
21268 (define_expand "acos<mode>2"
21269 [(use (match_operand:MODEF 0 "register_operand"))
21270 (use (match_operand:MODEF 1 "general_operand"))]
21271 "TARGET_USE_FANCY_MATH_387
21272 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21273 || TARGET_MIX_SSE_I387)
21274 && flag_unsafe_math_optimizations"
21276 rtx op0 = gen_reg_rtx (XFmode);
21277 rtx op1 = gen_reg_rtx (XFmode);
21279 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21280 emit_insn (gen_acosxf2 (op0, op1));
21281 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21285 (define_expand "sinhxf2"
21286 [(use (match_operand:XF 0 "register_operand"))
21287 (use (match_operand:XF 1 "register_operand"))]
21288 "TARGET_USE_FANCY_MATH_387
21289 && flag_finite_math_only
21290 && flag_unsafe_math_optimizations"
21292 ix86_emit_i387_sinh (operands[0], operands[1]);
21296 (define_expand "sinh<mode>2"
21297 [(use (match_operand:MODEF 0 "register_operand"))
21298 (use (match_operand:MODEF 1 "general_operand"))]
21299 "TARGET_USE_FANCY_MATH_387
21300 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21301 || TARGET_MIX_SSE_I387)
21302 && flag_finite_math_only
21303 && flag_unsafe_math_optimizations"
21305 rtx op0 = gen_reg_rtx (XFmode);
21306 rtx op1 = gen_reg_rtx (XFmode);
21308 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21309 emit_insn (gen_sinhxf2 (op0, op1));
21310 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21314 (define_expand "coshxf2"
21315 [(use (match_operand:XF 0 "register_operand"))
21316 (use (match_operand:XF 1 "register_operand"))]
21317 "TARGET_USE_FANCY_MATH_387
21318 && flag_unsafe_math_optimizations"
21320 ix86_emit_i387_cosh (operands[0], operands[1]);
21324 (define_expand "cosh<mode>2"
21325 [(use (match_operand:MODEF 0 "register_operand"))
21326 (use (match_operand:MODEF 1 "general_operand"))]
21327 "TARGET_USE_FANCY_MATH_387
21328 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21329 || TARGET_MIX_SSE_I387)
21330 && flag_unsafe_math_optimizations"
21332 rtx op0 = gen_reg_rtx (XFmode);
21333 rtx op1 = gen_reg_rtx (XFmode);
21335 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21336 emit_insn (gen_coshxf2 (op0, op1));
21337 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21341 (define_expand "tanhxf2"
21342 [(use (match_operand:XF 0 "register_operand"))
21343 (use (match_operand:XF 1 "register_operand"))]
21344 "TARGET_USE_FANCY_MATH_387
21345 && flag_unsafe_math_optimizations"
21347 ix86_emit_i387_tanh (operands[0], operands[1]);
21351 (define_expand "tanh<mode>2"
21352 [(use (match_operand:MODEF 0 "register_operand"))
21353 (use (match_operand:MODEF 1 "general_operand"))]
21354 "TARGET_USE_FANCY_MATH_387
21355 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21356 || TARGET_MIX_SSE_I387)
21357 && flag_unsafe_math_optimizations"
21359 rtx op0 = gen_reg_rtx (XFmode);
21360 rtx op1 = gen_reg_rtx (XFmode);
21362 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21363 emit_insn (gen_tanhxf2 (op0, op1));
21364 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21368 (define_expand "asinhxf2"
21369 [(use (match_operand:XF 0 "register_operand"))
21370 (use (match_operand:XF 1 "register_operand"))]
21371 "TARGET_USE_FANCY_MATH_387
21372 && flag_finite_math_only
21373 && flag_unsafe_math_optimizations"
21375 ix86_emit_i387_asinh (operands[0], operands[1]);
21379 (define_expand "asinh<mode>2"
21380 [(use (match_operand:MODEF 0 "register_operand"))
21381 (use (match_operand:MODEF 1 "general_operand"))]
21382 "TARGET_USE_FANCY_MATH_387
21383 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21384 || TARGET_MIX_SSE_I387)
21385 && flag_finite_math_only
21386 && flag_unsafe_math_optimizations"
21388 rtx op0 = gen_reg_rtx (XFmode);
21389 rtx op1 = gen_reg_rtx (XFmode);
21391 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21392 emit_insn (gen_asinhxf2 (op0, op1));
21393 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21397 (define_expand "acoshxf2"
21398 [(use (match_operand:XF 0 "register_operand"))
21399 (use (match_operand:XF 1 "register_operand"))]
21400 "TARGET_USE_FANCY_MATH_387
21401 && flag_unsafe_math_optimizations"
21403 ix86_emit_i387_acosh (operands[0], operands[1]);
21407 (define_expand "acosh<mode>2"
21408 [(use (match_operand:MODEF 0 "register_operand"))
21409 (use (match_operand:MODEF 1 "general_operand"))]
21410 "TARGET_USE_FANCY_MATH_387
21411 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21412 || TARGET_MIX_SSE_I387)
21413 && flag_unsafe_math_optimizations"
21415 rtx op0 = gen_reg_rtx (XFmode);
21416 rtx op1 = gen_reg_rtx (XFmode);
21418 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21419 emit_insn (gen_acoshxf2 (op0, op1));
21420 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21424 (define_expand "atanhxf2"
21425 [(use (match_operand:XF 0 "register_operand"))
21426 (use (match_operand:XF 1 "register_operand"))]
21427 "TARGET_USE_FANCY_MATH_387
21428 && flag_unsafe_math_optimizations"
21430 ix86_emit_i387_atanh (operands[0], operands[1]);
21434 (define_expand "atanh<mode>2"
21435 [(use (match_operand:MODEF 0 "register_operand"))
21436 (use (match_operand:MODEF 1 "general_operand"))]
21437 "TARGET_USE_FANCY_MATH_387
21438 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21439 || TARGET_MIX_SSE_I387)
21440 && flag_unsafe_math_optimizations"
21442 rtx op0 = gen_reg_rtx (XFmode);
21443 rtx op1 = gen_reg_rtx (XFmode);
21445 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21446 emit_insn (gen_atanhxf2 (op0, op1));
21447 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21451 (define_insn "fyl2xxf3_i387"
21452 [(set (match_operand:XF 0 "register_operand" "=f")
21453 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
21454 (match_operand:XF 2 "register_operand" "f")]
21456 (clobber (match_scratch:XF 3 "=2"))]
21457 "TARGET_USE_FANCY_MATH_387
21458 && flag_unsafe_math_optimizations"
21460 [(set_attr "type" "fpspc")
21461 (set_attr "znver1_decode" "vector")
21462 (set_attr "mode" "XF")])
21464 (define_expand "logxf2"
21465 [(parallel [(set (match_operand:XF 0 "register_operand")
21466 (unspec:XF [(match_operand:XF 1 "register_operand")
21467 (match_dup 2)] UNSPEC_FYL2X))
21468 (clobber (scratch:XF))])]
21469 "TARGET_USE_FANCY_MATH_387
21470 && flag_unsafe_math_optimizations"
21473 = force_reg (XFmode, standard_80387_constant_rtx (4)); /* fldln2 */
21476 (define_expand "log<mode>2"
21477 [(use (match_operand:MODEF 0 "register_operand"))
21478 (use (match_operand:MODEF 1 "general_operand"))]
21479 "TARGET_USE_FANCY_MATH_387
21480 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21481 || TARGET_MIX_SSE_I387)
21482 && flag_unsafe_math_optimizations"
21484 rtx op0 = gen_reg_rtx (XFmode);
21485 rtx op1 = gen_reg_rtx (XFmode);
21487 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21488 emit_insn (gen_logxf2 (op0, op1));
21489 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21493 (define_expand "log10xf2"
21494 [(parallel [(set (match_operand:XF 0 "register_operand")
21495 (unspec:XF [(match_operand:XF 1 "register_operand")
21496 (match_dup 2)] UNSPEC_FYL2X))
21497 (clobber (scratch:XF))])]
21498 "TARGET_USE_FANCY_MATH_387
21499 && flag_unsafe_math_optimizations"
21502 = force_reg (XFmode, standard_80387_constant_rtx (3)); /* fldlg2 */
21505 (define_expand "log10<mode>2"
21506 [(use (match_operand:MODEF 0 "register_operand"))
21507 (use (match_operand:MODEF 1 "general_operand"))]
21508 "TARGET_USE_FANCY_MATH_387
21509 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21510 || TARGET_MIX_SSE_I387)
21511 && flag_unsafe_math_optimizations"
21513 rtx op0 = gen_reg_rtx (XFmode);
21514 rtx op1 = gen_reg_rtx (XFmode);
21516 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21517 emit_insn (gen_log10xf2 (op0, op1));
21518 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21522 (define_expand "log2xf2"
21523 [(parallel [(set (match_operand:XF 0 "register_operand")
21524 (unspec:XF [(match_operand:XF 1 "register_operand")
21525 (match_dup 2)] UNSPEC_FYL2X))
21526 (clobber (scratch:XF))])]
21527 "TARGET_USE_FANCY_MATH_387
21528 && flag_unsafe_math_optimizations"
21529 "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
21531 (define_expand "log2<mode>2"
21532 [(use (match_operand:MODEF 0 "register_operand"))
21533 (use (match_operand:MODEF 1 "general_operand"))]
21534 "TARGET_USE_FANCY_MATH_387
21535 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21536 || TARGET_MIX_SSE_I387)
21537 && flag_unsafe_math_optimizations"
21539 rtx op0 = gen_reg_rtx (XFmode);
21540 rtx op1 = gen_reg_rtx (XFmode);
21542 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21543 emit_insn (gen_log2xf2 (op0, op1));
21544 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21548 (define_insn "fyl2xp1xf3_i387"
21549 [(set (match_operand:XF 0 "register_operand" "=f")
21550 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
21551 (match_operand:XF 2 "register_operand" "f")]
21553 (clobber (match_scratch:XF 3 "=2"))]
21554 "TARGET_USE_FANCY_MATH_387
21555 && flag_unsafe_math_optimizations"
21557 [(set_attr "type" "fpspc")
21558 (set_attr "znver1_decode" "vector")
21559 (set_attr "mode" "XF")])
21561 (define_expand "log1pxf2"
21562 [(use (match_operand:XF 0 "register_operand"))
21563 (use (match_operand:XF 1 "register_operand"))]
21564 "TARGET_USE_FANCY_MATH_387
21565 && flag_unsafe_math_optimizations"
21567 ix86_emit_i387_log1p (operands[0], operands[1]);
21571 (define_expand "log1p<mode>2"
21572 [(use (match_operand:MODEF 0 "register_operand"))
21573 (use (match_operand:MODEF 1 "general_operand"))]
21574 "TARGET_USE_FANCY_MATH_387
21575 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21576 || TARGET_MIX_SSE_I387)
21577 && flag_unsafe_math_optimizations"
21579 rtx op0 = gen_reg_rtx (XFmode);
21580 rtx op1 = gen_reg_rtx (XFmode);
21582 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21583 emit_insn (gen_log1pxf2 (op0, op1));
21584 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21588 (define_insn "fxtractxf3_i387"
21589 [(set (match_operand:XF 0 "register_operand" "=f")
21590 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
21591 UNSPEC_XTRACT_FRACT))
21592 (set (match_operand:XF 1 "register_operand" "=f")
21593 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
21594 "TARGET_USE_FANCY_MATH_387
21595 && flag_unsafe_math_optimizations"
21597 [(set_attr "type" "fpspc")
21598 (set_attr "znver1_decode" "vector")
21599 (set_attr "mode" "XF")])
21601 (define_expand "logbxf2"
21602 [(parallel [(set (match_dup 2)
21603 (unspec:XF [(match_operand:XF 1 "register_operand")]
21604 UNSPEC_XTRACT_FRACT))
21605 (set (match_operand:XF 0 "register_operand")
21606 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
21607 "TARGET_USE_FANCY_MATH_387
21608 && flag_unsafe_math_optimizations"
21609 "operands[2] = gen_reg_rtx (XFmode);")
21611 (define_expand "logb<mode>2"
21612 [(use (match_operand:MODEF 0 "register_operand"))
21613 (use (match_operand:MODEF 1 "general_operand"))]
21614 "TARGET_USE_FANCY_MATH_387
21615 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21616 || TARGET_MIX_SSE_I387)
21617 && flag_unsafe_math_optimizations"
21619 rtx op0 = gen_reg_rtx (XFmode);
21620 rtx op1 = gen_reg_rtx (XFmode);
21622 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21623 emit_insn (gen_logbxf2 (op0, op1));
21624 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
21628 (define_expand "ilogbxf2"
21629 [(use (match_operand:SI 0 "register_operand"))
21630 (use (match_operand:XF 1 "register_operand"))]
21631 "TARGET_USE_FANCY_MATH_387
21632 && flag_unsafe_math_optimizations"
21636 if (optimize_insn_for_size_p ())
21639 op0 = gen_reg_rtx (XFmode);
21640 op1 = gen_reg_rtx (XFmode);
21642 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
21643 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
21647 (define_expand "ilogb<mode>2"
21648 [(use (match_operand:SI 0 "register_operand"))
21649 (use (match_operand:MODEF 1 "general_operand"))]
21650 "TARGET_USE_FANCY_MATH_387
21651 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21652 || TARGET_MIX_SSE_I387)
21653 && flag_unsafe_math_optimizations"
21657 if (optimize_insn_for_size_p ())
21660 op0 = gen_reg_rtx (XFmode);
21661 op1 = gen_reg_rtx (XFmode);
21662 op2 = gen_reg_rtx (XFmode);
21664 emit_insn (gen_extend<mode>xf2 (op2, operands[1]));
21665 emit_insn (gen_fxtractxf3_i387 (op0, op1, op2));
21666 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
21670 (define_insn "*f2xm1xf2_i387"
21671 [(set (match_operand:XF 0 "register_operand" "=f")
21672 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
21674 "TARGET_USE_FANCY_MATH_387
21675 && flag_unsafe_math_optimizations"
21677 [(set_attr "type" "fpspc")
21678 (set_attr "znver1_decode" "vector")
21679 (set_attr "mode" "XF")])
21681 (define_insn "fscalexf4_i387"
21682 [(set (match_operand:XF 0 "register_operand" "=f")
21683 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
21684 (match_operand:XF 3 "register_operand" "1")]
21685 UNSPEC_FSCALE_FRACT))
21686 (set (match_operand:XF 1 "register_operand" "=f")
21687 (unspec:XF [(match_dup 2) (match_dup 3)]
21688 UNSPEC_FSCALE_EXP))]
21689 "TARGET_USE_FANCY_MATH_387
21690 && flag_unsafe_math_optimizations"
21692 [(set_attr "type" "fpspc")
21693 (set_attr "znver1_decode" "vector")
21694 (set_attr "mode" "XF")])
21696 (define_expand "expNcorexf3"
21697 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
21698 (match_operand:XF 2 "register_operand")))
21699 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
21700 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
21701 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
21702 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
21703 (parallel [(set (match_operand:XF 0 "register_operand")
21704 (unspec:XF [(match_dup 8) (match_dup 4)]
21705 UNSPEC_FSCALE_FRACT))
21707 (unspec:XF [(match_dup 8) (match_dup 4)]
21708 UNSPEC_FSCALE_EXP))])]
21709 "TARGET_USE_FANCY_MATH_387
21710 && flag_unsafe_math_optimizations"
21714 for (i = 3; i < 10; i++)
21715 operands[i] = gen_reg_rtx (XFmode);
21717 emit_move_insn (operands[7], CONST1_RTX (XFmode));
21720 (define_expand "expxf2"
21721 [(use (match_operand:XF 0 "register_operand"))
21722 (use (match_operand:XF 1 "register_operand"))]
21723 "TARGET_USE_FANCY_MATH_387
21724 && flag_unsafe_math_optimizations"
21726 rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (5)); /* fldl2e */
21728 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
21732 (define_expand "exp<mode>2"
21733 [(use (match_operand:MODEF 0 "register_operand"))
21734 (use (match_operand:MODEF 1 "general_operand"))]
21735 "TARGET_USE_FANCY_MATH_387
21736 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21737 || TARGET_MIX_SSE_I387)
21738 && flag_unsafe_math_optimizations"
21740 rtx op0 = gen_reg_rtx (XFmode);
21741 rtx op1 = gen_reg_rtx (XFmode);
21743 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21744 emit_insn (gen_expxf2 (op0, op1));
21745 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21749 (define_expand "exp10xf2"
21750 [(use (match_operand:XF 0 "register_operand"))
21751 (use (match_operand:XF 1 "register_operand"))]
21752 "TARGET_USE_FANCY_MATH_387
21753 && flag_unsafe_math_optimizations"
21755 rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (6)); /* fldl2t */
21757 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
21761 (define_expand "exp10<mode>2"
21762 [(use (match_operand:MODEF 0 "register_operand"))
21763 (use (match_operand:MODEF 1 "general_operand"))]
21764 "TARGET_USE_FANCY_MATH_387
21765 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21766 || TARGET_MIX_SSE_I387)
21767 && flag_unsafe_math_optimizations"
21769 rtx op0 = gen_reg_rtx (XFmode);
21770 rtx op1 = gen_reg_rtx (XFmode);
21772 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21773 emit_insn (gen_exp10xf2 (op0, op1));
21774 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21778 (define_expand "exp2xf2"
21779 [(use (match_operand:XF 0 "register_operand"))
21780 (use (match_operand:XF 1 "register_operand"))]
21781 "TARGET_USE_FANCY_MATH_387
21782 && flag_unsafe_math_optimizations"
21784 rtx op2 = force_reg (XFmode, CONST1_RTX (XFmode));
21786 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
21790 (define_expand "exp2<mode>2"
21791 [(use (match_operand:MODEF 0 "register_operand"))
21792 (use (match_operand:MODEF 1 "general_operand"))]
21793 "TARGET_USE_FANCY_MATH_387
21794 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21795 || TARGET_MIX_SSE_I387)
21796 && flag_unsafe_math_optimizations"
21798 rtx op0 = gen_reg_rtx (XFmode);
21799 rtx op1 = gen_reg_rtx (XFmode);
21801 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21802 emit_insn (gen_exp2xf2 (op0, op1));
21803 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21807 (define_expand "expm1xf2"
21808 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
21810 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
21811 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
21812 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
21813 (parallel [(set (match_dup 7)
21814 (unspec:XF [(match_dup 6) (match_dup 4)]
21815 UNSPEC_FSCALE_FRACT))
21817 (unspec:XF [(match_dup 6) (match_dup 4)]
21818 UNSPEC_FSCALE_EXP))])
21819 (parallel [(set (match_dup 10)
21820 (unspec:XF [(match_dup 9) (match_dup 8)]
21821 UNSPEC_FSCALE_FRACT))
21822 (set (match_dup 11)
21823 (unspec:XF [(match_dup 9) (match_dup 8)]
21824 UNSPEC_FSCALE_EXP))])
21825 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
21826 (set (match_operand:XF 0 "register_operand")
21827 (plus:XF (match_dup 12) (match_dup 7)))]
21828 "TARGET_USE_FANCY_MATH_387
21829 && flag_unsafe_math_optimizations"
21833 for (i = 2; i < 13; i++)
21834 operands[i] = gen_reg_rtx (XFmode);
21836 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
21837 emit_move_insn (operands[9], CONST1_RTX (XFmode));
21840 (define_expand "expm1<mode>2"
21841 [(use (match_operand:MODEF 0 "register_operand"))
21842 (use (match_operand:MODEF 1 "general_operand"))]
21843 "TARGET_USE_FANCY_MATH_387
21844 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21845 || TARGET_MIX_SSE_I387)
21846 && flag_unsafe_math_optimizations"
21848 rtx op0 = gen_reg_rtx (XFmode);
21849 rtx op1 = gen_reg_rtx (XFmode);
21851 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21852 emit_insn (gen_expm1xf2 (op0, op1));
21853 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21857 (define_insn "avx512f_scalef<mode>2"
21858 [(set (match_operand:MODEF 0 "register_operand" "=v")
21860 [(match_operand:MODEF 1 "register_operand" "v")
21861 (match_operand:MODEF 2 "nonimmediate_operand" "vm")]
21864 "vscalef<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
21865 [(set_attr "prefix" "evex")
21866 (set_attr "mode" "<MODE>")])
21868 (define_expand "ldexpxf3"
21869 [(match_operand:XF 0 "register_operand")
21870 (match_operand:XF 1 "register_operand")
21871 (match_operand:SI 2 "register_operand")]
21872 "TARGET_USE_FANCY_MATH_387
21873 && flag_unsafe_math_optimizations"
21875 rtx tmp1 = gen_reg_rtx (XFmode);
21876 rtx tmp2 = gen_reg_rtx (XFmode);
21878 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
21879 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
21880 operands[1], tmp1));
21884 (define_expand "ldexp<mode>3"
21885 [(use (match_operand:MODEF 0 "register_operand"))
21886 (use (match_operand:MODEF 1 "general_operand"))
21887 (use (match_operand:SI 2 "register_operand"))]
21888 "((TARGET_USE_FANCY_MATH_387
21889 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21890 || TARGET_MIX_SSE_I387))
21891 || (TARGET_AVX512F && TARGET_SSE_MATH))
21892 && flag_unsafe_math_optimizations"
21894 /* Prefer avx512f version. */
21895 if (TARGET_AVX512F && TARGET_SSE_MATH)
21897 rtx op2 = gen_reg_rtx (<MODE>mode);
21898 operands[1] = force_reg (<MODE>mode, operands[1]);
21900 emit_insn (gen_floatsi<mode>2 (op2, operands[2]));
21901 emit_insn (gen_avx512f_scalef<mode>2 (operands[0], operands[1], op2));
21905 rtx op0 = gen_reg_rtx (XFmode);
21906 rtx op1 = gen_reg_rtx (XFmode);
21908 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21909 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
21910 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21915 (define_expand "scalbxf3"
21916 [(parallel [(set (match_operand:XF 0 " register_operand")
21917 (unspec:XF [(match_operand:XF 1 "register_operand")
21918 (match_operand:XF 2 "register_operand")]
21919 UNSPEC_FSCALE_FRACT))
21921 (unspec:XF [(match_dup 1) (match_dup 2)]
21922 UNSPEC_FSCALE_EXP))])]
21923 "TARGET_USE_FANCY_MATH_387
21924 && flag_unsafe_math_optimizations"
21925 "operands[3] = gen_reg_rtx (XFmode);")
21927 (define_expand "scalb<mode>3"
21928 [(use (match_operand:MODEF 0 "register_operand"))
21929 (use (match_operand:MODEF 1 "general_operand"))
21930 (use (match_operand:MODEF 2 "general_operand"))]
21931 "TARGET_USE_FANCY_MATH_387
21932 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21933 || TARGET_MIX_SSE_I387)
21934 && flag_unsafe_math_optimizations"
21936 rtx op0 = gen_reg_rtx (XFmode);
21937 rtx op1 = gen_reg_rtx (XFmode);
21938 rtx op2 = gen_reg_rtx (XFmode);
21940 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21941 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
21942 emit_insn (gen_scalbxf3 (op0, op1, op2));
21943 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21947 (define_expand "significandxf2"
21948 [(parallel [(set (match_operand:XF 0 "register_operand")
21949 (unspec:XF [(match_operand:XF 1 "register_operand")]
21950 UNSPEC_XTRACT_FRACT))
21952 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
21953 "TARGET_USE_FANCY_MATH_387
21954 && flag_unsafe_math_optimizations"
21955 "operands[2] = gen_reg_rtx (XFmode);")
21957 (define_expand "significand<mode>2"
21958 [(use (match_operand:MODEF 0 "register_operand"))
21959 (use (match_operand:MODEF 1 "general_operand"))]
21960 "TARGET_USE_FANCY_MATH_387
21961 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21962 || TARGET_MIX_SSE_I387)
21963 && flag_unsafe_math_optimizations"
21965 rtx op0 = gen_reg_rtx (XFmode);
21966 rtx op1 = gen_reg_rtx (XFmode);
21968 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21969 emit_insn (gen_significandxf2 (op0, op1));
21970 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21975 (define_insn "sse4_1_round<mode>2"
21976 [(set (match_operand:MODEFH 0 "register_operand" "=x,x,x,v,v")
21978 [(match_operand:MODEFH 1 "nonimmediate_operand" "0,x,jm,v,m")
21979 (match_operand:SI 2 "const_0_to_15_operand")]
21983 %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
21984 %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
21985 %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
21986 vrndscale<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
21987 vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
21988 [(set_attr "type" "ssecvt")
21989 (set_attr "prefix_extra" "1,1,1,*,*")
21990 (set_attr "length_immediate" "1")
21991 (set_attr "addr" "*,*,gpr16,*,*")
21992 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,evex,evex")
21993 (set_attr "isa" "noavx512f,noavx512f,noavx512f,avx512f,avx512f")
21994 (set_attr "avx_partial_xmm_update" "false,false,true,false,true")
21995 (set_attr "mode" "<MODE>")
21996 (set (attr "preferred_for_speed")
21997 (cond [(match_test "TARGET_AVX")
21998 (symbol_ref "true")
21999 (eq_attr "alternative" "1,2")
22000 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
22002 (symbol_ref "true")))])
22004 (define_insn "rintxf2"
22005 [(set (match_operand:XF 0 "register_operand" "=f")
22006 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
22008 "TARGET_USE_FANCY_MATH_387"
22010 [(set_attr "type" "fpspc")
22011 (set_attr "znver1_decode" "vector")
22012 (set_attr "mode" "XF")])
22014 (define_expand "rinthf2"
22015 [(match_operand:HF 0 "register_operand")
22016 (match_operand:HF 1 "nonimmediate_operand")]
22017 "TARGET_AVX512FP16"
22019 emit_insn (gen_sse4_1_roundhf2 (operands[0],
22021 GEN_INT (ROUND_MXCSR)));
22025 (define_expand "rint<mode>2"
22026 [(use (match_operand:MODEF 0 "register_operand"))
22027 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
22028 "TARGET_USE_FANCY_MATH_387
22029 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
22031 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22034 emit_insn (gen_sse4_1_round<mode>2
22035 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
22037 ix86_expand_rint (operands[0], operands[1]);
22041 rtx op0 = gen_reg_rtx (XFmode);
22042 rtx op1 = gen_reg_rtx (XFmode);
22044 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22045 emit_insn (gen_rintxf2 (op0, op1));
22046 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
22051 (define_expand "nearbyintxf2"
22052 [(set (match_operand:XF 0 "register_operand")
22053 (unspec:XF [(match_operand:XF 1 "register_operand")]
22055 "TARGET_USE_FANCY_MATH_387
22056 && !flag_trapping_math")
22058 (define_expand "nearbyinthf2"
22059 [(match_operand:HF 0 "register_operand")
22060 (match_operand:HF 1 "nonimmediate_operand")]
22061 "TARGET_AVX512FP16"
22063 emit_insn (gen_sse4_1_roundhf2 (operands[0],
22065 GEN_INT (ROUND_MXCSR | ROUND_NO_EXC)));
22069 (define_expand "nearbyint<mode>2"
22070 [(use (match_operand:MODEF 0 "register_operand"))
22071 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
22072 "(TARGET_USE_FANCY_MATH_387
22073 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22074 || TARGET_MIX_SSE_I387)
22075 && !flag_trapping_math)
22076 || (TARGET_SSE4_1 && TARGET_SSE_MATH)"
22078 if (TARGET_SSE4_1 && TARGET_SSE_MATH)
22079 emit_insn (gen_sse4_1_round<mode>2
22080 (operands[0], operands[1], GEN_INT (ROUND_MXCSR
22084 rtx op0 = gen_reg_rtx (XFmode);
22085 rtx op1 = gen_reg_rtx (XFmode);
22087 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22088 emit_insn (gen_nearbyintxf2 (op0, op1));
22089 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
22094 (define_expand "roundhf2"
22095 [(match_operand:HF 0 "register_operand")
22096 (match_operand:HF 1 "register_operand")]
22097 "TARGET_AVX512FP16 && !flag_trapping_math && !flag_rounding_math"
22099 ix86_expand_round_sse4 (operands[0], operands[1]);
22103 (define_expand "round<mode>2"
22104 [(match_operand:X87MODEF 0 "register_operand")
22105 (match_operand:X87MODEF 1 "nonimmediate_operand")]
22106 "(TARGET_USE_FANCY_MATH_387
22107 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22108 || TARGET_MIX_SSE_I387)
22109 && flag_unsafe_math_optimizations
22110 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
22111 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
22112 && !flag_trapping_math && !flag_rounding_math)"
22114 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
22115 && !flag_trapping_math && !flag_rounding_math)
22119 operands[1] = force_reg (<MODE>mode, operands[1]);
22120 ix86_expand_round_sse4 (operands[0], operands[1]);
22122 else if (TARGET_64BIT || (<MODE>mode != DFmode))
22123 ix86_expand_round (operands[0], operands[1]);
22125 ix86_expand_rounddf_32 (operands[0], operands[1]);
22129 operands[1] = force_reg (<MODE>mode, operands[1]);
22130 ix86_emit_i387_round (operands[0], operands[1]);
22135 (define_insn "lrintxfdi2"
22136 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
22137 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
22139 (clobber (match_scratch:XF 2 "=&f"))]
22140 "TARGET_USE_FANCY_MATH_387"
22141 "* return output_fix_trunc (insn, operands, false);"
22142 [(set_attr "type" "fpspc")
22143 (set_attr "mode" "DI")])
22145 (define_insn "lrintxf<mode>2"
22146 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
22147 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
22149 "TARGET_USE_FANCY_MATH_387"
22150 "* return output_fix_trunc (insn, operands, false);"
22151 [(set_attr "type" "fpspc")
22152 (set_attr "mode" "<MODE>")])
22154 (define_expand "lroundhf<mode>2"
22155 [(set (match_operand:SWI248 0 "register_operand")
22156 (unspec:SWI248 [(match_operand:HF 1 "nonimmediate_operand")]
22157 UNSPEC_FIX_NOTRUNC))]
22158 "TARGET_AVX512FP16 && !flag_trapping_math && !flag_rounding_math"
22160 ix86_expand_lround (operands[0], operands[1]);
22164 (define_expand "lrinthf<mode>2"
22165 [(set (match_operand:SWI48 0 "register_operand")
22166 (unspec:SWI48 [(match_operand:HF 1 "nonimmediate_operand")]
22167 UNSPEC_FIX_NOTRUNC))]
22168 "TARGET_AVX512FP16")
22170 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
22171 [(set (match_operand:SWI48 0 "register_operand")
22172 (unspec:SWI48 [(match_operand:MODEF 1 "nonimmediate_operand")]
22173 UNSPEC_FIX_NOTRUNC))]
22174 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
22176 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
22177 [(match_operand:SWI248x 0 "nonimmediate_operand")
22178 (match_operand:X87MODEF 1 "register_operand")]
22179 "(TARGET_USE_FANCY_MATH_387
22180 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
22181 || TARGET_MIX_SSE_I387)
22182 && flag_unsafe_math_optimizations)
22183 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
22184 && <SWI248x:MODE>mode != HImode
22185 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
22186 && !flag_trapping_math && !flag_rounding_math)"
22188 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
22189 && <SWI248x:MODE>mode != HImode
22190 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
22191 && !flag_trapping_math && !flag_rounding_math)
22192 ix86_expand_lround (operands[0], operands[1]);
22194 ix86_emit_i387_round (operands[0], operands[1]);
22198 (define_int_iterator FRNDINT_ROUNDING
22199 [UNSPEC_FRNDINT_ROUNDEVEN
22200 UNSPEC_FRNDINT_FLOOR
22201 UNSPEC_FRNDINT_CEIL
22202 UNSPEC_FRNDINT_TRUNC])
22204 (define_int_iterator FIST_ROUNDING
22208 ;; Base name for define_insn
22209 (define_int_attr rounding_insn
22210 [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven")
22211 (UNSPEC_FRNDINT_FLOOR "floor")
22212 (UNSPEC_FRNDINT_CEIL "ceil")
22213 (UNSPEC_FRNDINT_TRUNC "btrunc")
22214 (UNSPEC_FIST_FLOOR "floor")
22215 (UNSPEC_FIST_CEIL "ceil")])
22217 (define_int_attr rounding
22218 [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven")
22219 (UNSPEC_FRNDINT_FLOOR "floor")
22220 (UNSPEC_FRNDINT_CEIL "ceil")
22221 (UNSPEC_FRNDINT_TRUNC "trunc")
22222 (UNSPEC_FIST_FLOOR "floor")
22223 (UNSPEC_FIST_CEIL "ceil")])
22225 (define_int_attr ROUNDING
22226 [(UNSPEC_FRNDINT_ROUNDEVEN "ROUNDEVEN")
22227 (UNSPEC_FRNDINT_FLOOR "FLOOR")
22228 (UNSPEC_FRNDINT_CEIL "CEIL")
22229 (UNSPEC_FRNDINT_TRUNC "TRUNC")
22230 (UNSPEC_FIST_FLOOR "FLOOR")
22231 (UNSPEC_FIST_CEIL "CEIL")])
22233 ;; Rounding mode control word calculation could clobber FLAGS_REG.
22234 (define_insn_and_split "frndintxf2_<rounding>"
22235 [(set (match_operand:XF 0 "register_operand")
22236 (unspec:XF [(match_operand:XF 1 "register_operand")]
22238 (clobber (reg:CC FLAGS_REG))]
22239 "TARGET_USE_FANCY_MATH_387
22240 && (flag_fp_int_builtin_inexact || !flag_trapping_math)
22241 && ix86_pre_reload_split ()"
22246 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
22248 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
22249 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
22251 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
22252 operands[2], operands[3]));
22255 [(set_attr "type" "frndint")
22256 (set_attr "i387_cw" "<rounding>")
22257 (set_attr "mode" "XF")])
22259 (define_insn "frndintxf2_<rounding>_i387"
22260 [(set (match_operand:XF 0 "register_operand" "=f")
22261 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
22263 (use (match_operand:HI 2 "memory_operand" "m"))
22264 (use (match_operand:HI 3 "memory_operand" "m"))]
22265 "TARGET_USE_FANCY_MATH_387
22266 && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
22267 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
22268 [(set_attr "type" "frndint")
22269 (set_attr "i387_cw" "<rounding>")
22270 (set_attr "mode" "XF")])
22272 (define_expand "<rounding_insn>xf2"
22273 [(parallel [(set (match_operand:XF 0 "register_operand")
22274 (unspec:XF [(match_operand:XF 1 "register_operand")]
22276 (clobber (reg:CC FLAGS_REG))])]
22277 "TARGET_USE_FANCY_MATH_387
22278 && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
22280 (define_expand "<rounding_insn>hf2"
22281 [(parallel [(set (match_operand:HF 0 "register_operand")
22282 (unspec:HF [(match_operand:HF 1 "register_operand")]
22284 (clobber (reg:CC FLAGS_REG))])]
22285 "TARGET_AVX512FP16"
22287 emit_insn (gen_sse4_1_roundhf2 (operands[0], operands[1],
22288 GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
22292 (define_expand "<rounding_insn><mode>2"
22293 [(parallel [(set (match_operand:MODEF 0 "register_operand")
22294 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
22296 (clobber (reg:CC FLAGS_REG))])]
22297 "(TARGET_USE_FANCY_MATH_387
22298 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22299 || TARGET_MIX_SSE_I387)
22300 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
22301 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
22303 || (ROUND_<ROUNDING> != ROUND_ROUNDEVEN
22304 && (flag_fp_int_builtin_inexact || !flag_trapping_math))))"
22306 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
22308 || (ROUND_<ROUNDING> != ROUND_ROUNDEVEN
22309 && (flag_fp_int_builtin_inexact || !flag_trapping_math))))
22312 emit_insn (gen_sse4_1_round<mode>2
22313 (operands[0], operands[1],
22314 GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
22315 else if (TARGET_64BIT || (<MODE>mode != DFmode))
22317 if (ROUND_<ROUNDING> == ROUND_FLOOR)
22318 ix86_expand_floorceil (operands[0], operands[1], true);
22319 else if (ROUND_<ROUNDING> == ROUND_CEIL)
22320 ix86_expand_floorceil (operands[0], operands[1], false);
22321 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
22322 ix86_expand_trunc (operands[0], operands[1]);
22324 gcc_unreachable ();
22328 if (ROUND_<ROUNDING> == ROUND_FLOOR)
22329 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
22330 else if (ROUND_<ROUNDING> == ROUND_CEIL)
22331 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
22332 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
22333 ix86_expand_truncdf_32 (operands[0], operands[1]);
22335 gcc_unreachable ();
22340 rtx op0 = gen_reg_rtx (XFmode);
22341 rtx op1 = gen_reg_rtx (XFmode);
22343 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22344 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
22345 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
22350 ;; Rounding mode control word calculation could clobber FLAGS_REG.
22351 (define_insn_and_split "*fist<mode>2_<rounding>_1"
22352 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
22353 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
22355 (clobber (reg:CC FLAGS_REG))]
22356 "TARGET_USE_FANCY_MATH_387
22357 && flag_unsafe_math_optimizations
22358 && ix86_pre_reload_split ()"
22363 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
22365 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
22366 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
22368 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
22369 operands[2], operands[3]));
22372 [(set_attr "type" "fistp")
22373 (set_attr "i387_cw" "<rounding>")
22374 (set_attr "mode" "<MODE>")])
22376 (define_insn "fistdi2_<rounding>"
22377 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
22378 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
22380 (use (match_operand:HI 2 "memory_operand" "m"))
22381 (use (match_operand:HI 3 "memory_operand" "m"))
22382 (clobber (match_scratch:XF 4 "=&f"))]
22383 "TARGET_USE_FANCY_MATH_387
22384 && flag_unsafe_math_optimizations"
22385 "* return output_fix_trunc (insn, operands, false);"
22386 [(set_attr "type" "fistp")
22387 (set_attr "i387_cw" "<rounding>")
22388 (set_attr "mode" "DI")])
22390 (define_insn "fist<mode>2_<rounding>"
22391 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
22392 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
22394 (use (match_operand:HI 2 "memory_operand" "m"))
22395 (use (match_operand:HI 3 "memory_operand" "m"))]
22396 "TARGET_USE_FANCY_MATH_387
22397 && flag_unsafe_math_optimizations"
22398 "* return output_fix_trunc (insn, operands, false);"
22399 [(set_attr "type" "fistp")
22400 (set_attr "i387_cw" "<rounding>")
22401 (set_attr "mode" "<MODE>")])
22403 (define_expand "l<rounding_insn>xf<mode>2"
22404 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
22405 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
22407 (clobber (reg:CC FLAGS_REG))])]
22408 "TARGET_USE_FANCY_MATH_387
22409 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
22410 && flag_unsafe_math_optimizations")
22412 (define_expand "l<rounding_insn>hf<mode>2"
22413 [(set (match_operand:SWI48 0 "nonimmediate_operand")
22414 (unspec:SWI48 [(match_operand:HF 1 "register_operand")]
22416 "TARGET_AVX512FP16"
22418 rtx tmp = gen_reg_rtx (HFmode);
22419 emit_insn (gen_sse4_1_roundhf2 (tmp, operands[1],
22420 GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
22421 emit_insn (gen_fix_trunchf<mode>2 (operands[0], tmp));
22425 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
22426 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
22427 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
22429 (clobber (reg:CC FLAGS_REG))])]
22430 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
22431 && (TARGET_SSE4_1 || !flag_trapping_math)"
22435 rtx tmp = gen_reg_rtx (<MODEF:MODE>mode);
22437 emit_insn (gen_sse4_1_round<MODEF:mode>2
22438 (tmp, operands[1], GEN_INT (ROUND_<ROUNDING>
22440 emit_insn (gen_fix_trunc<MODEF:mode><SWI48:mode>2
22441 (operands[0], tmp));
22443 else if (ROUND_<ROUNDING> == ROUND_FLOOR)
22444 ix86_expand_lfloorceil (operands[0], operands[1], true);
22445 else if (ROUND_<ROUNDING> == ROUND_CEIL)
22446 ix86_expand_lfloorceil (operands[0], operands[1], false);
22448 gcc_unreachable ();
22453 (define_insn "fxam<mode>2_i387"
22454 [(set (match_operand:HI 0 "register_operand" "=a")
22456 [(match_operand:X87MODEF 1 "register_operand" "f")]
22458 "TARGET_USE_FANCY_MATH_387"
22459 "fxam\n\tfnstsw\t%0"
22460 [(set_attr "type" "multi")
22461 (set_attr "length" "4")
22462 (set_attr "unit" "i387")
22463 (set_attr "mode" "<MODE>")])
22465 (define_expand "signbittf2"
22466 [(use (match_operand:SI 0 "register_operand"))
22467 (use (match_operand:TF 1 "register_operand"))]
22472 rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
22473 rtx scratch = gen_reg_rtx (QImode);
22475 emit_insn (gen_ptesttf2 (operands[1], mask));
22476 ix86_expand_setcc (scratch, NE,
22477 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
22479 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
22483 emit_insn (gen_sse_movmskps (operands[0],
22484 gen_lowpart (V4SFmode, operands[1])));
22485 emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8)));
22490 (define_expand "signbitxf2"
22491 [(use (match_operand:SI 0 "register_operand"))
22492 (use (match_operand:XF 1 "register_operand"))]
22493 "TARGET_USE_FANCY_MATH_387"
22495 rtx scratch = gen_reg_rtx (HImode);
22497 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
22498 emit_insn (gen_andsi3 (operands[0],
22499 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
22503 (define_insn "movmsk_df"
22504 [(set (match_operand:SI 0 "register_operand" "=r,jr")
22506 [(match_operand:DF 1 "register_operand" "x,x")]
22508 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
22509 "%vmovmskpd\t{%1, %0|%0, %1}"
22510 [(set_attr "isa" "noavx,avx")
22511 (set_attr "type" "ssemov")
22512 (set_attr "prefix" "maybe_evex")
22513 (set_attr "mode" "DF")])
22515 ;; Use movmskpd in SSE mode to avoid store forwarding stall
22516 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
22517 (define_expand "signbitdf2"
22518 [(use (match_operand:SI 0 "register_operand"))
22519 (use (match_operand:DF 1 "register_operand"))]
22520 "TARGET_USE_FANCY_MATH_387
22521 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
22523 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
22525 emit_insn (gen_movmsk_df (operands[0], operands[1]));
22526 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
22530 rtx scratch = gen_reg_rtx (HImode);
22532 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
22533 emit_insn (gen_andsi3 (operands[0],
22534 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
22539 (define_expand "signbitsf2"
22540 [(use (match_operand:SI 0 "register_operand"))
22541 (use (match_operand:SF 1 "register_operand"))]
22542 "TARGET_USE_FANCY_MATH_387
22543 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
22545 rtx scratch = gen_reg_rtx (HImode);
22547 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
22548 emit_insn (gen_andsi3 (operands[0],
22549 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
22553 ;; Block operation instructions
22556 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
22559 [(set_attr "length" "1")
22560 (set_attr "length_immediate" "0")
22561 (set_attr "modrm" "0")])
22563 (define_expand "cpymem<mode>"
22564 [(use (match_operand:BLK 0 "memory_operand"))
22565 (use (match_operand:BLK 1 "memory_operand"))
22566 (use (match_operand:SWI48 2 "nonmemory_operand"))
22567 (use (match_operand:SWI48 3 "const_int_operand"))
22568 (use (match_operand:SI 4 "const_int_operand"))
22569 (use (match_operand:SI 5 "const_int_operand"))
22570 (use (match_operand:SI 6 ""))
22571 (use (match_operand:SI 7 ""))
22572 (use (match_operand:SI 8 ""))]
22575 if (ix86_expand_set_or_cpymem (operands[0], operands[1],
22576 operands[2], NULL, operands[3],
22577 operands[4], operands[5],
22578 operands[6], operands[7],
22579 operands[8], false))
22585 ;; Most CPUs don't like single string operations
22586 ;; Handle this case here to simplify previous expander.
22588 (define_expand "strmov"
22589 [(set (match_dup 4) (match_operand 3 "memory_operand"))
22590 (set (match_operand 1 "memory_operand") (match_dup 4))
22591 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
22592 (clobber (reg:CC FLAGS_REG))])
22593 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
22594 (clobber (reg:CC FLAGS_REG))])]
22597 /* Can't use this for non-default address spaces. */
22598 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
22601 int piece_size = GET_MODE_SIZE (GET_MODE (operands[1]));
22603 /* If .md ever supports :P for Pmode, these can be directly
22604 in the pattern above. */
22605 operands[5] = plus_constant (Pmode, operands[0], piece_size);
22606 operands[6] = plus_constant (Pmode, operands[2], piece_size);
22608 /* Can't use this if the user has appropriated esi or edi. */
22609 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
22610 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
22612 emit_insn (gen_strmov_singleop (operands[0], operands[1],
22613 operands[2], operands[3],
22614 operands[5], operands[6]));
22618 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
22621 (define_expand "strmov_singleop"
22622 [(parallel [(set (match_operand 1 "memory_operand")
22623 (match_operand 3 "memory_operand"))
22624 (set (match_operand 0 "register_operand")
22626 (set (match_operand 2 "register_operand")
22627 (match_operand 5))])]
22631 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22634 (define_insn "*strmovdi_rex_1"
22635 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
22636 (mem:DI (match_operand:P 3 "register_operand" "1")))
22637 (set (match_operand:P 0 "register_operand" "=D")
22638 (plus:P (match_dup 2)
22640 (set (match_operand:P 1 "register_operand" "=S")
22641 (plus:P (match_dup 3)
22644 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22645 && ix86_check_no_addr_space (insn)"
22647 [(set_attr "type" "str")
22648 (set_attr "memory" "both")
22649 (set_attr "mode" "DI")])
22651 (define_insn "*strmovsi_1"
22652 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
22653 (mem:SI (match_operand:P 3 "register_operand" "1")))
22654 (set (match_operand:P 0 "register_operand" "=D")
22655 (plus:P (match_dup 2)
22657 (set (match_operand:P 1 "register_operand" "=S")
22658 (plus:P (match_dup 3)
22660 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22661 && ix86_check_no_addr_space (insn)"
22663 [(set_attr "type" "str")
22664 (set_attr "memory" "both")
22665 (set_attr "mode" "SI")])
22667 (define_insn "*strmovhi_1"
22668 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
22669 (mem:HI (match_operand:P 3 "register_operand" "1")))
22670 (set (match_operand:P 0 "register_operand" "=D")
22671 (plus:P (match_dup 2)
22673 (set (match_operand:P 1 "register_operand" "=S")
22674 (plus:P (match_dup 3)
22676 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22677 && ix86_check_no_addr_space (insn)"
22679 [(set_attr "type" "str")
22680 (set_attr "memory" "both")
22681 (set_attr "mode" "HI")])
22683 (define_insn "*strmovqi_1"
22684 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
22685 (mem:QI (match_operand:P 3 "register_operand" "1")))
22686 (set (match_operand:P 0 "register_operand" "=D")
22687 (plus:P (match_dup 2)
22689 (set (match_operand:P 1 "register_operand" "=S")
22690 (plus:P (match_dup 3)
22692 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22693 && ix86_check_no_addr_space (insn)"
22695 [(set_attr "type" "str")
22696 (set_attr "memory" "both")
22697 (set (attr "prefix_rex")
22699 (match_test "<P:MODE>mode == DImode")
22701 (const_string "*")))
22702 (set_attr "mode" "QI")])
22704 (define_expand "rep_mov"
22705 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
22706 (set (match_operand 0 "register_operand")
22708 (set (match_operand 2 "register_operand")
22710 (set (match_operand 1 "memory_operand")
22711 (match_operand 3 "memory_operand"))
22712 (use (match_dup 4))])]
22716 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22719 (define_insn "*rep_movdi_rex64"
22720 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
22721 (set (match_operand:P 0 "register_operand" "=D")
22722 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
22724 (match_operand:P 3 "register_operand" "0")))
22725 (set (match_operand:P 1 "register_operand" "=S")
22726 (plus:P (ashift:P (match_dup 5) (const_int 3))
22727 (match_operand:P 4 "register_operand" "1")))
22728 (set (mem:BLK (match_dup 3))
22729 (mem:BLK (match_dup 4)))
22730 (use (match_dup 5))]
22732 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22733 && ix86_check_no_addr_space (insn)"
22735 [(set_attr "type" "str")
22736 (set_attr "prefix_rep" "1")
22737 (set_attr "memory" "both")
22738 (set_attr "mode" "DI")])
22740 (define_insn "*rep_movsi"
22741 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
22742 (set (match_operand:P 0 "register_operand" "=D")
22743 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
22745 (match_operand:P 3 "register_operand" "0")))
22746 (set (match_operand:P 1 "register_operand" "=S")
22747 (plus:P (ashift:P (match_dup 5) (const_int 2))
22748 (match_operand:P 4 "register_operand" "1")))
22749 (set (mem:BLK (match_dup 3))
22750 (mem:BLK (match_dup 4)))
22751 (use (match_dup 5))]
22752 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22753 && ix86_check_no_addr_space (insn)"
22754 "%^rep{%;} movs{l|d}"
22755 [(set_attr "type" "str")
22756 (set_attr "prefix_rep" "1")
22757 (set_attr "memory" "both")
22758 (set_attr "mode" "SI")])
22760 (define_insn "*rep_movqi"
22761 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
22762 (set (match_operand:P 0 "register_operand" "=D")
22763 (plus:P (match_operand:P 3 "register_operand" "0")
22764 (match_operand:P 5 "register_operand" "2")))
22765 (set (match_operand:P 1 "register_operand" "=S")
22766 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
22767 (set (mem:BLK (match_dup 3))
22768 (mem:BLK (match_dup 4)))
22769 (use (match_dup 5))]
22770 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22771 && ix86_check_no_addr_space (insn)"
22773 [(set_attr "type" "str")
22774 (set_attr "prefix_rep" "1")
22775 (set_attr "memory" "both")
22776 (set_attr "mode" "QI")])
22778 (define_expand "setmem<mode>"
22779 [(use (match_operand:BLK 0 "memory_operand"))
22780 (use (match_operand:SWI48 1 "nonmemory_operand"))
22781 (use (match_operand:QI 2 "nonmemory_operand"))
22782 (use (match_operand 3 "const_int_operand"))
22783 (use (match_operand:SI 4 "const_int_operand"))
22784 (use (match_operand:SI 5 "const_int_operand"))
22785 (use (match_operand:SI 6 ""))
22786 (use (match_operand:SI 7 ""))
22787 (use (match_operand:SI 8 ""))]
22790 if (ix86_expand_set_or_cpymem (operands[0], NULL,
22791 operands[1], operands[2],
22792 operands[3], operands[4],
22793 operands[5], operands[6],
22794 operands[7], operands[8], true))
22800 ;; Most CPUs don't like single string operations
22801 ;; Handle this case here to simplify previous expander.
22803 (define_expand "strset"
22804 [(set (match_operand 1 "memory_operand")
22805 (match_operand 2 "register_operand"))
22806 (parallel [(set (match_operand 0 "register_operand")
22808 (clobber (reg:CC FLAGS_REG))])]
22811 /* Can't use this for non-default address spaces. */
22812 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
22815 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
22816 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
22818 /* If .md ever supports :P for Pmode, this can be directly
22819 in the pattern above. */
22820 operands[3] = plus_constant (Pmode, operands[0],
22821 GET_MODE_SIZE (GET_MODE (operands[2])));
22823 /* Can't use this if the user has appropriated eax or edi. */
22824 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
22825 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
22827 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
22833 (define_expand "strset_singleop"
22834 [(parallel [(set (match_operand 1 "memory_operand")
22835 (match_operand 2 "register_operand"))
22836 (set (match_operand 0 "register_operand")
22838 (unspec [(const_int 0)] UNSPEC_STOS)])]
22842 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22845 (define_insn "*strsetdi_rex_1"
22846 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
22847 (match_operand:DI 2 "register_operand" "a"))
22848 (set (match_operand:P 0 "register_operand" "=D")
22849 (plus:P (match_dup 1)
22851 (unspec [(const_int 0)] UNSPEC_STOS)]
22853 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22854 && ix86_check_no_addr_space (insn)"
22856 [(set_attr "type" "str")
22857 (set_attr "memory" "store")
22858 (set_attr "mode" "DI")])
22860 (define_insn "*strsetsi_1"
22861 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
22862 (match_operand:SI 2 "register_operand" "a"))
22863 (set (match_operand:P 0 "register_operand" "=D")
22864 (plus:P (match_dup 1)
22866 (unspec [(const_int 0)] UNSPEC_STOS)]
22867 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22868 && ix86_check_no_addr_space (insn)"
22870 [(set_attr "type" "str")
22871 (set_attr "memory" "store")
22872 (set_attr "mode" "SI")])
22874 (define_insn "*strsethi_1"
22875 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
22876 (match_operand:HI 2 "register_operand" "a"))
22877 (set (match_operand:P 0 "register_operand" "=D")
22878 (plus:P (match_dup 1)
22880 (unspec [(const_int 0)] UNSPEC_STOS)]
22881 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22882 && ix86_check_no_addr_space (insn)"
22884 [(set_attr "type" "str")
22885 (set_attr "memory" "store")
22886 (set_attr "mode" "HI")])
22888 (define_insn "*strsetqi_1"
22889 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
22890 (match_operand:QI 2 "register_operand" "a"))
22891 (set (match_operand:P 0 "register_operand" "=D")
22892 (plus:P (match_dup 1)
22894 (unspec [(const_int 0)] UNSPEC_STOS)]
22895 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22896 && ix86_check_no_addr_space (insn)"
22898 [(set_attr "type" "str")
22899 (set_attr "memory" "store")
22900 (set (attr "prefix_rex")
22902 (match_test "<P:MODE>mode == DImode")
22904 (const_string "*")))
22905 (set_attr "mode" "QI")])
22907 (define_expand "rep_stos"
22908 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
22909 (set (match_operand 0 "register_operand")
22911 (set (match_operand 2 "memory_operand") (const_int 0))
22912 (use (match_operand 3 "register_operand"))
22913 (use (match_dup 1))])]
22917 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22920 (define_insn "*rep_stosdi_rex64"
22921 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
22922 (set (match_operand:P 0 "register_operand" "=D")
22923 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
22925 (match_operand:P 3 "register_operand" "0")))
22926 (set (mem:BLK (match_dup 3))
22928 (use (match_operand:DI 2 "register_operand" "a"))
22929 (use (match_dup 4))]
22931 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
22932 && ix86_check_no_addr_space (insn)"
22934 [(set_attr "type" "str")
22935 (set_attr "prefix_rep" "1")
22936 (set_attr "memory" "store")
22937 (set_attr "mode" "DI")])
22939 (define_insn "*rep_stossi"
22940 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
22941 (set (match_operand:P 0 "register_operand" "=D")
22942 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
22944 (match_operand:P 3 "register_operand" "0")))
22945 (set (mem:BLK (match_dup 3))
22947 (use (match_operand:SI 2 "register_operand" "a"))
22948 (use (match_dup 4))]
22949 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
22950 && ix86_check_no_addr_space (insn)"
22951 "%^rep{%;} stos{l|d}"
22952 [(set_attr "type" "str")
22953 (set_attr "prefix_rep" "1")
22954 (set_attr "memory" "store")
22955 (set_attr "mode" "SI")])
22957 (define_insn "*rep_stosqi"
22958 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
22959 (set (match_operand:P 0 "register_operand" "=D")
22960 (plus:P (match_operand:P 3 "register_operand" "0")
22961 (match_operand:P 4 "register_operand" "1")))
22962 (set (mem:BLK (match_dup 3))
22964 (use (match_operand:QI 2 "register_operand" "a"))
22965 (use (match_dup 4))]
22966 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
22967 && ix86_check_no_addr_space (insn)"
22969 [(set_attr "type" "str")
22970 (set_attr "prefix_rep" "1")
22971 (set_attr "memory" "store")
22972 (set (attr "prefix_rex")
22974 (match_test "<P:MODE>mode == DImode")
22976 (const_string "*")))
22977 (set_attr "mode" "QI")])
22979 (define_expand "cmpmemsi"
22980 [(set (match_operand:SI 0 "register_operand" "")
22981 (compare:SI (match_operand:BLK 1 "memory_operand" "")
22982 (match_operand:BLK 2 "memory_operand" "") ) )
22983 (use (match_operand 3 "general_operand"))
22984 (use (match_operand 4 "immediate_operand"))]
22987 if (ix86_expand_cmpstrn_or_cmpmem (operands[0], operands[1],
22988 operands[2], operands[3],
22989 operands[4], false))
22995 (define_expand "cmpstrnsi"
22996 [(set (match_operand:SI 0 "register_operand")
22997 (compare:SI (match_operand:BLK 1 "general_operand")
22998 (match_operand:BLK 2 "general_operand")))
22999 (use (match_operand 3 "general_operand"))
23000 (use (match_operand 4 "immediate_operand"))]
23003 if (ix86_expand_cmpstrn_or_cmpmem (operands[0], operands[1],
23004 operands[2], operands[3],
23005 operands[4], true))
23011 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
23013 (define_expand "cmpintqi"
23014 [(set (match_dup 1)
23015 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
23017 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
23018 (parallel [(set (match_operand:QI 0 "register_operand")
23019 (minus:QI (match_dup 1)
23021 (clobber (reg:CC FLAGS_REG))])]
23024 operands[1] = gen_reg_rtx (QImode);
23025 operands[2] = gen_reg_rtx (QImode);
23028 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
23029 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
23031 (define_expand "cmpstrnqi_nz_1"
23032 [(parallel [(set (reg:CC FLAGS_REG)
23033 (compare:CC (match_operand 4 "memory_operand")
23034 (match_operand 5 "memory_operand")))
23035 (use (match_operand 2 "register_operand"))
23036 (use (match_operand:SI 3 "immediate_operand"))
23037 (clobber (match_operand 0 "register_operand"))
23038 (clobber (match_operand 1 "register_operand"))
23039 (clobber (match_dup 2))])]
23043 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
23046 (define_insn "*cmpstrnqi_nz_1"
23047 [(set (reg:CC FLAGS_REG)
23048 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
23049 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
23050 (use (match_operand:P 6 "register_operand" "2"))
23051 (use (match_operand:SI 3 "immediate_operand" "i"))
23052 (clobber (match_operand:P 0 "register_operand" "=S"))
23053 (clobber (match_operand:P 1 "register_operand" "=D"))
23054 (clobber (match_operand:P 2 "register_operand" "=c"))]
23055 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
23056 && ix86_check_no_addr_space (insn)"
23058 [(set_attr "type" "str")
23059 (set_attr "mode" "QI")
23060 (set (attr "prefix_rex")
23062 (match_test "<P:MODE>mode == DImode")
23064 (const_string "*")))
23065 (set_attr "prefix_rep" "1")])
23067 ;; The same, but the count is not known to not be zero.
23069 (define_expand "cmpstrnqi_1"
23070 [(parallel [(set (reg:CC FLAGS_REG)
23071 (if_then_else:CC (ne (match_operand 2 "register_operand")
23073 (compare:CC (match_operand 4 "memory_operand")
23074 (match_operand 5 "memory_operand"))
23076 (use (match_operand:SI 3 "immediate_operand"))
23077 (use (reg:CC FLAGS_REG))
23078 (clobber (match_operand 0 "register_operand"))
23079 (clobber (match_operand 1 "register_operand"))
23080 (clobber (match_dup 2))])]
23084 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
23087 (define_insn "*cmpstrnqi_1"
23088 [(set (reg:CC FLAGS_REG)
23089 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
23091 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
23092 (mem:BLK (match_operand:P 5 "register_operand" "1")))
23094 (use (match_operand:SI 3 "immediate_operand" "i"))
23095 (use (reg:CC FLAGS_REG))
23096 (clobber (match_operand:P 0 "register_operand" "=S"))
23097 (clobber (match_operand:P 1 "register_operand" "=D"))
23098 (clobber (match_operand:P 2 "register_operand" "=c"))]
23099 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
23100 && ix86_check_no_addr_space (insn)"
23102 [(set_attr "type" "str")
23103 (set_attr "mode" "QI")
23104 (set (attr "prefix_rex")
23106 (match_test "<P:MODE>mode == DImode")
23108 (const_string "*")))
23109 (set_attr "prefix_rep" "1")])
23111 (define_expand "strlen<mode>"
23112 [(set (match_operand:P 0 "register_operand")
23113 (unspec:P [(match_operand:BLK 1 "general_operand")
23114 (match_operand:QI 2 "immediate_operand")
23115 (match_operand 3 "immediate_operand")]
23119 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
23125 (define_expand "strlenqi_1"
23126 [(parallel [(set (match_operand 0 "register_operand")
23128 (clobber (match_operand 1 "register_operand"))
23129 (clobber (reg:CC FLAGS_REG))])]
23133 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
23136 (define_insn "*strlenqi_1"
23137 [(set (match_operand:P 0 "register_operand" "=&c")
23138 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
23139 (match_operand:QI 2 "register_operand" "a")
23140 (match_operand:P 3 "immediate_operand" "i")
23141 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
23142 (clobber (match_operand:P 1 "register_operand" "=D"))
23143 (clobber (reg:CC FLAGS_REG))]
23144 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
23145 && ix86_check_no_addr_space (insn)"
23146 "%^repnz{%;} scasb"
23147 [(set_attr "type" "str")
23148 (set_attr "mode" "QI")
23149 (set (attr "prefix_rex")
23151 (match_test "<P:MODE>mode == DImode")
23153 (const_string "*")))
23154 (set_attr "prefix_rep" "1")])
23156 ;; Peephole optimizations to clean up after cmpstrn*. This should be
23157 ;; handled in combine, but it is not currently up to the task.
23158 ;; When used for their truth value, the cmpstrn* expanders generate
23167 ;; The intermediate three instructions are unnecessary.
23169 ;; This one handles cmpstrn*_nz_1...
23172 (set (reg:CC FLAGS_REG)
23173 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
23174 (mem:BLK (match_operand 5 "register_operand"))))
23175 (use (match_operand 6 "register_operand"))
23176 (use (match_operand:SI 3 "immediate_operand"))
23177 (clobber (match_operand 0 "register_operand"))
23178 (clobber (match_operand 1 "register_operand"))
23179 (clobber (match_operand 2 "register_operand"))])
23180 (set (match_operand:QI 7 "register_operand")
23181 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
23182 (set (match_operand:QI 8 "register_operand")
23183 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
23184 (set (reg FLAGS_REG)
23185 (compare (match_dup 7) (match_dup 8)))
23187 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
23189 (set (reg:CC FLAGS_REG)
23190 (compare:CC (mem:BLK (match_dup 4))
23191 (mem:BLK (match_dup 5))))
23192 (use (match_dup 6))
23193 (use (match_dup 3))
23194 (clobber (match_dup 0))
23195 (clobber (match_dup 1))
23196 (clobber (match_dup 2))])])
23198 ;; ...and this one handles cmpstrn*_1.
23201 (set (reg:CC FLAGS_REG)
23202 (if_then_else:CC (ne (match_operand 6 "register_operand")
23204 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
23205 (mem:BLK (match_operand 5 "register_operand")))
23207 (use (match_operand:SI 3 "immediate_operand"))
23208 (use (reg:CC FLAGS_REG))
23209 (clobber (match_operand 0 "register_operand"))
23210 (clobber (match_operand 1 "register_operand"))
23211 (clobber (match_operand 2 "register_operand"))])
23212 (set (match_operand:QI 7 "register_operand")
23213 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
23214 (set (match_operand:QI 8 "register_operand")
23215 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
23216 (set (reg FLAGS_REG)
23217 (compare (match_dup 7) (match_dup 8)))
23219 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
23221 (set (reg:CC FLAGS_REG)
23222 (if_then_else:CC (ne (match_dup 6)
23224 (compare:CC (mem:BLK (match_dup 4))
23225 (mem:BLK (match_dup 5)))
23227 (use (match_dup 3))
23228 (use (reg:CC FLAGS_REG))
23229 (clobber (match_dup 0))
23230 (clobber (match_dup 1))
23231 (clobber (match_dup 2))])])
23233 ;; Conditional move instructions.
23235 (define_expand "mov<mode>cc"
23236 [(set (match_operand:SWIM 0 "register_operand")
23237 (if_then_else:SWIM (match_operand 1 "comparison_operator")
23238 (match_operand:SWIM 2 "<general_operand>")
23239 (match_operand:SWIM 3 "<general_operand>")))]
23241 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
23243 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
23244 ;; the register first winds up with `sbbl $0,reg', which is also weird.
23245 ;; So just document what we're doing explicitly.
23247 (define_expand "x86_mov<mode>cc_0_m1"
23249 [(set (match_operand:SWI48 0 "register_operand")
23250 (if_then_else:SWI48
23251 (match_operator:SWI48 2 "ix86_carry_flag_operator"
23252 [(match_operand 1 "flags_reg_operand")
23256 (clobber (reg:CC FLAGS_REG))])])
23258 (define_insn "*x86_mov<mode>cc_0_m1"
23259 [(set (match_operand:SWI48 0 "register_operand" "=r")
23260 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
23261 [(reg FLAGS_REG) (const_int 0)])
23264 (clobber (reg:CC FLAGS_REG))]
23266 "sbb{<imodesuffix>}\t%0, %0"
23267 [(set_attr "type" "alu1")
23268 (set_attr "use_carry" "1")
23269 (set_attr "pent_pair" "pu")
23270 (set_attr "mode" "<MODE>")
23271 (set_attr "length_immediate" "0")])
23273 (define_insn "*x86_mov<mode>cc_0_m1_se"
23274 [(set (match_operand:SWI48 0 "register_operand" "=r")
23275 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
23276 [(reg FLAGS_REG) (const_int 0)])
23279 (clobber (reg:CC FLAGS_REG))]
23281 "sbb{<imodesuffix>}\t%0, %0"
23282 [(set_attr "type" "alu1")
23283 (set_attr "use_carry" "1")
23284 (set_attr "pent_pair" "pu")
23285 (set_attr "mode" "<MODE>")
23286 (set_attr "length_immediate" "0")])
23288 (define_insn "*x86_mov<mode>cc_0_m1_neg"
23289 [(set (match_operand:SWI 0 "register_operand" "=<r>")
23290 (neg:SWI (match_operator 1 "ix86_carry_flag_operator"
23291 [(reg FLAGS_REG) (const_int 0)])))
23292 (clobber (reg:CC FLAGS_REG))]
23294 "sbb{<imodesuffix>}\t%0, %0"
23295 [(set_attr "type" "alu1")
23296 (set_attr "use_carry" "1")
23297 (set_attr "pent_pair" "pu")
23298 (set_attr "mode" "<MODE>")
23299 (set_attr "length_immediate" "0")])
23301 (define_expand "x86_mov<mode>cc_0_m1_neg"
23303 [(set (match_operand:SWI48 0 "register_operand")
23304 (neg:SWI48 (ltu:SWI48 (reg:CCC FLAGS_REG) (const_int 0))))
23305 (clobber (reg:CC FLAGS_REG))])])
23308 [(set (match_operand:SWI48 0 "register_operand")
23311 (match_operand 1 "int_nonimmediate_operand")
23312 (match_operand 2 "const_int_operand"))))]
23313 "x86_64_immediate_operand (operands[2], VOIDmode)
23314 && INTVAL (operands[2]) != -1
23315 && INTVAL (operands[2]) != 2147483647"
23316 [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
23318 (neg:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))))]
23319 "operands[2] = GEN_INT (INTVAL (operands[2]) + 1);")
23322 [(set (match_operand:SWI 0 "register_operand")
23325 (match_operand 1 "int_nonimmediate_operand")
23328 [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (const_int 1)))
23330 (neg:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))))])
23333 [(set (match_operand:SWI 0 "register_operand")
23336 (match_operand 1 "int_nonimmediate_operand")
23339 [(set (reg:CCC FLAGS_REG)
23340 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
23342 (neg:SWI (ltu:SWI (reg:CCC FLAGS_REG) (const_int 0))))])
23344 (define_insn "*mov<mode>cc_noc"
23345 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
23346 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
23347 [(reg FLAGS_REG) (const_int 0)])
23348 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
23349 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
23350 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23352 cmov%O2%C1\t{%2, %0|%0, %2}
23353 cmov%O2%c1\t{%3, %0|%0, %3}"
23354 [(set_attr "type" "icmov")
23355 (set_attr "mode" "<MODE>")])
23357 (define_insn "*movsicc_noc_zext"
23358 [(set (match_operand:DI 0 "register_operand" "=r,r")
23359 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
23360 [(reg FLAGS_REG) (const_int 0)])
23362 (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
23364 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
23366 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23368 cmov%O2%C1\t{%2, %k0|%k0, %2}
23369 cmov%O2%c1\t{%3, %k0|%k0, %3}"
23370 [(set_attr "type" "icmov")
23371 (set_attr "mode" "SI")])
23373 (define_insn "*movsicc_noc_zext_1"
23374 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r")
23376 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
23377 [(reg FLAGS_REG) (const_int 0)])
23378 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
23379 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
23381 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23383 cmov%O2%C1\t{%2, %k0|%k0, %2}
23384 cmov%O2%c1\t{%3, %k0|%k0, %3}"
23385 [(set_attr "type" "icmov")
23386 (set_attr "mode" "SI")])
23389 ;; Don't do conditional moves with memory inputs. This splitter helps
23390 ;; register starved x86_32 by forcing inputs into registers before reload.
23392 [(set (match_operand:SWI248 0 "register_operand")
23393 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
23394 [(reg FLAGS_REG) (const_int 0)])
23395 (match_operand:SWI248 2 "nonimmediate_operand")
23396 (match_operand:SWI248 3 "nonimmediate_operand")))]
23397 "!TARGET_64BIT && TARGET_CMOVE
23398 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23399 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23400 && can_create_pseudo_p ()
23401 && optimize_insn_for_speed_p ()"
23402 [(set (match_dup 0)
23403 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
23405 operands[2] = force_reg (<MODE>mode, operands[2]);
23406 operands[3] = force_reg (<MODE>mode, operands[3]);
23409 (define_insn "*movqicc_noc"
23410 [(set (match_operand:QI 0 "register_operand" "=r,r")
23411 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
23412 [(reg FLAGS_REG) (const_int 0)])
23413 (match_operand:QI 2 "register_operand" "r,0")
23414 (match_operand:QI 3 "register_operand" "0,r")))]
23415 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
23417 [(set_attr "type" "icmov")
23418 (set_attr "mode" "QI")])
23421 [(set (match_operand:SWI12 0 "register_operand")
23422 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
23423 [(reg FLAGS_REG) (const_int 0)])
23424 (match_operand:SWI12 2 "register_operand")
23425 (match_operand:SWI12 3 "register_operand")))]
23426 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
23427 && reload_completed"
23428 [(set (match_dup 0)
23429 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
23431 operands[0] = gen_lowpart (SImode, operands[0]);
23432 operands[2] = gen_lowpart (SImode, operands[2]);
23433 operands[3] = gen_lowpart (SImode, operands[3]);
23436 ;; Don't do conditional moves with memory inputs
23438 [(match_scratch:SWI248 4 "r")
23439 (set (match_operand:SWI248 0 "register_operand")
23440 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
23441 [(reg FLAGS_REG) (const_int 0)])
23442 (match_operand:SWI248 2 "nonimmediate_operand")
23443 (match_operand:SWI248 3 "nonimmediate_operand")))]
23444 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23445 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23446 && optimize_insn_for_speed_p ()"
23447 [(set (match_dup 4) (match_dup 5))
23449 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
23451 if (MEM_P (operands[2]))
23453 operands[5] = operands[2];
23454 operands[2] = operands[4];
23456 else if (MEM_P (operands[3]))
23458 operands[5] = operands[3];
23459 operands[3] = operands[4];
23462 gcc_unreachable ();
23466 [(match_scratch:SI 4 "r")
23467 (set (match_operand:DI 0 "register_operand")
23468 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
23469 [(reg FLAGS_REG) (const_int 0)])
23471 (match_operand:SI 2 "nonimmediate_operand"))
23473 (match_operand:SI 3 "nonimmediate_operand"))))]
23475 && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23476 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23477 && optimize_insn_for_speed_p ()"
23478 [(set (match_dup 4) (match_dup 5))
23480 (if_then_else:DI (match_dup 1)
23481 (zero_extend:DI (match_dup 2))
23482 (zero_extend:DI (match_dup 3))))]
23484 if (MEM_P (operands[2]))
23486 operands[5] = operands[2];
23487 operands[2] = operands[4];
23489 else if (MEM_P (operands[3]))
23491 operands[5] = operands[3];
23492 operands[3] = operands[4];
23495 gcc_unreachable ();
23498 ;; Eliminate a reg-reg mov by inverting the condition of a cmov (#1).
23499 ;; mov r0,r1; dec r0; mov r2,r3; cmov r0,r2 -> dec r1; mov r0,r3; cmov r0, r1
23501 [(set (match_operand:SWI248 0 "general_reg_operand")
23502 (match_operand:SWI248 1 "general_reg_operand"))
23503 (parallel [(set (reg FLAGS_REG) (match_operand 5))
23504 (set (match_dup 0) (match_operand:SWI248 6))])
23505 (set (match_operand:SWI248 2 "general_reg_operand")
23506 (match_operand:SWI248 3 "general_gr_operand"))
23508 (if_then_else:SWI248 (match_operator 4 "ix86_comparison_operator"
23509 [(reg FLAGS_REG) (const_int 0)])
23513 && REGNO (operands[2]) != REGNO (operands[0])
23514 && REGNO (operands[2]) != REGNO (operands[1])
23515 && peep2_reg_dead_p (1, operands[1])
23516 && peep2_reg_dead_p (4, operands[2])
23517 && !reg_overlap_mentioned_p (operands[0], operands[3])"
23518 [(parallel [(set (match_dup 7) (match_dup 8))
23519 (set (match_dup 1) (match_dup 9))])
23520 (set (match_dup 0) (match_dup 3))
23521 (set (match_dup 0) (if_then_else:SWI248 (match_dup 4)
23525 operands[7] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
23527 = ix86_replace_reg_with_reg (operands[5], operands[0], operands[1]);
23529 = ix86_replace_reg_with_reg (operands[6], operands[0], operands[1]);
23532 ;; Eliminate a reg-reg mov by inverting the condition of a cmov (#2).
23533 ;; mov r2,r3; mov r0,r1; dec r0; cmov r0,r2 -> dec r1; mov r0,r3; cmov r0, r1
23535 [(set (match_operand:SWI248 2 "general_reg_operand")
23536 (match_operand:SWI248 3 "general_gr_operand"))
23537 (set (match_operand:SWI248 0 "general_reg_operand")
23538 (match_operand:SWI248 1 "general_reg_operand"))
23539 (parallel [(set (reg FLAGS_REG) (match_operand 5))
23540 (set (match_dup 0) (match_operand:SWI248 6))])
23542 (if_then_else:SWI248 (match_operator 4 "ix86_comparison_operator"
23543 [(reg FLAGS_REG) (const_int 0)])
23547 && REGNO (operands[2]) != REGNO (operands[0])
23548 && REGNO (operands[2]) != REGNO (operands[1])
23549 && peep2_reg_dead_p (2, operands[1])
23550 && peep2_reg_dead_p (4, operands[2])
23551 && !reg_overlap_mentioned_p (operands[0], operands[3])
23552 && !reg_mentioned_p (operands[2], operands[6])"
23553 [(parallel [(set (match_dup 7) (match_dup 8))
23554 (set (match_dup 1) (match_dup 9))])
23555 (set (match_dup 0) (match_dup 3))
23556 (set (match_dup 0) (if_then_else:SWI248 (match_dup 4)
23560 operands[7] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (2)), 0, 0));
23562 = ix86_replace_reg_with_reg (operands[5], operands[0], operands[1]);
23564 = ix86_replace_reg_with_reg (operands[6], operands[0], operands[1]);
23567 (define_insn "movhf_mask"
23568 [(set (match_operand:HF 0 "nonimmediate_operand" "=v,m,v")
23570 [(match_operand:HF 1 "nonimmediate_operand" "m,v,v")
23571 (match_operand:HF 2 "nonimm_or_0_operand" "0C,0C,0C")
23572 (match_operand:QI 3 "register_operand" "Yk,Yk,Yk")]
23573 UNSPEC_MOVCC_MASK))]
23574 "TARGET_AVX512FP16"
23576 vmovsh\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}
23577 vmovsh\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}
23578 vmovsh\t{%d1, %0%{%3%}%N2|%0%{%3%}%N2, %d1}"
23579 [(set_attr "type" "ssemov")
23580 (set_attr "prefix" "evex")
23581 (set_attr "mode" "HF")])
23583 (define_expand "movhfcc"
23584 [(set (match_operand:HF 0 "register_operand")
23586 (match_operand 1 "comparison_operator")
23587 (match_operand:HF 2 "register_operand")
23588 (match_operand:HF 3 "register_operand")))]
23589 "TARGET_AVX512FP16"
23590 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
23592 (define_expand "mov<mode>cc"
23593 [(set (match_operand:X87MODEF 0 "register_operand")
23594 (if_then_else:X87MODEF
23595 (match_operand 1 "comparison_operator")
23596 (match_operand:X87MODEF 2 "register_operand")
23597 (match_operand:X87MODEF 3 "register_operand")))]
23598 "(TARGET_80387 && TARGET_CMOVE)
23599 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
23600 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
23602 (define_insn "*movxfcc_1"
23603 [(set (match_operand:XF 0 "register_operand" "=f,f")
23604 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
23605 [(reg FLAGS_REG) (const_int 0)])
23606 (match_operand:XF 2 "register_operand" "f,0")
23607 (match_operand:XF 3 "register_operand" "0,f")))]
23608 "TARGET_80387 && TARGET_CMOVE"
23610 fcmov%F1\t{%2, %0|%0, %2}
23611 fcmov%f1\t{%3, %0|%0, %3}"
23612 [(set_attr "type" "fcmov")
23613 (set_attr "mode" "XF")])
23615 (define_insn "*movdfcc_1"
23616 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
23617 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
23618 [(reg FLAGS_REG) (const_int 0)])
23619 (match_operand:DF 2 "nonimmediate_operand"
23621 (match_operand:DF 3 "nonimmediate_operand"
23622 "0 ,f,0 ,rm,0, rm")))]
23623 "TARGET_80387 && TARGET_CMOVE
23624 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23626 fcmov%F1\t{%2, %0|%0, %2}
23627 fcmov%f1\t{%3, %0|%0, %3}
23630 cmov%O2%C1\t{%2, %0|%0, %2}
23631 cmov%O2%c1\t{%3, %0|%0, %3}"
23632 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
23633 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
23634 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
23637 [(set (match_operand:DF 0 "general_reg_operand")
23638 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
23639 [(reg FLAGS_REG) (const_int 0)])
23640 (match_operand:DF 2 "nonimmediate_operand")
23641 (match_operand:DF 3 "nonimmediate_operand")))]
23642 "!TARGET_64BIT && reload_completed"
23643 [(set (match_dup 2)
23644 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
23646 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
23648 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
23649 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
23652 (define_insn "*movsfcc_1_387"
23653 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
23654 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
23655 [(reg FLAGS_REG) (const_int 0)])
23656 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
23657 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
23658 "TARGET_80387 && TARGET_CMOVE
23659 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23661 fcmov%F1\t{%2, %0|%0, %2}
23662 fcmov%f1\t{%3, %0|%0, %3}
23663 cmov%O2%C1\t{%2, %0|%0, %2}
23664 cmov%O2%c1\t{%3, %0|%0, %3}"
23665 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
23666 (set_attr "mode" "SF,SF,SI,SI")])
23668 ;; Don't do conditional moves with memory inputs. This splitter helps
23669 ;; register starved x86_32 by forcing inputs into registers before reload.
23671 [(set (match_operand:MODEF 0 "register_operand")
23672 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
23673 [(reg FLAGS_REG) (const_int 0)])
23674 (match_operand:MODEF 2 "nonimmediate_operand")
23675 (match_operand:MODEF 3 "nonimmediate_operand")))]
23676 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
23677 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23678 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23679 && can_create_pseudo_p ()
23680 && optimize_insn_for_speed_p ()"
23681 [(set (match_dup 0)
23682 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
23684 operands[2] = force_reg (<MODE>mode, operands[2]);
23685 operands[3] = force_reg (<MODE>mode, operands[3]);
23688 ;; Don't do conditional moves with memory inputs
23690 [(match_scratch:MODEF 4 "r")
23691 (set (match_operand:MODEF 0 "general_reg_operand")
23692 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
23693 [(reg FLAGS_REG) (const_int 0)])
23694 (match_operand:MODEF 2 "nonimmediate_operand")
23695 (match_operand:MODEF 3 "nonimmediate_operand")))]
23696 "(<MODE>mode != DFmode || TARGET_64BIT)
23697 && TARGET_80387 && TARGET_CMOVE
23698 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23699 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23700 && optimize_insn_for_speed_p ()"
23701 [(set (match_dup 4) (match_dup 5))
23703 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
23705 if (MEM_P (operands[2]))
23707 operands[5] = operands[2];
23708 operands[2] = operands[4];
23710 else if (MEM_P (operands[3]))
23712 operands[5] = operands[3];
23713 operands[3] = operands[4];
23716 gcc_unreachable ();
23719 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
23720 ;; the scalar versions to have only XMM registers as operands.
23722 ;; XOP conditional move
23723 (define_insn "*xop_pcmov_<mode>"
23724 [(set (match_operand:MODEF 0 "register_operand" "=x")
23725 (if_then_else:MODEF
23726 (match_operand:MODEF 1 "register_operand" "x")
23727 (match_operand:MODEF 2 "register_operand" "x")
23728 (match_operand:MODEF 3 "register_operand" "x")))]
23730 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
23731 [(set_attr "type" "sse4arg")
23732 (set_attr "mode" "TI")])
23734 ;; These versions of the min/max patterns are intentionally ignorant of
23735 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
23736 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
23737 ;; are undefined in this condition, we're certain this is correct.
23739 (define_insn "<code><mode>3"
23740 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
23742 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
23743 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
23744 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
23746 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
23747 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
23748 [(set_attr "isa" "noavx,avx")
23749 (set_attr "prefix" "orig,vex")
23750 (set_attr "type" "sseadd")
23751 (set_attr "mode" "<MODE>")])
23753 (define_insn "<code>hf3"
23754 [(set (match_operand:HF 0 "register_operand" "=v")
23756 (match_operand:HF 1 "nonimmediate_operand" "%v")
23757 (match_operand:HF 2 "nonimmediate_operand" "vm")))]
23758 "TARGET_AVX512FP16"
23759 "v<maxmin_float>sh\t{%2, %1, %0|%0, %1, %2}"
23760 [(set_attr "prefix" "evex")
23761 (set_attr "type" "sseadd")
23762 (set_attr "mode" "HF")])
23764 ;; These versions of the min/max patterns implement exactly the operations
23765 ;; min = (op1 < op2 ? op1 : op2)
23766 ;; max = (!(op1 < op2) ? op1 : op2)
23767 ;; Their operands are not commutative, and thus they may be used in the
23768 ;; presence of -0.0 and NaN.
23770 (define_insn "*ieee_s<ieee_maxmin>hf3"
23771 [(set (match_operand:HF 0 "register_operand" "=v")
23773 [(match_operand:HF 1 "register_operand" "v")
23774 (match_operand:HF 2 "nonimmediate_operand" "vm")]
23776 "TARGET_AVX512FP16"
23777 "v<ieee_maxmin>sh\t{%2, %1, %0|%0, %1, %2}"
23778 [(set_attr "prefix" "evex")
23779 (set_attr "type" "sseadd")
23780 (set_attr "mode" "HF")])
23782 (define_insn "*ieee_s<ieee_maxmin><mode>3"
23783 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
23785 [(match_operand:MODEF 1 "register_operand" "0,v")
23786 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
23788 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
23790 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
23791 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
23792 [(set_attr "isa" "noavx,avx")
23793 (set_attr "prefix" "orig,maybe_evex")
23794 (set_attr "type" "sseadd")
23795 (set_attr "mode" "<MODE>")])
23797 ;; Operands order in min/max instruction matters for signed zero and NANs.
23798 (define_insn_and_split "*ieee_max<mode>3_1"
23799 [(set (match_operand:MODEF 0 "register_operand")
23801 [(match_operand:MODEF 1 "register_operand")
23802 (match_operand:MODEF 2 "register_operand")
23804 (match_operand:MODEF 3 "register_operand")
23805 (match_operand:MODEF 4 "register_operand"))]
23807 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
23808 && (rtx_equal_p (operands[1], operands[3])
23809 && rtx_equal_p (operands[2], operands[4]))
23810 && ix86_pre_reload_split ()"
23813 [(set (match_dup 0)
23817 UNSPEC_IEEE_MAX))])
23819 (define_insn_and_split "*ieee_min<mode>3_1"
23820 [(set (match_operand:MODEF 0 "register_operand")
23822 [(match_operand:MODEF 1 "register_operand")
23823 (match_operand:MODEF 2 "register_operand")
23825 (match_operand:MODEF 3 "register_operand")
23826 (match_operand:MODEF 4 "register_operand"))]
23828 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
23829 && (rtx_equal_p (operands[1], operands[4])
23830 && rtx_equal_p (operands[2], operands[3]))
23831 && ix86_pre_reload_split ()"
23834 [(set (match_dup 0)
23838 UNSPEC_IEEE_MIN))])
23840 ;; Make two stack loads independent:
23842 ;; fld %st(0) -> fld bb
23843 ;; fmul bb fmul %st(1), %st
23845 ;; Actually we only match the last two instructions for simplicity.
23848 [(set (match_operand 0 "fp_register_operand")
23849 (match_operand 1 "fp_register_operand"))
23851 (match_operator 2 "binary_fp_operator"
23853 (match_operand 3 "memory_operand")]))]
23854 "REGNO (operands[0]) != REGNO (operands[1])"
23855 [(set (match_dup 0) (match_dup 3))
23858 [(match_dup 5) (match_dup 4)]))]
23860 operands[4] = operands[0];
23861 operands[5] = operands[1];
23863 /* The % modifier is not operational anymore in peephole2's, so we have to
23864 swap the operands manually in the case of addition and multiplication. */
23865 if (COMMUTATIVE_ARITH_P (operands[2]))
23866 std::swap (operands[4], operands[5]);
23870 [(set (match_operand 0 "fp_register_operand")
23871 (match_operand 1 "fp_register_operand"))
23873 (match_operator 2 "binary_fp_operator"
23874 [(match_operand 3 "memory_operand")
23876 "REGNO (operands[0]) != REGNO (operands[1])"
23877 [(set (match_dup 0) (match_dup 3))
23880 [(match_dup 4) (match_dup 5)]))]
23882 operands[4] = operands[0];
23883 operands[5] = operands[1];
23885 /* The % modifier is not operational anymore in peephole2's, so we have to
23886 swap the operands manually in the case of addition and multiplication. */
23887 if (COMMUTATIVE_ARITH_P (operands[2]))
23888 std::swap (operands[4], operands[5]);
23891 ;; Conditional addition patterns
23892 (define_expand "add<mode>cc"
23893 [(match_operand:SWI 0 "register_operand")
23894 (match_operand 1 "ordered_comparison_operator")
23895 (match_operand:SWI 2 "register_operand")
23896 (match_operand:SWI 3 "const_int_operand")]
23898 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
23900 ;; min/max patterns
23902 (define_code_attr maxmin_rel
23903 [(smax "GE") (smin "LE") (umax "GEU") (umin "LEU")])
23905 (define_expand "<code><mode>3"
23907 [(set (match_operand:SDWIM 0 "register_operand")
23909 (match_operand:SDWIM 1 "register_operand")
23910 (match_operand:SDWIM 2 "general_operand")))
23911 (clobber (reg:CC FLAGS_REG))])]
23913 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)")
23915 (define_insn_and_split "*<code><dwi>3_doubleword"
23916 [(set (match_operand:<DWI> 0 "register_operand")
23918 (match_operand:<DWI> 1 "register_operand")
23919 (match_operand:<DWI> 2 "general_operand")))
23920 (clobber (reg:CC FLAGS_REG))]
23922 && ix86_pre_reload_split ()"
23925 [(set (match_dup 0)
23926 (if_then_else:DWIH (match_dup 6)
23930 (if_then_else:DWIH (match_dup 6)
23934 operands[2] = force_reg (<DWI>mode, operands[2]);
23936 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
23938 rtx cmplo[2] = { operands[1], operands[2] };
23939 rtx cmphi[2] = { operands[4], operands[5] };
23941 enum rtx_code code = <maxmin_rel>;
23946 std::swap (cmplo[0], cmplo[1]);
23947 std::swap (cmphi[0], cmphi[1]);
23948 code = swap_condition (code);
23953 bool uns = (code == GEU);
23954 rtx (*sbb_insn) (machine_mode, rtx, rtx, rtx)
23955 = uns ? gen_sub3_carry_ccc : gen_sub3_carry_ccgz;
23957 emit_insn (gen_cmp_1 (<MODE>mode, cmplo[0], cmplo[1]));
23959 rtx tmp = gen_rtx_SCRATCH (<MODE>mode);
23960 emit_insn (sbb_insn (<MODE>mode, tmp, cmphi[0], cmphi[1]));
23962 rtx flags = gen_rtx_REG (uns ? CCCmode : CCGZmode, FLAGS_REG);
23963 operands[6] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
23969 gcc_unreachable ();
23973 (define_insn_and_split "*<code><mode>3_1"
23974 [(set (match_operand:SWI 0 "register_operand")
23976 (match_operand:SWI 1 "register_operand")
23977 (match_operand:SWI 2 "general_operand")))
23978 (clobber (reg:CC FLAGS_REG))]
23980 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
23981 && ix86_pre_reload_split ()"
23984 [(set (match_dup 0)
23985 (if_then_else:SWI (match_dup 3)
23989 machine_mode mode = <MODE>mode;
23990 rtx cmp_op = operands[2];
23992 operands[2] = force_reg (mode, cmp_op);
23994 enum rtx_code code = <maxmin_rel>;
23996 if (cmp_op == const1_rtx)
23998 /* Convert smax (x, 1) into (x > 0 ? x : 1).
23999 Convert umax (x, 1) into (x != 0 ? x : 1).
24000 Convert ?min (x, 1) into (x <= 0 ? x : 1). */
24001 cmp_op = const0_rtx;
24004 else if (code == GEU)
24007 /* Convert smin (x, -1) into (x < 0 ? x : -1). */
24008 else if (cmp_op == constm1_rtx && code == LE)
24010 cmp_op = const0_rtx;
24013 /* Convert smax (x, -1) into (x >= 0 ? x : -1). */
24014 else if (cmp_op == constm1_rtx && code == GE)
24015 cmp_op = const0_rtx;
24016 else if (cmp_op != const0_rtx)
24017 cmp_op = operands[2];
24019 machine_mode cmpmode = SELECT_CC_MODE (code, operands[1], cmp_op);
24020 rtx flags = gen_rtx_REG (cmpmode, FLAGS_REG);
24022 rtx tmp = gen_rtx_COMPARE (cmpmode, operands[1], cmp_op);
24023 emit_insn (gen_rtx_SET (flags, tmp));
24025 operands[3] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
24028 ;; Avoid clearing a register between a flags setting comparison and its use,
24029 ;; i.e. prefer "xorl %eax,%eax; test/cmp" over "test/cmp; movl $0, %eax".
24031 [(set (reg FLAGS_REG) (match_operand 0))
24032 (set (match_operand:SWI 1 "general_reg_operand") (const_int 0))]
24033 "peep2_regno_dead_p (0, FLAGS_REG)
24034 && !reg_overlap_mentioned_p (operands[1], operands[0])"
24035 [(set (match_dup 2) (match_dup 0))]
24037 operands[2] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
24038 ix86_expand_clear (operands[1]);
24041 ;; When optimizing for size, zeroing memory should use a register.
24043 [(match_scratch:SWI48 0 "r")
24044 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
24045 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))
24046 (set (match_operand:SWI48 3 "memory_operand") (const_int 0))
24047 (set (match_operand:SWI48 4 "memory_operand") (const_int 0))]
24048 "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
24051 ix86_expand_clear (operands[0]);
24052 emit_move_insn (operands[1], operands[0]);
24053 emit_move_insn (operands[2], operands[0]);
24054 emit_move_insn (operands[3], operands[0]);
24055 ix86_last_zero_store_uid
24056 = INSN_UID (emit_move_insn (operands[4], operands[0]));
24061 [(match_scratch:SWI48 0 "r")
24062 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
24063 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))]
24064 "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
24067 ix86_expand_clear (operands[0]);
24068 emit_move_insn (operands[1], operands[0]);
24069 ix86_last_zero_store_uid
24070 = INSN_UID (emit_move_insn (operands[2], operands[0]));
24075 [(match_scratch:SWI48 0 "r")
24076 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))]
24077 "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
24080 ix86_expand_clear (operands[0]);
24081 ix86_last_zero_store_uid
24082 = INSN_UID (emit_move_insn (operands[1], operands[0]));
24087 [(set (match_operand:SWI48 5 "memory_operand")
24088 (match_operand:SWI48 0 "general_reg_operand"))
24089 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
24090 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))
24091 (set (match_operand:SWI48 3 "memory_operand") (const_int 0))
24092 (set (match_operand:SWI48 4 "memory_operand") (const_int 0))]
24093 "optimize_insn_for_size_p ()
24094 && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
24097 emit_move_insn (operands[5], operands[0]);
24098 emit_move_insn (operands[1], operands[0]);
24099 emit_move_insn (operands[2], operands[0]);
24100 emit_move_insn (operands[3], operands[0]);
24101 ix86_last_zero_store_uid
24102 = INSN_UID (emit_move_insn (operands[4], operands[0]));
24107 [(set (match_operand:SWI48 3 "memory_operand")
24108 (match_operand:SWI48 0 "general_reg_operand"))
24109 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
24110 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))]
24111 "optimize_insn_for_size_p ()
24112 && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
24115 emit_move_insn (operands[3], operands[0]);
24116 emit_move_insn (operands[1], operands[0]);
24117 ix86_last_zero_store_uid
24118 = INSN_UID (emit_move_insn (operands[2], operands[0]));
24123 [(set (match_operand:SWI48 2 "memory_operand")
24124 (match_operand:SWI48 0 "general_reg_operand"))
24125 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))]
24126 "optimize_insn_for_size_p ()
24127 && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
24130 emit_move_insn (operands[2], operands[0]);
24131 ix86_last_zero_store_uid
24132 = INSN_UID (emit_move_insn (operands[1], operands[0]));
24136 ;; Reload dislikes loading constants directly into class_likely_spilled
24137 ;; hard registers. Try to tidy things up here.
24139 [(set (match_operand:SWI 0 "general_reg_operand")
24140 (match_operand:SWI 1 "x86_64_general_operand"))
24141 (set (match_operand:SWI 2 "general_reg_operand")
24143 "peep2_reg_dead_p (2, operands[0])"
24144 [(set (match_dup 2) (match_dup 1))])
24146 ;; Misc patterns (?)
24148 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
24149 ;; Otherwise there will be nothing to keep
24151 ;; [(set (reg ebp) (reg esp))]
24152 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
24153 ;; (clobber (eflags)]
24154 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
24156 ;; in proper program order.
24158 (define_insn "@pro_epilogue_adjust_stack_add_<mode>"
24159 [(set (match_operand:P 0 "register_operand" "=r,r")
24160 (plus:P (match_operand:P 1 "register_operand" "0,r")
24161 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
24162 (clobber (reg:CC FLAGS_REG))
24163 (clobber (mem:BLK (scratch)))]
24166 switch (get_attr_type (insn))
24169 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
24172 gcc_assert (rtx_equal_p (operands[0], operands[1]));
24173 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
24174 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
24176 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
24179 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
24180 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
24183 [(set (attr "type")
24184 (cond [(and (eq_attr "alternative" "0")
24185 (not (match_test "TARGET_OPT_AGU")))
24186 (const_string "alu")
24187 (match_operand:<MODE> 2 "const0_operand")
24188 (const_string "imov")
24190 (const_string "lea")))
24191 (set (attr "length_immediate")
24192 (cond [(eq_attr "type" "imov")
24194 (and (eq_attr "type" "alu")
24195 (match_operand 2 "const128_operand"))
24198 (const_string "*")))
24199 (set_attr "mode" "<MODE>")])
24201 (define_insn "@pro_epilogue_adjust_stack_sub_<mode>"
24202 [(set (match_operand:P 0 "register_operand" "=r")
24203 (minus:P (match_operand:P 1 "register_operand" "0")
24204 (match_operand:P 2 "register_operand" "r")))
24205 (clobber (reg:CC FLAGS_REG))
24206 (clobber (mem:BLK (scratch)))]
24208 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
24209 [(set_attr "type" "alu")
24210 (set_attr "mode" "<MODE>")])
24212 (define_insn "@allocate_stack_worker_probe_<mode>"
24213 [(set (match_operand:P 0 "register_operand" "=a")
24214 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
24215 UNSPECV_STACK_PROBE))
24216 (clobber (reg:CC FLAGS_REG))]
24217 "ix86_target_stack_probe ()"
24218 "call\t___chkstk_ms"
24219 [(set_attr "type" "multi")
24220 (set_attr "length" "5")])
24222 (define_expand "allocate_stack"
24223 [(match_operand 0 "register_operand")
24224 (match_operand 1 "general_operand")]
24225 "ix86_target_stack_probe ()"
24229 #ifndef CHECK_STACK_LIMIT
24230 #define CHECK_STACK_LIMIT 0
24233 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
24234 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
24238 x = copy_to_mode_reg (Pmode, operands[1]);
24240 emit_insn (gen_allocate_stack_worker_probe (Pmode, x, x));
24243 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
24244 stack_pointer_rtx, 0, OPTAB_DIRECT);
24246 if (x != stack_pointer_rtx)
24247 emit_move_insn (stack_pointer_rtx, x);
24249 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
24253 (define_expand "probe_stack"
24254 [(match_operand 0 "memory_operand")]
24257 emit_insn (gen_probe_stack_1
24258 (word_mode, operands[0], const0_rtx));
24262 ;; Use OR for stack probes, this is shorter.
24263 (define_insn "@probe_stack_1_<mode>"
24264 [(set (match_operand:W 0 "memory_operand" "=m")
24265 (unspec:W [(match_operand:W 1 "const0_operand")]
24266 UNSPEC_PROBE_STACK))
24267 (clobber (reg:CC FLAGS_REG))]
24269 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
24270 [(set_attr "type" "alu1")
24271 (set_attr "mode" "<MODE>")
24272 (set_attr "length_immediate" "1")])
24274 (define_insn "@adjust_stack_and_probe_<mode>"
24275 [(set (match_operand:P 0 "register_operand" "=r")
24276 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
24277 UNSPECV_PROBE_STACK_RANGE))
24278 (set (reg:P SP_REG)
24279 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand")))
24280 (clobber (reg:CC FLAGS_REG))
24281 (clobber (mem:BLK (scratch)))]
24283 "* return output_adjust_stack_and_probe (operands[0]);"
24284 [(set_attr "type" "multi")])
24286 (define_insn "@probe_stack_range_<mode>"
24287 [(set (match_operand:P 0 "register_operand" "=r")
24288 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
24289 (match_operand:P 2 "const_int_operand")]
24290 UNSPECV_PROBE_STACK_RANGE))
24291 (clobber (reg:CC FLAGS_REG))]
24293 "* return output_probe_stack_range (operands[0], operands[2]);"
24294 [(set_attr "type" "multi")])
24296 (define_expand "builtin_setjmp_receiver"
24297 [(label_ref (match_operand 0))]
24298 "!TARGET_64BIT && flag_pic"
24304 rtx_code_label *label_rtx = gen_label_rtx ();
24305 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
24306 xops[0] = xops[1] = pic_offset_table_rtx;
24307 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
24308 ix86_expand_binary_operator (MINUS, SImode, xops);
24312 emit_insn (gen_set_got (pic_offset_table_rtx));
24316 (define_expand "save_stack_nonlocal"
24317 [(set (match_operand 0 "memory_operand")
24318 (match_operand 1 "register_operand"))]
24323 if (flag_cf_protection & CF_RETURN)
24325 /* Copy shadow stack pointer to the first slot
24326 and stack pointer to the second slot. */
24327 rtx ssp_slot = adjust_address (operands[0], word_mode, 0);
24328 stack_slot = adjust_address (operands[0], Pmode, UNITS_PER_WORD);
24330 rtx reg_ssp = force_reg (word_mode, const0_rtx);
24331 emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
24332 emit_move_insn (ssp_slot, reg_ssp);
24335 stack_slot = adjust_address (operands[0], Pmode, 0);
24336 emit_move_insn (stack_slot, operands[1]);
24340 (define_expand "restore_stack_nonlocal"
24341 [(set (match_operand 0 "register_operand" "")
24342 (match_operand 1 "memory_operand" ""))]
24347 if (flag_cf_protection & CF_RETURN)
24349 /* Restore shadow stack pointer from the first slot
24350 and stack pointer from the second slot. */
24351 rtx ssp_slot = adjust_address (operands[1], word_mode, 0);
24352 stack_slot = adjust_address (operands[1], Pmode, UNITS_PER_WORD);
24354 /* Get the current shadow stack pointer. The code below will check if
24355 SHSTK feature is enabled. If it is not enabled the RDSSP instruction
24357 rtx reg_ssp = force_reg (word_mode, const0_rtx);
24358 emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
24360 /* Compare through subtraction the saved and the current ssp
24361 to decide if ssp has to be adjusted. */
24362 reg_ssp = expand_simple_binop (word_mode, MINUS,
24364 reg_ssp, 1, OPTAB_DIRECT);
24366 /* Compare and jump over adjustment code. */
24367 rtx noadj_label = gen_label_rtx ();
24368 emit_cmp_and_jump_insns (reg_ssp, const0_rtx, EQ, NULL_RTX,
24369 word_mode, 1, noadj_label);
24371 /* Compute the number of frames to adjust. */
24372 rtx reg_adj = gen_lowpart (ptr_mode, reg_ssp);
24373 rtx reg_adj_neg = expand_simple_unop (ptr_mode, NEG, reg_adj,
24376 reg_adj = expand_simple_binop (ptr_mode, LSHIFTRT, reg_adj_neg,
24377 GEN_INT (exact_log2 (UNITS_PER_WORD)),
24378 reg_adj, 1, OPTAB_DIRECT);
24380 /* Check if number of frames <= 255 so no loop is needed. */
24381 rtx inc_label = gen_label_rtx ();
24382 emit_cmp_and_jump_insns (reg_adj, GEN_INT (255), LEU, NULL_RTX,
24383 ptr_mode, 1, inc_label);
24385 /* Adjust the ssp in a loop. */
24386 rtx loop_label = gen_label_rtx ();
24387 emit_label (loop_label);
24388 LABEL_NUSES (loop_label) = 1;
24390 rtx reg_255 = force_reg (word_mode, GEN_INT (255));
24391 emit_insn (gen_incssp (word_mode, reg_255));
24393 reg_adj = expand_simple_binop (ptr_mode, MINUS,
24394 reg_adj, GEN_INT (255),
24395 reg_adj, 1, OPTAB_DIRECT);
24397 /* Compare and jump to the loop label. */
24398 emit_cmp_and_jump_insns (reg_adj, GEN_INT (255), GTU, NULL_RTX,
24399 ptr_mode, 1, loop_label);
24401 emit_label (inc_label);
24402 LABEL_NUSES (inc_label) = 1;
24404 emit_insn (gen_incssp (word_mode, reg_ssp));
24406 emit_label (noadj_label);
24407 LABEL_NUSES (noadj_label) = 1;
24410 stack_slot = adjust_address (operands[1], Pmode, 0);
24411 emit_move_insn (operands[0], stack_slot);
24415 (define_expand "stack_protect_set"
24416 [(match_operand 0 "memory_operand")
24417 (match_operand 1 "memory_operand")]
24420 rtx scratch = gen_reg_rtx (word_mode);
24422 emit_insn (gen_stack_protect_set_1
24423 (ptr_mode, word_mode, operands[0], operands[1], scratch));
24427 (define_insn "@stack_protect_set_1_<PTR:mode>_<W:mode>"
24428 [(set (match_operand:PTR 0 "memory_operand" "=m")
24429 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
24431 (set (match_operand:W 2 "register_operand" "=&r") (const_int 0))
24432 (clobber (reg:CC FLAGS_REG))]
24435 output_asm_insn ("mov{<PTR:imodesuffix>}\t{%1, %<PTR:k>2|%<PTR:k>2, %1}",
24437 output_asm_insn ("mov{<PTR:imodesuffix>}\t{%<PTR:k>2, %0|%0, %<PTR:k>2}",
24439 if (!TARGET_USE_MOV0 || optimize_insn_for_size_p ())
24440 return "xor{l}\t%k2, %k2";
24442 return "mov{l}\t{$0, %k2|%k2, 0}";
24444 [(set_attr "type" "multi")])
24446 ;; Patterns and peephole2s to optimize stack_protect_set_1_<mode>
24447 ;; immediately followed by *mov{s,d}i_internal, where we can avoid
24448 ;; the xor{l} above. We don't split this, so that scheduling or
24449 ;; anything else doesn't separate the *stack_protect_set* pattern from
24450 ;; the set of the register that overwrites the register with a new value.
24453 [(parallel [(set (match_operand:PTR 0 "memory_operand")
24454 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
24456 (set (match_operand 2 "general_reg_operand") (const_int 0))
24457 (clobber (reg:CC FLAGS_REG))])
24458 (set (match_operand 3 "general_reg_operand")
24459 (match_operand 4 "const0_operand"))]
24460 "GET_MODE (operands[2]) == word_mode
24461 && GET_MODE_SIZE (GET_MODE (operands[3])) <= UNITS_PER_WORD
24462 && peep2_reg_dead_p (0, operands[3])
24463 && peep2_reg_dead_p (1, operands[2])"
24464 [(parallel [(set (match_dup 0)
24465 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
24466 (set (match_dup 3) (const_int 0))
24467 (clobber (reg:CC FLAGS_REG))])]
24468 "operands[3] = gen_lowpart (word_mode, operands[3]);")
24470 (define_insn "*stack_protect_set_2_<mode>_si"
24471 [(set (match_operand:PTR 0 "memory_operand" "=m")
24472 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
24474 (set (match_operand:SI 1 "register_operand" "=&r")
24475 (match_operand:SI 2 "general_operand" "g"))]
24478 output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
24479 output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
24480 if (pic_32bit_operand (operands[2], SImode)
24481 || ix86_use_lea_for_mov (insn, operands + 1))
24482 return "lea{l}\t{%E2, %1|%1, %E2}";
24484 return "mov{l}\t{%2, %1|%1, %2}";
24486 [(set_attr "type" "multi")
24487 (set_attr "length" "24")])
24489 (define_insn "*stack_protect_set_2_<mode>_di"
24490 [(set (match_operand:PTR 0 "memory_operand" "=m,m,m")
24491 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m,m,m")]
24493 (set (match_operand:DI 1 "register_operand" "=&r,&r,&r")
24494 (match_operand:DI 2 "general_operand" "Z,rem,i"))]
24495 "TARGET_64BIT && reload_completed"
24497 output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
24498 output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
24499 if (pic_32bit_operand (operands[2], DImode))
24500 return "lea{q}\t{%E2, %1|%1, %E2}";
24501 else if (which_alternative == 0)
24502 return "mov{l}\t{%k2, %k1|%k1, %k2}";
24503 else if (which_alternative == 2)
24504 return "movabs{q}\t{%2, %1|%1, %2}";
24505 else if (ix86_use_lea_for_mov (insn, operands + 1))
24506 return "lea{q}\t{%E2, %1|%1, %E2}";
24508 return "mov{q}\t{%2, %1|%1, %2}";
24510 [(set_attr "type" "multi")
24511 (set_attr "length" "24")])
24514 [(parallel [(set (match_operand:PTR 0 "memory_operand")
24515 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
24517 (set (match_operand 2 "general_reg_operand") (const_int 0))
24518 (clobber (reg:CC FLAGS_REG))])
24519 (set (match_operand:SWI48 3 "general_reg_operand")
24520 (match_operand:SWI48 4 "general_gr_operand"))]
24521 "GET_MODE (operands[2]) == word_mode
24522 && peep2_reg_dead_p (0, operands[3])
24523 && peep2_reg_dead_p (1, operands[2])"
24524 [(parallel [(set (match_dup 0)
24525 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
24526 (set (match_dup 3) (match_dup 4))])])
24529 [(set (match_operand:SWI48 3 "general_reg_operand")
24530 (match_operand:SWI48 4 "general_gr_operand"))
24531 (parallel [(set (match_operand:PTR 0 "memory_operand")
24532 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
24534 (set (match_operand 2 "general_reg_operand") (const_int 0))
24535 (clobber (reg:CC FLAGS_REG))])]
24536 "GET_MODE (operands[2]) == word_mode
24537 && peep2_reg_dead_p (0, operands[3])
24538 && peep2_reg_dead_p (2, operands[2])
24539 && !reg_mentioned_p (operands[3], operands[0])
24540 && !reg_mentioned_p (operands[3], operands[1])"
24541 [(parallel [(set (match_dup 0)
24542 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
24543 (set (match_dup 3) (match_dup 4))])])
24545 (define_insn "*stack_protect_set_3_<PTR:mode>_<SWI48:mode>"
24546 [(set (match_operand:PTR 0 "memory_operand" "=m")
24547 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
24549 (set (match_operand:SWI48 1 "register_operand" "=&r")
24550 (match_operand:SWI48 2 "address_no_seg_operand" "Ts"))]
24553 output_asm_insn ("mov{<PTR:imodesuffix>}\t{%3, %<PTR:k>1|%<PTR:k>1, %3}",
24555 output_asm_insn ("mov{<PTR:imodesuffix>}\t{%<PTR:k>1, %0|%0, %<PTR:k>1}",
24557 if (SImode_address_operand (operands[2], VOIDmode))
24559 gcc_assert (TARGET_64BIT);
24560 return "lea{l}\t{%E2, %k1|%k1, %E2}";
24563 return "lea{<SWI48:imodesuffix>}\t{%E2, %1|%1, %E2}";
24565 [(set_attr "type" "multi")
24566 (set_attr "length" "24")])
24569 [(parallel [(set (match_operand:PTR 0 "memory_operand")
24570 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
24572 (set (match_operand 2 "general_reg_operand") (const_int 0))
24573 (clobber (reg:CC FLAGS_REG))])
24574 (set (match_operand:SWI48 3 "general_reg_operand")
24575 (match_operand:SWI48 4 "address_no_seg_operand"))]
24576 "GET_MODE (operands[2]) == word_mode
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) (match_dup 4))])])
24583 (define_insn "*stack_protect_set_4z_<mode>_di"
24584 [(set (match_operand:PTR 0 "memory_operand" "=m")
24585 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
24587 (set (match_operand:DI 1 "register_operand" "=&r")
24588 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))]
24589 "TARGET_64BIT && reload_completed"
24591 output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
24592 output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
24593 if (ix86_use_lea_for_mov (insn, operands + 1))
24594 return "lea{l}\t{%E2, %k1|%k1, %E2}";
24596 return "mov{l}\t{%2, %k1|%k1, %2}";
24598 [(set_attr "type" "multi")
24599 (set_attr "length" "24")])
24601 (define_insn "*stack_protect_set_4s_<mode>_di"
24602 [(set (match_operand:PTR 0 "memory_operand" "=m")
24603 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
24605 (set (match_operand:DI 1 "register_operand" "=&r")
24606 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))]
24607 "TARGET_64BIT && reload_completed"
24609 output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
24610 output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
24611 return "movs{lq|x}\t{%2, %1|%1, %2}";
24613 [(set_attr "type" "multi")
24614 (set_attr "length" "24")])
24617 [(parallel [(set (match_operand:PTR 0 "memory_operand")
24618 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
24620 (set (match_operand 2 "general_reg_operand") (const_int 0))
24621 (clobber (reg:CC FLAGS_REG))])
24622 (set (match_operand:DI 3 "general_reg_operand")
24624 (match_operand:SI 4 "nonimmediate_gr_operand")))]
24626 && GET_MODE (operands[2]) == word_mode
24627 && peep2_reg_dead_p (0, operands[3])
24628 && peep2_reg_dead_p (1, operands[2])"
24629 [(parallel [(set (match_dup 0)
24630 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
24632 (any_extend:DI (match_dup 4)))])])
24634 (define_expand "stack_protect_test"
24635 [(match_operand 0 "memory_operand")
24636 (match_operand 1 "memory_operand")
24640 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
24642 emit_insn (gen_stack_protect_test_1
24643 (ptr_mode, flags, operands[0], operands[1]));
24645 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
24646 flags, const0_rtx, operands[2]));
24650 (define_insn "@stack_protect_test_1_<mode>"
24651 [(set (match_operand:CCZ 0 "flags_reg_operand")
24652 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
24653 (match_operand:PTR 2 "memory_operand" "m")]
24655 (clobber (match_scratch:PTR 3 "=&r"))]
24658 output_asm_insn ("mov{<imodesuffix>}\t{%1, %3|%3, %1}", operands);
24659 return "sub{<imodesuffix>}\t{%2, %3|%3, %2}";
24661 [(set_attr "type" "multi")])
24663 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
24664 ;; Do not split instructions with mask registers.
24666 [(set (match_operand 0 "general_reg_operand")
24667 (match_operator 3 "promotable_binary_operator"
24668 [(match_operand 1 "general_reg_operand")
24669 (match_operand 2 "aligned_operand")]))
24670 (clobber (reg:CC FLAGS_REG))]
24671 "! TARGET_PARTIAL_REG_STALL && reload_completed
24672 && ((GET_MODE (operands[0]) == HImode
24673 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
24674 /* ??? next two lines just !satisfies_constraint_K (...) */
24675 || !CONST_INT_P (operands[2])
24676 || satisfies_constraint_K (operands[2])))
24677 || (GET_MODE (operands[0]) == QImode
24678 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
24679 [(parallel [(set (match_dup 0)
24680 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
24681 (clobber (reg:CC FLAGS_REG))])]
24683 operands[0] = gen_lowpart (SImode, operands[0]);
24684 operands[1] = gen_lowpart (SImode, operands[1]);
24685 if (GET_CODE (operands[3]) != ASHIFT)
24686 operands[2] = gen_lowpart (SImode, operands[2]);
24687 operands[3] = shallow_copy_rtx (operands[3]);
24688 PUT_MODE (operands[3], SImode);
24691 ; Promote the QImode tests, as i386 has encoding of the AND
24692 ; instruction with 32-bit sign-extended immediate and thus the
24693 ; instruction size is unchanged, except in the %eax case for
24694 ; which it is increased by one byte, hence the ! optimize_size.
24696 [(set (match_operand 0 "flags_reg_operand")
24697 (match_operator 2 "compare_operator"
24698 [(and (match_operand 3 "aligned_operand")
24699 (match_operand 4 "const_int_operand"))
24701 (set (match_operand 1 "register_operand")
24702 (and (match_dup 3) (match_dup 4)))]
24703 "! TARGET_PARTIAL_REG_STALL && reload_completed
24704 && optimize_insn_for_speed_p ()
24705 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
24706 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
24707 /* Ensure that the operand will remain sign-extended immediate. */
24708 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
24709 [(parallel [(set (match_dup 0)
24710 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
24713 (and:SI (match_dup 3) (match_dup 4)))])]
24716 = gen_int_mode (INTVAL (operands[4])
24717 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
24718 operands[1] = gen_lowpart (SImode, operands[1]);
24719 operands[3] = gen_lowpart (SImode, operands[3]);
24722 ; Don't promote the QImode tests, as i386 doesn't have encoding of
24723 ; the TEST instruction with 32-bit sign-extended immediate and thus
24724 ; the instruction size would at least double, which is not what we
24725 ; want even with ! optimize_size.
24727 [(set (match_operand 0 "flags_reg_operand")
24728 (match_operator 1 "compare_operator"
24729 [(and (match_operand:HI 2 "aligned_operand")
24730 (match_operand:HI 3 "const_int_operand"))
24732 "! TARGET_PARTIAL_REG_STALL && reload_completed
24733 && ! TARGET_FAST_PREFIX
24734 && optimize_insn_for_speed_p ()
24735 /* Ensure that the operand will remain sign-extended immediate. */
24736 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
24737 [(set (match_dup 0)
24738 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
24742 = gen_int_mode (INTVAL (operands[3])
24743 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
24744 operands[2] = gen_lowpart (SImode, operands[2]);
24748 [(set (match_operand 0 "register_operand")
24749 (neg (match_operand 1 "register_operand")))
24750 (clobber (reg:CC FLAGS_REG))]
24751 "! TARGET_PARTIAL_REG_STALL && reload_completed
24752 && (GET_MODE (operands[0]) == HImode
24753 || (GET_MODE (operands[0]) == QImode
24754 && (TARGET_PROMOTE_QImode
24755 || optimize_insn_for_size_p ())))"
24756 [(parallel [(set (match_dup 0)
24757 (neg:SI (match_dup 1)))
24758 (clobber (reg:CC FLAGS_REG))])]
24760 operands[0] = gen_lowpart (SImode, operands[0]);
24761 operands[1] = gen_lowpart (SImode, operands[1]);
24764 ;; Do not split instructions with mask regs.
24766 [(set (match_operand 0 "general_reg_operand")
24767 (not (match_operand 1 "general_reg_operand")))]
24768 "! TARGET_PARTIAL_REG_STALL && reload_completed
24769 && (GET_MODE (operands[0]) == HImode
24770 || (GET_MODE (operands[0]) == QImode
24771 && (TARGET_PROMOTE_QImode
24772 || optimize_insn_for_size_p ())))"
24773 [(set (match_dup 0)
24774 (not:SI (match_dup 1)))]
24776 operands[0] = gen_lowpart (SImode, operands[0]);
24777 operands[1] = gen_lowpart (SImode, operands[1]);
24780 ;; RTL Peephole optimizations, run before sched2. These primarily look to
24781 ;; transform a complex memory operation into two memory to register operations.
24783 ;; Don't push memory operands
24785 [(set (match_operand:SWI 0 "push_operand")
24786 (match_operand:SWI 1 "memory_operand"))
24787 (match_scratch:SWI 2 "<r>")]
24788 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
24789 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
24790 [(set (match_dup 2) (match_dup 1))
24791 (set (match_dup 0) (match_dup 2))])
24793 ;; We need to handle SFmode only, because DFmode and XFmode are split to
24796 [(set (match_operand:SF 0 "push_operand")
24797 (match_operand:SF 1 "memory_operand"))
24798 (match_scratch:SF 2 "r")]
24799 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
24800 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
24801 [(set (match_dup 2) (match_dup 1))
24802 (set (match_dup 0) (match_dup 2))])
24804 ;; Don't move an immediate directly to memory when the instruction
24805 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
24807 [(match_scratch:SWI124 1 "<r>")
24808 (set (match_operand:SWI124 0 "memory_operand")
24810 "optimize_insn_for_speed_p ()
24811 && ((<MODE>mode == HImode
24812 && TARGET_LCP_STALL)
24813 || (!TARGET_USE_MOV0
24814 && TARGET_SPLIT_LONG_MOVES
24815 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
24816 && peep2_regno_dead_p (0, FLAGS_REG)"
24817 [(parallel [(set (match_dup 2) (const_int 0))
24818 (clobber (reg:CC FLAGS_REG))])
24819 (set (match_dup 0) (match_dup 1))]
24820 "operands[2] = gen_lowpart (SImode, operands[1]);")
24823 [(match_scratch:SWI124 2 "<r>")
24824 (set (match_operand:SWI124 0 "memory_operand")
24825 (match_operand:SWI124 1 "immediate_operand"))]
24826 "optimize_insn_for_speed_p ()
24827 && ((<MODE>mode == HImode
24828 && TARGET_LCP_STALL)
24829 || (TARGET_SPLIT_LONG_MOVES
24830 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
24831 [(set (match_dup 2) (match_dup 1))
24832 (set (match_dup 0) (match_dup 2))])
24834 ;; Don't compare memory with zero, load and use a test instead.
24836 [(set (match_operand 0 "flags_reg_operand")
24837 (match_operator 1 "compare_operator"
24838 [(match_operand:SI 2 "memory_operand")
24840 (match_scratch:SI 3 "r")]
24841 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
24842 [(set (match_dup 3) (match_dup 2))
24843 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
24845 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
24846 ;; Don't split NOTs with a displacement operand, because resulting XOR
24847 ;; will not be pairable anyway.
24849 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
24850 ;; represented using a modRM byte. The XOR replacement is long decoded,
24851 ;; so this split helps here as well.
24853 ;; Note: Can't do this as a regular split because we can't get proper
24854 ;; lifetime information then.
24857 [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
24858 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
24859 "optimize_insn_for_speed_p ()
24860 && ((TARGET_NOT_UNPAIRABLE
24861 && (!MEM_P (operands[0])
24862 || !memory_displacement_operand (operands[0], <MODE>mode)))
24863 || (TARGET_NOT_VECTORMODE
24864 && long_memory_operand (operands[0], <MODE>mode)))
24865 && peep2_regno_dead_p (0, FLAGS_REG)"
24866 [(parallel [(set (match_dup 0)
24867 (xor:SWI124 (match_dup 1) (const_int -1)))
24868 (clobber (reg:CC FLAGS_REG))])])
24870 ;; Non pairable "test imm, reg" instructions can be translated to
24871 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
24872 ;; byte opcode instead of two, have a short form for byte operands),
24873 ;; so do it for other CPUs as well. Given that the value was dead,
24874 ;; this should not create any new dependencies. Pass on the sub-word
24875 ;; versions if we're concerned about partial register stalls.
24878 [(set (match_operand 0 "flags_reg_operand")
24879 (match_operator 1 "compare_operator"
24880 [(and:SI (match_operand:SI 2 "register_operand")
24881 (match_operand:SI 3 "immediate_operand"))
24883 "ix86_match_ccmode (insn, CCNOmode)
24884 && (REGNO (operands[2]) != AX_REG
24885 || satisfies_constraint_K (operands[3]))
24886 && peep2_reg_dead_p (1, operands[2])"
24888 [(set (match_dup 0)
24889 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
24892 (and:SI (match_dup 2) (match_dup 3)))])])
24894 ;; We don't need to handle HImode case, because it will be promoted to SImode
24895 ;; on ! TARGET_PARTIAL_REG_STALL
24898 [(set (match_operand 0 "flags_reg_operand")
24899 (match_operator 1 "compare_operator"
24900 [(and:QI (match_operand:QI 2 "register_operand")
24901 (match_operand:QI 3 "immediate_operand"))
24903 "! TARGET_PARTIAL_REG_STALL
24904 && ix86_match_ccmode (insn, CCNOmode)
24905 && REGNO (operands[2]) != AX_REG
24906 && peep2_reg_dead_p (1, operands[2])"
24908 [(set (match_dup 0)
24909 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
24912 (and:QI (match_dup 2) (match_dup 3)))])])
24915 [(set (match_operand 0 "flags_reg_operand")
24916 (match_operator 1 "compare_operator"
24919 (match_operator:SWI248 4 "extract_operator"
24920 [(match_operand 2 "int248_register_operand")
24923 (match_operand 3 "const_int_operand"))
24925 "! TARGET_PARTIAL_REG_STALL
24926 && ix86_match_ccmode (insn, CCNOmode)
24927 && REGNO (operands[2]) != AX_REG
24928 && peep2_reg_dead_p (1, operands[2])"
24930 [(set (match_dup 0)
24934 (match_op_dup 4 [(match_dup 2)
24939 (set (zero_extract:SWI248 (match_dup 2)
24945 (match_op_dup 4 [(match_dup 2)
24948 (match_dup 3)) 0))])])
24950 ;; Don't do logical operations with memory inputs.
24952 [(match_scratch:SWI 2 "<r>")
24953 (parallel [(set (match_operand:SWI 0 "register_operand")
24954 (match_operator:SWI 3 "arith_or_logical_operator"
24956 (match_operand:SWI 1 "memory_operand")]))
24957 (clobber (reg:CC FLAGS_REG))])]
24958 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
24959 [(set (match_dup 2) (match_dup 1))
24960 (parallel [(set (match_dup 0)
24961 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
24962 (clobber (reg:CC FLAGS_REG))])])
24965 [(match_scratch:SWI 2 "<r>")
24966 (parallel [(set (match_operand:SWI 0 "register_operand")
24967 (match_operator:SWI 3 "arith_or_logical_operator"
24968 [(match_operand:SWI 1 "memory_operand")
24970 (clobber (reg:CC FLAGS_REG))])]
24971 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
24972 [(set (match_dup 2) (match_dup 1))
24973 (parallel [(set (match_dup 0)
24974 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
24975 (clobber (reg:CC FLAGS_REG))])])
24977 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when
24978 ;; the memory address refers to the destination of the load!
24981 [(set (match_operand:SWI 0 "general_reg_operand")
24982 (match_operand:SWI 1 "general_reg_operand"))
24983 (parallel [(set (match_dup 0)
24984 (match_operator:SWI 3 "commutative_operator"
24986 (match_operand:SWI 2 "memory_operand")]))
24987 (clobber (reg:CC FLAGS_REG))])]
24988 "REGNO (operands[0]) != REGNO (operands[1])
24989 && (<MODE>mode != QImode
24990 || any_QIreg_operand (operands[1], QImode))"
24991 [(set (match_dup 0) (match_dup 4))
24992 (parallel [(set (match_dup 0)
24993 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
24994 (clobber (reg:CC FLAGS_REG))])]
24997 = ix86_replace_reg_with_reg (operands[2], operands[0], operands[1]);
25001 [(set (match_operand 0 "mmx_reg_operand")
25002 (match_operand 1 "mmx_reg_operand"))
25004 (match_operator 3 "commutative_operator"
25006 (match_operand 2 "memory_operand")]))]
25007 "REGNO (operands[0]) != REGNO (operands[1])"
25008 [(set (match_dup 0) (match_dup 2))
25010 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
25013 [(set (match_operand 0 "sse_reg_operand")
25014 (match_operand 1 "sse_reg_operand"))
25016 (match_operator 3 "commutative_operator"
25018 (match_operand 2 "memory_operand")]))]
25019 "REGNO (operands[0]) != REGNO (operands[1])
25020 /* Punt if operands[1] is %[xy]mm16+ and AVX512BW is not enabled,
25021 as EVEX encoded vpadd[bw], vpmullw, vpmin[su][bw] and vpmax[su][bw]
25022 instructions require AVX512BW and AVX512VL, but with the original
25023 instructions it might require just AVX512VL.
25024 AVX512VL is implied from TARGET_HARD_REGNO_MODE_OK. */
25025 && (!EXT_REX_SSE_REGNO_P (REGNO (operands[1]))
25027 || GET_MODE_SIZE (GET_MODE_INNER (GET_MODE (operands[0]))) > 2
25028 || logic_operator (operands[3], VOIDmode))"
25029 [(set (match_dup 0) (match_dup 2))
25031 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
25033 ; Don't do logical operations with memory outputs
25035 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
25036 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
25037 ; the same decoder scheduling characteristics as the original.
25040 [(match_scratch:SWI 2 "<r>")
25041 (parallel [(set (match_operand:SWI 0 "memory_operand")
25042 (match_operator:SWI 3 "arith_or_logical_operator"
25044 (match_operand:SWI 1 "<nonmemory_operand>")]))
25045 (clobber (reg:CC FLAGS_REG))])]
25046 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
25047 [(set (match_dup 2) (match_dup 0))
25048 (parallel [(set (match_dup 2)
25049 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
25050 (clobber (reg:CC FLAGS_REG))])
25051 (set (match_dup 0) (match_dup 2))])
25054 [(match_scratch:SWI 2 "<r>")
25055 (parallel [(set (match_operand:SWI 0 "memory_operand")
25056 (match_operator:SWI 3 "arith_or_logical_operator"
25057 [(match_operand:SWI 1 "<nonmemory_operand>")
25059 (clobber (reg:CC FLAGS_REG))])]
25060 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
25061 [(set (match_dup 2) (match_dup 0))
25062 (parallel [(set (match_dup 2)
25063 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
25064 (clobber (reg:CC FLAGS_REG))])
25065 (set (match_dup 0) (match_dup 2))])
25067 ;; Attempt to use arith or logical operations with memory outputs with
25068 ;; setting of flags.
25070 [(set (match_operand:SWI 0 "register_operand")
25071 (match_operand:SWI 1 "memory_operand"))
25072 (parallel [(set (match_dup 0)
25073 (match_operator:SWI 3 "plusminuslogic_operator"
25075 (match_operand:SWI 2 "<nonmemory_operand>")]))
25076 (clobber (reg:CC FLAGS_REG))])
25077 (set (match_dup 1) (match_dup 0))
25078 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
25079 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25080 && peep2_reg_dead_p (4, operands[0])
25081 && !reg_overlap_mentioned_p (operands[0], operands[1])
25082 && !reg_overlap_mentioned_p (operands[0], operands[2])
25083 && (<MODE>mode != QImode
25084 || immediate_operand (operands[2], QImode)
25085 || any_QIreg_operand (operands[2], QImode))
25086 && ix86_match_ccmode (peep2_next_insn (3),
25087 (GET_CODE (operands[3]) == PLUS
25088 || GET_CODE (operands[3]) == MINUS)
25089 ? CCGOCmode : CCNOmode)"
25090 [(parallel [(set (match_dup 4) (match_dup 6))
25091 (set (match_dup 1) (match_dup 5))])]
25093 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
25095 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
25096 copy_rtx (operands[1]),
25099 = gen_rtx_COMPARE (GET_MODE (operands[4]),
25100 copy_rtx (operands[5]),
25104 ;; Likewise for cmpelim optimized pattern.
25106 [(set (match_operand:SWI 0 "register_operand")
25107 (match_operand:SWI 1 "memory_operand"))
25108 (parallel [(set (reg FLAGS_REG)
25109 (compare (match_operator:SWI 3 "plusminuslogic_operator"
25111 (match_operand:SWI 2 "<nonmemory_operand>")])
25113 (set (match_dup 0) (match_dup 3))])
25114 (set (match_dup 1) (match_dup 0))]
25115 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25116 && peep2_reg_dead_p (3, operands[0])
25117 && !reg_overlap_mentioned_p (operands[0], operands[1])
25118 && !reg_overlap_mentioned_p (operands[0], operands[2])
25119 && ix86_match_ccmode (peep2_next_insn (1),
25120 (GET_CODE (operands[3]) == PLUS
25121 || GET_CODE (operands[3]) == MINUS)
25122 ? CCGOCmode : CCNOmode)"
25123 [(parallel [(set (match_dup 4) (match_dup 6))
25124 (set (match_dup 1) (match_dup 5))])]
25126 operands[4] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
25128 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
25129 copy_rtx (operands[1]), operands[2]);
25131 = gen_rtx_COMPARE (GET_MODE (operands[4]), copy_rtx (operands[5]),
25135 ;; Likewise for instances where we have a lea pattern.
25137 [(set (match_operand:SWI 0 "register_operand")
25138 (match_operand:SWI 1 "memory_operand"))
25139 (set (match_operand:<LEAMODE> 3 "register_operand")
25140 (plus:<LEAMODE> (match_operand:<LEAMODE> 4 "register_operand")
25141 (match_operand:<LEAMODE> 2 "<nonmemory_operand>")))
25142 (set (match_dup 1) (match_operand:SWI 5 "register_operand"))
25143 (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
25144 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25145 && REGNO (operands[4]) == REGNO (operands[0])
25146 && REGNO (operands[5]) == REGNO (operands[3])
25147 && peep2_reg_dead_p (4, operands[3])
25148 && ((REGNO (operands[0]) == REGNO (operands[3]))
25149 || peep2_reg_dead_p (2, operands[0]))
25150 && !reg_overlap_mentioned_p (operands[0], operands[1])
25151 && !reg_overlap_mentioned_p (operands[3], operands[1])
25152 && !reg_overlap_mentioned_p (operands[0], operands[2])
25153 && (<MODE>mode != QImode
25154 || immediate_operand (operands[2], QImode)
25155 || any_QIreg_operand (operands[2], QImode))
25156 && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
25157 [(parallel [(set (match_dup 6) (match_dup 8))
25158 (set (match_dup 1) (match_dup 7))])]
25160 operands[6] = SET_DEST (PATTERN (peep2_next_insn (3)));
25162 = gen_rtx_PLUS (<MODE>mode,
25163 copy_rtx (operands[1]),
25164 gen_lowpart (<MODE>mode, operands[2]));
25166 = gen_rtx_COMPARE (GET_MODE (operands[6]),
25167 copy_rtx (operands[7]),
25172 [(parallel [(set (match_operand:SWI 0 "register_operand")
25173 (match_operator:SWI 2 "plusminuslogic_operator"
25175 (match_operand:SWI 1 "memory_operand")]))
25176 (clobber (reg:CC FLAGS_REG))])
25177 (set (match_dup 1) (match_dup 0))
25178 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
25179 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25180 && COMMUTATIVE_ARITH_P (operands[2])
25181 && peep2_reg_dead_p (3, operands[0])
25182 && !reg_overlap_mentioned_p (operands[0], operands[1])
25183 && ix86_match_ccmode (peep2_next_insn (2),
25184 GET_CODE (operands[2]) == PLUS
25185 ? CCGOCmode : CCNOmode)"
25186 [(parallel [(set (match_dup 3) (match_dup 5))
25187 (set (match_dup 1) (match_dup 4))])]
25189 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
25191 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
25192 copy_rtx (operands[1]),
25195 = gen_rtx_COMPARE (GET_MODE (operands[3]),
25196 copy_rtx (operands[4]),
25200 ;; Likewise for cmpelim optimized pattern.
25202 [(parallel [(set (reg FLAGS_REG)
25203 (compare (match_operator:SWI 2 "plusminuslogic_operator"
25204 [(match_operand:SWI 0 "register_operand")
25205 (match_operand:SWI 1 "memory_operand")])
25207 (set (match_dup 0) (match_dup 2))])
25208 (set (match_dup 1) (match_dup 0))]
25209 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25210 && COMMUTATIVE_ARITH_P (operands[2])
25211 && peep2_reg_dead_p (2, operands[0])
25212 && !reg_overlap_mentioned_p (operands[0], operands[1])
25213 && ix86_match_ccmode (peep2_next_insn (0),
25214 GET_CODE (operands[2]) == PLUS
25215 ? CCGOCmode : CCNOmode)"
25216 [(parallel [(set (match_dup 3) (match_dup 5))
25217 (set (match_dup 1) (match_dup 4))])]
25219 operands[3] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (0)), 0, 0));
25221 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
25222 copy_rtx (operands[1]), operands[0]);
25224 = gen_rtx_COMPARE (GET_MODE (operands[3]), copy_rtx (operands[4]),
25229 [(set (match_operand:SWI12 0 "register_operand")
25230 (match_operand:SWI12 1 "memory_operand"))
25231 (parallel [(set (match_operand:SI 4 "register_operand")
25232 (match_operator:SI 3 "plusminuslogic_operator"
25234 (match_operand:SI 2 "nonmemory_operand")]))
25235 (clobber (reg:CC FLAGS_REG))])
25236 (set (match_dup 1) (match_dup 0))
25237 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
25238 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25239 && REGNO (operands[0]) == REGNO (operands[4])
25240 && peep2_reg_dead_p (4, operands[0])
25241 && (<MODE>mode != QImode
25242 || immediate_operand (operands[2], SImode)
25243 || any_QIreg_operand (operands[2], SImode))
25244 && !reg_overlap_mentioned_p (operands[0], operands[1])
25245 && !reg_overlap_mentioned_p (operands[0], operands[2])
25246 && ix86_match_ccmode (peep2_next_insn (3),
25247 (GET_CODE (operands[3]) == PLUS
25248 || GET_CODE (operands[3]) == MINUS)
25249 ? CCGOCmode : CCNOmode)"
25250 [(parallel [(set (match_dup 5) (match_dup 7))
25251 (set (match_dup 1) (match_dup 6))])]
25253 operands[5] = SET_DEST (PATTERN (peep2_next_insn (3)));
25255 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
25256 copy_rtx (operands[1]),
25257 gen_lowpart (<MODE>mode, operands[2]));
25259 = gen_rtx_COMPARE (GET_MODE (operands[5]),
25260 copy_rtx (operands[6]),
25264 ;; peephole2 comes before regcprop, so deal also with a case that
25265 ;; would be cleaned up by regcprop.
25267 [(set (match_operand:SWI 0 "register_operand")
25268 (match_operand:SWI 1 "memory_operand"))
25269 (parallel [(set (match_dup 0)
25270 (match_operator:SWI 3 "plusminuslogic_operator"
25272 (match_operand:SWI 2 "<nonmemory_operand>")]))
25273 (clobber (reg:CC FLAGS_REG))])
25274 (set (match_operand:SWI 4 "register_operand") (match_dup 0))
25275 (set (match_dup 1) (match_dup 4))
25276 (set (reg FLAGS_REG) (compare (match_dup 4) (const_int 0)))]
25277 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25278 && peep2_reg_dead_p (3, operands[0])
25279 && peep2_reg_dead_p (5, operands[4])
25280 && !reg_overlap_mentioned_p (operands[0], operands[1])
25281 && !reg_overlap_mentioned_p (operands[0], operands[2])
25282 && !reg_overlap_mentioned_p (operands[4], operands[1])
25283 && (<MODE>mode != QImode
25284 || immediate_operand (operands[2], QImode)
25285 || any_QIreg_operand (operands[2], QImode))
25286 && ix86_match_ccmode (peep2_next_insn (4),
25287 (GET_CODE (operands[3]) == PLUS
25288 || GET_CODE (operands[3]) == MINUS)
25289 ? CCGOCmode : CCNOmode)"
25290 [(parallel [(set (match_dup 5) (match_dup 7))
25291 (set (match_dup 1) (match_dup 6))])]
25293 operands[5] = SET_DEST (PATTERN (peep2_next_insn (4)));
25295 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
25296 copy_rtx (operands[1]),
25299 = gen_rtx_COMPARE (GET_MODE (operands[5]),
25300 copy_rtx (operands[6]),
25305 [(set (match_operand:SWI12 0 "register_operand")
25306 (match_operand:SWI12 1 "memory_operand"))
25307 (parallel [(set (match_operand:SI 4 "register_operand")
25308 (match_operator:SI 3 "plusminuslogic_operator"
25310 (match_operand:SI 2 "nonmemory_operand")]))
25311 (clobber (reg:CC FLAGS_REG))])
25312 (set (match_operand:SWI12 5 "register_operand") (match_dup 0))
25313 (set (match_dup 1) (match_dup 5))
25314 (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
25315 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25316 && REGNO (operands[0]) == REGNO (operands[4])
25317 && peep2_reg_dead_p (3, operands[0])
25318 && peep2_reg_dead_p (5, operands[5])
25319 && (<MODE>mode != QImode
25320 || immediate_operand (operands[2], SImode)
25321 || any_QIreg_operand (operands[2], SImode))
25322 && !reg_overlap_mentioned_p (operands[0], operands[1])
25323 && !reg_overlap_mentioned_p (operands[0], operands[2])
25324 && !reg_overlap_mentioned_p (operands[5], operands[1])
25325 && ix86_match_ccmode (peep2_next_insn (4),
25326 (GET_CODE (operands[3]) == PLUS
25327 || GET_CODE (operands[3]) == MINUS)
25328 ? CCGOCmode : CCNOmode)"
25329 [(parallel [(set (match_dup 6) (match_dup 8))
25330 (set (match_dup 1) (match_dup 7))])]
25332 operands[6] = SET_DEST (PATTERN (peep2_next_insn (4)));
25334 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
25335 copy_rtx (operands[1]),
25336 gen_lowpart (<MODE>mode, operands[2]));
25338 = gen_rtx_COMPARE (GET_MODE (operands[6]),
25339 copy_rtx (operands[7]),
25343 ;; Likewise for cmpelim optimized pattern.
25345 [(set (match_operand:SWI 0 "register_operand")
25346 (match_operand:SWI 1 "memory_operand"))
25347 (parallel [(set (reg FLAGS_REG)
25348 (compare (match_operator:SWI 3 "plusminuslogic_operator"
25350 (match_operand:SWI 2 "<nonmemory_operand>")])
25352 (set (match_dup 0) (match_dup 3))])
25353 (set (match_operand:SWI 4 "register_operand") (match_dup 0))
25354 (set (match_dup 1) (match_dup 4))]
25355 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25356 && peep2_reg_dead_p (3, operands[0])
25357 && peep2_reg_dead_p (4, operands[4])
25358 && !reg_overlap_mentioned_p (operands[0], operands[1])
25359 && !reg_overlap_mentioned_p (operands[0], operands[2])
25360 && !reg_overlap_mentioned_p (operands[4], operands[1])
25361 && ix86_match_ccmode (peep2_next_insn (1),
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 (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
25370 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
25371 copy_rtx (operands[1]), operands[2]);
25373 = gen_rtx_COMPARE (GET_MODE (operands[5]), copy_rtx (operands[6]),
25377 ;; Special cases for xor, where (x ^= y) != 0 is (misoptimized)
25378 ;; into x = z; x ^= y; x != z
25380 [(set (match_operand:SWI 0 "register_operand")
25381 (match_operand:SWI 1 "memory_operand"))
25382 (set (match_operand:SWI 3 "register_operand") (match_dup 0))
25383 (parallel [(set (match_operand:SWI 4 "register_operand")
25384 (xor:SWI (match_dup 4)
25385 (match_operand:SWI 2 "<nonmemory_operand>")))
25386 (clobber (reg:CC FLAGS_REG))])
25387 (set (match_dup 1) (match_dup 4))
25388 (set (reg:CCZ FLAGS_REG)
25389 (compare:CCZ (match_operand:SWI 5 "register_operand")
25390 (match_operand:SWI 6 "<nonmemory_operand>")))]
25391 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25392 && (REGNO (operands[4]) == REGNO (operands[0])
25393 || REGNO (operands[4]) == REGNO (operands[3]))
25394 && (rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
25395 ? 3 : 0], operands[5])
25396 ? rtx_equal_p (operands[2], operands[6])
25397 : rtx_equal_p (operands[2], operands[5])
25398 && rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
25399 ? 3 : 0], operands[6]))
25400 && peep2_reg_dead_p (4, operands[4])
25401 && peep2_reg_dead_p (5, operands[REGNO (operands[4]) == REGNO (operands[0])
25403 && !reg_overlap_mentioned_p (operands[0], operands[1])
25404 && !reg_overlap_mentioned_p (operands[0], operands[2])
25405 && !reg_overlap_mentioned_p (operands[3], operands[0])
25406 && !reg_overlap_mentioned_p (operands[3], operands[1])
25407 && !reg_overlap_mentioned_p (operands[3], operands[2])
25408 && (<MODE>mode != QImode
25409 || immediate_operand (operands[2], QImode)
25410 || any_QIreg_operand (operands[2], QImode))"
25411 [(parallel [(set (match_dup 7) (match_dup 9))
25412 (set (match_dup 1) (match_dup 8))])]
25414 operands[7] = SET_DEST (PATTERN (peep2_next_insn (4)));
25415 operands[8] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
25418 = gen_rtx_COMPARE (GET_MODE (operands[7]),
25419 copy_rtx (operands[8]),
25424 [(set (match_operand:SWI12 0 "register_operand")
25425 (match_operand:SWI12 1 "memory_operand"))
25426 (set (match_operand:SWI12 3 "register_operand") (match_dup 0))
25427 (parallel [(set (match_operand:SI 4 "register_operand")
25428 (xor:SI (match_dup 4)
25429 (match_operand:SI 2 "<nonmemory_operand>")))
25430 (clobber (reg:CC FLAGS_REG))])
25431 (set (match_dup 1) (match_operand:SWI12 5 "register_operand"))
25432 (set (reg:CCZ FLAGS_REG)
25433 (compare:CCZ (match_operand:SWI12 6 "register_operand")
25434 (match_operand:SWI12 7 "<nonmemory_operand>")))]
25435 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25436 && (REGNO (operands[5]) == REGNO (operands[0])
25437 || REGNO (operands[5]) == REGNO (operands[3]))
25438 && REGNO (operands[5]) == REGNO (operands[4])
25439 && (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
25440 ? 3 : 0], operands[6])
25441 ? (REG_P (operands[2])
25442 ? REG_P (operands[7]) && REGNO (operands[2]) == REGNO (operands[7])
25443 : rtx_equal_p (operands[2], operands[7]))
25444 : (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
25445 ? 3 : 0], operands[7])
25446 && REG_P (operands[2])
25447 && REGNO (operands[2]) == REGNO (operands[6])))
25448 && peep2_reg_dead_p (4, operands[5])
25449 && peep2_reg_dead_p (5, operands[REGNO (operands[5]) == REGNO (operands[0])
25451 && !reg_overlap_mentioned_p (operands[0], operands[1])
25452 && !reg_overlap_mentioned_p (operands[0], operands[2])
25453 && !reg_overlap_mentioned_p (operands[3], operands[0])
25454 && !reg_overlap_mentioned_p (operands[3], operands[1])
25455 && !reg_overlap_mentioned_p (operands[3], operands[2])
25456 && (<MODE>mode != QImode
25457 || immediate_operand (operands[2], SImode)
25458 || any_QIreg_operand (operands[2], SImode))"
25459 [(parallel [(set (match_dup 8) (match_dup 10))
25460 (set (match_dup 1) (match_dup 9))])]
25462 operands[8] = SET_DEST (PATTERN (peep2_next_insn (4)));
25463 operands[9] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
25464 gen_lowpart (<MODE>mode, operands[2]));
25466 = gen_rtx_COMPARE (GET_MODE (operands[8]),
25467 copy_rtx (operands[9]),
25471 ;; Attempt to optimize away memory stores of values the memory already
25472 ;; has. See PR79593.
25474 [(set (match_operand 0 "register_operand")
25475 (match_operand 1 "memory_operand"))
25476 (set (match_operand 2 "memory_operand") (match_dup 0))]
25477 "!MEM_VOLATILE_P (operands[1])
25478 && !MEM_VOLATILE_P (operands[2])
25479 && rtx_equal_p (operands[1], operands[2])
25480 && !reg_overlap_mentioned_p (operands[0], operands[2])"
25481 [(set (match_dup 0) (match_dup 1))])
25483 ;; Attempt to always use XOR for zeroing registers (including FP modes).
25485 [(set (match_operand 0 "general_reg_operand")
25486 (match_operand 1 "const0_operand"))]
25487 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
25488 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
25489 && peep2_regno_dead_p (0, FLAGS_REG)"
25490 [(parallel [(set (match_dup 0) (const_int 0))
25491 (clobber (reg:CC FLAGS_REG))])]
25492 "operands[0] = gen_lowpart (word_mode, operands[0]);")
25495 [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
25497 "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
25498 && peep2_regno_dead_p (0, FLAGS_REG)"
25499 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
25500 (clobber (reg:CC FLAGS_REG))])])
25502 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
25504 [(set (match_operand:SWI248 0 "general_reg_operand")
25506 "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
25507 && peep2_regno_dead_p (0, FLAGS_REG)"
25508 [(parallel [(set (match_dup 0) (const_int -1))
25509 (clobber (reg:CC FLAGS_REG))])]
25511 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
25512 operands[0] = gen_lowpart (SImode, operands[0]);
25515 ;; Attempt to convert simple lea to add/shift.
25516 ;; These can be created by move expanders.
25517 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
25518 ;; relevant lea instructions were already split.
25521 [(set (match_operand:SWI48 0 "register_operand")
25522 (plus:SWI48 (match_dup 0)
25523 (match_operand:SWI48 1 "<nonmemory_operand>")))]
25525 && peep2_regno_dead_p (0, FLAGS_REG)"
25526 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
25527 (clobber (reg:CC FLAGS_REG))])])
25530 [(set (match_operand:SWI48 0 "register_operand")
25531 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
25534 && peep2_regno_dead_p (0, FLAGS_REG)"
25535 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
25536 (clobber (reg:CC FLAGS_REG))])])
25539 [(set (match_operand:DI 0 "register_operand")
25541 (plus:SI (match_operand:SI 1 "register_operand")
25542 (match_operand:SI 2 "nonmemory_operand"))))]
25543 "TARGET_64BIT && !TARGET_OPT_AGU
25544 && REGNO (operands[0]) == REGNO (operands[1])
25545 && peep2_regno_dead_p (0, FLAGS_REG)"
25546 [(parallel [(set (match_dup 0)
25547 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
25548 (clobber (reg:CC FLAGS_REG))])])
25551 [(set (match_operand:DI 0 "register_operand")
25553 (plus:SI (match_operand:SI 1 "nonmemory_operand")
25554 (match_operand:SI 2 "register_operand"))))]
25555 "TARGET_64BIT && !TARGET_OPT_AGU
25556 && REGNO (operands[0]) == REGNO (operands[2])
25557 && peep2_regno_dead_p (0, FLAGS_REG)"
25558 [(parallel [(set (match_dup 0)
25559 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
25560 (clobber (reg:CC FLAGS_REG))])])
25563 [(set (match_operand:SWI48 0 "register_operand")
25564 (mult:SWI48 (match_dup 0)
25565 (match_operand:SWI48 1 "const_int_operand")))]
25566 "pow2p_hwi (INTVAL (operands[1]))
25567 && peep2_regno_dead_p (0, FLAGS_REG)"
25568 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
25569 (clobber (reg:CC FLAGS_REG))])]
25570 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
25573 [(set (match_operand:DI 0 "register_operand")
25575 (mult:SI (match_operand:SI 1 "register_operand")
25576 (match_operand:SI 2 "const_int_operand"))))]
25578 && pow2p_hwi (INTVAL (operands[2]))
25579 && REGNO (operands[0]) == REGNO (operands[1])
25580 && peep2_regno_dead_p (0, FLAGS_REG)"
25581 [(parallel [(set (match_dup 0)
25582 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
25583 (clobber (reg:CC FLAGS_REG))])]
25584 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
25586 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
25587 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
25588 ;; On many CPUs it is also faster, since special hardware to avoid esp
25589 ;; dependencies is present.
25591 ;; While some of these conversions may be done using splitters, we use
25592 ;; peepholes in order to allow combine_stack_adjustments pass to see
25593 ;; nonobfuscated RTL.
25595 ;; Convert prologue esp subtractions to push.
25596 ;; We need register to push. In order to keep verify_flow_info happy we have
25598 ;; - use scratch and clobber it in order to avoid dependencies
25599 ;; - use already live register
25600 ;; We can't use the second way right now, since there is no reliable way how to
25601 ;; verify that given register is live. First choice will also most likely in
25602 ;; fewer dependencies. On the place of esp adjustments it is very likely that
25603 ;; call clobbered registers are dead. We may want to use base pointer as an
25604 ;; alternative when no register is available later.
25607 [(match_scratch:W 1 "r")
25608 (parallel [(set (reg:P SP_REG)
25609 (plus:P (reg:P SP_REG)
25610 (match_operand:P 0 "const_int_operand")))
25611 (clobber (reg:CC FLAGS_REG))
25612 (clobber (mem:BLK (scratch)))])]
25613 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
25614 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
25615 && !ix86_red_zone_used"
25616 [(clobber (match_dup 1))
25617 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
25618 (clobber (mem:BLK (scratch)))])])
25621 [(match_scratch:W 1 "r")
25622 (parallel [(set (reg:P SP_REG)
25623 (plus:P (reg:P SP_REG)
25624 (match_operand:P 0 "const_int_operand")))
25625 (clobber (reg:CC FLAGS_REG))
25626 (clobber (mem:BLK (scratch)))])]
25627 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
25628 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
25629 && !ix86_red_zone_used"
25630 [(clobber (match_dup 1))
25631 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
25632 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
25633 (clobber (mem:BLK (scratch)))])])
25635 ;; Convert esp subtractions to push.
25637 [(match_scratch:W 1 "r")
25638 (parallel [(set (reg:P SP_REG)
25639 (plus:P (reg:P SP_REG)
25640 (match_operand:P 0 "const_int_operand")))
25641 (clobber (reg:CC FLAGS_REG))])]
25642 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
25643 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
25644 && !ix86_red_zone_used"
25645 [(clobber (match_dup 1))
25646 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
25649 [(match_scratch:W 1 "r")
25650 (parallel [(set (reg:P SP_REG)
25651 (plus:P (reg:P SP_REG)
25652 (match_operand:P 0 "const_int_operand")))
25653 (clobber (reg:CC FLAGS_REG))])]
25654 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
25655 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
25656 && !ix86_red_zone_used"
25657 [(clobber (match_dup 1))
25658 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
25659 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
25661 ;; Convert epilogue deallocator to pop.
25663 [(match_scratch:W 1 "r")
25664 (parallel [(set (reg:P SP_REG)
25665 (plus:P (reg:P SP_REG)
25666 (match_operand:P 0 "const_int_operand")))
25667 (clobber (reg:CC FLAGS_REG))
25668 (clobber (mem:BLK (scratch)))])]
25669 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
25670 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
25671 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25672 (clobber (mem:BLK (scratch)))])])
25674 ;; Two pops case is tricky, since pop causes dependency
25675 ;; on destination register. We use two registers if available.
25677 [(match_scratch:W 1 "r")
25678 (match_scratch:W 2 "r")
25679 (parallel [(set (reg:P SP_REG)
25680 (plus:P (reg:P SP_REG)
25681 (match_operand:P 0 "const_int_operand")))
25682 (clobber (reg:CC FLAGS_REG))
25683 (clobber (mem:BLK (scratch)))])]
25684 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
25685 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
25686 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25687 (clobber (mem:BLK (scratch)))])
25688 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
25691 [(match_scratch:W 1 "r")
25692 (parallel [(set (reg:P SP_REG)
25693 (plus:P (reg:P SP_REG)
25694 (match_operand:P 0 "const_int_operand")))
25695 (clobber (reg:CC FLAGS_REG))
25696 (clobber (mem:BLK (scratch)))])]
25697 "optimize_insn_for_size_p ()
25698 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
25699 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25700 (clobber (mem:BLK (scratch)))])
25701 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
25703 ;; Convert esp additions to pop.
25705 [(match_scratch:W 1 "r")
25706 (parallel [(set (reg:P SP_REG)
25707 (plus:P (reg:P SP_REG)
25708 (match_operand:P 0 "const_int_operand")))
25709 (clobber (reg:CC FLAGS_REG))])]
25710 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
25711 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
25713 ;; Two pops case is tricky, since pop causes dependency
25714 ;; on destination register. We use two registers if available.
25716 [(match_scratch:W 1 "r")
25717 (match_scratch:W 2 "r")
25718 (parallel [(set (reg:P SP_REG)
25719 (plus:P (reg:P SP_REG)
25720 (match_operand:P 0 "const_int_operand")))
25721 (clobber (reg:CC FLAGS_REG))])]
25722 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
25723 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25724 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
25727 [(match_scratch:W 1 "r")
25728 (parallel [(set (reg:P SP_REG)
25729 (plus:P (reg:P SP_REG)
25730 (match_operand:P 0 "const_int_operand")))
25731 (clobber (reg:CC FLAGS_REG))])]
25732 "optimize_insn_for_size_p ()
25733 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
25734 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25735 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
25737 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
25738 ;; required and register dies. Similarly for 128 to -128.
25740 [(set (match_operand 0 "flags_reg_operand")
25741 (match_operator 1 "compare_operator"
25742 [(match_operand 2 "register_operand")
25743 (match_operand 3 "const_int_operand")]))]
25744 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
25745 && incdec_operand (operands[3], GET_MODE (operands[3])))
25746 || (!TARGET_FUSE_CMP_AND_BRANCH
25747 && INTVAL (operands[3]) == 128))
25748 && ix86_match_ccmode (insn, CCGCmode)
25749 && peep2_reg_dead_p (1, operands[2])"
25750 [(parallel [(set (match_dup 0)
25751 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
25752 (clobber (match_dup 2))])])
25754 ;; Convert imul by three, five and nine into lea
25757 [(set (match_operand:SWI48 0 "register_operand")
25758 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
25759 (match_operand:SWI48 2 "const359_operand")))
25760 (clobber (reg:CC FLAGS_REG))])]
25761 "!TARGET_PARTIAL_REG_STALL
25762 || <MODE>mode == SImode
25763 || optimize_function_for_size_p (cfun)"
25764 [(set (match_dup 0)
25765 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
25767 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
25771 [(set (match_operand:SWI48 0 "register_operand")
25772 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
25773 (match_operand:SWI48 2 "const359_operand")))
25774 (clobber (reg:CC FLAGS_REG))])]
25775 "optimize_insn_for_speed_p ()
25776 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
25777 [(set (match_dup 0) (match_dup 1))
25779 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
25781 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
25783 ;; imul $32bit_imm, mem, reg is vector decoded, while
25784 ;; imul $32bit_imm, reg, reg is direct decoded.
25786 [(match_scratch:SWI48 3 "r")
25787 (parallel [(set (match_operand:SWI48 0 "register_operand")
25788 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
25789 (match_operand:SWI48 2 "immediate_operand")))
25790 (clobber (reg:CC FLAGS_REG))])]
25791 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
25792 && !satisfies_constraint_K (operands[2])"
25793 [(set (match_dup 3) (match_dup 1))
25794 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
25795 (clobber (reg:CC FLAGS_REG))])])
25798 [(match_scratch:SI 3 "r")
25799 (parallel [(set (match_operand:DI 0 "register_operand")
25801 (mult:SI (match_operand:SI 1 "memory_operand")
25802 (match_operand:SI 2 "immediate_operand"))))
25803 (clobber (reg:CC FLAGS_REG))])]
25805 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
25806 && !satisfies_constraint_K (operands[2])"
25807 [(set (match_dup 3) (match_dup 1))
25808 (parallel [(set (match_dup 0)
25809 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
25810 (clobber (reg:CC FLAGS_REG))])])
25812 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
25813 ;; Convert it into imul reg, reg
25814 ;; It would be better to force assembler to encode instruction using long
25815 ;; immediate, but there is apparently no way to do so.
25817 [(parallel [(set (match_operand:SWI248 0 "register_operand")
25819 (match_operand:SWI248 1 "nonimmediate_operand")
25820 (match_operand:SWI248 2 "const_int_operand")))
25821 (clobber (reg:CC FLAGS_REG))])
25822 (match_scratch:SWI248 3 "r")]
25823 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
25824 && satisfies_constraint_K (operands[2])"
25825 [(set (match_dup 3) (match_dup 2))
25826 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
25827 (clobber (reg:CC FLAGS_REG))])]
25829 if (!rtx_equal_p (operands[0], operands[1]))
25830 emit_move_insn (operands[0], operands[1]);
25833 ;; After splitting up read-modify operations, array accesses with memory
25834 ;; operands might end up in form:
25836 ;; movl 4(%esp), %edx
25838 ;; instead of pre-splitting:
25840 ;; addl 4(%esp), %eax
25842 ;; movl 4(%esp), %edx
25843 ;; leal (%edx,%eax,4), %eax
25846 [(match_scratch:W 5 "r")
25847 (parallel [(set (match_operand 0 "register_operand")
25848 (ashift (match_operand 1 "register_operand")
25849 (match_operand 2 "const_int_operand")))
25850 (clobber (reg:CC FLAGS_REG))])
25851 (parallel [(set (match_operand 3 "register_operand")
25852 (plus (match_dup 0)
25853 (match_operand 4 "x86_64_general_operand")))
25854 (clobber (reg:CC FLAGS_REG))])]
25855 "IN_RANGE (INTVAL (operands[2]), 1, 3)
25856 /* Validate MODE for lea. */
25857 && ((!TARGET_PARTIAL_REG_STALL
25858 && (GET_MODE (operands[0]) == QImode
25859 || GET_MODE (operands[0]) == HImode))
25860 || GET_MODE (operands[0]) == SImode
25861 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
25862 && (rtx_equal_p (operands[0], operands[3])
25863 || peep2_reg_dead_p (2, operands[0]))
25864 /* We reorder load and the shift. */
25865 && !reg_overlap_mentioned_p (operands[0], operands[4])"
25866 [(set (match_dup 5) (match_dup 4))
25867 (set (match_dup 0) (match_dup 1))]
25869 machine_mode op1mode = GET_MODE (operands[1]);
25870 machine_mode mode = op1mode == DImode ? DImode : SImode;
25871 int scale = 1 << INTVAL (operands[2]);
25872 rtx index = gen_lowpart (word_mode, operands[1]);
25873 rtx base = gen_lowpart (word_mode, operands[5]);
25874 rtx dest = gen_lowpart (mode, operands[3]);
25876 operands[1] = gen_rtx_PLUS (word_mode, base,
25877 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
25878 if (mode != word_mode)
25879 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
25881 operands[5] = base;
25882 if (op1mode != word_mode)
25883 operands[5] = gen_lowpart (op1mode, operands[5]);
25885 operands[0] = dest;
25888 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
25889 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
25890 ;; caught for use by garbage collectors and the like. Using an insn that
25891 ;; maps to SIGILL makes it more likely the program will rightfully die.
25892 ;; Keeping with tradition, "6" is in honor of #UD.
25893 (define_insn "trap"
25894 [(trap_if (const_int 1) (const_int 6))]
25897 #ifdef HAVE_AS_IX86_UD2
25900 return ASM_SHORT "0x0b0f";
25903 [(set_attr "length" "2")])
25906 [(unspec_volatile [(const_int 0)] UNSPECV_UD2)]
25909 #ifdef HAVE_AS_IX86_UD2
25912 return ASM_SHORT "0x0b0f";
25915 [(set_attr "length" "2")])
25917 (define_expand "prefetch"
25918 [(prefetch (match_operand 0 "address_operand")
25919 (match_operand:SI 1 "const_int_operand")
25920 (match_operand:SI 2 "const_int_operand"))]
25921 "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
25923 bool write = operands[1] != const0_rtx;
25924 int locality = INTVAL (operands[2]);
25926 gcc_assert (IN_RANGE (locality, 0, 3));
25928 /* Use 3dNOW prefetch in case we are asking for write prefetch not
25929 supported by SSE counterpart (non-SSE2 athlon machines) or the
25930 SSE prefetch is not available (K6 machines). Otherwise use SSE
25931 prefetch as it allows specifying of locality. */
25935 if (TARGET_PREFETCHWT1)
25936 operands[2] = GEN_INT (MAX (locality, 2));
25937 else if (TARGET_PRFCHW)
25938 operands[2] = GEN_INT (3);
25939 else if (TARGET_3DNOW && !TARGET_SSE2)
25940 operands[2] = GEN_INT (3);
25941 else if (TARGET_PREFETCH_SSE)
25942 operands[1] = const0_rtx;
25945 gcc_assert (TARGET_3DNOW);
25946 operands[2] = GEN_INT (3);
25951 if (TARGET_PREFETCH_SSE)
25955 gcc_assert (TARGET_3DNOW);
25956 operands[2] = GEN_INT (3);
25961 (define_insn "*prefetch_sse"
25962 [(prefetch (match_operand 0 "address_operand" "p")
25964 (match_operand:SI 1 "const_int_operand"))]
25965 "TARGET_PREFETCH_SSE"
25967 static const char * const patterns[4] = {
25968 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
25971 int locality = INTVAL (operands[1]);
25972 gcc_assert (IN_RANGE (locality, 0, 3));
25974 return patterns[locality];
25976 [(set_attr "type" "sse")
25977 (set_attr "atom_sse_attr" "prefetch")
25978 (set (attr "length_address")
25979 (symbol_ref "memory_address_length (operands[0], false)"))
25980 (set_attr "memory" "none")])
25982 (define_insn "*prefetch_3dnow"
25983 [(prefetch (match_operand 0 "address_operand" "p")
25984 (match_operand:SI 1 "const_int_operand")
25986 "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1"
25988 if (operands[1] == const0_rtx)
25989 return "prefetch\t%a0";
25991 return "prefetchw\t%a0";
25993 [(set_attr "type" "mmx")
25994 (set (attr "length_address")
25995 (symbol_ref "memory_address_length (operands[0], false)"))
25996 (set_attr "memory" "none")])
25998 (define_insn "*prefetch_prefetchwt1"
25999 [(prefetch (match_operand 0 "address_operand" "p")
26002 "TARGET_PREFETCHWT1"
26003 "prefetchwt1\t%a0";
26004 [(set_attr "type" "sse")
26005 (set (attr "length_address")
26006 (symbol_ref "memory_address_length (operands[0], false)"))
26007 (set_attr "memory" "none")])
26009 (define_insn "prefetchi"
26010 [(unspec_volatile [(match_operand 0 "local_func_symbolic_operand" "p")
26011 (match_operand:SI 1 "const_int_operand")]
26012 UNSPECV_PREFETCHI)]
26013 "TARGET_PREFETCHI && TARGET_64BIT"
26015 static const char * const patterns[2] = {
26016 "prefetchit1\t%0", "prefetchit0\t%0"
26019 int locality = INTVAL (operands[1]);
26020 gcc_assert (IN_RANGE (locality, 2, 3));
26022 return patterns[locality - 2];
26024 [(set_attr "type" "sse")
26025 (set (attr "length_address")
26026 (symbol_ref "memory_address_length (operands[0], false)"))
26027 (set_attr "memory" "none")])
26029 (define_insn "sse4_2_crc32<mode>"
26030 [(set (match_operand:SI 0 "register_operand" "=r")
26032 [(match_operand:SI 1 "register_operand" "0")
26033 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
26036 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
26037 [(set_attr "type" "sselog1")
26038 (set_attr "prefix_rep" "1")
26039 (set_attr "prefix_extra" "1")
26040 (set (attr "prefix_data16")
26041 (if_then_else (match_operand:HI 2)
26043 (const_string "*")))
26044 (set (attr "prefix_rex")
26045 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
26047 (const_string "*")))
26048 (set_attr "mode" "SI")])
26050 (define_insn "sse4_2_crc32di"
26051 [(set (match_operand:DI 0 "register_operand" "=r")
26054 [(match_operand:SI 1 "register_operand" "0")
26055 (match_operand:DI 2 "nonimmediate_operand" "rm")]
26057 "TARGET_64BIT && TARGET_CRC32"
26058 "crc32{q}\t{%2, %0|%0, %2}"
26059 [(set_attr "type" "sselog1")
26060 (set_attr "prefix_rep" "1")
26061 (set_attr "prefix_extra" "1")
26062 (set_attr "mode" "DI")])
26064 (define_insn "rdpmc"
26065 [(set (match_operand:DI 0 "register_operand" "=A")
26066 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
26070 [(set_attr "type" "other")
26071 (set_attr "length" "2")])
26073 (define_insn "rdpmc_rex64"
26074 [(set (match_operand:DI 0 "register_operand" "=a")
26075 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
26077 (set (match_operand:DI 1 "register_operand" "=d")
26078 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
26081 [(set_attr "type" "other")
26082 (set_attr "length" "2")])
26084 (define_insn "rdtsc"
26085 [(set (match_operand:DI 0 "register_operand" "=A")
26086 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
26089 [(set_attr "type" "other")
26090 (set_attr "length" "2")])
26092 (define_insn "rdtsc_rex64"
26093 [(set (match_operand:DI 0 "register_operand" "=a")
26094 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
26095 (set (match_operand:DI 1 "register_operand" "=d")
26096 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
26099 [(set_attr "type" "other")
26100 (set_attr "length" "2")])
26102 (define_insn "rdtscp"
26103 [(set (match_operand:DI 0 "register_operand" "=A")
26104 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
26105 (set (match_operand:SI 1 "register_operand" "=c")
26106 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
26109 [(set_attr "type" "other")
26110 (set_attr "length" "3")])
26112 (define_insn "rdtscp_rex64"
26113 [(set (match_operand:DI 0 "register_operand" "=a")
26114 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
26115 (set (match_operand:DI 1 "register_operand" "=d")
26116 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
26117 (set (match_operand:SI 2 "register_operand" "=c")
26118 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
26121 [(set_attr "type" "other")
26122 (set_attr "length" "3")])
26124 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26126 ;; FXSR, XSAVE and XSAVEOPT instructions
26128 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26130 (define_insn "fxsave"
26131 [(set (match_operand:BLK 0 "memory_operand" "=m")
26132 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
26135 [(set_attr "type" "other")
26136 (set_attr "memory" "store")
26137 (set (attr "length")
26138 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
26140 (define_insn "fxsave64"
26141 [(set (match_operand:BLK 0 "memory_operand" "=jm")
26142 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
26143 "TARGET_64BIT && TARGET_FXSR"
26145 [(set_attr "type" "other")
26146 (set_attr "addr" "gpr16")
26147 (set_attr "memory" "store")
26148 (set (attr "length")
26149 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
26151 (define_insn "fxrstor"
26152 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
26156 [(set_attr "type" "other")
26157 (set_attr "memory" "load")
26158 (set (attr "length")
26159 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
26161 (define_insn "fxrstor64"
26162 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "jm")]
26163 UNSPECV_FXRSTOR64)]
26164 "TARGET_64BIT && TARGET_FXSR"
26166 [(set_attr "type" "other")
26167 (set_attr "addr" "gpr16")
26168 (set_attr "memory" "load")
26169 (set (attr "length")
26170 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
26172 (define_int_iterator ANY_XSAVE
26174 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
26175 (UNSPECV_XSAVEC "TARGET_XSAVEC")
26176 (UNSPECV_XSAVES "TARGET_XSAVES")])
26178 (define_int_iterator ANY_XSAVE64
26180 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
26181 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
26182 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
26184 (define_int_attr xsave
26185 [(UNSPECV_XSAVE "xsave")
26186 (UNSPECV_XSAVE64 "xsave64")
26187 (UNSPECV_XSAVEOPT "xsaveopt")
26188 (UNSPECV_XSAVEOPT64 "xsaveopt64")
26189 (UNSPECV_XSAVEC "xsavec")
26190 (UNSPECV_XSAVEC64 "xsavec64")
26191 (UNSPECV_XSAVES "xsaves")
26192 (UNSPECV_XSAVES64 "xsaves64")])
26194 (define_int_iterator ANY_XRSTOR
26196 (UNSPECV_XRSTORS "TARGET_XSAVES")])
26198 (define_int_iterator ANY_XRSTOR64
26200 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
26202 (define_int_attr xrstor
26203 [(UNSPECV_XRSTOR "xrstor")
26204 (UNSPECV_XRSTOR64 "xrstor")
26205 (UNSPECV_XRSTORS "xrstors")
26206 (UNSPECV_XRSTORS64 "xrstors")])
26208 (define_insn "<xsave>"
26209 [(set (match_operand:BLK 0 "memory_operand" "=m")
26210 (unspec_volatile:BLK
26211 [(match_operand:DI 1 "register_operand" "A")]
26213 "!TARGET_64BIT && TARGET_XSAVE"
26215 [(set_attr "type" "other")
26216 (set_attr "memory" "store")
26217 (set (attr "length")
26218 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
26220 (define_insn "<xsave>_rex64"
26221 [(set (match_operand:BLK 0 "memory_operand" "=jm")
26222 (unspec_volatile:BLK
26223 [(match_operand:SI 1 "register_operand" "a")
26224 (match_operand:SI 2 "register_operand" "d")]
26226 "TARGET_64BIT && TARGET_XSAVE"
26228 [(set_attr "type" "other")
26229 (set_attr "memory" "store")
26230 (set_attr "addr" "gpr16")
26231 (set (attr "length")
26232 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
26234 (define_insn "<xsave>"
26235 [(set (match_operand:BLK 0 "memory_operand" "=jm")
26236 (unspec_volatile:BLK
26237 [(match_operand:SI 1 "register_operand" "a")
26238 (match_operand:SI 2 "register_operand" "d")]
26240 "TARGET_64BIT && TARGET_XSAVE"
26242 [(set_attr "type" "other")
26243 (set_attr "memory" "store")
26244 (set_attr "addr" "gpr16")
26245 (set (attr "length")
26246 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
26248 (define_insn "<xrstor>"
26249 [(unspec_volatile:BLK
26250 [(match_operand:BLK 0 "memory_operand" "m")
26251 (match_operand:DI 1 "register_operand" "A")]
26253 "!TARGET_64BIT && TARGET_XSAVE"
26255 [(set_attr "type" "other")
26256 (set_attr "memory" "load")
26257 (set (attr "length")
26258 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
26260 (define_insn "<xrstor>_rex64"
26261 [(unspec_volatile:BLK
26262 [(match_operand:BLK 0 "memory_operand" "jm")
26263 (match_operand:SI 1 "register_operand" "a")
26264 (match_operand:SI 2 "register_operand" "d")]
26266 "TARGET_64BIT && TARGET_XSAVE"
26268 [(set_attr "type" "other")
26269 (set_attr "memory" "load")
26270 (set_attr "addr" "gpr16")
26271 (set (attr "length")
26272 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
26274 (define_insn "<xrstor>64"
26275 [(unspec_volatile:BLK
26276 [(match_operand:BLK 0 "memory_operand" "jm")
26277 (match_operand:SI 1 "register_operand" "a")
26278 (match_operand:SI 2 "register_operand" "d")]
26280 "TARGET_64BIT && TARGET_XSAVE"
26282 [(set_attr "type" "other")
26283 (set_attr "memory" "load")
26284 (set_attr "addr" "gpr16")
26285 (set (attr "length")
26286 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
26288 (define_insn "xsetbv"
26289 [(unspec_volatile:SI
26290 [(match_operand:SI 0 "register_operand" "c")
26291 (match_operand:DI 1 "register_operand" "A")]
26293 "!TARGET_64BIT && TARGET_XSAVE"
26295 [(set_attr "type" "other")])
26297 (define_insn "xsetbv_rex64"
26298 [(unspec_volatile:SI
26299 [(match_operand:SI 0 "register_operand" "c")
26300 (match_operand:SI 1 "register_operand" "a")
26301 (match_operand:SI 2 "register_operand" "d")]
26303 "TARGET_64BIT && TARGET_XSAVE"
26305 [(set_attr "type" "other")])
26307 (define_insn "xgetbv"
26308 [(set (match_operand:DI 0 "register_operand" "=A")
26309 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
26311 "!TARGET_64BIT && TARGET_XSAVE"
26313 [(set_attr "type" "other")])
26315 (define_insn "xgetbv_rex64"
26316 [(set (match_operand:DI 0 "register_operand" "=a")
26317 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
26319 (set (match_operand:DI 1 "register_operand" "=d")
26320 (unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))]
26321 "TARGET_64BIT && TARGET_XSAVE"
26323 [(set_attr "type" "other")])
26325 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26327 ;; Floating-point instructions for atomic compound assignments
26329 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26331 ; Clobber all floating-point registers on environment save and restore
26332 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
26333 (define_insn "fnstenv"
26334 [(set (match_operand:BLK 0 "memory_operand" "=m")
26335 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
26336 (clobber (reg:XF ST0_REG))
26337 (clobber (reg:XF ST1_REG))
26338 (clobber (reg:XF ST2_REG))
26339 (clobber (reg:XF ST3_REG))
26340 (clobber (reg:XF ST4_REG))
26341 (clobber (reg:XF ST5_REG))
26342 (clobber (reg:XF ST6_REG))
26343 (clobber (reg:XF ST7_REG))]
26346 [(set_attr "type" "other")
26347 (set_attr "memory" "store")
26348 (set (attr "length")
26349 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
26351 (define_insn "fldenv"
26352 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
26354 (clobber (reg:XF ST0_REG))
26355 (clobber (reg:XF ST1_REG))
26356 (clobber (reg:XF ST2_REG))
26357 (clobber (reg:XF ST3_REG))
26358 (clobber (reg:XF ST4_REG))
26359 (clobber (reg:XF ST5_REG))
26360 (clobber (reg:XF ST6_REG))
26361 (clobber (reg:XF ST7_REG))]
26364 [(set_attr "type" "other")
26365 (set_attr "memory" "load")
26366 (set (attr "length")
26367 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
26369 (define_insn "fnstsw"
26370 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
26371 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
26374 [(set_attr "type" "other,other")
26375 (set_attr "memory" "none,store")
26376 (set (attr "length")
26377 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
26379 (define_insn "fnclex"
26380 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
26383 [(set_attr "type" "other")
26384 (set_attr "memory" "none")
26385 (set_attr "length" "2")])
26387 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26389 ;; LWP instructions
26391 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26393 (define_insn "@lwp_llwpcb<mode>"
26394 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
26395 UNSPECV_LLWP_INTRINSIC)]
26398 [(set_attr "type" "lwp")
26399 (set_attr "mode" "<MODE>")
26400 (set_attr "length" "5")])
26402 (define_insn "@lwp_slwpcb<mode>"
26403 [(set (match_operand:P 0 "register_operand" "=r")
26404 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
26407 [(set_attr "type" "lwp")
26408 (set_attr "mode" "<MODE>")
26409 (set_attr "length" "5")])
26411 (define_insn "@lwp_lwpval<mode>"
26412 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
26413 (match_operand:SI 1 "nonimmediate_operand" "rm")
26414 (match_operand:SI 2 "const_int_operand")]
26415 UNSPECV_LWPVAL_INTRINSIC)]
26417 "lwpval\t{%2, %1, %0|%0, %1, %2}"
26418 [(set_attr "type" "lwp")
26419 (set_attr "mode" "<MODE>")
26420 (set (attr "length")
26421 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
26423 (define_insn "@lwp_lwpins<mode>"
26424 [(set (reg:CCC FLAGS_REG)
26425 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
26426 (match_operand:SI 1 "nonimmediate_operand" "rm")
26427 (match_operand:SI 2 "const_int_operand")]
26428 UNSPECV_LWPINS_INTRINSIC))]
26430 "lwpins\t{%2, %1, %0|%0, %1, %2}"
26431 [(set_attr "type" "lwp")
26432 (set_attr "mode" "<MODE>")
26433 (set (attr "length")
26434 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
26436 (define_int_iterator RDFSGSBASE
26440 (define_int_iterator WRFSGSBASE
26444 (define_int_attr fsgs
26445 [(UNSPECV_RDFSBASE "fs")
26446 (UNSPECV_RDGSBASE "gs")
26447 (UNSPECV_WRFSBASE "fs")
26448 (UNSPECV_WRGSBASE "gs")])
26450 (define_insn "rd<fsgs>base<mode>"
26451 [(set (match_operand:SWI48 0 "register_operand" "=r")
26452 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
26453 "TARGET_64BIT && TARGET_FSGSBASE"
26455 [(set_attr "type" "other")
26456 (set_attr "prefix_0f" "1")
26457 (set_attr "prefix_rep" "1")])
26459 (define_insn "wr<fsgs>base<mode>"
26460 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
26462 "TARGET_64BIT && TARGET_FSGSBASE"
26464 [(set_attr "type" "other")
26465 (set_attr "prefix_0f" "1")
26466 (set_attr "prefix_rep" "1")])
26468 (define_insn "ptwrite<mode>"
26469 [(unspec_volatile [(match_operand:SWI48 0 "nonimmediate_operand" "rm")]
26473 [(set_attr "type" "other")
26474 (set_attr "prefix_0f" "1")
26475 (set_attr "prefix_rep" "1")])
26477 (define_insn "@rdrand<mode>"
26478 [(set (match_operand:SWI248 0 "register_operand" "=r")
26479 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
26480 (set (reg:CCC FLAGS_REG)
26481 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
26484 [(set_attr "type" "other")
26485 (set_attr "prefix_0f" "1")])
26487 (define_insn "@rdseed<mode>"
26488 [(set (match_operand:SWI248 0 "register_operand" "=r")
26489 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
26490 (set (reg:CCC FLAGS_REG)
26491 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
26494 [(set_attr "type" "other")
26495 (set_attr "prefix_0f" "1")])
26497 (define_expand "pause"
26498 [(set (match_dup 0)
26499 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
26502 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
26503 MEM_VOLATILE_P (operands[0]) = 1;
26506 ;; Use "rep; nop", instead of "pause", to support older assemblers.
26507 ;; They have the same encoding.
26508 (define_insn "*pause"
26509 [(set (match_operand:BLK 0)
26510 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
26513 [(set_attr "length" "2")
26514 (set_attr "memory" "unknown")])
26516 ;; CET instructions
26517 (define_insn "@rdssp<mode>"
26518 [(set (match_operand:SWI48 0 "register_operand" "=r")
26519 (unspec_volatile:SWI48 [(match_operand:SWI48 1 "register_operand" "0")]
26520 UNSPECV_NOP_RDSSP))]
26521 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
26522 "rdssp<mskmodesuffix>\t%0"
26523 [(set_attr "length" "6")
26524 (set_attr "type" "other")])
26526 (define_insn "@incssp<mode>"
26527 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
26529 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
26530 "incssp<mskmodesuffix>\t%0"
26531 [(set_attr "length" "4")
26532 (set_attr "type" "other")])
26534 (define_insn "saveprevssp"
26535 [(unspec_volatile [(const_int 0)] UNSPECV_SAVEPREVSSP)]
26538 [(set_attr "length" "5")
26539 (set_attr "type" "other")])
26541 (define_insn "rstorssp"
26542 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")]
26546 [(set_attr "length" "5")
26547 (set_attr "type" "other")])
26549 (define_insn "@wrss<mode>"
26550 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
26551 (match_operand:SWI48 1 "memory_operand" "m")]
26554 "wrss<mskmodesuffix>\t%0, %1"
26555 [(set_attr "length" "3")
26556 (set_attr "type" "other")])
26558 (define_insn "@wruss<mode>"
26559 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
26560 (match_operand:SWI48 1 "memory_operand" "m")]
26563 "wruss<mskmodesuffix>\t%0, %1"
26564 [(set_attr "length" "4")
26565 (set_attr "type" "other")])
26567 (define_insn "setssbsy"
26568 [(unspec_volatile [(const_int 0)] UNSPECV_SETSSBSY)]
26571 [(set_attr "length" "4")
26572 (set_attr "type" "other")])
26574 (define_insn "clrssbsy"
26575 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")]
26579 [(set_attr "length" "4")
26580 (set_attr "type" "other")])
26582 (define_insn "nop_endbr"
26583 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]
26584 "(flag_cf_protection & CF_BRANCH)"
26586 return TARGET_64BIT ? "endbr64" : "endbr32";
26588 [(set_attr "length" "4")
26589 (set_attr "length_immediate" "0")
26590 (set_attr "modrm" "0")])
26593 (define_expand "xbegin"
26594 [(set (match_operand:SI 0 "register_operand")
26595 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
26598 rtx_code_label *label = gen_label_rtx ();
26600 /* xbegin is emitted as jump_insn, so reload won't be able
26601 to reload its operand. Force the value into AX hard register. */
26602 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
26603 emit_move_insn (ax_reg, constm1_rtx);
26605 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
26607 emit_label (label);
26608 LABEL_NUSES (label) = 1;
26610 emit_move_insn (operands[0], ax_reg);
26615 (define_insn "xbegin_1"
26617 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
26619 (label_ref (match_operand 1))
26621 (set (match_operand:SI 0 "register_operand" "+a")
26622 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
26625 [(set_attr "type" "other")
26626 (set_attr "length" "6")])
26628 (define_insn "xend"
26629 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
26632 [(set_attr "type" "other")
26633 (set_attr "length" "3")])
26635 (define_insn "xabort"
26636 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand")]
26640 [(set_attr "type" "other")
26641 (set_attr "length" "3")])
26643 (define_expand "xtest"
26644 [(set (match_operand:QI 0 "register_operand")
26645 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
26648 emit_insn (gen_xtest_1 ());
26650 ix86_expand_setcc (operands[0], NE,
26651 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
26655 (define_insn "xtest_1"
26656 [(set (reg:CCZ FLAGS_REG)
26657 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
26660 [(set_attr "type" "other")
26661 (set_attr "length" "3")])
26663 (define_insn "clwb"
26664 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
26668 [(set_attr "type" "sse")
26669 (set_attr "atom_sse_attr" "fence")
26670 (set_attr "memory" "unknown")])
26672 (define_insn "clflushopt"
26673 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
26674 UNSPECV_CLFLUSHOPT)]
26675 "TARGET_CLFLUSHOPT"
26677 [(set_attr "type" "sse")
26678 (set_attr "atom_sse_attr" "fence")
26679 (set_attr "memory" "unknown")])
26681 ;; MONITORX and MWAITX
26682 (define_insn "mwaitx"
26683 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
26684 (match_operand:SI 1 "register_operand" "a")
26685 (match_operand:SI 2 "register_operand" "b")]
26688 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
26689 ;; Since 32bit register operands are implicitly zero extended to 64bit,
26690 ;; we only need to set up 32bit registers.
26692 [(set_attr "length" "3")])
26694 (define_insn "@monitorx_<mode>"
26695 [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
26696 (match_operand:SI 1 "register_operand" "c")
26697 (match_operand:SI 2 "register_operand" "d")]
26700 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
26701 ;; RCX and RDX are used. Since 32bit register operands are implicitly
26702 ;; zero extended to 64bit, we only need to set up 32bit registers.
26704 [(set (attr "length")
26705 (symbol_ref ("(Pmode != word_mode) + 3")))])
26708 (define_insn "@clzero_<mode>"
26709 [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
26713 [(set_attr "length" "3")
26714 (set_attr "memory" "unknown")])
26716 ;; RDPKRU and WRPKRU
26718 (define_expand "rdpkru"
26720 [(set (match_operand:SI 0 "register_operand")
26721 (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
26722 (set (match_dup 2) (const_int 0))])]
26725 operands[1] = force_reg (SImode, const0_rtx);
26726 operands[2] = gen_reg_rtx (SImode);
26729 (define_insn "*rdpkru"
26730 [(set (match_operand:SI 0 "register_operand" "=a")
26731 (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
26733 (set (match_operand:SI 1 "register_operand" "=d")
26737 [(set_attr "type" "other")])
26739 (define_expand "wrpkru"
26740 [(unspec_volatile:SI
26741 [(match_operand:SI 0 "register_operand")
26742 (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
26745 operands[1] = force_reg (SImode, const0_rtx);
26746 operands[2] = force_reg (SImode, const0_rtx);
26749 (define_insn "*wrpkru"
26750 [(unspec_volatile:SI
26751 [(match_operand:SI 0 "register_operand" "a")
26752 (match_operand:SI 1 "register_operand" "d")
26753 (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
26756 [(set_attr "type" "other")])
26758 (define_insn "rdpid"
26759 [(set (match_operand:SI 0 "register_operand" "=r")
26760 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDPID))]
26761 "!TARGET_64BIT && TARGET_RDPID"
26763 [(set_attr "type" "other")])
26765 (define_insn "rdpid_rex64"
26766 [(set (match_operand:DI 0 "register_operand" "=r")
26767 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPID))]
26768 "TARGET_64BIT && TARGET_RDPID"
26770 [(set_attr "type" "other")])
26772 ;; Intirinsics for > i486
26774 (define_insn "wbinvd"
26775 [(unspec_volatile [(const_int 0)] UNSPECV_WBINVD)]
26778 [(set_attr "type" "other")])
26780 (define_insn "wbnoinvd"
26781 [(unspec_volatile [(const_int 0)] UNSPECV_WBNOINVD)]
26784 [(set_attr "type" "other")])
26786 ;; MOVDIRI and MOVDIR64B
26788 (define_insn "movdiri<mode>"
26789 [(set (match_operand:SWI48 0 "memory_operand" "=m")
26790 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")]
26793 "movdiri\t{%1, %0|%0, %1}"
26794 [(set_attr "type" "other")])
26796 (define_insn "@movdir64b_<mode>"
26797 [(set (mem:XI (match_operand:P 0 "register_operand" "r"))
26798 (unspec:XI [(match_operand:XI 1 "memory_operand" "m")]
26799 UNSPEC_MOVDIR64B))]
26801 "movdir64b\t{%1, %0|%0, %1}"
26802 [(set_attr "type" "other")])
26805 (define_int_iterator TSXLDTRK [UNSPECV_XSUSLDTRK UNSPECV_XRESLDTRK])
26806 (define_int_attr tsxldtrk [(UNSPECV_XSUSLDTRK "xsusldtrk")
26807 (UNSPECV_XRESLDTRK "xresldtrk")])
26808 (define_insn "<tsxldtrk>"
26809 [(unspec_volatile [(const_int 0)] TSXLDTRK)]
26812 [(set_attr "type" "other")
26813 (set_attr "length" "4")])
26815 ;; ENQCMD and ENQCMDS
26817 (define_int_iterator ENQCMD [UNSPECV_ENQCMD UNSPECV_ENQCMDS])
26818 (define_int_attr enqcmd_sfx [(UNSPECV_ENQCMD "") (UNSPECV_ENQCMDS "s")])
26820 (define_insn "@enqcmd<enqcmd_sfx>_<mode>"
26821 [(set (reg:CCZ FLAGS_REG)
26822 (unspec_volatile:CCZ [(match_operand:P 0 "register_operand" "r")
26823 (match_operand:XI 1 "memory_operand" "m")]
26826 "enqcmd<enqcmd_sfx>\t{%1, %0|%0, %1}"
26827 [(set_attr "type" "other")])
26830 (define_int_iterator UINTR [UNSPECV_CLUI UNSPECV_STUI])
26831 (define_int_attr uintr [(UNSPECV_CLUI "clui") (UNSPECV_STUI "stui")])
26833 (define_insn "<uintr>"
26834 [(unspec_volatile [(const_int 0)] UINTR)]
26835 "TARGET_UINTR && TARGET_64BIT"
26837 [(set_attr "type" "other")
26838 (set_attr "length" "4")])
26840 (define_insn "testui"
26841 [(set (reg:CCC FLAGS_REG)
26842 (unspec_volatile:CCC [(const_int 0)] UNSPECV_TESTUI))]
26843 "TARGET_UINTR && TARGET_64BIT"
26845 [(set_attr "type" "other")
26846 (set_attr "length" "4")])
26848 (define_insn "senduipi"
26850 [(match_operand:DI 0 "register_operand" "r")]
26852 "TARGET_UINTR && TARGET_64BIT"
26854 [(set_attr "type" "other")
26855 (set_attr "length" "4")])
26859 (define_insn "umwait"
26860 [(set (reg:CCC FLAGS_REG)
26861 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26862 (match_operand:DI 1 "register_operand" "A")]
26864 "!TARGET_64BIT && TARGET_WAITPKG"
26866 [(set_attr "length" "3")])
26868 (define_insn "umwait_rex64"
26869 [(set (reg:CCC FLAGS_REG)
26870 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26871 (match_operand:SI 1 "register_operand" "a")
26872 (match_operand:SI 2 "register_operand" "d")]
26874 "TARGET_64BIT && TARGET_WAITPKG"
26876 [(set_attr "length" "3")])
26878 (define_insn "@umonitor_<mode>"
26879 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
26883 [(set (attr "length")
26884 (symbol_ref ("(Pmode != word_mode) + 3")))])
26886 (define_insn "tpause"
26887 [(set (reg:CCC FLAGS_REG)
26888 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26889 (match_operand:DI 1 "register_operand" "A")]
26891 "!TARGET_64BIT && TARGET_WAITPKG"
26893 [(set_attr "length" "3")])
26895 (define_insn "tpause_rex64"
26896 [(set (reg:CCC FLAGS_REG)
26897 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26898 (match_operand:SI 1 "register_operand" "a")
26899 (match_operand:SI 2 "register_operand" "d")]
26901 "TARGET_64BIT && TARGET_WAITPKG"
26903 [(set_attr "length" "3")])
26905 (define_insn "cldemote"
26906 [(unspec_volatile[(match_operand 0 "address_operand" "p")]
26910 [(set_attr "type" "other")
26911 (set_attr "memory" "unknown")])
26913 (define_insn "speculation_barrier"
26914 [(unspec_volatile [(const_int 0)] UNSPECV_SPECULATION_BARRIER)]
26917 [(set_attr "type" "other")
26918 (set_attr "length" "3")])
26920 (define_insn "serialize"
26921 [(unspec_volatile [(const_int 0)] UNSPECV_SERIALIZE)]
26924 [(set_attr "type" "other")
26925 (set_attr "length" "3")])
26927 (define_insn "patchable_area"
26928 [(unspec_volatile [(match_operand 0 "const_int_operand")
26929 (match_operand 1 "const_int_operand")]
26930 UNSPECV_PATCHABLE_AREA)]
26933 ix86_output_patchable_area (INTVAL (operands[0]),
26934 INTVAL (operands[1]) != 0);
26937 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
26938 (set_attr "length_immediate" "0")
26939 (set_attr "modrm" "0")])
26941 (define_insn "hreset"
26942 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")]
26946 [(set_attr "type" "other")
26947 (set_attr "length" "4")])
26949 ;; Spaceship optimization
26950 (define_expand "spaceship<mode>3"
26951 [(match_operand:SI 0 "register_operand")
26952 (match_operand:MODEF 1 "cmp_fp_expander_operand")
26953 (match_operand:MODEF 2 "cmp_fp_expander_operand")]
26954 "(TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
26955 && (TARGET_CMOVE || (TARGET_SAHF && TARGET_USE_SAHF))"
26957 ix86_expand_fp_spaceship (operands[0], operands[1], operands[2]);
26961 (define_expand "spaceshipxf3"
26962 [(match_operand:SI 0 "register_operand")
26963 (match_operand:XF 1 "nonmemory_operand")
26964 (match_operand:XF 2 "nonmemory_operand")]
26965 "TARGET_80387 && (TARGET_CMOVE || (TARGET_SAHF && TARGET_USE_SAHF))"
26967 ix86_expand_fp_spaceship (operands[0], operands[1], operands[2]);
26971 ;; Defined because the generic expand_builtin_issignaling for XFmode
26972 ;; only tests for sNaNs, but i387 treats also pseudo numbers as always
26974 (define_expand "issignalingxf2"
26975 [(match_operand:SI 0 "register_operand")
26976 (match_operand:XF 1 "general_operand")]
26979 rtx temp = operands[1];
26982 rtx mem = assign_stack_temp (XFmode, GET_MODE_SIZE (XFmode));
26983 emit_move_insn (mem, temp);
26986 rtx ex = adjust_address (temp, HImode, 8);
26987 rtx hi = adjust_address (temp, SImode, 4);
26988 rtx lo = adjust_address (temp, SImode, 0);
26989 rtx val = GEN_INT (HOST_WIDE_INT_M1U << 30);
26990 rtx mask = GEN_INT (0x7fff);
26991 rtx bit = GEN_INT (HOST_WIDE_INT_1U << 30);
26993 ((ex & mask) && (int) hi >= 0)
26994 || ((ex & mask) == mask && ((hi ^ bit) | ((lo | -lo) >> 31)) > val). */
26995 rtx nlo = expand_unop (SImode, neg_optab, lo, NULL_RTX, 0);
26996 lo = expand_binop (SImode, ior_optab, lo, nlo,
26997 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26998 lo = expand_shift (RSHIFT_EXPR, SImode, lo, 31, NULL_RTX, 1);
26999 temp = expand_binop (SImode, xor_optab, hi, bit,
27000 NULL_RTX, 1, OPTAB_LIB_WIDEN);
27001 temp = expand_binop (SImode, ior_optab, temp, lo,
27002 NULL_RTX, 1, OPTAB_LIB_WIDEN);
27003 temp = emit_store_flag_force (gen_reg_rtx (SImode), GTU, temp, val,
27005 ex = expand_binop (HImode, and_optab, ex, mask,
27006 NULL_RTX, 1, OPTAB_LIB_WIDEN);
27007 rtx temp2 = emit_store_flag_force (gen_reg_rtx (SImode), NE,
27008 ex, const0_rtx, SImode, 1, 1);
27009 ex = emit_store_flag_force (gen_reg_rtx (SImode), EQ,
27010 ex, mask, HImode, 1, 1);
27011 temp = expand_binop (SImode, and_optab, temp, ex,
27012 NULL_RTX, 1, OPTAB_LIB_WIDEN);
27013 rtx temp3 = emit_store_flag_force (gen_reg_rtx (SImode), GE,
27014 hi, const0_rtx, SImode, 0, 1);
27015 temp2 = expand_binop (SImode, and_optab, temp2, temp3,
27016 NULL_RTX, 1, OPTAB_LIB_WIDEN);
27017 temp = expand_binop (SImode, ior_optab, temp, temp2,
27018 NULL_RTX, 1, OPTAB_LIB_WIDEN);
27019 emit_move_insn (operands[0], temp);
27023 (define_insn "urdmsr"
27024 [(set (match_operand:DI 0 "register_operand" "=r")
27025 (unspec_volatile:DI
27026 [(match_operand:DI 1 "x86_64_szext_nonmemory_operand" "reZ")]
27028 "TARGET_USER_MSR && TARGET_64BIT"
27029 "urdmsr\t{%1, %0|%0, %1}"
27030 [(set_attr "prefix" "vex")
27031 (set_attr "type" "other")])
27033 (define_insn "uwrmsr"
27035 [(match_operand:DI 0 "x86_64_szext_nonmemory_operand" "reZ")
27036 (match_operand:DI 1 "register_operand" "r")]
27038 "TARGET_USER_MSR && TARGET_64BIT"
27039 "uwrmsr\t{%1, %0|%0, %1}"
27040 [(set_attr "prefix" "vex")
27041 (set_attr "type" "other")])
27045 (include "sync.md")