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 ;; Split non destructive adds if we cannot use lea.
6620 [(set (match_operand:SWI48 0 "register_operand")
6621 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
6622 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
6623 (clobber (reg:CC FLAGS_REG))]
6624 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
6625 [(set (match_dup 0) (match_dup 1))
6626 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
6627 (clobber (reg:CC FLAGS_REG))])])
6629 ;; Split non destructive adds if we cannot use lea.
6631 [(set (match_operand:DI 0 "register_operand")
6633 (plus:SI (match_operand:SI 1 "register_operand")
6634 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
6635 (clobber (reg:CC FLAGS_REG))]
6637 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
6638 [(set (match_dup 3) (match_dup 1))
6639 (parallel [(set (match_dup 0)
6640 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
6641 (clobber (reg:CC FLAGS_REG))])]
6642 "operands[3] = gen_lowpart (SImode, operands[0]);")
6644 ;; Convert add to the lea pattern to avoid flags dependency.
6646 [(set (match_operand:SWI 0 "register_operand")
6647 (plus:SWI (match_operand:SWI 1 "register_operand")
6648 (match_operand:SWI 2 "<nonmemory_operand>")))
6649 (clobber (reg:CC FLAGS_REG))]
6650 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
6652 (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
6654 if (<MODE>mode != <LEAMODE>mode)
6656 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
6657 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
6658 operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
6662 ;; Convert add to the lea pattern to avoid flags dependency.
6664 [(set (match_operand:DI 0 "register_operand")
6666 (plus:SI (match_operand:SI 1 "register_operand")
6667 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
6668 (clobber (reg:CC FLAGS_REG))]
6669 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
6671 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
6673 (define_insn "*add<mode>_2"
6674 [(set (reg FLAGS_REG)
6677 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
6678 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,0"))
6680 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,<r>")
6681 (plus:SWI (match_dup 1) (match_dup 2)))]
6682 "ix86_match_ccmode (insn, CCGOCmode)
6683 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6685 switch (get_attr_type (insn))
6688 if (operands[2] == const1_rtx)
6689 return "inc{<imodesuffix>}\t%0";
6692 gcc_assert (operands[2] == constm1_rtx);
6693 return "dec{<imodesuffix>}\t%0";
6697 if (which_alternative == 2)
6698 std::swap (operands[1], operands[2]);
6700 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6701 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6702 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6704 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6708 (if_then_else (match_operand:SWI 2 "incdec_operand")
6709 (const_string "incdec")
6710 (const_string "alu")))
6711 (set (attr "length_immediate")
6713 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6715 (const_string "*")))
6716 (set_attr "mode" "<MODE>")])
6718 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6719 (define_insn "*addsi_2_zext"
6720 [(set (reg FLAGS_REG)
6722 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6723 (match_operand:SI 2 "x86_64_general_operand" "rBMe,0"))
6725 (set (match_operand:DI 0 "register_operand" "=r,r")
6726 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6727 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6728 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6730 switch (get_attr_type (insn))
6733 if (operands[2] == const1_rtx)
6734 return "inc{l}\t%k0";
6737 gcc_assert (operands[2] == constm1_rtx);
6738 return "dec{l}\t%k0";
6742 if (which_alternative == 1)
6743 std::swap (operands[1], operands[2]);
6745 if (x86_maybe_negate_const_int (&operands[2], SImode))
6746 return "sub{l}\t{%2, %k0|%k0, %2}";
6748 return "add{l}\t{%2, %k0|%k0, %2}";
6752 (if_then_else (match_operand:SI 2 "incdec_operand")
6753 (const_string "incdec")
6754 (const_string "alu")))
6755 (set (attr "length_immediate")
6757 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6759 (const_string "*")))
6760 (set_attr "mode" "SI")])
6762 (define_insn "*add<mode>_3"
6763 [(set (reg FLAGS_REG)
6765 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6766 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
6767 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6768 "ix86_match_ccmode (insn, CCZmode)
6769 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6771 switch (get_attr_type (insn))
6774 if (operands[2] == const1_rtx)
6775 return "inc{<imodesuffix>}\t%0";
6778 gcc_assert (operands[2] == constm1_rtx);
6779 return "dec{<imodesuffix>}\t%0";
6783 if (which_alternative == 1)
6784 std::swap (operands[1], operands[2]);
6786 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6787 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6788 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6790 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6794 (if_then_else (match_operand:SWI 2 "incdec_operand")
6795 (const_string "incdec")
6796 (const_string "alu")))
6797 (set (attr "length_immediate")
6799 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6801 (const_string "*")))
6802 (set_attr "mode" "<MODE>")])
6804 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6805 (define_insn "*addsi_3_zext"
6806 [(set (reg FLAGS_REG)
6808 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rBMe,0"))
6809 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
6810 (set (match_operand:DI 0 "register_operand" "=r,r")
6811 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6812 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6813 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6815 switch (get_attr_type (insn))
6818 if (operands[2] == const1_rtx)
6819 return "inc{l}\t%k0";
6822 gcc_assert (operands[2] == constm1_rtx);
6823 return "dec{l}\t%k0";
6827 if (which_alternative == 1)
6828 std::swap (operands[1], operands[2]);
6830 if (x86_maybe_negate_const_int (&operands[2], SImode))
6831 return "sub{l}\t{%2, %k0|%k0, %2}";
6833 return "add{l}\t{%2, %k0|%k0, %2}";
6837 (if_then_else (match_operand:SI 2 "incdec_operand")
6838 (const_string "incdec")
6839 (const_string "alu")))
6840 (set (attr "length_immediate")
6842 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6844 (const_string "*")))
6845 (set_attr "mode" "SI")])
6847 ; For comparisons against 1, -1 and 128, we may generate better code
6848 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6849 ; is matched then. We can't accept general immediate, because for
6850 ; case of overflows, the result is messed up.
6851 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6852 ; only for comparisons not depending on it.
6854 (define_insn "*adddi_4"
6855 [(set (reg FLAGS_REG)
6857 (match_operand:DI 1 "nonimmediate_operand" "0")
6858 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6859 (clobber (match_scratch:DI 0 "=r"))]
6861 && ix86_match_ccmode (insn, CCGCmode)"
6863 switch (get_attr_type (insn))
6866 if (operands[2] == constm1_rtx)
6867 return "inc{q}\t%0";
6870 gcc_assert (operands[2] == const1_rtx);
6871 return "dec{q}\t%0";
6875 if (x86_maybe_negate_const_int (&operands[2], DImode))
6876 return "add{q}\t{%2, %0|%0, %2}";
6878 return "sub{q}\t{%2, %0|%0, %2}";
6882 (if_then_else (match_operand:DI 2 "incdec_operand")
6883 (const_string "incdec")
6884 (const_string "alu")))
6885 (set (attr "length_immediate")
6887 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6889 (const_string "*")))
6890 (set_attr "mode" "DI")])
6892 ; For comparisons against 1, -1 and 128, we may generate better code
6893 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6894 ; is matched then. We can't accept general immediate, because for
6895 ; case of overflows, the result is messed up.
6896 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6897 ; only for comparisons not depending on it.
6899 (define_insn "*add<mode>_4"
6900 [(set (reg FLAGS_REG)
6902 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6903 (match_operand:SWI124 2 "const_int_operand")))
6904 (clobber (match_scratch:SWI124 0 "=<r>"))]
6905 "ix86_match_ccmode (insn, CCGCmode)"
6907 switch (get_attr_type (insn))
6910 if (operands[2] == constm1_rtx)
6911 return "inc{<imodesuffix>}\t%0";
6914 gcc_assert (operands[2] == const1_rtx);
6915 return "dec{<imodesuffix>}\t%0";
6919 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6920 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6922 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6926 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6927 (const_string "incdec")
6928 (const_string "alu")))
6929 (set (attr "length_immediate")
6931 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6933 (const_string "*")))
6934 (set_attr "mode" "<MODE>")])
6936 (define_insn "*add<mode>_5"
6937 [(set (reg FLAGS_REG)
6940 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6941 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6943 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6944 "ix86_match_ccmode (insn, CCGOCmode)
6945 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6947 switch (get_attr_type (insn))
6950 if (operands[2] == const1_rtx)
6951 return "inc{<imodesuffix>}\t%0";
6954 gcc_assert (operands[2] == constm1_rtx);
6955 return "dec{<imodesuffix>}\t%0";
6959 if (which_alternative == 1)
6960 std::swap (operands[1], operands[2]);
6962 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6963 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6964 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6966 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6970 (if_then_else (match_operand:SWI 2 "incdec_operand")
6971 (const_string "incdec")
6972 (const_string "alu")))
6973 (set (attr "length_immediate")
6975 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6977 (const_string "*")))
6978 (set_attr "mode" "<MODE>")])
6980 (define_insn "*addqi_ext<mode>_0"
6981 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn")
6984 (match_operator:SWI248 3 "extract_operator"
6985 [(match_operand 2 "int248_register_operand" "Q")
6988 (match_operand:QI 1 "nonimmediate_operand" "0")))
6989 (clobber (reg:CC FLAGS_REG))]
6991 "add{b}\t{%h2, %0|%0, %h2}"
6992 [(set_attr "addr" "gpr8")
6993 (set_attr "type" "alu")
6994 (set_attr "mode" "QI")])
6996 (define_expand "addqi_ext_1"
6998 [(set (zero_extract:HI (match_operand:HI 0 "register_operand")
7004 (zero_extract:HI (match_operand:HI 1 "register_operand")
7007 (match_operand:QI 2 "const_int_operand")) 0))
7008 (clobber (reg:CC FLAGS_REG))])])
7010 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
7011 (define_insn_and_split "*addqi_ext<mode>_1"
7012 [(set (zero_extract:SWI248
7013 (match_operand 0 "int248_register_operand" "+Q,&Q")
7019 (match_operator:SWI248 3 "extract_operator"
7020 [(match_operand 1 "int248_register_operand" "0,!Q")
7023 (match_operand:QI 2 "general_operand" "QnBn,QnBn")) 0))
7024 (clobber (reg:CC FLAGS_REG))]
7027 if (which_alternative)
7030 switch (get_attr_type (insn))
7033 if (operands[2] == const1_rtx)
7034 return "inc{b}\t%h0";
7037 gcc_assert (operands[2] == constm1_rtx);
7038 return "dec{b}\t%h0";
7042 return "add{b}\t{%2, %h0|%h0, %2}";
7046 && !rtx_equal_p (operands[0], operands[1])"
7047 [(set (zero_extract:SWI248
7048 (match_dup 0) (const_int 8) (const_int 8))
7049 (zero_extract:SWI248
7050 (match_dup 1) (const_int 8) (const_int 8)))
7052 [(set (zero_extract:SWI248
7053 (match_dup 0) (const_int 8) (const_int 8))
7058 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
7060 (clobber (reg:CC FLAGS_REG))])]
7062 [(set_attr "addr" "gpr8")
7064 (if_then_else (match_operand:QI 2 "incdec_operand")
7065 (const_string "incdec")
7066 (const_string "alu")))
7067 (set_attr "mode" "QI")])
7069 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
7070 (define_insn_and_split "*<insn>qi_ext<mode>_2"
7071 [(set (zero_extract:SWI248
7072 (match_operand 0 "int248_register_operand" "+Q,&Q")
7078 (match_operator:SWI248 3 "extract_operator"
7079 [(match_operand 1 "int248_register_operand" "<comm>0,!Q")
7083 (match_operator:SWI248 4 "extract_operator"
7084 [(match_operand 2 "int248_register_operand" "Q,Q")
7086 (const_int 8)]) 0)) 0))
7087 (clobber (reg:CC FLAGS_REG))]
7090 <insn>{b}\t{%h2, %h0|%h0, %h2}
7093 && !(rtx_equal_p (operands[0], operands[1])
7094 || (<CODE> == PLUS && rtx_equal_p (operands[0], operands[2])))"
7095 [(set (zero_extract:SWI248
7096 (match_dup 0) (const_int 8) (const_int 8))
7097 (zero_extract:SWI248
7098 (match_dup 1) (const_int 8) (const_int 8)))
7100 [(set (zero_extract:SWI248
7101 (match_dup 0) (const_int 8) (const_int 8))
7106 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
7109 [(match_dup 2) (const_int 8) (const_int 8)]) 0)) 0))
7110 (clobber (reg:CC FLAGS_REG))])]
7112 [(set_attr "type" "alu")
7113 (set_attr "mode" "QI")])
7115 ;; Like DWI, but use POImode instead of OImode.
7116 (define_mode_attr DPWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI") (TI "POI")])
7118 ;; Add with jump on overflow.
7119 (define_expand "addv<mode>4"
7120 [(parallel [(set (reg:CCO FLAGS_REG)
7124 (match_operand:SWIDWI 1 "nonimmediate_operand"))
7127 (plus:SWIDWI (match_dup 1)
7128 (match_operand:SWIDWI 2
7129 "<general_hilo_operand>")))))
7130 (set (match_operand:SWIDWI 0 "register_operand")
7131 (plus:SWIDWI (match_dup 1) (match_dup 2)))])
7132 (set (pc) (if_then_else
7133 (eq (reg:CCO FLAGS_REG) (const_int 0))
7134 (label_ref (match_operand 3))
7138 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
7139 if (CONST_SCALAR_INT_P (operands[2]))
7140 operands[4] = operands[2];
7142 operands[4] = gen_rtx_SIGN_EXTEND (<DPWI>mode, operands[2]);
7145 (define_insn "*addv<mode>4"
7146 [(set (reg:CCO FLAGS_REG)
7149 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
7151 (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m")))
7153 (plus:SWI (match_dup 1) (match_dup 2)))))
7154 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7155 (plus:SWI (match_dup 1) (match_dup 2)))]
7156 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7157 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7158 [(set_attr "type" "alu")
7159 (set_attr "mode" "<MODE>")])
7161 (define_insn "addv<mode>4_1"
7162 [(set (reg:CCO FLAGS_REG)
7165 (match_operand:SWI 1 "nonimmediate_operand" "0"))
7166 (match_operand:<DWI> 3 "const_int_operand"))
7170 (match_operand:SWI 2 "x86_64_immediate_operand" "<i>")))))
7171 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
7172 (plus:SWI (match_dup 1) (match_dup 2)))]
7173 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
7174 && CONST_INT_P (operands[2])
7175 && INTVAL (operands[2]) == INTVAL (operands[3])"
7176 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7177 [(set_attr "type" "alu")
7178 (set_attr "mode" "<MODE>")
7179 (set (attr "length_immediate")
7180 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7182 (match_test "<MODE_SIZE> == 8")
7184 (const_string "<MODE_SIZE>")))])
7186 ;; Quad word integer modes as mode attribute.
7187 (define_mode_attr QPWI [(SI "TI") (DI "POI")])
7189 (define_insn_and_split "*addv<dwi>4_doubleword"
7190 [(set (reg:CCO FLAGS_REG)
7194 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0"))
7196 (match_operand:<DWI> 2 "nonimmediate_operand" "r,o")))
7198 (plus:<DWI> (match_dup 1) (match_dup 2)))))
7199 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
7200 (plus:<DWI> (match_dup 1) (match_dup 2)))]
7201 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
7203 "&& reload_completed"
7204 [(parallel [(set (reg:CCC FLAGS_REG)
7206 (plus:DWIH (match_dup 1) (match_dup 2))
7209 (plus:DWIH (match_dup 1) (match_dup 2)))])
7210 (parallel [(set (reg:CCO FLAGS_REG)
7214 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7215 (sign_extend:<DWI> (match_dup 4)))
7216 (sign_extend:<DWI> (match_dup 5)))
7220 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7226 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7230 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7233 (define_insn_and_split "*addv<dwi>4_doubleword_1"
7234 [(set (reg:CCO FLAGS_REG)
7238 (match_operand:<DWI> 1 "nonimmediate_operand" "%0"))
7239 (match_operand:<QPWI> 3 "const_scalar_int_operand" "n"))
7243 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>")))))
7244 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
7245 (plus:<DWI> (match_dup 1) (match_dup 2)))]
7246 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)
7247 && CONST_SCALAR_INT_P (operands[2])
7248 && rtx_equal_p (operands[2], operands[3])"
7250 "&& reload_completed"
7251 [(parallel [(set (reg:CCC FLAGS_REG)
7253 (plus:DWIH (match_dup 1) (match_dup 2))
7256 (plus:DWIH (match_dup 1) (match_dup 2)))])
7257 (parallel [(set (reg:CCO FLAGS_REG)
7261 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7262 (sign_extend:<DWI> (match_dup 4)))
7267 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7273 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7277 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7278 if (operands[2] == const0_rtx)
7280 emit_insn (gen_addv<mode>4_1 (operands[3], operands[4], operands[5],
7286 (define_insn "*addv<mode>4_overflow_1"
7287 [(set (reg:CCO FLAGS_REG)
7291 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7292 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7294 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")))
7296 (match_operand:SWI 2 "<general_sext_operand>" "rWe,m")))
7300 (match_operator:SWI 5 "ix86_carry_flag_operator"
7301 [(match_dup 3) (const_int 0)])
7304 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r")
7307 (match_op_dup 5 [(match_dup 3) (const_int 0)])
7310 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7311 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
7312 [(set_attr "type" "alu")
7313 (set_attr "mode" "<MODE>")])
7315 (define_insn "*addv<mode>4_overflow_2"
7316 [(set (reg:CCO FLAGS_REG)
7320 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7321 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7323 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
7324 (match_operand:<DWI> 6 "const_int_operand" "n"))
7328 (match_operator:SWI 5 "ix86_carry_flag_operator"
7329 [(match_dup 3) (const_int 0)])
7331 (match_operand:SWI 2 "x86_64_immediate_operand" "e")))))
7332 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm")
7335 (match_op_dup 5 [(match_dup 3) (const_int 0)])
7338 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
7339 && CONST_INT_P (operands[2])
7340 && INTVAL (operands[2]) == INTVAL (operands[6])"
7341 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
7342 [(set_attr "type" "alu")
7343 (set_attr "mode" "<MODE>")
7344 (set (attr "length_immediate")
7345 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7347 (const_string "4")))])
7349 (define_expand "uaddv<mode>4"
7350 [(parallel [(set (reg:CCC FLAGS_REG)
7353 (match_operand:SWIDWI 1 "nonimmediate_operand")
7354 (match_operand:SWIDWI 2 "<general_hilo_operand>"))
7356 (set (match_operand:SWIDWI 0 "register_operand")
7357 (plus:SWIDWI (match_dup 1) (match_dup 2)))])
7358 (set (pc) (if_then_else
7359 (ltu (reg:CCC FLAGS_REG) (const_int 0))
7360 (label_ref (match_operand 3))
7363 "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
7365 ;; The lea patterns for modes less than 32 bits need to be matched by
7366 ;; several insns converted to real lea by splitters.
7368 (define_insn_and_split "*lea<mode>_general_1"
7369 [(set (match_operand:SWI12 0 "register_operand" "=r")
7371 (plus:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7372 (match_operand:SWI12 2 "register_operand" "r"))
7373 (match_operand:SWI12 3 "immediate_operand" "i")))]
7374 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7376 "&& reload_completed"
7379 (plus:SI (match_dup 1) (match_dup 2))
7382 operands[0] = gen_lowpart (SImode, operands[0]);
7383 operands[1] = gen_lowpart (SImode, operands[1]);
7384 operands[2] = gen_lowpart (SImode, operands[2]);
7385 operands[3] = gen_lowpart (SImode, operands[3]);
7387 [(set_attr "type" "lea")
7388 (set_attr "mode" "SI")])
7390 (define_insn_and_split "*lea<mode>_general_2"
7391 [(set (match_operand:SWI12 0 "register_operand" "=r")
7393 (mult:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7394 (match_operand 2 "const248_operand" "n"))
7395 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
7396 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7398 "&& reload_completed"
7401 (mult:SI (match_dup 1) (match_dup 2))
7404 operands[0] = gen_lowpart (SImode, operands[0]);
7405 operands[1] = gen_lowpart (SImode, operands[1]);
7406 operands[3] = gen_lowpart (SImode, operands[3]);
7408 [(set_attr "type" "lea")
7409 (set_attr "mode" "SI")])
7411 (define_insn_and_split "*lea<mode>_general_2b"
7412 [(set (match_operand:SWI12 0 "register_operand" "=r")
7414 (ashift:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7415 (match_operand 2 "const123_operand" "n"))
7416 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
7417 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7419 "&& reload_completed"
7422 (ashift:SI (match_dup 1) (match_dup 2))
7425 operands[0] = gen_lowpart (SImode, operands[0]);
7426 operands[1] = gen_lowpart (SImode, operands[1]);
7427 operands[3] = gen_lowpart (SImode, operands[3]);
7429 [(set_attr "type" "lea")
7430 (set_attr "mode" "SI")])
7432 (define_insn_and_split "*lea<mode>_general_3"
7433 [(set (match_operand:SWI12 0 "register_operand" "=r")
7436 (mult:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7437 (match_operand 2 "const248_operand" "n"))
7438 (match_operand:SWI12 3 "register_operand" "r"))
7439 (match_operand:SWI12 4 "immediate_operand" "i")))]
7440 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7442 "&& reload_completed"
7446 (mult:SI (match_dup 1) (match_dup 2))
7450 operands[0] = gen_lowpart (SImode, operands[0]);
7451 operands[1] = gen_lowpart (SImode, operands[1]);
7452 operands[3] = gen_lowpart (SImode, operands[3]);
7453 operands[4] = gen_lowpart (SImode, operands[4]);
7455 [(set_attr "type" "lea")
7456 (set_attr "mode" "SI")])
7458 (define_insn_and_split "*lea<mode>_general_3b"
7459 [(set (match_operand:SWI12 0 "register_operand" "=r")
7462 (ashift:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7463 (match_operand 2 "const123_operand" "n"))
7464 (match_operand:SWI12 3 "register_operand" "r"))
7465 (match_operand:SWI12 4 "immediate_operand" "i")))]
7466 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7468 "&& reload_completed"
7472 (ashift:SI (match_dup 1) (match_dup 2))
7476 operands[0] = gen_lowpart (SImode, operands[0]);
7477 operands[1] = gen_lowpart (SImode, operands[1]);
7478 operands[3] = gen_lowpart (SImode, operands[3]);
7479 operands[4] = gen_lowpart (SImode, operands[4]);
7481 [(set_attr "type" "lea")
7482 (set_attr "mode" "SI")])
7484 (define_insn_and_split "*lea<mode>_general_4"
7485 [(set (match_operand:SWI12 0 "register_operand" "=r")
7488 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7489 (match_operand 2 "const_0_to_3_operand"))
7490 (match_operand 3 "const_int_operand")))]
7491 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7492 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
7493 < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
7495 "&& reload_completed"
7498 (mult:SI (match_dup 1) (match_dup 2))
7501 operands[0] = gen_lowpart (SImode, operands[0]);
7502 operands[1] = gen_lowpart (SImode, operands[1]);
7503 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
7505 [(set_attr "type" "lea")
7506 (set_attr "mode" "SI")])
7508 (define_insn_and_split "*lea<mode>_general_4"
7509 [(set (match_operand:SWI48 0 "register_operand" "=r")
7512 (match_operand:SWI48 1 "register_no_SP_operand" "l")
7513 (match_operand 2 "const_0_to_3_operand"))
7514 (match_operand 3 "const_int_operand")))]
7515 "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
7516 < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
7518 "&& reload_completed"
7521 (mult:SWI48 (match_dup 1) (match_dup 2))
7523 "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
7524 [(set_attr "type" "lea")
7525 (set_attr "mode" "<MODE>")])
7527 ;; Subtract instructions
7529 (define_expand "sub<mode>3"
7530 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
7531 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
7532 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
7534 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
7536 (define_insn_and_split "*sub<dwi>3_doubleword"
7537 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
7539 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7540 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
7541 (clobber (reg:CC FLAGS_REG))]
7542 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7544 "&& reload_completed"
7545 [(parallel [(set (reg:CC FLAGS_REG)
7546 (compare:CC (match_dup 1) (match_dup 2)))
7548 (minus:DWIH (match_dup 1) (match_dup 2)))])
7549 (parallel [(set (match_dup 3)
7553 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7555 (clobber (reg:CC FLAGS_REG))])]
7557 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7558 if (operands[2] == const0_rtx)
7560 ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
7565 (define_insn_and_split "*sub<dwi>3_doubleword_zext"
7566 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
7568 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7570 (match_operand:DWIH 2 "nonimmediate_operand" "rm,r"))))
7571 (clobber (reg:CC FLAGS_REG))]
7572 "ix86_binary_operator_ok (UNKNOWN, <DWI>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))])]
7586 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[3]);")
7588 (define_insn "*sub<mode>_1"
7589 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7591 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7592 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
7593 (clobber (reg:CC FLAGS_REG))]
7594 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7595 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7596 [(set_attr "type" "alu")
7597 (set_attr "mode" "<MODE>")])
7599 (define_insn "*subsi_1_zext"
7600 [(set (match_operand:DI 0 "register_operand" "=r")
7602 (minus:SI (match_operand:SI 1 "register_operand" "0")
7603 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
7604 (clobber (reg:CC FLAGS_REG))]
7605 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7606 "sub{l}\t{%2, %k0|%k0, %2}"
7607 [(set_attr "type" "alu")
7608 (set_attr "mode" "SI")])
7610 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
7611 (define_insn_and_split "*sub<mode>_1_slp"
7612 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
7613 (minus:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
7614 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
7615 (clobber (reg:CC FLAGS_REG))]
7616 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7618 sub{<imodesuffix>}\t{%2, %0|%0, %2}
7620 "&& reload_completed
7621 && !(rtx_equal_p (operands[0], operands[1]))"
7622 [(set (strict_low_part (match_dup 0)) (match_dup 1))
7624 [(set (strict_low_part (match_dup 0))
7625 (minus:SWI12 (match_dup 0) (match_dup 2)))
7626 (clobber (reg:CC FLAGS_REG))])]
7628 [(set_attr "type" "alu")
7629 (set_attr "mode" "<MODE>")])
7631 (define_insn "*sub<mode>_2"
7632 [(set (reg FLAGS_REG)
7635 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7636 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
7638 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7639 (minus:SWI (match_dup 1) (match_dup 2)))]
7640 "ix86_match_ccmode (insn, CCGOCmode)
7641 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7642 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7643 [(set_attr "type" "alu")
7644 (set_attr "mode" "<MODE>")])
7646 (define_insn "*subsi_2_zext"
7647 [(set (reg FLAGS_REG)
7649 (minus:SI (match_operand:SI 1 "register_operand" "0")
7650 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
7652 (set (match_operand:DI 0 "register_operand" "=r")
7654 (minus:SI (match_dup 1)
7656 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7657 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7658 "sub{l}\t{%2, %k0|%k0, %2}"
7659 [(set_attr "type" "alu")
7660 (set_attr "mode" "SI")])
7662 (define_insn "*subqi_ext<mode>_0"
7663 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn")
7665 (match_operand:QI 1 "nonimmediate_operand" "0")
7667 (match_operator:SWI248 3 "extract_operator"
7668 [(match_operand 2 "int248_register_operand" "Q")
7670 (const_int 8)]) 0)))
7671 (clobber (reg:CC FLAGS_REG))]
7673 "sub{b}\t{%h2, %0|%0, %h2}"
7674 [(set_attr "addr" "gpr8")
7675 (set_attr "type" "alu")
7676 (set_attr "mode" "QI")])
7678 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
7679 (define_insn_and_split "*subqi_ext<mode>_1"
7680 [(set (zero_extract:SWI248
7681 (match_operand 0 "int248_register_operand" "+Q,&Q")
7687 (match_operator:SWI248 3 "extract_operator"
7688 [(match_operand 1 "int248_register_operand" "0,!Q")
7691 (match_operand:QI 2 "general_operand" "QnBn,QnBn")) 0))
7692 (clobber (reg:CC FLAGS_REG))]
7695 sub{b}\t{%2, %h0|%h0, %2}
7698 && !(rtx_equal_p (operands[0], operands[1]))"
7699 [(set (zero_extract:SWI248
7700 (match_dup 0) (const_int 8) (const_int 8))
7701 (zero_extract:SWI248
7702 (match_dup 1) (const_int 8) (const_int 8)))
7704 [(set (zero_extract:SWI248
7705 (match_dup 0) (const_int 8) (const_int 8))
7710 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
7712 (clobber (reg:CC FLAGS_REG))])]
7714 [(set_attr "addr" "gpr8")
7715 (set_attr "type" "alu")
7716 (set_attr "mode" "QI")])
7718 ;; Subtract with jump on overflow.
7719 (define_expand "subv<mode>4"
7720 [(parallel [(set (reg:CCO FLAGS_REG)
7724 (match_operand:SWIDWI 1 "nonimmediate_operand"))
7727 (minus:SWIDWI (match_dup 1)
7728 (match_operand:SWIDWI 2
7729 "<general_hilo_operand>")))))
7730 (set (match_operand:SWIDWI 0 "register_operand")
7731 (minus:SWIDWI (match_dup 1) (match_dup 2)))])
7732 (set (pc) (if_then_else
7733 (eq (reg:CCO FLAGS_REG) (const_int 0))
7734 (label_ref (match_operand 3))
7738 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
7739 if (CONST_SCALAR_INT_P (operands[2]))
7740 operands[4] = operands[2];
7742 operands[4] = gen_rtx_SIGN_EXTEND (<DPWI>mode, operands[2]);
7745 (define_insn "*subv<mode>4"
7746 [(set (reg:CCO FLAGS_REG)
7747 (eq:CCO (minus:<DWI>
7749 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
7751 (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m")))
7753 (minus:SWI (match_dup 1) (match_dup 2)))))
7754 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7755 (minus:SWI (match_dup 1) (match_dup 2)))]
7756 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7757 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7758 [(set_attr "type" "alu")
7759 (set_attr "mode" "<MODE>")])
7761 (define_insn "subv<mode>4_1"
7762 [(set (reg:CCO FLAGS_REG)
7763 (eq:CCO (minus:<DWI>
7765 (match_operand:SWI 1 "nonimmediate_operand" "0"))
7766 (match_operand:<DWI> 3 "const_int_operand"))
7770 (match_operand:SWI 2 "x86_64_immediate_operand" "<i>")))))
7771 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
7772 (minus:SWI (match_dup 1) (match_dup 2)))]
7773 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7774 && CONST_INT_P (operands[2])
7775 && INTVAL (operands[2]) == INTVAL (operands[3])"
7776 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7777 [(set_attr "type" "alu")
7778 (set_attr "mode" "<MODE>")
7779 (set (attr "length_immediate")
7780 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7782 (match_test "<MODE_SIZE> == 8")
7784 (const_string "<MODE_SIZE>")))])
7786 (define_insn_and_split "*subv<dwi>4_doubleword"
7787 [(set (reg:CCO FLAGS_REG)
7791 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0"))
7793 (match_operand:<DWI> 2 "nonimmediate_operand" "r,o")))
7795 (minus:<DWI> (match_dup 1) (match_dup 2)))))
7796 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
7797 (minus:<DWI> (match_dup 1) (match_dup 2)))]
7798 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7800 "&& reload_completed"
7801 [(parallel [(set (reg:CC FLAGS_REG)
7802 (compare:CC (match_dup 1) (match_dup 2)))
7804 (minus:DWIH (match_dup 1) (match_dup 2)))])
7805 (parallel [(set (reg:CCO FLAGS_REG)
7809 (sign_extend:<DWI> (match_dup 4))
7810 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))
7811 (sign_extend:<DWI> (match_dup 5)))
7816 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7822 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7825 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7828 (define_insn_and_split "*subv<dwi>4_doubleword_1"
7829 [(set (reg:CCO FLAGS_REG)
7833 (match_operand:<DWI> 1 "nonimmediate_operand" "0"))
7834 (match_operand:<QPWI> 3 "const_scalar_int_operand"))
7838 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>")))))
7839 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
7840 (minus:<DWI> (match_dup 1) (match_dup 2)))]
7841 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7842 && CONST_SCALAR_INT_P (operands[2])
7843 && rtx_equal_p (operands[2], operands[3])"
7845 "&& reload_completed"
7846 [(parallel [(set (reg:CC FLAGS_REG)
7847 (compare:CC (match_dup 1) (match_dup 2)))
7849 (minus:DWIH (match_dup 1) (match_dup 2)))])
7850 (parallel [(set (reg:CCO FLAGS_REG)
7854 (sign_extend:<DWI> (match_dup 4))
7855 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))
7861 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7867 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7870 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7871 if (operands[2] == const0_rtx)
7873 emit_insn (gen_subv<mode>4_1 (operands[3], operands[4], operands[5],
7879 (define_insn "*subv<mode>4_overflow_1"
7880 [(set (reg:CCO FLAGS_REG)
7885 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
7886 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7887 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
7889 (match_operand:SWI 2 "<general_sext_operand>" "rWe,m")))
7894 (match_operator:SWI 5 "ix86_carry_flag_operator"
7895 [(match_dup 3) (const_int 0)]))
7897 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r")
7901 (match_op_dup 5 [(match_dup 3) (const_int 0)]))
7903 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7904 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7905 [(set_attr "type" "alu")
7906 (set_attr "mode" "<MODE>")])
7908 (define_insn "*subv<mode>4_overflow_2"
7909 [(set (reg:CCO FLAGS_REG)
7914 (match_operand:SWI 1 "nonimmediate_operand" "%0"))
7915 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7916 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
7917 (match_operand:<DWI> 6 "const_int_operand" "n"))
7922 (match_operator:SWI 5 "ix86_carry_flag_operator"
7923 [(match_dup 3) (const_int 0)]))
7924 (match_operand:SWI 2 "x86_64_immediate_operand" "e")))))
7925 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm")
7929 (match_op_dup 5 [(match_dup 3) (const_int 0)]))
7931 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7932 && CONST_INT_P (operands[2])
7933 && INTVAL (operands[2]) == INTVAL (operands[6])"
7934 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7935 [(set_attr "type" "alu")
7936 (set_attr "mode" "<MODE>")
7937 (set (attr "length_immediate")
7938 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7940 (const_string "4")))])
7942 (define_expand "usubv<mode>4"
7943 [(parallel [(set (reg:CC FLAGS_REG)
7945 (match_operand:SWI 1 "nonimmediate_operand")
7946 (match_operand:SWI 2 "<general_operand>")))
7947 (set (match_operand:SWI 0 "register_operand")
7948 (minus:SWI (match_dup 1) (match_dup 2)))])
7949 (set (pc) (if_then_else
7950 (ltu (reg:CC FLAGS_REG) (const_int 0))
7951 (label_ref (match_operand 3))
7954 "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
7956 (define_insn "*sub<mode>_3"
7957 [(set (reg FLAGS_REG)
7958 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7959 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
7960 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7961 (minus:SWI (match_dup 1) (match_dup 2)))]
7962 "ix86_match_ccmode (insn, CCmode)
7963 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7964 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7965 [(set_attr "type" "alu")
7966 (set_attr "mode" "<MODE>")])
7970 [(set (reg:CC FLAGS_REG)
7971 (compare:CC (match_operand:SWI 0 "general_reg_operand")
7972 (match_operand:SWI 1 "general_gr_operand")))
7974 (minus:SWI (match_dup 0) (match_dup 1)))])]
7975 "find_regno_note (peep2_next_insn (0), REG_UNUSED, REGNO (operands[0])) != 0"
7976 [(set (reg:CC FLAGS_REG)
7977 (compare:CC (match_dup 0) (match_dup 1)))])
7980 [(set (match_operand:SWI 0 "general_reg_operand")
7981 (match_operand:SWI 1 "memory_operand"))
7982 (parallel [(set (reg:CC FLAGS_REG)
7983 (compare:CC (match_dup 0)
7984 (match_operand:SWI 2 "memory_operand")))
7986 (minus:SWI (match_dup 0) (match_dup 2)))])
7987 (set (match_dup 1) (match_dup 0))]
7988 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
7989 && peep2_reg_dead_p (3, operands[0])
7990 && !reg_overlap_mentioned_p (operands[0], operands[1])
7991 && !reg_overlap_mentioned_p (operands[0], operands[2])"
7992 [(set (match_dup 0) (match_dup 2))
7993 (parallel [(set (reg:CC FLAGS_REG)
7994 (compare:CC (match_dup 1) (match_dup 0)))
7996 (minus:SWI (match_dup 1) (match_dup 0)))])])
7998 ;; decl %eax; cmpl $-1, %eax; jne .Lxx; can be optimized into
7999 ;; subl $1, %eax; jnc .Lxx;
8002 [(set (match_operand:SWI 0 "general_reg_operand")
8003 (plus:SWI (match_dup 0) (const_int -1)))
8004 (clobber (reg FLAGS_REG))])
8005 (set (reg:CCZ FLAGS_REG)
8006 (compare:CCZ (match_dup 0) (const_int -1)))
8008 (if_then_else (match_operator 1 "bt_comparison_operator"
8009 [(reg:CCZ FLAGS_REG) (const_int 0)])
8012 "peep2_regno_dead_p (3, FLAGS_REG)"
8014 [(set (reg:CC FLAGS_REG)
8015 (compare:CC (match_dup 0) (const_int 1)))
8017 (minus:SWI (match_dup 0) (const_int 1)))])
8019 (if_then_else (match_dup 3)
8023 rtx cc = gen_rtx_REG (CCmode, FLAGS_REG);
8024 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE
8025 ? GEU : LTU, VOIDmode, cc, const0_rtx);
8028 ;; Help combine use borrow flag to test for -1 after dec (add $-1).
8029 (define_insn_and_split "*dec_cmov<mode>"
8030 [(set (match_operand:SWI248 0 "register_operand" "=r")
8031 (if_then_else:SWI248
8032 (match_operator 1 "bt_comparison_operator"
8033 [(match_operand:SWI248 2 "register_operand" "0") (const_int 0)])
8034 (plus:SWI248 (match_dup 2) (const_int -1))
8035 (match_operand:SWI248 3 "nonimmediate_operand" "rm")))
8036 (clobber (reg:CC FLAGS_REG))]
8039 "&& reload_completed"
8040 [(parallel [(set (reg:CC FLAGS_REG)
8041 (compare:CC (match_dup 2) (const_int 1)))
8042 (set (match_dup 0) (minus:SWI248 (match_dup 2) (const_int 1)))])
8044 (if_then_else:SWI248 (match_dup 4) (match_dup 0) (match_dup 3)))]
8046 rtx cc = gen_rtx_REG (CCCmode, FLAGS_REG);
8047 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE
8048 ? GEU : LTU, VOIDmode, cc, const0_rtx);
8051 (define_insn "*subsi_3_zext"
8052 [(set (reg FLAGS_REG)
8053 (compare (match_operand:SI 1 "register_operand" "0")
8054 (match_operand:SI 2 "x86_64_general_operand" "rBMe")))
8055 (set (match_operand:DI 0 "register_operand" "=r")
8057 (minus:SI (match_dup 1)
8059 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
8060 && ix86_binary_operator_ok (MINUS, SImode, operands)"
8061 "sub{l}\t{%2, %1|%1, %2}"
8062 [(set_attr "type" "alu")
8063 (set_attr "mode" "SI")])
8065 ;; Add with carry and subtract with borrow
8067 (define_insn "@add<mode>3_carry"
8068 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
8071 (match_operator:SWI 4 "ix86_carry_flag_operator"
8072 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8073 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
8074 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
8075 (clobber (reg:CC FLAGS_REG))]
8076 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
8077 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
8078 [(set_attr "type" "alu")
8079 (set_attr "use_carry" "1")
8080 (set_attr "pent_pair" "pu")
8081 (set_attr "mode" "<MODE>")])
8084 [(set (match_operand:SWI 0 "general_reg_operand")
8085 (match_operand:SWI 1 "memory_operand"))
8086 (parallel [(set (match_dup 0)
8089 (match_operator:SWI 4 "ix86_carry_flag_operator"
8090 [(match_operand 3 "flags_reg_operand")
8093 (match_operand:SWI 2 "memory_operand")))
8094 (clobber (reg:CC FLAGS_REG))])
8095 (set (match_dup 1) (match_dup 0))]
8096 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8097 && peep2_reg_dead_p (3, operands[0])
8098 && !reg_overlap_mentioned_p (operands[0], operands[1])
8099 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8100 [(set (match_dup 0) (match_dup 2))
8101 (parallel [(set (match_dup 1)
8102 (plus:SWI (plus:SWI (match_op_dup 4
8103 [(match_dup 3) (const_int 0)])
8106 (clobber (reg:CC FLAGS_REG))])])
8109 [(set (match_operand:SWI 0 "general_reg_operand")
8110 (match_operand:SWI 1 "memory_operand"))
8111 (parallel [(set (match_dup 0)
8114 (match_operator:SWI 4 "ix86_carry_flag_operator"
8115 [(match_operand 3 "flags_reg_operand")
8118 (match_operand:SWI 2 "memory_operand")))
8119 (clobber (reg:CC FLAGS_REG))])
8120 (set (match_operand:SWI 5 "general_reg_operand") (match_dup 0))
8121 (set (match_dup 1) (match_dup 5))]
8122 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8123 && peep2_reg_dead_p (3, operands[0])
8124 && peep2_reg_dead_p (4, operands[5])
8125 && !reg_overlap_mentioned_p (operands[0], operands[1])
8126 && !reg_overlap_mentioned_p (operands[0], operands[2])
8127 && !reg_overlap_mentioned_p (operands[5], operands[1])"
8128 [(set (match_dup 0) (match_dup 2))
8129 (parallel [(set (match_dup 1)
8130 (plus:SWI (plus:SWI (match_op_dup 4
8131 [(match_dup 3) (const_int 0)])
8134 (clobber (reg:CC FLAGS_REG))])])
8136 (define_insn "*add<mode>3_carry_0"
8137 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8139 (match_operator:SWI 2 "ix86_carry_flag_operator"
8140 [(reg FLAGS_REG) (const_int 0)])
8141 (match_operand:SWI 1 "nonimmediate_operand" "0")))
8142 (clobber (reg:CC FLAGS_REG))]
8143 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8144 "adc{<imodesuffix>}\t{$0, %0|%0, 0}"
8145 [(set_attr "type" "alu")
8146 (set_attr "use_carry" "1")
8147 (set_attr "pent_pair" "pu")
8148 (set_attr "mode" "<MODE>")])
8150 (define_insn "*add<mode>3_carry_0r"
8151 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8153 (match_operator:SWI 2 "ix86_carry_flag_unset_operator"
8154 [(reg FLAGS_REG) (const_int 0)])
8155 (match_operand:SWI 1 "nonimmediate_operand" "0")))
8156 (clobber (reg:CC FLAGS_REG))]
8157 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8158 "sbb{<imodesuffix>}\t{$-1, %0|%0, -1}"
8159 [(set_attr "type" "alu")
8160 (set_attr "use_carry" "1")
8161 (set_attr "pent_pair" "pu")
8162 (set_attr "mode" "<MODE>")])
8164 (define_insn "*addsi3_carry_zext"
8165 [(set (match_operand:DI 0 "register_operand" "=r")
8168 (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
8169 [(reg FLAGS_REG) (const_int 0)])
8170 (match_operand:SI 1 "register_operand" "%0"))
8171 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
8172 (clobber (reg:CC FLAGS_REG))]
8173 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
8174 "adc{l}\t{%2, %k0|%k0, %2}"
8175 [(set_attr "type" "alu")
8176 (set_attr "use_carry" "1")
8177 (set_attr "pent_pair" "pu")
8178 (set_attr "mode" "SI")])
8180 (define_insn "*addsi3_carry_zext_0"
8181 [(set (match_operand:DI 0 "register_operand" "=r")
8183 (plus:SI (match_operator:SI 2 "ix86_carry_flag_operator"
8184 [(reg FLAGS_REG) (const_int 0)])
8185 (match_operand:SI 1 "register_operand" "0"))))
8186 (clobber (reg:CC FLAGS_REG))]
8188 "adc{l}\t{$0, %k0|%k0, 0}"
8189 [(set_attr "type" "alu")
8190 (set_attr "use_carry" "1")
8191 (set_attr "pent_pair" "pu")
8192 (set_attr "mode" "SI")])
8194 (define_insn "*addsi3_carry_zext_0r"
8195 [(set (match_operand:DI 0 "register_operand" "=r")
8197 (plus:SI (match_operator:SI 2 "ix86_carry_flag_unset_operator"
8198 [(reg FLAGS_REG) (const_int 0)])
8199 (match_operand:SI 1 "register_operand" "0"))))
8200 (clobber (reg:CC FLAGS_REG))]
8202 "sbb{l}\t{$-1, %k0|%k0, -1}"
8203 [(set_attr "type" "alu")
8204 (set_attr "use_carry" "1")
8205 (set_attr "pent_pair" "pu")
8206 (set_attr "mode" "SI")])
8208 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
8210 (define_insn "addcarry<mode>"
8211 [(set (reg:CCC FLAGS_REG)
8216 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8217 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8218 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0"))
8219 (match_operand:SWI48 2 "nonimmediate_operand" "r,rm")))
8221 (zero_extend:<DWI> (match_dup 2))
8222 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8223 [(match_dup 3) (const_int 0)]))))
8224 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
8225 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8226 [(match_dup 3) (const_int 0)])
8229 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
8230 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
8231 [(set_attr "type" "alu")
8232 (set_attr "use_carry" "1")
8233 (set_attr "pent_pair" "pu")
8234 (set_attr "mode" "<MODE>")])
8237 [(parallel [(set (reg:CCC FLAGS_REG)
8242 (match_operator:SWI48 4 "ix86_carry_flag_operator"
8243 [(match_operand 2 "flags_reg_operand")
8245 (match_operand:SWI48 0 "general_reg_operand"))
8246 (match_operand:SWI48 1 "memory_operand")))
8248 (zero_extend:<DWI> (match_dup 1))
8249 (match_operator:<DWI> 3 "ix86_carry_flag_operator"
8250 [(match_dup 2) (const_int 0)]))))
8252 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8253 [(match_dup 2) (const_int 0)])
8256 (set (match_dup 1) (match_dup 0))]
8257 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8258 && peep2_reg_dead_p (2, operands[0])
8259 && !reg_overlap_mentioned_p (operands[0], operands[1])"
8260 [(parallel [(set (reg:CCC FLAGS_REG)
8266 [(match_dup 2) (const_int 0)])
8270 (zero_extend:<DWI> (match_dup 0))
8272 [(match_dup 2) (const_int 0)]))))
8274 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8275 [(match_dup 2) (const_int 0)])
8280 [(set (match_operand:SWI48 0 "general_reg_operand")
8281 (match_operand:SWI48 1 "memory_operand"))
8282 (parallel [(set (reg:CCC FLAGS_REG)
8287 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8288 [(match_operand 3 "flags_reg_operand")
8291 (match_operand:SWI48 2 "memory_operand")))
8293 (zero_extend:<DWI> (match_dup 2))
8294 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8295 [(match_dup 3) (const_int 0)]))))
8297 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8298 [(match_dup 3) (const_int 0)])
8301 (set (match_dup 1) (match_dup 0))]
8302 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8303 && peep2_reg_dead_p (3, operands[0])
8304 && !reg_overlap_mentioned_p (operands[0], operands[1])
8305 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8306 [(set (match_dup 0) (match_dup 2))
8307 (parallel [(set (reg:CCC FLAGS_REG)
8313 [(match_dup 3) (const_int 0)])
8317 (zero_extend:<DWI> (match_dup 0))
8319 [(match_dup 3) (const_int 0)]))))
8321 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8322 [(match_dup 3) (const_int 0)])
8327 [(parallel [(set (reg:CCC FLAGS_REG)
8332 (match_operator:SWI48 4 "ix86_carry_flag_operator"
8333 [(match_operand 2 "flags_reg_operand")
8335 (match_operand:SWI48 0 "general_reg_operand"))
8336 (match_operand:SWI48 1 "memory_operand")))
8338 (zero_extend:<DWI> (match_dup 1))
8339 (match_operator:<DWI> 3 "ix86_carry_flag_operator"
8340 [(match_dup 2) (const_int 0)]))))
8342 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8343 [(match_dup 2) (const_int 0)])
8346 (set (match_operand:QI 5 "general_reg_operand")
8347 (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8348 (set (match_operand:SWI48 6 "general_reg_operand")
8349 (zero_extend:SWI48 (match_dup 5)))
8350 (set (match_dup 1) (match_dup 0))]
8351 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8352 && peep2_reg_dead_p (4, operands[0])
8353 && !reg_overlap_mentioned_p (operands[0], operands[1])
8354 && !reg_overlap_mentioned_p (operands[0], operands[5])
8355 && !reg_overlap_mentioned_p (operands[5], operands[1])
8356 && !reg_overlap_mentioned_p (operands[0], operands[6])
8357 && !reg_overlap_mentioned_p (operands[6], operands[1])"
8358 [(parallel [(set (reg:CCC FLAGS_REG)
8364 [(match_dup 2) (const_int 0)])
8368 (zero_extend:<DWI> (match_dup 0))
8370 [(match_dup 2) (const_int 0)]))))
8372 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8373 [(match_dup 2) (const_int 0)])
8376 (set (match_dup 5) (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8377 (set (match_dup 6) (zero_extend:SWI48 (match_dup 5)))])
8379 (define_expand "addcarry<mode>_0"
8381 [(set (reg:CCC FLAGS_REG)
8384 (match_operand:SWI48 1 "nonimmediate_operand")
8385 (match_operand:SWI48 2 "x86_64_general_operand"))
8387 (set (match_operand:SWI48 0 "nonimmediate_operand")
8388 (plus:SWI48 (match_dup 1) (match_dup 2)))])]
8389 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)")
8391 (define_insn "*addcarry<mode>_1"
8392 [(set (reg:CCC FLAGS_REG)
8397 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8398 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8399 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
8400 (match_operand:SWI48 2 "x86_64_immediate_operand" "e")))
8402 (match_operand:<DWI> 6 "const_scalar_int_operand")
8403 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8404 [(match_dup 3) (const_int 0)]))))
8405 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
8406 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8407 [(match_dup 3) (const_int 0)])
8410 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
8411 && CONST_INT_P (operands[2])
8412 /* Check that operands[6] is operands[2] zero extended from
8413 <MODE>mode to <DWI>mode. */
8414 && ((<MODE>mode == SImode || INTVAL (operands[2]) >= 0)
8415 ? (CONST_INT_P (operands[6])
8416 && UINTVAL (operands[6]) == (UINTVAL (operands[2])
8417 & GET_MODE_MASK (<MODE>mode)))
8418 : (CONST_WIDE_INT_P (operands[6])
8419 && CONST_WIDE_INT_NUNITS (operands[6]) == 2
8420 && ((unsigned HOST_WIDE_INT) CONST_WIDE_INT_ELT (operands[6], 0)
8421 == UINTVAL (operands[2]))
8422 && CONST_WIDE_INT_ELT (operands[6], 1) == 0))"
8423 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
8424 [(set_attr "type" "alu")
8425 (set_attr "use_carry" "1")
8426 (set_attr "pent_pair" "pu")
8427 (set_attr "mode" "<MODE>")
8428 (set (attr "length_immediate")
8429 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
8431 (const_string "4")))])
8433 (define_insn "@sub<mode>3_carry"
8434 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
8437 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
8438 (match_operator:SWI 4 "ix86_carry_flag_operator"
8439 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
8440 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
8441 (clobber (reg:CC FLAGS_REG))]
8442 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
8443 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8444 [(set_attr "type" "alu")
8445 (set_attr "use_carry" "1")
8446 (set_attr "pent_pair" "pu")
8447 (set_attr "mode" "<MODE>")])
8450 [(set (match_operand:SWI 0 "general_reg_operand")
8451 (match_operand:SWI 1 "memory_operand"))
8452 (parallel [(set (match_dup 0)
8456 (match_operator:SWI 4 "ix86_carry_flag_operator"
8457 [(match_operand 3 "flags_reg_operand")
8459 (match_operand:SWI 2 "memory_operand")))
8460 (clobber (reg:CC FLAGS_REG))])
8461 (set (match_dup 1) (match_dup 0))]
8462 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8463 && peep2_reg_dead_p (3, operands[0])
8464 && !reg_overlap_mentioned_p (operands[0], operands[1])
8465 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8466 [(set (match_dup 0) (match_dup 2))
8467 (parallel [(set (match_dup 1)
8468 (minus:SWI (minus:SWI (match_dup 1)
8470 [(match_dup 3) (const_int 0)]))
8472 (clobber (reg:CC FLAGS_REG))])])
8475 [(set (match_operand:SWI 0 "general_reg_operand")
8476 (match_operand:SWI 1 "memory_operand"))
8477 (parallel [(set (match_dup 0)
8481 (match_operator:SWI 4 "ix86_carry_flag_operator"
8482 [(match_operand 3 "flags_reg_operand")
8484 (match_operand:SWI 2 "memory_operand")))
8485 (clobber (reg:CC FLAGS_REG))])
8486 (set (match_operand:SWI 5 "general_reg_operand") (match_dup 0))
8487 (set (match_dup 1) (match_dup 5))]
8488 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8489 && peep2_reg_dead_p (3, operands[0])
8490 && peep2_reg_dead_p (4, operands[5])
8491 && !reg_overlap_mentioned_p (operands[0], operands[1])
8492 && !reg_overlap_mentioned_p (operands[0], operands[2])
8493 && !reg_overlap_mentioned_p (operands[5], operands[1])"
8494 [(set (match_dup 0) (match_dup 2))
8495 (parallel [(set (match_dup 1)
8496 (minus:SWI (minus:SWI (match_dup 1)
8498 [(match_dup 3) (const_int 0)]))
8500 (clobber (reg:CC FLAGS_REG))])])
8502 (define_insn "*sub<mode>3_carry_0"
8503 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8505 (match_operand:SWI 1 "nonimmediate_operand" "0")
8506 (match_operator:SWI 2 "ix86_carry_flag_operator"
8507 [(reg FLAGS_REG) (const_int 0)])))
8508 (clobber (reg:CC FLAGS_REG))]
8509 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8510 "sbb{<imodesuffix>}\t{$0, %0|%0, 0}"
8511 [(set_attr "type" "alu")
8512 (set_attr "use_carry" "1")
8513 (set_attr "pent_pair" "pu")
8514 (set_attr "mode" "<MODE>")])
8516 (define_insn "*sub<mode>3_carry_0r"
8517 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8519 (match_operand:SWI 1 "nonimmediate_operand" "0")
8520 (match_operator:SWI 2 "ix86_carry_flag_unset_operator"
8521 [(reg FLAGS_REG) (const_int 0)])))
8522 (clobber (reg:CC FLAGS_REG))]
8523 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8524 "adc{<imodesuffix>}\t{$-1, %0|%0, -1}"
8525 [(set_attr "type" "alu")
8526 (set_attr "use_carry" "1")
8527 (set_attr "pent_pair" "pu")
8528 (set_attr "mode" "<MODE>")])
8530 (define_insn "*subsi3_carry_zext"
8531 [(set (match_operand:DI 0 "register_operand" "=r")
8535 (match_operand:SI 1 "register_operand" "0")
8536 (match_operator:SI 3 "ix86_carry_flag_operator"
8537 [(reg FLAGS_REG) (const_int 0)]))
8538 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
8539 (clobber (reg:CC FLAGS_REG))]
8540 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
8541 "sbb{l}\t{%2, %k0|%k0, %2}"
8542 [(set_attr "type" "alu")
8543 (set_attr "use_carry" "1")
8544 (set_attr "pent_pair" "pu")
8545 (set_attr "mode" "SI")])
8547 (define_insn "*subsi3_carry_zext_0"
8548 [(set (match_operand:DI 0 "register_operand" "=r")
8551 (match_operand:SI 1 "register_operand" "0")
8552 (match_operator:SI 2 "ix86_carry_flag_operator"
8553 [(reg FLAGS_REG) (const_int 0)]))))
8554 (clobber (reg:CC FLAGS_REG))]
8556 "sbb{l}\t{$0, %k0|%k0, 0}"
8557 [(set_attr "type" "alu")
8558 (set_attr "use_carry" "1")
8559 (set_attr "pent_pair" "pu")
8560 (set_attr "mode" "SI")])
8562 (define_insn "*subsi3_carry_zext_0r"
8563 [(set (match_operand:DI 0 "register_operand" "=r")
8566 (match_operand:SI 1 "register_operand" "0")
8567 (match_operator:SI 2 "ix86_carry_flag_unset_operator"
8568 [(reg FLAGS_REG) (const_int 0)]))))
8569 (clobber (reg:CC FLAGS_REG))]
8571 "adc{l}\t{$-1, %k0|%k0, -1}"
8572 [(set_attr "type" "alu")
8573 (set_attr "use_carry" "1")
8574 (set_attr "pent_pair" "pu")
8575 (set_attr "mode" "SI")])
8577 (define_insn "@sub<mode>3_carry_ccc"
8578 [(set (reg:CCC FLAGS_REG)
8580 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
8582 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
8584 (match_operand:DWIH 2 "x86_64_sext_operand" "rmWe")))))
8585 (clobber (match_scratch:DWIH 0 "=r"))]
8587 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8588 [(set_attr "type" "alu")
8589 (set_attr "mode" "<MODE>")])
8591 (define_insn "*sub<mode>3_carry_ccc_1"
8592 [(set (reg:CCC FLAGS_REG)
8594 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
8596 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
8597 (match_operand:<DWI> 2 "x86_64_dwzext_immediate_operand" "Wf"))))
8598 (clobber (match_scratch:DWIH 0 "=r"))]
8601 operands[3] = simplify_subreg (<MODE>mode, operands[2], <DWI>mode, 0);
8602 return "sbb{<imodesuffix>}\t{%3, %0|%0, %3}";
8604 [(set_attr "type" "alu")
8605 (set_attr "mode" "<MODE>")])
8607 ;; The sign flag is set from the
8608 ;; (compare (match_dup 1) (plus:DWIH (ltu:DWIH ...) (match_dup 2)))
8609 ;; result, the overflow flag likewise, but the overflow flag is also
8610 ;; set if the (plus:DWIH (ltu:DWIH ...) (match_dup 2)) overflows.
8611 (define_insn "@sub<mode>3_carry_ccgz"
8612 [(set (reg:CCGZ FLAGS_REG)
8613 (unspec:CCGZ [(match_operand:DWIH 1 "register_operand" "0")
8614 (match_operand:DWIH 2 "x86_64_general_operand" "rBMe")
8615 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))]
8617 (clobber (match_scratch:DWIH 0 "=r"))]
8619 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8620 [(set_attr "type" "alu")
8621 (set_attr "mode" "<MODE>")])
8623 (define_insn "subborrow<mode>"
8624 [(set (reg:CCC FLAGS_REG)
8627 (match_operand:SWI48 1 "nonimmediate_operand" "0,0"))
8629 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8630 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8632 (match_operand:SWI48 2 "nonimmediate_operand" "r,rm")))))
8633 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
8634 (minus:SWI48 (minus:SWI48
8636 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8637 [(match_dup 3) (const_int 0)]))
8639 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
8640 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8641 [(set_attr "type" "alu")
8642 (set_attr "use_carry" "1")
8643 (set_attr "pent_pair" "pu")
8644 (set_attr "mode" "<MODE>")])
8647 [(set (match_operand:SWI48 0 "general_reg_operand")
8648 (match_operand:SWI48 1 "memory_operand"))
8649 (parallel [(set (reg:CCC FLAGS_REG)
8651 (zero_extend:<DWI> (match_dup 0))
8653 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8654 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8656 (match_operand:SWI48 2 "memory_operand")))))
8661 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8662 [(match_dup 3) (const_int 0)]))
8664 (set (match_dup 1) (match_dup 0))]
8665 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8666 && peep2_reg_dead_p (3, operands[0])
8667 && !reg_overlap_mentioned_p (operands[0], operands[1])
8668 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8669 [(set (match_dup 0) (match_dup 2))
8670 (parallel [(set (reg:CCC FLAGS_REG)
8672 (zero_extend:<DWI> (match_dup 1))
8673 (plus:<DWI> (match_op_dup 4
8674 [(match_dup 3) (const_int 0)])
8675 (zero_extend:<DWI> (match_dup 0)))))
8677 (minus:SWI48 (minus:SWI48 (match_dup 1)
8679 [(match_dup 3) (const_int 0)]))
8683 [(set (match_operand:SWI48 6 "general_reg_operand")
8684 (match_operand:SWI48 7 "memory_operand"))
8685 (set (match_operand:SWI48 8 "general_reg_operand")
8686 (match_operand:SWI48 9 "memory_operand"))
8687 (parallel [(set (reg:CCC FLAGS_REG)
8690 (match_operand:SWI48 0 "general_reg_operand"))
8692 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8693 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8695 (match_operand:SWI48 2 "general_reg_operand")))))
8700 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8701 [(match_dup 3) (const_int 0)]))
8703 (set (match_operand:SWI48 1 "memory_operand") (match_dup 0))]
8704 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8705 && peep2_reg_dead_p (4, operands[0])
8706 && peep2_reg_dead_p (3, operands[2])
8707 && !reg_overlap_mentioned_p (operands[0], operands[1])
8708 && !reg_overlap_mentioned_p (operands[2], operands[1])
8709 && !reg_overlap_mentioned_p (operands[6], operands[9])
8710 && (rtx_equal_p (operands[6], operands[0])
8711 ? (rtx_equal_p (operands[7], operands[1])
8712 && rtx_equal_p (operands[8], operands[2]))
8713 : (rtx_equal_p (operands[8], operands[0])
8714 && rtx_equal_p (operands[9], operands[1])
8715 && rtx_equal_p (operands[6], operands[2])))"
8716 [(set (match_dup 0) (match_dup 9))
8717 (parallel [(set (reg:CCC FLAGS_REG)
8719 (zero_extend:<DWI> (match_dup 1))
8720 (plus:<DWI> (match_op_dup 4
8721 [(match_dup 3) (const_int 0)])
8722 (zero_extend:<DWI> (match_dup 0)))))
8724 (minus:SWI48 (minus:SWI48 (match_dup 1)
8726 [(match_dup 3) (const_int 0)]))
8729 if (!rtx_equal_p (operands[6], operands[0]))
8730 operands[9] = operands[7];
8734 [(set (match_operand:SWI48 6 "general_reg_operand")
8735 (match_operand:SWI48 7 "memory_operand"))
8736 (set (match_operand:SWI48 8 "general_reg_operand")
8737 (match_operand:SWI48 9 "memory_operand"))
8738 (parallel [(set (reg:CCC FLAGS_REG)
8741 (match_operand:SWI48 0 "general_reg_operand"))
8743 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8744 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8746 (match_operand:SWI48 2 "general_reg_operand")))))
8751 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8752 [(match_dup 3) (const_int 0)]))
8754 (set (match_operand:QI 10 "general_reg_operand")
8755 (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8756 (set (match_operand:SWI48 11 "general_reg_operand")
8757 (zero_extend:SWI48 (match_dup 10)))
8758 (set (match_operand:SWI48 1 "memory_operand") (match_dup 0))]
8759 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8760 && peep2_reg_dead_p (6, operands[0])
8761 && peep2_reg_dead_p (3, operands[2])
8762 && !reg_overlap_mentioned_p (operands[0], operands[1])
8763 && !reg_overlap_mentioned_p (operands[2], operands[1])
8764 && !reg_overlap_mentioned_p (operands[6], operands[9])
8765 && !reg_overlap_mentioned_p (operands[0], operands[10])
8766 && !reg_overlap_mentioned_p (operands[10], operands[1])
8767 && !reg_overlap_mentioned_p (operands[0], operands[11])
8768 && !reg_overlap_mentioned_p (operands[11], operands[1])
8769 && (rtx_equal_p (operands[6], operands[0])
8770 ? (rtx_equal_p (operands[7], operands[1])
8771 && rtx_equal_p (operands[8], operands[2]))
8772 : (rtx_equal_p (operands[8], operands[0])
8773 && rtx_equal_p (operands[9], operands[1])
8774 && rtx_equal_p (operands[6], operands[2])))"
8775 [(set (match_dup 0) (match_dup 9))
8776 (parallel [(set (reg:CCC FLAGS_REG)
8778 (zero_extend:<DWI> (match_dup 1))
8779 (plus:<DWI> (match_op_dup 4
8780 [(match_dup 3) (const_int 0)])
8781 (zero_extend:<DWI> (match_dup 0)))))
8783 (minus:SWI48 (minus:SWI48 (match_dup 1)
8785 [(match_dup 3) (const_int 0)]))
8787 (set (match_dup 10) (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8788 (set (match_dup 11) (zero_extend:SWI48 (match_dup 10)))]
8790 if (!rtx_equal_p (operands[6], operands[0]))
8791 operands[9] = operands[7];
8794 (define_expand "subborrow<mode>_0"
8796 [(set (reg:CC FLAGS_REG)
8798 (match_operand:SWI48 1 "nonimmediate_operand")
8799 (match_operand:SWI48 2 "<general_operand>")))
8800 (set (match_operand:SWI48 0 "register_operand")
8801 (minus:SWI48 (match_dup 1) (match_dup 2)))])]
8802 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)")
8804 (define_expand "uaddc<mode>5"
8805 [(match_operand:SWI48 0 "register_operand")
8806 (match_operand:SWI48 1 "register_operand")
8807 (match_operand:SWI48 2 "register_operand")
8808 (match_operand:SWI48 3 "register_operand")
8809 (match_operand:SWI48 4 "nonmemory_operand")]
8812 rtx cf = gen_rtx_REG (CCCmode, FLAGS_REG), pat, pat2;
8813 if (operands[4] == const0_rtx)
8814 emit_insn (gen_addcarry<mode>_0 (operands[0], operands[2], operands[3]));
8817 ix86_expand_carry (operands[4]);
8818 pat = gen_rtx_LTU (<DWI>mode, cf, const0_rtx);
8819 pat2 = gen_rtx_LTU (<MODE>mode, cf, const0_rtx);
8820 emit_insn (gen_addcarry<mode> (operands[0], operands[2], operands[3],
8823 rtx cc = gen_reg_rtx (QImode);
8824 pat = gen_rtx_LTU (QImode, cf, const0_rtx);
8825 emit_insn (gen_rtx_SET (cc, pat));
8826 emit_insn (gen_zero_extendqi<mode>2 (operands[1], cc));
8830 (define_expand "usubc<mode>5"
8831 [(match_operand:SWI48 0 "register_operand")
8832 (match_operand:SWI48 1 "register_operand")
8833 (match_operand:SWI48 2 "register_operand")
8834 (match_operand:SWI48 3 "register_operand")
8835 (match_operand:SWI48 4 "nonmemory_operand")]
8839 if (operands[4] == const0_rtx)
8841 cf = gen_rtx_REG (CCmode, FLAGS_REG);
8842 emit_insn (gen_subborrow<mode>_0 (operands[0], operands[2],
8847 cf = gen_rtx_REG (CCCmode, FLAGS_REG);
8848 ix86_expand_carry (operands[4]);
8849 pat = gen_rtx_LTU (<DWI>mode, cf, const0_rtx);
8850 pat2 = gen_rtx_LTU (<MODE>mode, cf, const0_rtx);
8851 emit_insn (gen_subborrow<mode> (operands[0], operands[2], operands[3],
8854 rtx cc = gen_reg_rtx (QImode);
8855 pat = gen_rtx_LTU (QImode, cf, const0_rtx);
8856 emit_insn (gen_rtx_SET (cc, pat));
8857 emit_insn (gen_zero_extendqi<mode>2 (operands[1], cc));
8861 (define_mode_iterator CC_CCC [CC CCC])
8863 ;; Pre-reload splitter to optimize
8864 ;; *setcc_qi followed by *addqi3_cconly_overflow_1 with the same QI
8865 ;; operand and no intervening flags modifications into nothing.
8866 (define_insn_and_split "*setcc_qi_addqi3_cconly_overflow_1_<mode>"
8867 [(set (reg:CCC FLAGS_REG)
8868 (compare:CCC (neg:QI (geu:QI (reg:CC_CCC FLAGS_REG) (const_int 0)))
8869 (ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))))]
8870 "ix86_pre_reload_split ()"
8874 "emit_note (NOTE_INSN_DELETED); DONE;")
8876 ;; Set the carry flag from the carry flag.
8877 (define_insn_and_split "*setccc"
8878 [(set (reg:CCC FLAGS_REG)
8879 (reg:CCC FLAGS_REG))]
8880 "ix86_pre_reload_split ()"
8884 "emit_note (NOTE_INSN_DELETED); DONE;")
8886 ;; Set the carry flag from the carry flag.
8887 (define_insn_and_split "*setcc_qi_negqi_ccc_1_<mode>"
8888 [(set (reg:CCC FLAGS_REG)
8889 (ltu:CCC (reg:CC_CCC FLAGS_REG) (const_int 0)))]
8890 "ix86_pre_reload_split ()"
8894 "emit_note (NOTE_INSN_DELETED); DONE;")
8896 ;; Set the carry flag from the carry flag.
8897 (define_insn_and_split "*setcc_qi_negqi_ccc_2_<mode>"
8898 [(set (reg:CCC FLAGS_REG)
8899 (unspec:CCC [(ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))
8900 (const_int 0)] UNSPEC_CC_NE))]
8901 "ix86_pre_reload_split ()"
8905 "emit_note (NOTE_INSN_DELETED); DONE;")
8907 ;; Overflow setting add instructions
8909 (define_expand "addqi3_cconly_overflow"
8911 [(set (reg:CCC FLAGS_REG)
8914 (match_operand:QI 0 "nonimmediate_operand")
8915 (match_operand:QI 1 "general_operand"))
8917 (clobber (scratch:QI))])]
8918 "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
8920 (define_insn "*add<mode>3_cconly_overflow_1"
8921 [(set (reg:CCC FLAGS_REG)
8924 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8925 (match_operand:SWI 2 "<general_operand>" "<g>"))
8927 (clobber (match_scratch:SWI 0 "=<r>"))]
8928 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8929 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
8930 [(set_attr "type" "alu")
8931 (set_attr "mode" "<MODE>")])
8933 (define_insn "@add<mode>3_cc_overflow_1"
8934 [(set (reg:CCC FLAGS_REG)
8937 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8938 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
8940 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
8941 (plus:SWI (match_dup 1) (match_dup 2)))]
8942 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
8943 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
8944 [(set_attr "type" "alu")
8945 (set_attr "mode" "<MODE>")])
8948 [(parallel [(set (reg:CCC FLAGS_REG)
8950 (plus:SWI (match_operand:SWI 0 "general_reg_operand")
8951 (match_operand:SWI 1 "memory_operand"))
8953 (set (match_dup 0) (plus:SWI (match_dup 0) (match_dup 1)))])
8954 (set (match_dup 1) (match_dup 0))]
8955 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8956 && peep2_reg_dead_p (2, operands[0])
8957 && !reg_overlap_mentioned_p (operands[0], operands[1])"
8958 [(parallel [(set (reg:CCC FLAGS_REG)
8960 (plus:SWI (match_dup 1) (match_dup 0))
8962 (set (match_dup 1) (plus:SWI (match_dup 1) (match_dup 0)))])])
8965 [(set (match_operand:SWI 0 "general_reg_operand")
8966 (match_operand:SWI 1 "memory_operand"))
8967 (parallel [(set (reg:CCC FLAGS_REG)
8969 (plus:SWI (match_dup 0)
8970 (match_operand:SWI 2 "memory_operand"))
8972 (set (match_dup 0) (plus:SWI (match_dup 0) (match_dup 2)))])
8973 (set (match_dup 1) (match_dup 0))]
8974 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8975 && peep2_reg_dead_p (3, operands[0])
8976 && !reg_overlap_mentioned_p (operands[0], operands[1])
8977 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8978 [(set (match_dup 0) (match_dup 2))
8979 (parallel [(set (reg:CCC FLAGS_REG)
8981 (plus:SWI (match_dup 1) (match_dup 0))
8983 (set (match_dup 1) (plus:SWI (match_dup 1) (match_dup 0)))])])
8985 (define_insn "*addsi3_zext_cc_overflow_1"
8986 [(set (reg:CCC FLAGS_REG)
8989 (match_operand:SI 1 "nonimmediate_operand" "%0")
8990 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
8992 (set (match_operand:DI 0 "register_operand" "=r")
8993 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8994 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
8995 "add{l}\t{%2, %k0|%k0, %2}"
8996 [(set_attr "type" "alu")
8997 (set_attr "mode" "SI")])
8999 (define_insn "*add<mode>3_cconly_overflow_2"
9000 [(set (reg:CCC FLAGS_REG)
9003 (match_operand:SWI 1 "nonimmediate_operand" "%0")
9004 (match_operand:SWI 2 "<general_operand>" "<g>"))
9006 (clobber (match_scratch:SWI 0 "=<r>"))]
9007 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9008 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
9009 [(set_attr "type" "alu")
9010 (set_attr "mode" "<MODE>")])
9012 (define_insn "*add<mode>3_cc_overflow_2"
9013 [(set (reg:CCC FLAGS_REG)
9016 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
9017 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
9019 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
9020 (plus:SWI (match_dup 1) (match_dup 2)))]
9021 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
9022 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
9023 [(set_attr "type" "alu")
9024 (set_attr "mode" "<MODE>")])
9026 (define_insn "*addsi3_zext_cc_overflow_2"
9027 [(set (reg:CCC FLAGS_REG)
9030 (match_operand:SI 1 "nonimmediate_operand" "%0")
9031 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
9033 (set (match_operand:DI 0 "register_operand" "=r")
9034 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
9035 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
9036 "add{l}\t{%2, %k0|%k0, %2}"
9037 [(set_attr "type" "alu")
9038 (set_attr "mode" "SI")])
9040 (define_insn_and_split "*add<dwi>3_doubleword_cc_overflow_1"
9041 [(set (reg:CCC FLAGS_REG)
9044 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
9045 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o"))
9047 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
9048 (plus:<DWI> (match_dup 1) (match_dup 2)))]
9049 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
9051 "&& reload_completed"
9052 [(parallel [(set (reg:CCC FLAGS_REG)
9054 (plus:DWIH (match_dup 1) (match_dup 2))
9057 (plus:DWIH (match_dup 1) (match_dup 2)))])
9058 (parallel [(set (reg:CCC FLAGS_REG)
9063 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9068 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))))
9071 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9075 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
9076 if (operands[2] == const0_rtx)
9078 emit_insn (gen_addcarry<mode>_0 (operands[3], operands[4], operands[5]));
9081 if (CONST_INT_P (operands[5]))
9082 operands[6] = simplify_unary_operation (ZERO_EXTEND, <DWI>mode,
9083 operands[5], <MODE>mode);
9085 operands[6] = gen_rtx_ZERO_EXTEND (<DWI>mode, operands[5]);
9088 ;; x == 0 with zero flag test can be done also as x < 1U with carry flag
9089 ;; test, where the latter is preferrable if we have some carry consuming
9091 ;; For x != 0, we need to use x < 1U with negation of carry, i.e.
9093 (define_insn_and_split "*add<mode>3_eq"
9094 [(set (match_operand:SWI 0 "nonimmediate_operand")
9097 (eq:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0))
9098 (match_operand:SWI 1 "nonimmediate_operand"))
9099 (match_operand:SWI 2 "<general_operand>")))
9100 (clobber (reg:CC FLAGS_REG))]
9101 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
9102 && ix86_pre_reload_split ()"
9105 [(set (reg:CC FLAGS_REG)
9106 (compare:CC (match_dup 3) (const_int 1)))
9107 (parallel [(set (match_dup 0)
9109 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9112 (clobber (reg:CC FLAGS_REG))])])
9114 (define_insn_and_split "*add<mode>3_ne"
9115 [(set (match_operand:SWI 0 "nonimmediate_operand")
9118 (ne:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0))
9119 (match_operand:SWI 1 "nonimmediate_operand"))
9120 (match_operand:SWI 2 "<immediate_operand>")))
9121 (clobber (reg:CC FLAGS_REG))]
9122 "CONST_INT_P (operands[2])
9123 && (<MODE>mode != DImode
9124 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
9125 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
9126 && ix86_pre_reload_split ()"
9129 [(set (reg:CC FLAGS_REG)
9130 (compare:CC (match_dup 3) (const_int 1)))
9131 (parallel [(set (match_dup 0)
9133 (minus:SWI (match_dup 1)
9134 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9136 (clobber (reg:CC FLAGS_REG))])]
9138 operands[2] = gen_int_mode (~INTVAL (operands[2]),
9139 <MODE>mode == DImode ? SImode : <MODE>mode);
9142 (define_insn_and_split "*add<mode>3_eq_0"
9143 [(set (match_operand:SWI 0 "nonimmediate_operand")
9145 (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))
9146 (match_operand:SWI 1 "<general_operand>")))
9147 (clobber (reg:CC FLAGS_REG))]
9148 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)
9149 && ix86_pre_reload_split ()"
9152 [(set (reg:CC FLAGS_REG)
9153 (compare:CC (match_dup 2) (const_int 1)))
9154 (parallel [(set (match_dup 0)
9155 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9157 (clobber (reg:CC FLAGS_REG))])]
9159 if (!nonimmediate_operand (operands[1], <MODE>mode))
9160 operands[1] = force_reg (<MODE>mode, operands[1]);
9163 (define_insn_and_split "*add<mode>3_ne_0"
9164 [(set (match_operand:SWI 0 "nonimmediate_operand")
9166 (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))
9167 (match_operand:SWI 1 "<general_operand>")))
9168 (clobber (reg:CC FLAGS_REG))]
9169 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)
9170 && ix86_pre_reload_split ()"
9173 [(set (reg:CC FLAGS_REG)
9174 (compare:CC (match_dup 2) (const_int 1)))
9175 (parallel [(set (match_dup 0)
9176 (minus:SWI (minus:SWI
9178 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9180 (clobber (reg:CC FLAGS_REG))])]
9182 if (!nonimmediate_operand (operands[1], <MODE>mode))
9183 operands[1] = force_reg (<MODE>mode, operands[1]);
9186 (define_insn_and_split "*sub<mode>3_eq"
9187 [(set (match_operand:SWI 0 "nonimmediate_operand")
9190 (match_operand:SWI 1 "nonimmediate_operand")
9191 (eq:SWI (match_operand 3 "int_nonimmediate_operand")
9193 (match_operand:SWI 2 "<general_operand>")))
9194 (clobber (reg:CC FLAGS_REG))]
9195 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
9196 && ix86_pre_reload_split ()"
9199 [(set (reg:CC FLAGS_REG)
9200 (compare:CC (match_dup 3) (const_int 1)))
9201 (parallel [(set (match_dup 0)
9203 (minus:SWI (match_dup 1)
9204 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9206 (clobber (reg:CC FLAGS_REG))])])
9208 (define_insn_and_split "*sub<mode>3_ne"
9209 [(set (match_operand:SWI 0 "nonimmediate_operand")
9212 (match_operand:SWI 1 "nonimmediate_operand")
9213 (ne:SWI (match_operand 3 "int_nonimmediate_operand")
9215 (match_operand:SWI 2 "<immediate_operand>")))
9216 (clobber (reg:CC FLAGS_REG))]
9217 "CONST_INT_P (operands[2])
9218 && (<MODE>mode != DImode
9219 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
9220 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
9221 && ix86_pre_reload_split ()"
9224 [(set (reg:CC FLAGS_REG)
9225 (compare:CC (match_dup 3) (const_int 1)))
9226 (parallel [(set (match_dup 0)
9228 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9231 (clobber (reg:CC FLAGS_REG))])]
9233 operands[2] = gen_int_mode (INTVAL (operands[2]) - 1,
9234 <MODE>mode == DImode ? SImode : <MODE>mode);
9237 (define_insn_and_split "*sub<mode>3_eq_1"
9238 [(set (match_operand:SWI 0 "nonimmediate_operand")
9241 (match_operand:SWI 1 "nonimmediate_operand")
9242 (eq:SWI (match_operand 3 "int_nonimmediate_operand")
9244 (match_operand:SWI 2 "<immediate_operand>")))
9245 (clobber (reg:CC FLAGS_REG))]
9246 "CONST_INT_P (operands[2])
9247 && (<MODE>mode != DImode
9248 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
9249 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
9250 && ix86_pre_reload_split ()"
9253 [(set (reg:CC FLAGS_REG)
9254 (compare:CC (match_dup 3) (const_int 1)))
9255 (parallel [(set (match_dup 0)
9257 (minus:SWI (match_dup 1)
9258 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9260 (clobber (reg:CC FLAGS_REG))])]
9262 operands[2] = gen_int_mode (-INTVAL (operands[2]),
9263 <MODE>mode == DImode ? SImode : <MODE>mode);
9266 (define_insn_and_split "*sub<mode>3_eq_0"
9267 [(set (match_operand:SWI 0 "nonimmediate_operand")
9269 (match_operand:SWI 1 "<general_operand>")
9270 (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))))
9271 (clobber (reg:CC FLAGS_REG))]
9272 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)
9273 && ix86_pre_reload_split ()"
9276 [(set (reg:CC FLAGS_REG)
9277 (compare:CC (match_dup 2) (const_int 1)))
9278 (parallel [(set (match_dup 0)
9279 (minus:SWI (match_dup 1)
9280 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))))
9281 (clobber (reg:CC FLAGS_REG))])]
9283 if (!nonimmediate_operand (operands[1], <MODE>mode))
9284 operands[1] = force_reg (<MODE>mode, operands[1]);
9287 (define_insn_and_split "*sub<mode>3_ne_0"
9288 [(set (match_operand:SWI 0 "nonimmediate_operand")
9290 (match_operand:SWI 1 "<general_operand>")
9291 (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))))
9292 (clobber (reg:CC FLAGS_REG))]
9293 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)
9294 && ix86_pre_reload_split ()"
9297 [(set (reg:CC FLAGS_REG)
9298 (compare:CC (match_dup 2) (const_int 1)))
9299 (parallel [(set (match_dup 0)
9301 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9304 (clobber (reg:CC FLAGS_REG))])]
9306 if (!nonimmediate_operand (operands[1], <MODE>mode))
9307 operands[1] = force_reg (<MODE>mode, operands[1]);
9310 ;; The patterns that match these are at the end of this file.
9312 (define_expand "<insn>xf3"
9313 [(set (match_operand:XF 0 "register_operand")
9315 (match_operand:XF 1 "register_operand")
9316 (match_operand:XF 2 "register_operand")))]
9319 (define_expand "<insn>hf3"
9320 [(set (match_operand:HF 0 "register_operand")
9322 (match_operand:HF 1 "register_operand")
9323 (match_operand:HF 2 "nonimmediate_operand")))]
9324 "TARGET_AVX512FP16")
9326 (define_expand "<insn><mode>3"
9327 [(set (match_operand:MODEF 0 "register_operand")
9329 (match_operand:MODEF 1 "register_operand")
9330 (match_operand:MODEF 2 "nonimmediate_operand")))]
9331 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
9332 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
9334 ;; Multiply instructions
9336 (define_expand "mul<mode>3"
9337 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
9339 (match_operand:SWIM248 1 "register_operand")
9340 (match_operand:SWIM248 2 "<general_operand>")))
9341 (clobber (reg:CC FLAGS_REG))])])
9343 (define_expand "mulqi3"
9344 [(parallel [(set (match_operand:QI 0 "register_operand")
9346 (match_operand:QI 1 "register_operand")
9347 (match_operand:QI 2 "nonimmediate_operand")))
9348 (clobber (reg:CC FLAGS_REG))])]
9349 "TARGET_QIMODE_MATH")
9352 ;; IMUL reg32/64, reg32/64, imm8 Direct
9353 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
9354 ;; IMUL reg32/64, reg32/64, imm32 Direct
9355 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
9356 ;; IMUL reg32/64, reg32/64 Direct
9357 ;; IMUL reg32/64, mem32/64 Direct
9359 ;; On BDVER1, all above IMULs use DirectPath
9362 ;; IMUL reg16, reg16, imm8 VectorPath
9363 ;; IMUL reg16, mem16, imm8 VectorPath
9364 ;; IMUL reg16, reg16, imm16 VectorPath
9365 ;; IMUL reg16, mem16, imm16 VectorPath
9366 ;; IMUL reg16, reg16 Direct
9367 ;; IMUL reg16, mem16 Direct
9369 ;; On BDVER1, all HI MULs use DoublePath
9371 (define_insn "*mul<mode>3_1"
9372 [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
9374 (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
9375 (match_operand:SWIM248 2 "<general_operand>" "K,<i>,<m>r")))
9376 (clobber (reg:CC FLAGS_REG))]
9377 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9379 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9380 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9381 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
9382 [(set_attr "type" "imul")
9383 (set_attr "prefix_0f" "0,0,1")
9384 (set (attr "athlon_decode")
9385 (cond [(eq_attr "cpu" "athlon")
9386 (const_string "vector")
9387 (eq_attr "alternative" "1")
9388 (const_string "vector")
9389 (and (eq_attr "alternative" "2")
9390 (ior (match_test "<MODE>mode == HImode")
9391 (match_operand 1 "memory_operand")))
9392 (const_string "vector")]
9393 (const_string "direct")))
9394 (set (attr "amdfam10_decode")
9395 (cond [(and (eq_attr "alternative" "0,1")
9396 (ior (match_test "<MODE>mode == HImode")
9397 (match_operand 1 "memory_operand")))
9398 (const_string "vector")]
9399 (const_string "direct")))
9400 (set (attr "bdver1_decode")
9402 (match_test "<MODE>mode == HImode")
9403 (const_string "double")
9404 (const_string "direct")))
9405 (set_attr "mode" "<MODE>")])
9407 (define_insn "*mulsi3_1_zext"
9408 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9410 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
9411 (match_operand:SI 2 "x86_64_general_operand" "K,e,BMr"))))
9412 (clobber (reg:CC FLAGS_REG))]
9414 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9416 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
9417 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
9418 imul{l}\t{%2, %k0|%k0, %2}"
9419 [(set_attr "type" "imul")
9420 (set_attr "prefix_0f" "0,0,1")
9421 (set (attr "athlon_decode")
9422 (cond [(eq_attr "cpu" "athlon")
9423 (const_string "vector")
9424 (eq_attr "alternative" "1")
9425 (const_string "vector")
9426 (and (eq_attr "alternative" "2")
9427 (match_operand 1 "memory_operand"))
9428 (const_string "vector")]
9429 (const_string "direct")))
9430 (set (attr "amdfam10_decode")
9431 (cond [(and (eq_attr "alternative" "0,1")
9432 (match_operand 1 "memory_operand"))
9433 (const_string "vector")]
9434 (const_string "direct")))
9435 (set_attr "bdver1_decode" "direct")
9436 (set_attr "mode" "SI")])
9438 ;;On AMDFAM10 and BDVER1
9442 (define_insn "*mulqi3_1"
9443 [(set (match_operand:QI 0 "register_operand" "=a")
9444 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9445 (match_operand:QI 2 "nonimmediate_operand" "qm")))
9446 (clobber (reg:CC FLAGS_REG))]
9448 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9450 [(set_attr "type" "imul")
9451 (set_attr "length_immediate" "0")
9452 (set (attr "athlon_decode")
9453 (if_then_else (eq_attr "cpu" "athlon")
9454 (const_string "vector")
9455 (const_string "direct")))
9456 (set_attr "amdfam10_decode" "direct")
9457 (set_attr "bdver1_decode" "direct")
9458 (set_attr "mode" "QI")])
9460 ;; Multiply with jump on overflow.
9461 (define_expand "mulv<mode>4"
9462 [(parallel [(set (reg:CCO FLAGS_REG)
9465 (match_operand:SWI248 1 "register_operand"))
9468 (mult:SWI248 (match_dup 1)
9469 (match_operand:SWI248 2
9470 "<general_operand>")))))
9471 (set (match_operand:SWI248 0 "register_operand")
9472 (mult:SWI248 (match_dup 1) (match_dup 2)))])
9473 (set (pc) (if_then_else
9474 (eq (reg:CCO FLAGS_REG) (const_int 0))
9475 (label_ref (match_operand 3))
9479 if (CONST_INT_P (operands[2]))
9480 operands[4] = operands[2];
9482 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
9485 (define_insn "*mulv<mode>4"
9486 [(set (reg:CCO FLAGS_REG)
9489 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
9491 (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
9493 (mult:SWI48 (match_dup 1) (match_dup 2)))))
9494 (set (match_operand:SWI48 0 "register_operand" "=r,r")
9495 (mult:SWI48 (match_dup 1) (match_dup 2)))]
9496 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9498 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9499 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
9500 [(set_attr "type" "imul")
9501 (set_attr "prefix_0f" "0,1")
9502 (set (attr "athlon_decode")
9503 (cond [(eq_attr "cpu" "athlon")
9504 (const_string "vector")
9505 (eq_attr "alternative" "0")
9506 (const_string "vector")
9507 (and (eq_attr "alternative" "1")
9508 (match_operand 1 "memory_operand"))
9509 (const_string "vector")]
9510 (const_string "direct")))
9511 (set (attr "amdfam10_decode")
9512 (cond [(and (eq_attr "alternative" "1")
9513 (match_operand 1 "memory_operand"))
9514 (const_string "vector")]
9515 (const_string "direct")))
9516 (set_attr "bdver1_decode" "direct")
9517 (set_attr "mode" "<MODE>")])
9519 (define_insn "*mulvhi4"
9520 [(set (reg:CCO FLAGS_REG)
9523 (match_operand:HI 1 "nonimmediate_operand" "%0"))
9525 (match_operand:HI 2 "nonimmediate_operand" "mr")))
9527 (mult:HI (match_dup 1) (match_dup 2)))))
9528 (set (match_operand:HI 0 "register_operand" "=r")
9529 (mult:HI (match_dup 1) (match_dup 2)))]
9530 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9531 "imul{w}\t{%2, %0|%0, %2}"
9532 [(set_attr "type" "imul")
9533 (set_attr "prefix_0f" "1")
9534 (set_attr "athlon_decode" "vector")
9535 (set_attr "amdfam10_decode" "direct")
9536 (set_attr "bdver1_decode" "double")
9537 (set_attr "mode" "HI")])
9539 (define_insn "*mulv<mode>4_1"
9540 [(set (reg:CCO FLAGS_REG)
9543 (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
9544 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
9546 (mult:SWI248 (match_dup 1)
9547 (match_operand:SWI248 2
9548 "<immediate_operand>" "K,<i>")))))
9549 (set (match_operand:SWI248 0 "register_operand" "=r,r")
9550 (mult:SWI248 (match_dup 1) (match_dup 2)))]
9551 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
9552 && CONST_INT_P (operands[2])
9553 && INTVAL (operands[2]) == INTVAL (operands[3])"
9554 "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
9555 [(set_attr "type" "imul")
9556 (set (attr "prefix_0f")
9558 (match_test "<MODE>mode == HImode")
9560 (const_string "*")))
9561 (set (attr "athlon_decode")
9562 (cond [(eq_attr "cpu" "athlon")
9563 (const_string "vector")
9564 (eq_attr "alternative" "1")
9565 (const_string "vector")]
9566 (const_string "direct")))
9567 (set (attr "amdfam10_decode")
9568 (cond [(ior (match_test "<MODE>mode == HImode")
9569 (match_operand 1 "memory_operand"))
9570 (const_string "vector")]
9571 (const_string "direct")))
9572 (set (attr "bdver1_decode")
9574 (match_test "<MODE>mode == HImode")
9575 (const_string "double")
9576 (const_string "direct")))
9577 (set_attr "mode" "<MODE>")
9578 (set (attr "length_immediate")
9579 (cond [(eq_attr "alternative" "0")
9581 (match_test "<MODE_SIZE> == 8")
9583 (const_string "<MODE_SIZE>")))])
9585 (define_expand "umulv<mode>4"
9586 [(parallel [(set (reg:CCO FLAGS_REG)
9589 (match_operand:SWI248 1
9590 "nonimmediate_operand"))
9592 (match_operand:SWI248 2
9593 "nonimmediate_operand")))
9595 (mult:SWI248 (match_dup 1) (match_dup 2)))))
9596 (set (match_operand:SWI248 0 "register_operand")
9597 (mult:SWI248 (match_dup 1) (match_dup 2)))
9598 (clobber (scratch:SWI248))])
9599 (set (pc) (if_then_else
9600 (eq (reg:CCO FLAGS_REG) (const_int 0))
9601 (label_ref (match_operand 3))
9605 if (MEM_P (operands[1]) && MEM_P (operands[2]))
9606 operands[1] = force_reg (<MODE>mode, operands[1]);
9609 (define_insn "*umulv<mode>4"
9610 [(set (reg:CCO FLAGS_REG)
9613 (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
9615 (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
9617 (mult:SWI248 (match_dup 1) (match_dup 2)))))
9618 (set (match_operand:SWI248 0 "register_operand" "=a")
9619 (mult:SWI248 (match_dup 1) (match_dup 2)))
9620 (clobber (match_scratch:SWI248 3 "=d"))]
9621 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9622 "mul{<imodesuffix>}\t%2"
9623 [(set_attr "type" "imul")
9624 (set_attr "length_immediate" "0")
9625 (set (attr "athlon_decode")
9626 (if_then_else (eq_attr "cpu" "athlon")
9627 (const_string "vector")
9628 (const_string "double")))
9629 (set_attr "amdfam10_decode" "double")
9630 (set_attr "bdver1_decode" "direct")
9631 (set_attr "mode" "<MODE>")])
9633 (define_expand "<u>mulvqi4"
9634 [(parallel [(set (reg:CCO FLAGS_REG)
9637 (match_operand:QI 1 "nonimmediate_operand"))
9639 (match_operand:QI 2 "nonimmediate_operand")))
9641 (mult:QI (match_dup 1) (match_dup 2)))))
9642 (set (match_operand:QI 0 "register_operand")
9643 (mult:QI (match_dup 1) (match_dup 2)))])
9644 (set (pc) (if_then_else
9645 (eq (reg:CCO FLAGS_REG) (const_int 0))
9646 (label_ref (match_operand 3))
9648 "TARGET_QIMODE_MATH"
9650 if (MEM_P (operands[1]) && MEM_P (operands[2]))
9651 operands[1] = force_reg (QImode, operands[1]);
9654 (define_insn "*<u>mulvqi4"
9655 [(set (reg:CCO FLAGS_REG)
9658 (match_operand:QI 1 "nonimmediate_operand" "%0"))
9660 (match_operand:QI 2 "nonimmediate_operand" "qm")))
9662 (mult:QI (match_dup 1) (match_dup 2)))))
9663 (set (match_operand:QI 0 "register_operand" "=a")
9664 (mult:QI (match_dup 1) (match_dup 2)))]
9666 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9667 "<sgnprefix>mul{b}\t%2"
9668 [(set_attr "type" "imul")
9669 (set_attr "length_immediate" "0")
9670 (set (attr "athlon_decode")
9671 (if_then_else (eq_attr "cpu" "athlon")
9672 (const_string "vector")
9673 (const_string "direct")))
9674 (set_attr "amdfam10_decode" "direct")
9675 (set_attr "bdver1_decode" "direct")
9676 (set_attr "mode" "QI")])
9678 (define_expand "<u>mul<mode><dwi>3"
9679 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
9682 (match_operand:DWIH 1 "register_operand"))
9684 (match_operand:DWIH 2 "nonimmediate_operand"))))
9685 (clobber (reg:CC FLAGS_REG))])])
9687 (define_expand "<u>mulqihi3"
9688 [(parallel [(set (match_operand:HI 0 "register_operand")
9691 (match_operand:QI 1 "register_operand"))
9693 (match_operand:QI 2 "nonimmediate_operand"))))
9694 (clobber (reg:CC FLAGS_REG))])]
9695 "TARGET_QIMODE_MATH")
9697 (define_insn "*bmi2_umul<mode><dwi>3_1"
9698 [(set (match_operand:DWIH 0 "register_operand" "=r")
9700 (match_operand:DWIH 2 "register_operand" "%d")
9701 (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
9702 (set (match_operand:DWIH 1 "register_operand" "=r")
9703 (umul_highpart:DWIH (match_dup 2) (match_dup 3)))]
9705 "mulx\t{%3, %0, %1|%1, %0, %3}"
9706 [(set_attr "type" "imulx")
9707 (set_attr "prefix" "vex")
9708 (set_attr "mode" "<MODE>")])
9710 ;; Tweak *bmi2_umul<mode><dwi>3_1 to eliminate following mov.
9712 [(parallel [(set (match_operand:DWIH 0 "general_reg_operand")
9713 (mult:DWIH (match_operand:DWIH 2 "register_operand")
9714 (match_operand:DWIH 3 "nonimmediate_operand")))
9715 (set (match_operand:DWIH 1 "general_reg_operand")
9716 (umul_highpart:DWIH (match_dup 2) (match_dup 3)))])
9717 (set (match_operand:DWIH 4 "general_reg_operand")
9718 (match_operand:DWIH 5 "general_reg_operand"))]
9720 && ((REGNO (operands[5]) == REGNO (operands[0])
9721 && REGNO (operands[1]) != REGNO (operands[4]))
9722 || (REGNO (operands[5]) == REGNO (operands[1])
9723 && REGNO (operands[0]) != REGNO (operands[4])))
9724 && peep2_reg_dead_p (2, operands[5])"
9725 [(parallel [(set (match_dup 0) (mult:DWIH (match_dup 2) (match_dup 3)))
9727 (umul_highpart:DWIH (match_dup 2) (match_dup 3)))])]
9729 if (REGNO (operands[5]) == REGNO (operands[0]))
9730 operands[0] = operands[4];
9732 operands[1] = operands[4];
9735 (define_insn "*umul<mode><dwi>3_1"
9736 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
9739 (match_operand:DWIH 1 "register_operand" "%d,a"))
9741 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
9742 (clobber (reg:CC FLAGS_REG))]
9743 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9746 mul{<imodesuffix>}\t%2"
9747 [(set_attr "isa" "bmi2,*")
9748 (set_attr "type" "imulx,imul")
9749 (set_attr "length_immediate" "*,0")
9750 (set (attr "athlon_decode")
9751 (cond [(eq_attr "alternative" "1")
9752 (if_then_else (eq_attr "cpu" "athlon")
9753 (const_string "vector")
9754 (const_string "double"))]
9755 (const_string "*")))
9756 (set_attr "amdfam10_decode" "*,double")
9757 (set_attr "bdver1_decode" "*,direct")
9758 (set_attr "prefix" "vex,orig")
9759 (set_attr "mode" "<MODE>")])
9761 ;; Convert mul to the mulx pattern to avoid flags dependency.
9763 [(set (match_operand:<DWI> 0 "register_operand")
9766 (match_operand:DWIH 1 "register_operand"))
9768 (match_operand:DWIH 2 "nonimmediate_operand"))))
9769 (clobber (reg:CC FLAGS_REG))]
9770 "TARGET_BMI2 && reload_completed
9771 && REGNO (operands[1]) == DX_REG"
9772 [(parallel [(set (match_dup 3)
9773 (mult:DWIH (match_dup 1) (match_dup 2)))
9775 (umul_highpart:DWIH (match_dup 1) (match_dup 2)))])]
9777 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
9779 operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
9782 (define_insn "*mul<mode><dwi>3_1"
9783 [(set (match_operand:<DWI> 0 "register_operand" "=A")
9786 (match_operand:DWIH 1 "register_operand" "%a"))
9788 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
9789 (clobber (reg:CC FLAGS_REG))]
9790 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9791 "imul{<imodesuffix>}\t%2"
9792 [(set_attr "type" "imul")
9793 (set_attr "length_immediate" "0")
9794 (set (attr "athlon_decode")
9795 (if_then_else (eq_attr "cpu" "athlon")
9796 (const_string "vector")
9797 (const_string "double")))
9798 (set_attr "amdfam10_decode" "double")
9799 (set_attr "bdver1_decode" "direct")
9800 (set_attr "mode" "<MODE>")])
9802 (define_insn "*<u>mulqihi3_1"
9803 [(set (match_operand:HI 0 "register_operand" "=a")
9806 (match_operand:QI 1 "register_operand" "%0"))
9808 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
9809 (clobber (reg:CC FLAGS_REG))]
9811 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9812 "<sgnprefix>mul{b}\t%2"
9813 [(set_attr "type" "imul")
9814 (set_attr "length_immediate" "0")
9815 (set (attr "athlon_decode")
9816 (if_then_else (eq_attr "cpu" "athlon")
9817 (const_string "vector")
9818 (const_string "direct")))
9819 (set_attr "amdfam10_decode" "direct")
9820 (set_attr "bdver1_decode" "direct")
9821 (set_attr "mode" "QI")])
9823 ;; Widening multiplication peephole2s to tweak register allocation.
9824 ;; mov imm,%rdx; mov %rdi,%rax; mulq %rdx -> mov imm,%rax; mulq %rdi
9826 [(set (match_operand:DWIH 0 "general_reg_operand")
9827 (match_operand:DWIH 1 "immediate_operand"))
9828 (set (match_operand:DWIH 2 "general_reg_operand")
9829 (match_operand:DWIH 3 "general_reg_operand"))
9830 (parallel [(set (match_operand:<DWI> 4 "general_reg_operand")
9831 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
9832 (zero_extend:<DWI> (match_dup 0))))
9833 (clobber (reg:CC FLAGS_REG))])]
9834 "REGNO (operands[3]) != AX_REG
9835 && REGNO (operands[0]) != REGNO (operands[2])
9836 && REGNO (operands[0]) != REGNO (operands[3])
9837 && (REGNO (operands[0]) == REGNO (operands[4])
9838 || REGNO (operands[0]) == DX_REG
9839 || peep2_reg_dead_p (3, operands[0]))"
9840 [(set (match_dup 2) (match_dup 1))
9841 (parallel [(set (match_dup 4)
9842 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
9843 (zero_extend:<DWI> (match_dup 3))))
9844 (clobber (reg:CC FLAGS_REG))])])
9846 ;; mov imm,%rax; mov %rdi,%rdx; mulx %rax -> mov imm,%rdx; mulx %rdi
9848 [(set (match_operand:DWIH 0 "general_reg_operand")
9849 (match_operand:DWIH 1 "immediate_operand"))
9850 (set (match_operand:DWIH 2 "general_reg_operand")
9851 (match_operand:DWIH 3 "general_reg_operand"))
9852 (parallel [(set (match_operand:DWIH 4 "general_reg_operand")
9853 (mult:DWIH (match_dup 2) (match_dup 0)))
9854 (set (match_operand:DWIH 5 "general_reg_operand")
9855 (umul_highpart:DWIH (match_dup 2) (match_dup 0)))])]
9856 "REGNO (operands[3]) != DX_REG
9857 && REGNO (operands[0]) != REGNO (operands[2])
9858 && REGNO (operands[0]) != REGNO (operands[3])
9859 && (REGNO (operands[0]) == REGNO (operands[4])
9860 || REGNO (operands[0]) == REGNO (operands[5])
9861 || peep2_reg_dead_p (3, operands[0]))"
9862 [(set (match_dup 2) (match_dup 1))
9863 (parallel [(set (match_dup 4)
9864 (mult:DWIH (match_dup 2) (match_dup 3)))
9866 (umul_highpart:DWIH (match_dup 2) (match_dup 3)))])])
9868 ;; Highpart multiplication patterns
9869 (define_insn "<s>mul<mode>3_highpart"
9870 [(set (match_operand:DWIH 0 "register_operand" "=d")
9871 (any_mul_highpart:DWIH
9872 (match_operand:DWIH 1 "register_operand" "%a")
9873 (match_operand:DWIH 2 "nonimmediate_operand" "rm")))
9874 (clobber (match_scratch:DWIH 3 "=1"))
9875 (clobber (reg:CC FLAGS_REG))]
9877 "<sgnprefix>mul{<imodesuffix>}\t%2"
9878 [(set_attr "type" "imul")
9879 (set_attr "length_immediate" "0")
9880 (set (attr "athlon_decode")
9881 (if_then_else (eq_attr "cpu" "athlon")
9882 (const_string "vector")
9883 (const_string "double")))
9884 (set_attr "amdfam10_decode" "double")
9885 (set_attr "bdver1_decode" "direct")
9886 (set_attr "mode" "<MODE>")])
9888 (define_insn "*<s>mulsi3_highpart_zext"
9889 [(set (match_operand:DI 0 "register_operand" "=d")
9891 (any_mul_highpart:SI
9892 (match_operand:SI 1 "register_operand" "%a")
9893 (match_operand:SI 2 "nonimmediate_operand" "rm"))))
9894 (clobber (match_scratch:SI 3 "=1"))
9895 (clobber (reg:CC FLAGS_REG))]
9897 "<sgnprefix>mul{l}\t%2"
9898 [(set_attr "type" "imul")
9899 (set_attr "length_immediate" "0")
9900 (set (attr "athlon_decode")
9901 (if_then_else (eq_attr "cpu" "athlon")
9902 (const_string "vector")
9903 (const_string "double")))
9904 (set_attr "amdfam10_decode" "double")
9905 (set_attr "bdver1_decode" "direct")
9906 (set_attr "mode" "SI")])
9908 (define_insn "*<s>muldi3_highpart_1"
9909 [(set (match_operand:DI 0 "register_operand" "=d")
9914 (match_operand:DI 1 "nonimmediate_operand" "%a"))
9916 (match_operand:DI 2 "nonimmediate_operand" "rm")))
9918 (clobber (match_scratch:DI 3 "=1"))
9919 (clobber (reg:CC FLAGS_REG))]
9921 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9922 "<sgnprefix>mul{q}\t%2"
9923 [(set_attr "type" "imul")
9924 (set_attr "length_immediate" "0")
9925 (set (attr "athlon_decode")
9926 (if_then_else (eq_attr "cpu" "athlon")
9927 (const_string "vector")
9928 (const_string "double")))
9929 (set_attr "amdfam10_decode" "double")
9930 (set_attr "bdver1_decode" "direct")
9931 (set_attr "mode" "DI")])
9933 (define_insn "*<s>mulsi3_highpart_zext"
9934 [(set (match_operand:DI 0 "register_operand" "=d")
9935 (zero_extend:DI (truncate:SI
9937 (mult:DI (any_extend:DI
9938 (match_operand:SI 1 "nonimmediate_operand" "%a"))
9940 (match_operand:SI 2 "nonimmediate_operand" "rm")))
9942 (clobber (match_scratch:SI 3 "=1"))
9943 (clobber (reg:CC FLAGS_REG))]
9945 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9946 "<sgnprefix>mul{l}\t%2"
9947 [(set_attr "type" "imul")
9948 (set_attr "length_immediate" "0")
9949 (set (attr "athlon_decode")
9950 (if_then_else (eq_attr "cpu" "athlon")
9951 (const_string "vector")
9952 (const_string "double")))
9953 (set_attr "amdfam10_decode" "double")
9954 (set_attr "bdver1_decode" "direct")
9955 (set_attr "mode" "SI")])
9957 (define_insn "*<s>mulsi3_highpart_1"
9958 [(set (match_operand:SI 0 "register_operand" "=d")
9963 (match_operand:SI 1 "nonimmediate_operand" "%a"))
9965 (match_operand:SI 2 "nonimmediate_operand" "rm")))
9967 (clobber (match_scratch:SI 3 "=1"))
9968 (clobber (reg:CC FLAGS_REG))]
9969 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9970 "<sgnprefix>mul{l}\t%2"
9971 [(set_attr "type" "imul")
9972 (set_attr "length_immediate" "0")
9973 (set (attr "athlon_decode")
9974 (if_then_else (eq_attr "cpu" "athlon")
9975 (const_string "vector")
9976 (const_string "double")))
9977 (set_attr "amdfam10_decode" "double")
9978 (set_attr "bdver1_decode" "direct")
9979 (set_attr "mode" "SI")])
9981 ;; Highpart multiplication peephole2s to tweak register allocation.
9982 ;; mov imm,%rdx; mov %rdi,%rax; imulq %rdx -> mov imm,%rax; imulq %rdi
9984 [(set (match_operand:SWI48 0 "general_reg_operand")
9985 (match_operand:SWI48 1 "immediate_operand"))
9986 (set (match_operand:SWI48 2 "general_reg_operand")
9987 (match_operand:SWI48 3 "general_reg_operand"))
9988 (parallel [(set (match_operand:SWI48 4 "general_reg_operand")
9989 (any_mul_highpart:SWI48 (match_dup 2) (match_dup 0)))
9990 (clobber (match_dup 2))
9991 (clobber (reg:CC FLAGS_REG))])]
9992 "REGNO (operands[3]) != AX_REG
9993 && REGNO (operands[0]) != REGNO (operands[2])
9994 && REGNO (operands[0]) != REGNO (operands[3])
9995 && (REGNO (operands[0]) == REGNO (operands[4])
9996 || peep2_reg_dead_p (3, operands[0]))"
9997 [(set (match_dup 2) (match_dup 1))
9998 (parallel [(set (match_dup 4)
9999 (any_mul_highpart:SWI48 (match_dup 2) (match_dup 3)))
10000 (clobber (match_dup 2))
10001 (clobber (reg:CC FLAGS_REG))])])
10004 [(set (match_operand:SI 0 "general_reg_operand")
10005 (match_operand:SI 1 "immediate_operand"))
10006 (set (match_operand:SI 2 "general_reg_operand")
10007 (match_operand:SI 3 "general_reg_operand"))
10008 (parallel [(set (match_operand:DI 4 "general_reg_operand")
10010 (any_mul_highpart:SI (match_dup 2) (match_dup 0))))
10011 (clobber (match_dup 2))
10012 (clobber (reg:CC FLAGS_REG))])]
10014 && REGNO (operands[3]) != AX_REG
10015 && REGNO (operands[0]) != REGNO (operands[2])
10016 && REGNO (operands[2]) != REGNO (operands[3])
10017 && REGNO (operands[0]) != REGNO (operands[3])
10018 && (REGNO (operands[0]) == REGNO (operands[4])
10019 || peep2_reg_dead_p (3, operands[0]))"
10020 [(set (match_dup 2) (match_dup 1))
10021 (parallel [(set (match_dup 4)
10023 (any_mul_highpart:SI (match_dup 2) (match_dup 3))))
10024 (clobber (match_dup 2))
10025 (clobber (reg:CC FLAGS_REG))])])
10027 ;; The patterns that match these are at the end of this file.
10029 (define_expand "mulxf3"
10030 [(set (match_operand:XF 0 "register_operand")
10031 (mult:XF (match_operand:XF 1 "register_operand")
10032 (match_operand:XF 2 "register_operand")))]
10035 (define_expand "mulhf3"
10036 [(set (match_operand:HF 0 "register_operand")
10037 (mult:HF (match_operand:HF 1 "register_operand")
10038 (match_operand:HF 2 "nonimmediate_operand")))]
10039 "TARGET_AVX512FP16")
10041 (define_expand "mul<mode>3"
10042 [(set (match_operand:MODEF 0 "register_operand")
10043 (mult:MODEF (match_operand:MODEF 1 "register_operand")
10044 (match_operand:MODEF 2 "nonimmediate_operand")))]
10045 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
10046 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
10048 ;; Divide instructions
10050 ;; The patterns that match these are at the end of this file.
10052 (define_expand "divxf3"
10053 [(set (match_operand:XF 0 "register_operand")
10054 (div:XF (match_operand:XF 1 "register_operand")
10055 (match_operand:XF 2 "register_operand")))]
10058 /* There is no more precision loss than Newton-Rhapson approximation
10059 when using HFmode rcp/rsqrt, so do the transformation directly under
10060 TARGET_RECIP_DIV and fast-math. */
10061 (define_expand "divhf3"
10062 [(set (match_operand:HF 0 "register_operand")
10063 (div:HF (match_operand:HF 1 "register_operand")
10064 (match_operand:HF 2 "nonimmediate_operand")))]
10065 "TARGET_AVX512FP16"
10067 if (TARGET_RECIP_DIV
10068 && optimize_insn_for_speed_p ()
10069 && flag_finite_math_only && !flag_trapping_math
10070 && flag_unsafe_math_optimizations)
10072 rtx op = gen_reg_rtx (HFmode);
10073 operands[2] = force_reg (HFmode, operands[2]);
10074 emit_insn (gen_rcphf2 (op, operands[2]));
10075 emit_insn (gen_mulhf3 (operands[0], operands[1], op));
10080 (define_expand "div<mode>3"
10081 [(set (match_operand:MODEF 0 "register_operand")
10082 (div:MODEF (match_operand:MODEF 1 "register_operand")
10083 (match_operand:MODEF 2 "nonimmediate_operand")))]
10084 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
10085 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10087 if (<MODE>mode == SFmode
10088 && TARGET_SSE && TARGET_SSE_MATH
10089 && TARGET_RECIP_DIV
10090 && optimize_insn_for_speed_p ()
10091 && flag_finite_math_only && !flag_trapping_math
10092 && flag_unsafe_math_optimizations)
10094 ix86_emit_swdivsf (operands[0], operands[1],
10095 operands[2], SFmode);
10100 ;; Divmod instructions.
10102 (define_code_iterator any_div [div udiv])
10103 (define_code_attr paired_mod [(div "mod") (udiv "umod")])
10105 (define_expand "<u>divmod<mode>4"
10106 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
10108 (match_operand:SWIM248 1 "register_operand")
10109 (match_operand:SWIM248 2 "nonimmediate_operand")))
10110 (set (match_operand:SWIM248 3 "register_operand")
10111 (<paired_mod>:SWIM248 (match_dup 1) (match_dup 2)))
10112 (clobber (reg:CC FLAGS_REG))])])
10114 ;; Split with 8bit unsigned divide:
10115 ;; if (dividend an divisor are in [0-255])
10116 ;; use 8bit unsigned integer divide
10118 ;; use original integer divide
10120 [(set (match_operand:SWI48 0 "register_operand")
10121 (any_div:SWI48 (match_operand:SWI48 2 "register_operand")
10122 (match_operand:SWI48 3 "nonimmediate_operand")))
10123 (set (match_operand:SWI48 1 "register_operand")
10124 (<paired_mod>:SWI48 (match_dup 2) (match_dup 3)))
10125 (clobber (reg:CC FLAGS_REG))]
10126 "TARGET_USE_8BIT_IDIV
10127 && TARGET_QIMODE_MATH
10128 && can_create_pseudo_p ()
10129 && !optimize_insn_for_size_p ()"
10131 "ix86_split_idivmod (<MODE>mode, operands, <u_bool>); DONE;")
10134 [(set (match_operand:DI 0 "register_operand")
10136 (any_div:SI (match_operand:SI 2 "register_operand")
10137 (match_operand:SI 3 "nonimmediate_operand"))))
10138 (set (match_operand:SI 1 "register_operand")
10139 (<paired_mod>:SI (match_dup 2) (match_dup 3)))
10140 (clobber (reg:CC FLAGS_REG))]
10142 && TARGET_USE_8BIT_IDIV
10143 && TARGET_QIMODE_MATH
10144 && can_create_pseudo_p ()
10145 && !optimize_insn_for_size_p ()"
10147 "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
10150 [(set (match_operand:DI 1 "register_operand")
10152 (<paired_mod>:SI (match_operand:SI 2 "register_operand")
10153 (match_operand:SI 3 "nonimmediate_operand"))))
10154 (set (match_operand:SI 0 "register_operand")
10155 (any_div:SI (match_dup 2) (match_dup 3)))
10156 (clobber (reg:CC FLAGS_REG))]
10158 && TARGET_USE_8BIT_IDIV
10159 && TARGET_QIMODE_MATH
10160 && can_create_pseudo_p ()
10161 && !optimize_insn_for_size_p ()"
10163 "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
10165 (define_insn_and_split "divmod<mode>4_1"
10166 [(set (match_operand:SWI48 0 "register_operand" "=a")
10167 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
10168 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
10169 (set (match_operand:SWI48 1 "register_operand" "=&d")
10170 (mod:SWI48 (match_dup 2) (match_dup 3)))
10171 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10172 (clobber (reg:CC FLAGS_REG))]
10176 [(parallel [(set (match_dup 1)
10177 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
10178 (clobber (reg:CC FLAGS_REG))])
10179 (parallel [(set (match_dup 0)
10180 (div:SWI48 (match_dup 2) (match_dup 3)))
10182 (mod:SWI48 (match_dup 2) (match_dup 3)))
10183 (use (match_dup 1))
10184 (clobber (reg:CC FLAGS_REG))])]
10186 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
10188 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10189 operands[4] = operands[2];
10192 /* Avoid use of cltd in favor of a mov+shift. */
10193 emit_move_insn (operands[1], operands[2]);
10194 operands[4] = operands[1];
10197 [(set_attr "type" "multi")
10198 (set_attr "mode" "<MODE>")])
10200 (define_insn_and_split "udivmod<mode>4_1"
10201 [(set (match_operand:SWI48 0 "register_operand" "=a")
10202 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
10203 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
10204 (set (match_operand:SWI48 1 "register_operand" "=&d")
10205 (umod:SWI48 (match_dup 2) (match_dup 3)))
10206 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10207 (clobber (reg:CC FLAGS_REG))]
10211 [(set (match_dup 1) (const_int 0))
10212 (parallel [(set (match_dup 0)
10213 (udiv:SWI48 (match_dup 2) (match_dup 3)))
10215 (umod:SWI48 (match_dup 2) (match_dup 3)))
10216 (use (match_dup 1))
10217 (clobber (reg:CC FLAGS_REG))])]
10219 [(set_attr "type" "multi")
10220 (set_attr "mode" "<MODE>")])
10222 (define_insn_and_split "divmodsi4_zext_1"
10223 [(set (match_operand:DI 0 "register_operand" "=a")
10225 (div:SI (match_operand:SI 2 "register_operand" "0")
10226 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10227 (set (match_operand:SI 1 "register_operand" "=&d")
10228 (mod:SI (match_dup 2) (match_dup 3)))
10229 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10230 (clobber (reg:CC FLAGS_REG))]
10233 "&& reload_completed"
10234 [(parallel [(set (match_dup 1)
10235 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10236 (clobber (reg:CC FLAGS_REG))])
10237 (parallel [(set (match_dup 0)
10238 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
10240 (mod:SI (match_dup 2) (match_dup 3)))
10241 (use (match_dup 1))
10242 (clobber (reg:CC FLAGS_REG))])]
10244 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10246 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10247 operands[4] = operands[2];
10250 /* Avoid use of cltd in favor of a mov+shift. */
10251 emit_move_insn (operands[1], operands[2]);
10252 operands[4] = operands[1];
10255 [(set_attr "type" "multi")
10256 (set_attr "mode" "SI")])
10258 (define_insn_and_split "udivmodsi4_zext_1"
10259 [(set (match_operand:DI 0 "register_operand" "=a")
10261 (udiv:SI (match_operand:SI 2 "register_operand" "0")
10262 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10263 (set (match_operand:SI 1 "register_operand" "=&d")
10264 (umod:SI (match_dup 2) (match_dup 3)))
10265 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10266 (clobber (reg:CC FLAGS_REG))]
10269 "&& reload_completed"
10270 [(set (match_dup 1) (const_int 0))
10271 (parallel [(set (match_dup 0)
10272 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
10274 (umod:SI (match_dup 2) (match_dup 3)))
10275 (use (match_dup 1))
10276 (clobber (reg:CC FLAGS_REG))])]
10278 [(set_attr "type" "multi")
10279 (set_attr "mode" "SI")])
10281 (define_insn_and_split "divmodsi4_zext_2"
10282 [(set (match_operand:DI 1 "register_operand" "=&d")
10284 (mod:SI (match_operand:SI 2 "register_operand" "0")
10285 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10286 (set (match_operand:SI 0 "register_operand" "=a")
10287 (div:SI (match_dup 2) (match_dup 3)))
10288 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10289 (clobber (reg:CC FLAGS_REG))]
10292 "&& reload_completed"
10293 [(parallel [(set (match_dup 6)
10294 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10295 (clobber (reg:CC FLAGS_REG))])
10296 (parallel [(set (match_dup 1)
10297 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
10299 (div:SI (match_dup 2) (match_dup 3)))
10300 (use (match_dup 6))
10301 (clobber (reg:CC FLAGS_REG))])]
10303 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10304 operands[6] = gen_lowpart (SImode, operands[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[6], operands[2]);
10312 operands[4] = operands[6];
10315 [(set_attr "type" "multi")
10316 (set_attr "mode" "SI")])
10318 (define_insn_and_split "udivmodsi4_zext_2"
10319 [(set (match_operand:DI 1 "register_operand" "=&d")
10321 (umod:SI (match_operand:SI 2 "register_operand" "0")
10322 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10323 (set (match_operand:SI 0 "register_operand" "=a")
10324 (udiv: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 4) (const_int 0))
10331 (parallel [(set (match_dup 1)
10332 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
10334 (udiv:SI (match_dup 2) (match_dup 3)))
10335 (use (match_dup 4))
10336 (clobber (reg:CC FLAGS_REG))])]
10337 "operands[4] = gen_lowpart (SImode, operands[1]);"
10338 [(set_attr "type" "multi")
10339 (set_attr "mode" "SI")])
10341 (define_insn_and_split "*divmod<mode>4"
10342 [(set (match_operand:SWIM248 0 "register_operand" "=a")
10343 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
10344 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
10345 (set (match_operand:SWIM248 1 "register_operand" "=&d")
10346 (mod:SWIM248 (match_dup 2) (match_dup 3)))
10347 (clobber (reg:CC FLAGS_REG))]
10351 [(parallel [(set (match_dup 1)
10352 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
10353 (clobber (reg:CC FLAGS_REG))])
10354 (parallel [(set (match_dup 0)
10355 (div:SWIM248 (match_dup 2) (match_dup 3)))
10357 (mod:SWIM248 (match_dup 2) (match_dup 3)))
10358 (use (match_dup 1))
10359 (clobber (reg:CC FLAGS_REG))])]
10361 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
10363 if (<MODE>mode != HImode
10364 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
10365 operands[4] = operands[2];
10368 /* Avoid use of cltd in favor of a mov+shift. */
10369 emit_move_insn (operands[1], operands[2]);
10370 operands[4] = operands[1];
10373 [(set_attr "type" "multi")
10374 (set_attr "mode" "<MODE>")])
10376 (define_insn_and_split "*udivmod<mode>4"
10377 [(set (match_operand:SWIM248 0 "register_operand" "=a")
10378 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
10379 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
10380 (set (match_operand:SWIM248 1 "register_operand" "=&d")
10381 (umod:SWIM248 (match_dup 2) (match_dup 3)))
10382 (clobber (reg:CC FLAGS_REG))]
10386 [(set (match_dup 1) (const_int 0))
10387 (parallel [(set (match_dup 0)
10388 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
10390 (umod:SWIM248 (match_dup 2) (match_dup 3)))
10391 (use (match_dup 1))
10392 (clobber (reg:CC FLAGS_REG))])]
10394 [(set_attr "type" "multi")
10395 (set_attr "mode" "<MODE>")])
10397 ;; Optimize division or modulo by constant power of 2, if the constant
10398 ;; materializes only after expansion.
10399 (define_insn_and_split "*udivmod<mode>4_pow2"
10400 [(set (match_operand:SWI48 0 "register_operand" "=r")
10401 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
10402 (match_operand:SWI48 3 "const_int_operand")))
10403 (set (match_operand:SWI48 1 "register_operand" "=r")
10404 (umod:SWI48 (match_dup 2) (match_dup 3)))
10405 (clobber (reg:CC FLAGS_REG))]
10406 "IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
10408 "&& reload_completed"
10409 [(set (match_dup 1) (match_dup 2))
10410 (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
10411 (clobber (reg:CC FLAGS_REG))])
10412 (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
10413 (clobber (reg:CC FLAGS_REG))])]
10415 int v = exact_log2 (UINTVAL (operands[3]));
10416 operands[4] = GEN_INT (v);
10417 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
10419 [(set_attr "type" "multi")
10420 (set_attr "mode" "<MODE>")])
10422 (define_insn_and_split "*divmodsi4_zext_1"
10423 [(set (match_operand:DI 0 "register_operand" "=a")
10425 (div:SI (match_operand:SI 2 "register_operand" "0")
10426 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10427 (set (match_operand:SI 1 "register_operand" "=&d")
10428 (mod:SI (match_dup 2) (match_dup 3)))
10429 (clobber (reg:CC FLAGS_REG))]
10432 "&& reload_completed"
10433 [(parallel [(set (match_dup 1)
10434 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10435 (clobber (reg:CC FLAGS_REG))])
10436 (parallel [(set (match_dup 0)
10437 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
10439 (mod:SI (match_dup 2) (match_dup 3)))
10440 (use (match_dup 1))
10441 (clobber (reg:CC FLAGS_REG))])]
10443 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10445 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10446 operands[4] = operands[2];
10449 /* Avoid use of cltd in favor of a mov+shift. */
10450 emit_move_insn (operands[1], operands[2]);
10451 operands[4] = operands[1];
10454 [(set_attr "type" "multi")
10455 (set_attr "mode" "SI")])
10457 (define_insn_and_split "*udivmodsi4_zext_1"
10458 [(set (match_operand:DI 0 "register_operand" "=a")
10460 (udiv:SI (match_operand:SI 2 "register_operand" "0")
10461 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10462 (set (match_operand:SI 1 "register_operand" "=&d")
10463 (umod:SI (match_dup 2) (match_dup 3)))
10464 (clobber (reg:CC FLAGS_REG))]
10467 "&& reload_completed"
10468 [(set (match_dup 1) (const_int 0))
10469 (parallel [(set (match_dup 0)
10470 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
10472 (umod:SI (match_dup 2) (match_dup 3)))
10473 (use (match_dup 1))
10474 (clobber (reg:CC FLAGS_REG))])]
10476 [(set_attr "type" "multi")
10477 (set_attr "mode" "SI")])
10479 (define_insn_and_split "*udivmodsi4_pow2_zext_1"
10480 [(set (match_operand:DI 0 "register_operand" "=r")
10482 (udiv:SI (match_operand:SI 2 "register_operand" "0")
10483 (match_operand:SI 3 "const_int_operand"))))
10484 (set (match_operand:SI 1 "register_operand" "=r")
10485 (umod:SI (match_dup 2) (match_dup 3)))
10486 (clobber (reg:CC FLAGS_REG))]
10488 && IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
10490 "&& reload_completed"
10491 [(set (match_dup 1) (match_dup 2))
10492 (parallel [(set (match_dup 0)
10493 (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4))))
10494 (clobber (reg:CC FLAGS_REG))])
10495 (parallel [(set (match_dup 1) (and:SI (match_dup 1) (match_dup 5)))
10496 (clobber (reg:CC FLAGS_REG))])]
10498 int v = exact_log2 (UINTVAL (operands[3]));
10499 operands[4] = GEN_INT (v);
10500 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
10502 [(set_attr "type" "multi")
10503 (set_attr "mode" "SI")])
10505 (define_insn_and_split "*divmodsi4_zext_2"
10506 [(set (match_operand:DI 1 "register_operand" "=&d")
10508 (mod:SI (match_operand:SI 2 "register_operand" "0")
10509 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10510 (set (match_operand:SI 0 "register_operand" "=a")
10511 (div:SI (match_dup 2) (match_dup 3)))
10512 (clobber (reg:CC FLAGS_REG))]
10515 "&& reload_completed"
10516 [(parallel [(set (match_dup 6)
10517 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10518 (clobber (reg:CC FLAGS_REG))])
10519 (parallel [(set (match_dup 1)
10520 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
10522 (div:SI (match_dup 2) (match_dup 3)))
10523 (use (match_dup 6))
10524 (clobber (reg:CC FLAGS_REG))])]
10526 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10527 operands[6] = gen_lowpart (SImode, operands[1]);
10529 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10530 operands[4] = operands[2];
10533 /* Avoid use of cltd in favor of a mov+shift. */
10534 emit_move_insn (operands[6], operands[2]);
10535 operands[4] = operands[6];
10538 [(set_attr "type" "multi")
10539 (set_attr "mode" "SI")])
10541 (define_insn_and_split "*udivmodsi4_zext_2"
10542 [(set (match_operand:DI 1 "register_operand" "=&d")
10544 (umod:SI (match_operand:SI 2 "register_operand" "0")
10545 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10546 (set (match_operand:SI 0 "register_operand" "=a")
10547 (udiv:SI (match_dup 2) (match_dup 3)))
10548 (clobber (reg:CC FLAGS_REG))]
10551 "&& reload_completed"
10552 [(set (match_dup 4) (const_int 0))
10553 (parallel [(set (match_dup 1)
10554 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
10556 (udiv:SI (match_dup 2) (match_dup 3)))
10557 (use (match_dup 4))
10558 (clobber (reg:CC FLAGS_REG))])]
10559 "operands[4] = gen_lowpart (SImode, operands[1]);"
10560 [(set_attr "type" "multi")
10561 (set_attr "mode" "SI")])
10563 (define_insn_and_split "*udivmodsi4_pow2_zext_2"
10564 [(set (match_operand:DI 1 "register_operand" "=r")
10566 (umod:SI (match_operand:SI 2 "register_operand" "0")
10567 (match_operand:SI 3 "const_int_operand"))))
10568 (set (match_operand:SI 0 "register_operand" "=r")
10569 (udiv:SI (match_dup 2) (match_dup 3)))
10570 (clobber (reg:CC FLAGS_REG))]
10572 && IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
10574 "&& reload_completed"
10575 [(set (match_dup 1) (match_dup 2))
10576 (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4)))
10577 (clobber (reg:CC FLAGS_REG))])
10578 (parallel [(set (match_dup 1)
10579 (zero_extend:DI (and:SI (match_dup 1) (match_dup 5))))
10580 (clobber (reg:CC FLAGS_REG))])]
10582 int v = exact_log2 (UINTVAL (operands[3]));
10583 operands[4] = GEN_INT (v);
10584 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
10586 [(set_attr "type" "multi")
10587 (set_attr "mode" "SI")])
10589 (define_insn "*<u>divmod<mode>4_noext"
10590 [(set (match_operand:SWIM248 0 "register_operand" "=a")
10592 (match_operand:SWIM248 2 "register_operand" "0")
10593 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
10594 (set (match_operand:SWIM248 1 "register_operand" "=d")
10595 (<paired_mod>:SWIM248 (match_dup 2) (match_dup 3)))
10596 (use (match_operand:SWIM248 4 "register_operand" "1"))
10597 (clobber (reg:CC FLAGS_REG))]
10599 "<sgnprefix>div{<imodesuffix>}\t%3"
10600 [(set_attr "type" "idiv")
10601 (set_attr "mode" "<MODE>")])
10603 (define_insn "*<u>divmodsi4_noext_zext_1"
10604 [(set (match_operand:DI 0 "register_operand" "=a")
10606 (any_div:SI (match_operand:SI 2 "register_operand" "0")
10607 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10608 (set (match_operand:SI 1 "register_operand" "=d")
10609 (<paired_mod>:SI (match_dup 2) (match_dup 3)))
10610 (use (match_operand:SI 4 "register_operand" "1"))
10611 (clobber (reg:CC FLAGS_REG))]
10613 "<sgnprefix>div{l}\t%3"
10614 [(set_attr "type" "idiv")
10615 (set_attr "mode" "SI")])
10617 (define_insn "*<u>divmodsi4_noext_zext_2"
10618 [(set (match_operand:DI 1 "register_operand" "=d")
10620 (<paired_mod>:SI (match_operand:SI 2 "register_operand" "0")
10621 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10622 (set (match_operand:SI 0 "register_operand" "=a")
10623 (any_div:SI (match_dup 2) (match_dup 3)))
10624 (use (match_operand:SI 4 "register_operand" "1"))
10625 (clobber (reg:CC FLAGS_REG))]
10627 "<sgnprefix>div{l}\t%3"
10628 [(set_attr "type" "idiv")
10629 (set_attr "mode" "SI")])
10631 ;; Avoid sign-extension (using cdq) for constant numerators.
10632 (define_insn_and_split "*divmodsi4_const"
10633 [(set (match_operand:SI 0 "register_operand" "=&a")
10634 (div:SI (match_operand:SI 2 "const_int_operand")
10635 (match_operand:SI 3 "nonimmediate_operand" "rm")))
10636 (set (match_operand:SI 1 "register_operand" "=&d")
10637 (mod:SI (match_dup 2) (match_dup 3)))
10638 (clobber (reg:CC FLAGS_REG))]
10639 "!optimize_function_for_size_p (cfun)"
10641 "&& reload_completed"
10642 [(set (match_dup 0) (match_dup 2))
10643 (set (match_dup 1) (match_dup 4))
10644 (parallel [(set (match_dup 0)
10645 (div:SI (match_dup 0) (match_dup 3)))
10647 (mod:SI (match_dup 0) (match_dup 3)))
10648 (use (match_dup 1))
10649 (clobber (reg:CC FLAGS_REG))])]
10651 operands[4] = INTVAL (operands[2]) < 0 ? constm1_rtx : const0_rtx;
10653 [(set_attr "type" "multi")
10654 (set_attr "mode" "SI")])
10656 (define_expand "divmodqi4"
10657 [(parallel [(set (match_operand:QI 0 "register_operand")
10659 (match_operand:QI 1 "register_operand")
10660 (match_operand:QI 2 "nonimmediate_operand")))
10661 (set (match_operand:QI 3 "register_operand")
10662 (mod:QI (match_dup 1) (match_dup 2)))
10663 (clobber (reg:CC FLAGS_REG))])]
10664 "TARGET_QIMODE_MATH"
10669 tmp0 = gen_reg_rtx (HImode);
10670 tmp1 = gen_reg_rtx (HImode);
10672 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
10673 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
10674 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
10676 /* Extract remainder from AH. */
10677 tmp1 = gen_rtx_ZERO_EXTRACT (HImode, tmp0, GEN_INT (8), GEN_INT (8));
10678 tmp1 = lowpart_subreg (QImode, tmp1, HImode);
10679 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
10681 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
10682 set_unique_reg_note (insn, REG_EQUAL, mod);
10684 /* Extract quotient from AL. */
10685 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
10687 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
10688 set_unique_reg_note (insn, REG_EQUAL, div);
10693 (define_expand "udivmodqi4"
10694 [(parallel [(set (match_operand:QI 0 "register_operand")
10696 (match_operand:QI 1 "register_operand")
10697 (match_operand:QI 2 "nonimmediate_operand")))
10698 (set (match_operand:QI 3 "register_operand")
10699 (umod:QI (match_dup 1) (match_dup 2)))
10700 (clobber (reg:CC FLAGS_REG))])]
10701 "TARGET_QIMODE_MATH"
10706 tmp0 = gen_reg_rtx (HImode);
10707 tmp1 = gen_reg_rtx (HImode);
10709 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
10710 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
10711 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
10713 /* Extract remainder from AH. */
10714 tmp1 = gen_rtx_ZERO_EXTRACT (HImode, tmp0, GEN_INT (8), GEN_INT (8));
10715 tmp1 = lowpart_subreg (QImode, tmp1, HImode);
10716 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
10718 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
10719 set_unique_reg_note (insn, REG_EQUAL, mod);
10721 /* Extract quotient from AL. */
10722 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
10724 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
10725 set_unique_reg_note (insn, REG_EQUAL, div);
10730 ;; Divide AX by r/m8, with result stored in
10733 ;; Change div/mod to HImode and extend the second argument to HImode
10734 ;; so that mode of div/mod matches with mode of arguments. Otherwise
10735 ;; combine may fail.
10736 (define_insn "<u>divmodhiqi3"
10737 [(set (match_operand:HI 0 "register_operand" "=a")
10742 (mod:HI (match_operand:HI 1 "register_operand" "0")
10744 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
10748 (div:HI (match_dup 1) (any_extend:HI (match_dup 2)))))))
10749 (clobber (reg:CC FLAGS_REG))]
10750 "TARGET_QIMODE_MATH"
10751 "<sgnprefix>div{b}\t%2"
10752 [(set_attr "type" "idiv")
10753 (set_attr "mode" "QI")])
10755 ;; We cannot use div/idiv for double division, because it causes
10756 ;; "division by zero" on the overflow and that's not what we expect
10757 ;; from truncate. Because true (non truncating) double division is
10758 ;; never generated, we can't create this insn anyway.
10761 ; [(set (match_operand:SI 0 "register_operand" "=a")
10763 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
10765 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
10766 ; (set (match_operand:SI 3 "register_operand" "=d")
10768 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
10769 ; (clobber (reg:CC FLAGS_REG))]
10771 ; "div{l}\t{%2, %0|%0, %2}"
10772 ; [(set_attr "type" "idiv")])
10774 ;;- Logical AND instructions
10776 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
10777 ;; Note that this excludes ah.
10779 (define_expand "@test<mode>_ccno_1"
10780 [(set (reg:CCNO FLAGS_REG)
10783 (match_operand:SWI48 0 "nonimmediate_operand")
10784 (match_operand:SWI48 1 "<nonmemory_szext_operand>"))
10787 (define_expand "testqi_ccz_1"
10788 [(set (reg:CCZ FLAGS_REG)
10791 (match_operand:QI 0 "nonimmediate_operand")
10792 (match_operand:QI 1 "nonmemory_operand"))
10795 (define_insn "*testdi_1"
10796 [(set (reg FLAGS_REG)
10799 (match_operand:DI 0 "nonimmediate_operand" "%r,rm")
10800 (match_operand:DI 1 "x86_64_szext_nonmemory_operand" "Z,re"))
10803 && ix86_match_ccmode
10805 /* If we are going to emit testl instead of testq, and the operands[1]
10806 constant might have the SImode sign bit set, make sure the sign
10807 flag isn't tested, because the instruction will set the sign flag
10808 based on bit 31 rather than bit 63. If it isn't CONST_INT,
10809 conservatively assume it might have bit 31 set. */
10810 (satisfies_constraint_Z (operands[1])
10811 && (!CONST_INT_P (operands[1])
10812 || val_signbit_known_set_p (SImode, INTVAL (operands[1]))))
10813 ? CCZmode : CCNOmode)"
10815 test{l}\t{%k1, %k0|%k0, %k1}
10816 test{q}\t{%1, %0|%0, %1}"
10817 [(set_attr "type" "test")
10818 (set_attr "mode" "SI,DI")])
10820 (define_insn "*testqi_1_maybe_si"
10821 [(set (reg FLAGS_REG)
10824 (match_operand:QI 0 "nonimmediate_operand" "%qm,qm,r")
10825 (match_operand:QI 1 "nonmemory_operand" "q,n,n"))
10827 "ix86_match_ccmode (insn,
10828 CONST_INT_P (operands[1])
10829 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
10831 if (get_attr_mode (insn) == MODE_SI)
10833 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
10834 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
10835 return "test{l}\t{%1, %k0|%k0, %1}";
10837 return "test{b}\t{%1, %0|%0, %1}";
10839 [(set_attr "type" "test")
10841 (cond [(eq_attr "alternative" "2")
10842 (const_string "SI")
10843 (and (match_test "optimize_insn_for_size_p ()")
10844 (and (match_operand 0 "ext_QIreg_operand")
10845 (match_operand 1 "const_0_to_127_operand")))
10846 (const_string "SI")
10848 (const_string "QI")))
10849 (set_attr "pent_pair" "uv,np,np")])
10851 (define_insn "*test<mode>_1"
10852 [(set (reg FLAGS_REG)
10855 (match_operand:SWI124 0 "nonimmediate_operand" "%<r>m,*a,<r>m")
10856 (match_operand:SWI124 1 "<nonmemory_szext_operand>" "<r>,<i>,<i>"))
10858 "ix86_match_ccmode (insn, CCNOmode)"
10859 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
10860 [(set_attr "type" "test")
10861 (set_attr "mode" "<MODE>")
10862 (set_attr "pent_pair" "uv,uv,np")])
10864 (define_expand "testqi_ext_1_ccno"
10865 [(set (reg:CCNO FLAGS_REG)
10870 (match_operand:HI 0 "register_operand")
10873 (match_operand:QI 1 "const_int_operand"))
10876 (define_insn "*testqi_ext<mode>_1"
10877 [(set (reg FLAGS_REG)
10881 (match_operator:SWI248 2 "extract_operator"
10882 [(match_operand 0 "int248_register_operand" "Q")
10885 (match_operand:QI 1 "general_operand" "QnBn"))
10887 "ix86_match_ccmode (insn, CCNOmode)"
10888 "test{b}\t{%1, %h0|%h0, %1}"
10889 [(set_attr "addr" "gpr8")
10890 (set_attr "type" "test")
10891 (set_attr "mode" "QI")])
10893 (define_insn "*testqi_ext<mode>_2"
10894 [(set (reg FLAGS_REG)
10898 (match_operator:SWI248 2 "extract_operator"
10899 [(match_operand 0 "int248_register_operand" "Q")
10903 (match_operator:SWI248 3 "extract_operator"
10904 [(match_operand 1 "int248_register_operand" "Q")
10906 (const_int 8)]) 0))
10908 "ix86_match_ccmode (insn, CCNOmode)"
10909 "test{b}\t{%h1, %h0|%h0, %h1}"
10910 [(set_attr "type" "test")
10911 (set_attr "mode" "QI")])
10913 ;; Provide a *testti instruction that STV can implement using ptest.
10914 ;; This pattern splits into *andti3_doubleword and *cmpti_doubleword.
10915 (define_insn_and_split "*testti_doubleword"
10916 [(set (reg:CCZ FLAGS_REG)
10918 (and:TI (match_operand:TI 0 "register_operand")
10919 (match_operand:TI 1 "general_operand"))
10922 && ix86_pre_reload_split ()"
10925 [(parallel [(set (match_dup 2) (and:TI (match_dup 0) (match_dup 1)))
10926 (clobber (reg:CC FLAGS_REG))])
10927 (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 2) (const_int 0)))]
10929 operands[2] = gen_reg_rtx (TImode);
10930 if (!x86_64_hilo_general_operand (operands[1], TImode))
10931 operands[1] = force_reg (TImode, operands[1]);
10934 ;; Combine likes to form bit extractions for some tests. Humor it.
10935 (define_insn_and_split "*testqi_ext_3"
10936 [(set (match_operand 0 "flags_reg_operand")
10937 (match_operator 1 "compare_operator"
10938 [(zero_extract:SWI248
10939 (match_operand 2 "int_nonimmediate_operand" "rm")
10940 (match_operand:QI 3 "const_int_operand")
10941 (match_operand:QI 4 "const_int_operand"))
10943 "/* Ensure that resulting mask is zero or sign extended operand. */
10944 INTVAL (operands[4]) >= 0
10945 && ((INTVAL (operands[3]) > 0
10946 && INTVAL (operands[3]) + INTVAL (operands[4]) <= 32)
10947 || (<MODE>mode == DImode
10948 && INTVAL (operands[3]) > 32
10949 && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))
10950 && ix86_match_ccmode (insn,
10951 /* If zero_extract mode precision is the same
10952 as len, the SF of the zero_extract
10953 comparison will be the most significant
10954 extracted bit, but this could be matched
10955 after splitting only for pos 0 len all bits
10956 trivial extractions. Require CCZmode. */
10957 (GET_MODE_PRECISION (<MODE>mode)
10958 == INTVAL (operands[3]))
10959 /* Otherwise, require CCZmode if we'd use a mask
10960 with the most significant bit set and can't
10961 widen it to wider mode. *testdi_1 also
10962 requires CCZmode if the mask has bit
10963 31 set and all bits above it clear. */
10964 || (INTVAL (operands[3]) + INTVAL (operands[4])
10966 /* We can't widen also if val is not a REG. */
10967 || (INTVAL (operands[3]) + INTVAL (operands[4])
10968 == GET_MODE_PRECISION (GET_MODE (operands[2]))
10969 && !register_operand (operands[2],
10970 GET_MODE (operands[2])))
10971 /* And we shouldn't widen if
10972 TARGET_PARTIAL_REG_STALL. */
10973 || (TARGET_PARTIAL_REG_STALL
10974 && (INTVAL (operands[3]) + INTVAL (operands[4])
10975 >= (paradoxical_subreg_p (operands[2])
10977 (GET_MODE (SUBREG_REG (operands[2])))
10979 ? GET_MODE_PRECISION
10980 (GET_MODE (SUBREG_REG (operands[2])))
10981 : GET_MODE_PRECISION
10982 (GET_MODE (operands[2])))))
10983 ? CCZmode : CCNOmode)"
10986 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
10988 rtx val = operands[2];
10989 HOST_WIDE_INT len = INTVAL (operands[3]);
10990 HOST_WIDE_INT pos = INTVAL (operands[4]);
10991 machine_mode mode = GET_MODE (val);
10993 if (SUBREG_P (val))
10995 machine_mode submode = GET_MODE (SUBREG_REG (val));
10997 /* Narrow paradoxical subregs to prevent partial register stalls. */
10998 if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)
10999 && GET_MODE_CLASS (submode) == MODE_INT
11000 && (GET_MODE (operands[0]) == CCZmode
11001 || pos + len < GET_MODE_PRECISION (submode)
11002 || REG_P (SUBREG_REG (val))))
11004 val = SUBREG_REG (val);
11009 /* Small HImode tests can be converted to QImode. */
11011 && register_operand (val, HImode))
11013 rtx nval = gen_lowpart (QImode, val);
11015 || GET_MODE (operands[0]) == CCZmode
11023 gcc_assert (pos + len <= GET_MODE_PRECISION (mode));
11025 /* If the mask is going to have the sign bit set in the mode
11026 we want to do the comparison in and user isn't interested just
11027 in the zero flag, then we must widen the target mode. */
11028 if (pos + len == GET_MODE_PRECISION (mode)
11029 && GET_MODE (operands[0]) != CCZmode)
11031 gcc_assert (pos + len < 32 && !MEM_P (val));
11033 val = gen_lowpart (mode, val);
11037 = wi::shifted_mask (pos, len, false, GET_MODE_PRECISION (mode));
11039 operands[2] = gen_rtx_AND (mode, val, immed_wide_int_const (mask, mode));
11042 ;; Split and;cmp (as optimized by combine) into not;test
11043 ;; Except when TARGET_BMI provides andn (*andn_<mode>_ccno).
11044 (define_insn_and_split "*test<mode>_not"
11045 [(set (reg:CCZ FLAGS_REG)
11048 (not:SWI (match_operand:SWI 0 "register_operand"))
11049 (match_operand:SWI 1 "<nonmemory_szext_operand>"))
11051 "ix86_pre_reload_split ()
11052 && (!TARGET_BMI || !REG_P (operands[1]))"
11055 [(set (match_dup 2) (not:SWI (match_dup 0)))
11056 (set (reg:CCZ FLAGS_REG)
11057 (compare:CCZ (and:SWI (match_dup 2) (match_dup 1))
11059 "operands[2] = gen_reg_rtx (<MODE>mode);")
11061 ;; Split and;cmp (as optimized by combine) into andn;cmp $0
11062 (define_insn_and_split "*test<mode>_not_doubleword"
11063 [(set (reg:CCZ FLAGS_REG)
11066 (not:DWI (match_operand:DWI 0 "nonimmediate_operand"))
11067 (match_operand:DWI 1 "nonimmediate_operand"))
11069 "ix86_pre_reload_split ()"
11073 [(set (match_dup 2) (and:DWI (not:DWI (match_dup 0)) (match_dup 1)))
11074 (clobber (reg:CC FLAGS_REG))])
11075 (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 2) (const_int 0)))]
11077 operands[0] = force_reg (<MODE>mode, operands[0]);
11078 operands[2] = gen_reg_rtx (<MODE>mode);
11081 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
11082 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
11083 ;; this is relatively important trick.
11084 ;; Do the conversion only post-reload to avoid limiting of the register class
11087 [(set (match_operand 0 "flags_reg_operand")
11088 (match_operator 1 "compare_operator"
11089 [(and (match_operand 2 "QIreg_operand")
11090 (match_operand 3 "const_int_operand"))
11093 && GET_MODE (operands[2]) != QImode
11094 && ((ix86_match_ccmode (insn, CCZmode)
11095 && !(INTVAL (operands[3]) & ~(255 << 8)))
11096 || (ix86_match_ccmode (insn, CCNOmode)
11097 && !(INTVAL (operands[3]) & ~(127 << 8))))"
11098 [(set (match_dup 0)
11102 (zero_extract:HI (match_dup 2)
11108 operands[2] = gen_lowpart (HImode, operands[2]);
11109 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, QImode);
11113 [(set (match_operand 0 "flags_reg_operand")
11114 (match_operator 1 "compare_operator"
11115 [(and (match_operand 2 "nonimmediate_operand")
11116 (match_operand 3 "const_int_operand"))
11119 && GET_MODE (operands[2]) != QImode
11120 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
11121 && ((ix86_match_ccmode (insn, CCZmode)
11122 && !(INTVAL (operands[3]) & ~255))
11123 || (ix86_match_ccmode (insn, CCNOmode)
11124 && !(INTVAL (operands[3]) & ~127)))"
11125 [(set (match_dup 0)
11126 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
11129 operands[2] = gen_lowpart (QImode, operands[2]);
11130 operands[3] = gen_int_mode (INTVAL (operands[3]), QImode);
11133 ;; Narrow test instructions with immediate operands that test
11134 ;; memory locations for zero. E.g. testl $0x00aa0000, mem can be
11135 ;; converted to testb $0xaa, mem+2. Reject volatile locations and
11136 ;; targets where reading (possibly unaligned) part of memory
11137 ;; location after a large write to the same address causes
11138 ;; store-to-load forwarding stall.
11140 [(set (reg:CCZ FLAGS_REG)
11142 (and:SWI248 (match_operand:SWI248 0 "memory_operand")
11143 (match_operand 1 "const_int_operand"))
11145 "!TARGET_PARTIAL_MEMORY_READ_STALL && !MEM_VOLATILE_P (operands[0])"
11146 [(set (reg:CCZ FLAGS_REG)
11147 (compare:CCZ (match_dup 2) (const_int 0)))]
11149 unsigned HOST_WIDE_INT ival = UINTVAL (operands[1]);
11150 int first_nonzero_byte, bitsize;
11151 rtx new_addr, new_const;
11152 machine_mode new_mode;
11157 /* Clear bits outside mode width. */
11158 ival &= GET_MODE_MASK (<MODE>mode);
11160 first_nonzero_byte = ctz_hwi (ival) / BITS_PER_UNIT;
11162 ival >>= first_nonzero_byte * BITS_PER_UNIT;
11164 bitsize = sizeof (ival) * BITS_PER_UNIT - clz_hwi (ival);
11166 if (bitsize <= GET_MODE_BITSIZE (QImode))
11168 else if (bitsize <= GET_MODE_BITSIZE (HImode))
11170 else if (bitsize <= GET_MODE_BITSIZE (SImode))
11175 if (GET_MODE_SIZE (new_mode) >= GET_MODE_SIZE (<MODE>mode))
11178 new_addr = adjust_address (operands[0], new_mode, first_nonzero_byte);
11179 new_const = gen_int_mode (ival, new_mode);
11181 operands[2] = gen_rtx_AND (new_mode, new_addr, new_const);
11184 ;; %%% This used to optimize known byte-wide and operations to memory,
11185 ;; and sometimes to QImode registers. If this is considered useful,
11186 ;; it should be done with splitters.
11188 (define_expand "and<mode>3"
11189 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
11190 (and:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
11191 (match_operand:SDWIM 2 "<general_szext_operand>")))]
11194 machine_mode mode = <MODE>mode;
11196 if (GET_MODE_SIZE (<MODE>mode) > UNITS_PER_WORD
11197 && !x86_64_hilo_general_operand (operands[2], <MODE>mode))
11198 operands[2] = force_reg (<MODE>mode, operands[2]);
11200 if (GET_MODE_SIZE (<MODE>mode) <= UNITS_PER_WORD
11201 && const_int_operand (operands[2], <MODE>mode)
11202 && register_operand (operands[0], <MODE>mode)
11203 && !(TARGET_ZERO_EXTEND_WITH_AND
11204 && optimize_function_for_speed_p (cfun)))
11206 unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
11208 if (ival == GET_MODE_MASK (SImode))
11210 else if (ival == GET_MODE_MASK (HImode))
11212 else if (ival == GET_MODE_MASK (QImode))
11216 if (mode != <MODE>mode)
11217 emit_insn (gen_extend_insn
11218 (operands[0], gen_lowpart (mode, operands[1]),
11219 <MODE>mode, mode, 1));
11221 ix86_expand_binary_operator (AND, <MODE>mode, operands);
11226 (define_insn_and_split "*and<dwi>3_doubleword"
11227 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
11229 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
11230 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
11231 (clobber (reg:CC FLAGS_REG))]
11232 "ix86_binary_operator_ok (AND, <DWI>mode, operands)"
11234 "&& reload_completed"
11235 [(const_int:DWIH 0)]
11237 bool emit_insn_deleted_note_p = false;
11239 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
11241 if (operands[2] == const0_rtx)
11242 emit_move_insn (operands[0], const0_rtx);
11243 else if (operands[2] == constm1_rtx)
11244 emit_insn_deleted_note_p = true;
11246 ix86_expand_binary_operator (AND, <MODE>mode, &operands[0]);
11248 if (operands[5] == const0_rtx)
11249 emit_move_insn (operands[3], const0_rtx);
11250 else if (operands[5] == constm1_rtx)
11252 if (emit_insn_deleted_note_p)
11253 emit_note (NOTE_INSN_DELETED);
11256 ix86_expand_binary_operator (AND, <MODE>mode, &operands[3]);
11261 (define_insn "*anddi_1"
11262 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,?k")
11264 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
11265 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m,L,k")))
11266 (clobber (reg:CC FLAGS_REG))]
11267 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
11269 and{l}\t{%k2, %k0|%k0, %k2}
11270 and{q}\t{%2, %0|%0, %2}
11271 and{q}\t{%2, %0|%0, %2}
11274 [(set_attr "isa" "x64,x64,x64,x64,avx512bw_512")
11275 (set_attr "type" "alu,alu,alu,imovx,msklog")
11276 (set_attr "length_immediate" "*,*,*,0,*")
11277 (set (attr "prefix_rex")
11279 (and (eq_attr "type" "imovx")
11280 (and (match_test "INTVAL (operands[2]) == 0xff")
11281 (match_operand 1 "ext_QIreg_operand")))
11283 (const_string "*")))
11284 (set_attr "mode" "SI,DI,DI,SI,DI")])
11286 (define_insn_and_split "*anddi_1_btr"
11287 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11289 (match_operand:DI 1 "nonimmediate_operand" "%0")
11290 (match_operand:DI 2 "const_int_operand" "n")))
11291 (clobber (reg:CC FLAGS_REG))]
11292 "TARGET_64BIT && TARGET_USE_BT
11293 && ix86_binary_operator_ok (AND, DImode, operands)
11294 && IN_RANGE (exact_log2 (~INTVAL (operands[2])), 31, 63)"
11296 "&& reload_completed"
11297 [(parallel [(set (zero_extract:DI (match_dup 0)
11301 (clobber (reg:CC FLAGS_REG))])]
11302 "operands[3] = GEN_INT (exact_log2 (~INTVAL (operands[2])));"
11303 [(set_attr "type" "alu1")
11304 (set_attr "prefix_0f" "1")
11305 (set_attr "znver1_decode" "double")
11306 (set_attr "mode" "DI")])
11308 ;; Turn *anddi_1 into *andsi_1_zext if possible.
11310 [(set (match_operand:DI 0 "register_operand")
11311 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
11312 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
11313 (clobber (reg:CC FLAGS_REG))]
11315 [(parallel [(set (match_dup 0)
11316 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
11317 (clobber (reg:CC FLAGS_REG))])]
11319 if (GET_CODE (operands[2]) == SYMBOL_REF
11320 || GET_CODE (operands[2]) == LABEL_REF)
11322 operands[2] = shallow_copy_rtx (operands[2]);
11323 PUT_MODE (operands[2], SImode);
11325 else if (GET_CODE (operands[2]) == CONST)
11327 /* (const:DI (plus:DI (symbol_ref:DI ("...")) (const_int N))) */
11328 operands[2] = copy_rtx (operands[2]);
11329 PUT_MODE (operands[2], SImode);
11330 PUT_MODE (XEXP (operands[2], 0), SImode);
11331 PUT_MODE (XEXP (XEXP (operands[2], 0), 0), SImode);
11334 operands[2] = gen_lowpart (SImode, operands[2]);
11337 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
11338 (define_insn "*andsi_1_zext"
11339 [(set (match_operand:DI 0 "register_operand" "=r")
11341 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
11342 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
11343 (clobber (reg:CC FLAGS_REG))]
11344 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
11345 "and{l}\t{%2, %k0|%k0, %2}"
11346 [(set_attr "type" "alu")
11347 (set_attr "mode" "SI")])
11349 (define_insn "*and<mode>_1"
11350 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya,?k")
11351 (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm,k")
11352 (match_operand:SWI24 2 "<general_operand>" "r<i>,<m>,L,k")))
11353 (clobber (reg:CC FLAGS_REG))]
11354 "ix86_binary_operator_ok (AND, <MODE>mode, operands)"
11356 and{<imodesuffix>}\t{%2, %0|%0, %2}
11357 and{<imodesuffix>}\t{%2, %0|%0, %2}
11361 (cond [(eq_attr "alternative" "3")
11362 (if_then_else (eq_attr "mode" "SI")
11363 (const_string "avx512bw")
11364 (const_string "avx512f"))
11366 (const_string "*")))
11367 (set_attr "type" "alu,alu,imovx,msklog")
11368 (set_attr "length_immediate" "*,*,0,*")
11369 (set (attr "prefix_rex")
11371 (and (eq_attr "type" "imovx")
11372 (and (match_test "INTVAL (operands[2]) == 0xff")
11373 (match_operand 1 "ext_QIreg_operand")))
11375 (const_string "*")))
11376 (set_attr "mode" "<MODE>,<MODE>,SI,<MODE>")])
11378 (define_insn "*andqi_1"
11379 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,?k")
11380 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
11381 (match_operand:QI 2 "general_operand" "qn,m,rn,k")))
11382 (clobber (reg:CC FLAGS_REG))]
11383 "ix86_binary_operator_ok (AND, QImode, operands)"
11385 and{b}\t{%2, %0|%0, %2}
11386 and{b}\t{%2, %0|%0, %2}
11387 and{l}\t{%k2, %k0|%k0, %k2}
11389 [(set_attr "type" "alu,alu,alu,msklog")
11391 (cond [(eq_attr "alternative" "2")
11392 (const_string "SI")
11393 (and (eq_attr "alternative" "3")
11394 (match_test "!TARGET_AVX512DQ"))
11395 (const_string "HI")
11397 (const_string "QI")))
11398 ;; Potential partial reg stall on alternative 2.
11399 (set (attr "preferred_for_speed")
11400 (cond [(eq_attr "alternative" "2")
11401 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
11402 (symbol_ref "true")))])
11404 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
11405 (define_insn_and_split "*<code><mode>_1_slp"
11406 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
11407 (any_logic:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0,!<r>")
11408 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
11409 (clobber (reg:CC FLAGS_REG))]
11410 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
11412 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
11414 "&& reload_completed
11415 && !(rtx_equal_p (operands[0], operands[1])
11416 || rtx_equal_p (operands[0], operands[2]))"
11417 [(set (strict_low_part (match_dup 0)) (match_dup 1))
11419 [(set (strict_low_part (match_dup 0))
11420 (any_logic:SWI12 (match_dup 0) (match_dup 2)))
11421 (clobber (reg:CC FLAGS_REG))])]
11423 [(set_attr "type" "alu")
11424 (set_attr "mode" "<MODE>")])
11427 [(set (match_operand:SWI248 0 "register_operand")
11428 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
11429 (match_operand:SWI248 2 "const_int_operand")))
11430 (clobber (reg:CC FLAGS_REG))]
11432 && (!REG_P (operands[1])
11433 || REGNO (operands[0]) != REGNO (operands[1]))"
11436 unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
11439 if (ival == GET_MODE_MASK (SImode))
11441 else if (ival == GET_MODE_MASK (HImode))
11443 else if (ival == GET_MODE_MASK (QImode))
11446 gcc_unreachable ();
11448 /* Zero extend to SImode to avoid partial register stalls. */
11449 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
11450 operands[0] = gen_lowpart (SImode, operands[0]);
11452 emit_insn (gen_extend_insn
11453 (operands[0], gen_lowpart (mode, operands[1]),
11454 GET_MODE (operands[0]), mode, 1));
11459 [(set (match_operand:SWI48 0 "register_operand")
11460 (and:SWI48 (match_dup 0)
11461 (const_int -65536)))
11462 (clobber (reg:CC FLAGS_REG))]
11463 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
11464 || optimize_function_for_size_p (cfun)"
11465 [(set (strict_low_part (match_dup 1)) (const_int 0))]
11466 "operands[1] = gen_lowpart (HImode, operands[0]);")
11469 [(set (match_operand:SWI248 0 "any_QIreg_operand")
11470 (and:SWI248 (match_dup 0)
11472 (clobber (reg:CC FLAGS_REG))]
11473 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11474 && reload_completed"
11475 [(set (strict_low_part (match_dup 1)) (const_int 0))]
11476 "operands[1] = gen_lowpart (QImode, operands[0]);")
11479 [(set (match_operand:SWI248 0 "QIreg_operand")
11480 (and:SWI248 (match_dup 0)
11481 (const_int -65281)))
11482 (clobber (reg:CC FLAGS_REG))]
11483 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11484 && reload_completed"
11486 [(set (zero_extract:HI (match_dup 0)
11492 (zero_extract:HI (match_dup 0)
11496 (zero_extract:HI (match_dup 0)
11498 (const_int 8)) 0)) 0))
11499 (clobber (reg:CC FLAGS_REG))])]
11500 "operands[0] = gen_lowpart (HImode, operands[0]);")
11502 (define_insn "*anddi_2"
11503 [(set (reg FLAGS_REG)
11506 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
11507 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m"))
11509 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
11510 (and:DI (match_dup 1) (match_dup 2)))]
11512 && ix86_match_ccmode
11514 /* If we are going to emit andl instead of andq, and the operands[2]
11515 constant might have the SImode sign bit set, make sure the sign
11516 flag isn't tested, because the instruction will set the sign flag
11517 based on bit 31 rather than bit 63. If it isn't CONST_INT,
11518 conservatively assume it might have bit 31 set. */
11519 (satisfies_constraint_Z (operands[2])
11520 && (!CONST_INT_P (operands[2])
11521 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
11522 ? CCZmode : CCNOmode)
11523 && ix86_binary_operator_ok (AND, DImode, operands)"
11525 and{l}\t{%k2, %k0|%k0, %k2}
11526 and{q}\t{%2, %0|%0, %2}
11527 and{q}\t{%2, %0|%0, %2}"
11528 [(set_attr "type" "alu")
11529 (set_attr "mode" "SI,DI,DI")])
11531 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
11532 (define_insn "*andsi_2_zext"
11533 [(set (reg FLAGS_REG)
11535 (match_operand:SI 1 "nonimmediate_operand" "%0")
11536 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
11538 (set (match_operand:DI 0 "register_operand" "=r")
11539 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
11540 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
11541 && ix86_binary_operator_ok (AND, SImode, operands)"
11542 "and{l}\t{%2, %k0|%k0, %2}"
11543 [(set_attr "type" "alu")
11544 (set_attr "mode" "SI")])
11546 (define_insn "*andqi_2_maybe_si"
11547 [(set (reg FLAGS_REG)
11549 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
11550 (match_operand:QI 2 "general_operand" "qn,m,n"))
11552 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
11553 (and:QI (match_dup 1) (match_dup 2)))]
11554 "ix86_binary_operator_ok (AND, QImode, operands)
11555 && ix86_match_ccmode (insn,
11556 CONST_INT_P (operands[2])
11557 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
11559 if (get_attr_mode (insn) == MODE_SI)
11561 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
11562 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
11563 return "and{l}\t{%2, %k0|%k0, %2}";
11565 return "and{b}\t{%2, %0|%0, %2}";
11567 [(set_attr "type" "alu")
11569 (cond [(eq_attr "alternative" "2")
11570 (const_string "SI")
11571 (and (match_test "optimize_insn_for_size_p ()")
11572 (and (match_operand 0 "ext_QIreg_operand")
11573 (match_operand 2 "const_0_to_127_operand")))
11574 (const_string "SI")
11576 (const_string "QI")))
11577 ;; Potential partial reg stall on alternative 2.
11578 (set (attr "preferred_for_speed")
11579 (cond [(eq_attr "alternative" "2")
11580 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
11581 (symbol_ref "true")))])
11583 (define_insn "*and<mode>_2"
11584 [(set (reg FLAGS_REG)
11585 (compare (and:SWI124
11586 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
11587 (match_operand:SWI124 2 "<general_operand>" "<r><i>,<m>"))
11589 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>m,<r>")
11590 (and:SWI124 (match_dup 1) (match_dup 2)))]
11591 "ix86_match_ccmode (insn, CCNOmode)
11592 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
11593 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
11594 [(set_attr "type" "alu")
11595 (set_attr "mode" "<MODE>")])
11597 (define_insn "*<code>qi_ext<mode>_0"
11598 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn")
11601 (match_operator:SWI248 3 "extract_operator"
11602 [(match_operand 2 "int248_register_operand" "Q")
11605 (match_operand:QI 1 "nonimmediate_operand" "0")))
11606 (clobber (reg:CC FLAGS_REG))]
11608 "<logic>{b}\t{%h2, %0|%0, %h2}"
11609 [(set_attr "addr" "gpr8")
11610 (set_attr "type" "alu")
11611 (set_attr "mode" "QI")])
11613 (define_expand "andqi_ext_1"
11615 [(set (zero_extract:HI (match_operand:HI 0 "register_operand")
11621 (zero_extract:HI (match_operand:HI 1 "register_operand")
11624 (match_operand:QI 2 "const_int_operand")) 0))
11625 (clobber (reg:CC FLAGS_REG))])])
11627 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
11628 (define_insn_and_split "*<code>qi_ext<mode>_1"
11629 [(set (zero_extract:SWI248
11630 (match_operand 0 "int248_register_operand" "+Q,&Q")
11636 (match_operator:SWI248 3 "extract_operator"
11637 [(match_operand 1 "int248_register_operand" "0,!Q")
11640 (match_operand:QI 2 "general_operand" "QnBn,QnBn")) 0))
11641 (clobber (reg:CC FLAGS_REG))]
11644 <logic>{b}\t{%2, %h0|%h0, %2}
11647 && !(rtx_equal_p (operands[0], operands[1]))"
11648 [(set (zero_extract:SWI248
11649 (match_dup 0) (const_int 8) (const_int 8))
11650 (zero_extract:SWI248
11651 (match_dup 1) (const_int 8) (const_int 8)))
11653 [(set (zero_extract:SWI248
11654 (match_dup 0) (const_int 8) (const_int 8))
11659 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
11661 (clobber (reg:CC FLAGS_REG))])]
11663 [(set_attr "addr" "gpr8")
11664 (set_attr "type" "alu")
11665 (set_attr "mode" "QI")])
11667 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
11668 (define_insn_and_split "*<code>qi_ext<mode>_1_cc"
11669 [(set (match_operand 4 "flags_reg_operand")
11670 (match_operator 5 "compare_operator"
11673 (match_operator:SWI248 3 "extract_operator"
11674 [(match_operand 1 "int248_register_operand" "0,!Q")
11677 (match_operand:QI 2 "general_operand" "QnBn,QnBn"))
11679 (set (zero_extract:SWI248
11680 (match_operand 0 "int248_register_operand" "+Q,&Q")
11687 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
11688 (match_dup 2)) 0))]
11689 "ix86_match_ccmode (insn, CCNOmode)"
11691 <logic>{b}\t{%2, %h0|%h0, %2}
11693 "&& reload_completed
11694 && !(rtx_equal_p (operands[0], operands[1]))"
11695 [(set (zero_extract:SWI248
11696 (match_dup 0) (const_int 8) (const_int 8))
11697 (zero_extract:SWI248
11698 (match_dup 1) (const_int 8) (const_int 8)))
11700 [(set (match_dup 4)
11705 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
11708 (set (zero_extract:SWI248
11709 (match_dup 0) (const_int 8) (const_int 8))
11714 [(match_dup 1) (const_int 8) (const_int 8)]) 0)
11715 (match_dup 2)) 0))])]
11717 [(set_attr "addr" "gpr8")
11718 (set_attr "type" "alu")
11719 (set_attr "mode" "QI")])
11721 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
11722 (define_insn_and_split "*<code>qi_ext<mode>_2"
11723 [(set (zero_extract:SWI248
11724 (match_operand 0 "int248_register_operand" "+Q,&Q")
11730 (match_operator:SWI248 3 "extract_operator"
11731 [(match_operand 1 "int248_register_operand" "%0,!Q")
11735 (match_operator:SWI248 4 "extract_operator"
11736 [(match_operand 2 "int248_register_operand" "Q,Q")
11738 (const_int 8)]) 0)) 0))
11739 (clobber (reg:CC FLAGS_REG))]
11742 <logic>{b}\t{%h2, %h0|%h0, %h2}
11745 && !(rtx_equal_p (operands[0], operands[1])
11746 || rtx_equal_p (operands[0], operands[2]))"
11747 [(set (zero_extract:SWI248
11748 (match_dup 0) (const_int 8) (const_int 8))
11749 (zero_extract:SWI248
11750 (match_dup 1) (const_int 8) (const_int 8)))
11752 [(set (zero_extract:SWI248
11753 (match_dup 0) (const_int 8) (const_int 8))
11758 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
11761 [(match_dup 2) (const_int 8) (const_int 8)]) 0)) 0))
11762 (clobber (reg:CC FLAGS_REG))])]
11764 [(set_attr "type" "alu")
11765 (set_attr "mode" "QI")])
11767 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
11768 (define_insn_and_split "*<code>qi_ext<mode>_3"
11769 [(set (zero_extract:SWI248
11770 (match_operand 0 "int248_register_operand" "+Q,&Q")
11773 (match_operator:SWI248 3 "extract_operator"
11775 (match_operand 1 "int248_register_operand" "%0,!Q")
11776 (match_operand 2 "int248_register_operand" "Q,Q"))
11779 (clobber (reg:CC FLAGS_REG))]
11780 "GET_MODE (operands[1]) == GET_MODE (operands[2])"
11782 <logic>{b}\t{%h2, %h0|%h0, %h2}
11784 "&& reload_completed
11785 && !(rtx_equal_p (operands[0], operands[1])
11786 || rtx_equal_p (operands[0], operands[2]))"
11787 [(set (zero_extract:SWI248
11788 (match_dup 0) (const_int 8) (const_int 8))
11789 (zero_extract:SWI248
11790 (match_dup 1) (const_int 8) (const_int 8)))
11792 [(set (zero_extract:SWI248
11793 (match_dup 0) (const_int 8) (const_int 8))
11795 [(any_logic (match_dup 4) (match_dup 2))
11796 (const_int 8) (const_int 8)]))
11797 (clobber (reg:CC FLAGS_REG))])]
11798 "operands[4] = gen_lowpart (GET_MODE (operands[1]), operands[0]);"
11799 [(set_attr "type" "alu")
11800 (set_attr "mode" "QI")])
11802 ;; Convert wide AND instructions with immediate operand to shorter QImode
11803 ;; equivalents when possible.
11804 ;; Don't do the splitting with memory operands, since it introduces risk
11805 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
11806 ;; for size, but that can (should?) be handled by generic code instead.
11808 [(set (match_operand:SWI248 0 "QIreg_operand")
11809 (and:SWI248 (match_operand:SWI248 1 "register_operand")
11810 (match_operand:SWI248 2 "const_int_operand")))
11811 (clobber (reg:CC FLAGS_REG))]
11813 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11814 && !(~INTVAL (operands[2]) & ~(255 << 8))"
11816 [(set (zero_extract:HI (match_dup 0)
11822 (zero_extract:HI (match_dup 1)
11826 (clobber (reg:CC FLAGS_REG))])]
11828 operands[0] = gen_lowpart (HImode, operands[0]);
11829 operands[1] = gen_lowpart (HImode, operands[1]);
11830 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
11833 ;; Since AND can be encoded with sign extended immediate, this is only
11834 ;; profitable when 7th bit is not set.
11836 [(set (match_operand:SWI248 0 "any_QIreg_operand")
11837 (and:SWI248 (match_operand:SWI248 1 "general_operand")
11838 (match_operand:SWI248 2 "const_int_operand")))
11839 (clobber (reg:CC FLAGS_REG))]
11841 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11842 && !(~INTVAL (operands[2]) & ~255)
11843 && !(INTVAL (operands[2]) & 128)"
11844 [(parallel [(set (strict_low_part (match_dup 0))
11845 (and:QI (match_dup 1)
11847 (clobber (reg:CC FLAGS_REG))])]
11849 operands[0] = gen_lowpart (QImode, operands[0]);
11850 operands[1] = gen_lowpart (QImode, operands[1]);
11851 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
11854 (define_insn_and_split "*andn<dwi>3_doubleword_bmi"
11855 [(set (match_operand:<DWI> 0 "register_operand" "=&r,r,r")
11857 (not:<DWI> (match_operand:<DWI> 1 "register_operand" "r,0,r"))
11858 (match_operand:<DWI> 2 "nonimmediate_operand" "ro,ro,0")))
11859 (clobber (reg:CC FLAGS_REG))]
11862 "&& reload_completed"
11863 [(parallel [(set (match_dup 0)
11864 (and:DWIH (not:DWIH (match_dup 1)) (match_dup 2)))
11865 (clobber (reg:CC FLAGS_REG))])
11866 (parallel [(set (match_dup 3)
11867 (and:DWIH (not:DWIH (match_dup 4)) (match_dup 5)))
11868 (clobber (reg:CC FLAGS_REG))])]
11869 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
11871 (define_insn_and_split "*andn<mode>3_doubleword"
11872 [(set (match_operand:DWI 0 "register_operand")
11874 (not:DWI (match_operand:DWI 1 "register_operand"))
11875 (match_operand:DWI 2 "nonimmediate_operand")))
11876 (clobber (reg:CC FLAGS_REG))]
11878 && ix86_pre_reload_split ()"
11881 [(set (match_dup 3) (not:DWI (match_dup 1)))
11882 (parallel [(set (match_dup 0)
11883 (and:DWI (match_dup 3) (match_dup 2)))
11884 (clobber (reg:CC FLAGS_REG))])]
11885 "operands[3] = gen_reg_rtx (<MODE>mode);")
11887 (define_insn "*andn<mode>_1"
11888 [(set (match_operand:SWI48 0 "register_operand" "=r,r,?k")
11890 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r,k"))
11891 (match_operand:SWI48 2 "nonimmediate_operand" "r,m,k")))
11892 (clobber (reg:CC FLAGS_REG))]
11894 || (TARGET_AVX512BW && (<MODE>mode == SImode || TARGET_EVEX512))"
11896 andn\t{%2, %1, %0|%0, %1, %2}
11897 andn\t{%2, %1, %0|%0, %1, %2}
11899 [(set_attr "isa" "bmi,bmi,<kmov_isa>")
11900 (set_attr "type" "bitmanip,bitmanip,msklog")
11901 (set_attr "btver2_decode" "direct, double,*")
11902 (set_attr "mode" "<MODE>")])
11904 (define_insn "*andn<mode>_1"
11905 [(set (match_operand:SWI12 0 "register_operand" "=r,?k")
11907 (not:SWI12 (match_operand:SWI12 1 "register_operand" "r,k"))
11908 (match_operand:SWI12 2 "register_operand" "r,k")))
11909 (clobber (reg:CC FLAGS_REG))]
11910 "TARGET_BMI || TARGET_AVX512BW"
11912 andn\t{%k2, %k1, %k0|%k0, %k1, %k2}
11914 [(set_attr "isa" "bmi,avx512f")
11915 (set_attr "type" "bitmanip,msklog")
11916 (set_attr "btver2_decode" "direct,*")
11918 (cond [(eq_attr "alternative" "0")
11919 (const_string "SI")
11920 (and (eq_attr "alternative" "1")
11921 (match_test "!TARGET_AVX512DQ"))
11922 (const_string "HI")
11924 (const_string "<MODE>")))])
11926 (define_insn "*andn_<mode>_ccno"
11927 [(set (reg FLAGS_REG)
11930 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
11931 (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
11933 (clobber (match_scratch:SWI48 0 "=r,r"))]
11934 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
11935 "andn\t{%2, %1, %0|%0, %1, %2}"
11936 [(set_attr "type" "bitmanip")
11937 (set_attr "btver2_decode" "direct, double")
11938 (set_attr "mode" "<MODE>")])
11940 ;; Split *andnsi_1 after reload with -Oz when not;and is shorter.
11942 [(set (match_operand:SI 0 "register_operand")
11943 (and:SI (not:SI (match_operand:SI 1 "register_operand"))
11944 (match_operand:SI 2 "nonimmediate_operand")))
11945 (clobber (reg:CC FLAGS_REG))]
11947 && optimize_insn_for_size_p () && optimize_size > 1
11948 && REGNO (operands[0]) == REGNO (operands[1])
11949 && LEGACY_INT_REG_P (operands[0])
11950 && !REX_INT_REG_P (operands[2])
11951 && !reg_overlap_mentioned_p (operands[0], operands[2])"
11952 [(set (match_dup 0) (not:SI (match_dup 1)))
11953 (parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
11954 (clobber (reg:CC FLAGS_REG))])])
11956 ;; Split *andn_si_ccno with -Oz when not;test is shorter.
11958 [(set (match_operand 0 "flags_reg_operand")
11959 (match_operator 1 "compare_operator"
11960 [(and:SI (not:SI (match_operand:SI 2 "general_reg_operand"))
11961 (match_operand:SI 3 "nonimmediate_operand"))
11963 (clobber (match_dup 2))]
11965 && optimize_insn_for_size_p () && optimize_size > 1
11966 && LEGACY_INT_REG_P (operands[2])
11967 && !REX_INT_REG_P (operands[3])
11968 && !reg_overlap_mentioned_p (operands[2], operands[3])"
11969 [(set (match_dup 2) (not:SI (match_dup 2)))
11970 (set (match_dup 0) (match_op_dup 1
11971 [(and:SI (match_dup 3) (match_dup 2))
11974 ;; Variant 1 of 4: Split ((A | B) ^ A) ^ C as (B & ~A) ^ C.
11976 [(set (match_operand:SWI48 0 "register_operand")
11979 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
11980 (match_operand:SWI48 2 "nonimmediate_operand"))
11982 (match_operand:SWI48 3 "nonimmediate_operand")))
11983 (clobber (reg:CC FLAGS_REG))]
11986 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 1)) (match_dup 2)))
11987 (clobber (reg:CC FLAGS_REG))])
11989 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
11990 (clobber (reg:CC FLAGS_REG))])]
11991 "operands[4] = gen_reg_rtx (<MODE>mode);")
11993 ;; Variant 2 of 4: Split ((A | B) ^ B) ^ C as (A & ~B) ^ C.
11995 [(set (match_operand:SWI48 0 "register_operand")
11998 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
11999 (match_operand:SWI48 2 "register_operand"))
12001 (match_operand:SWI48 3 "nonimmediate_operand")))
12002 (clobber (reg:CC FLAGS_REG))]
12005 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 2)) (match_dup 1)))
12006 (clobber (reg:CC FLAGS_REG))])
12008 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
12009 (clobber (reg:CC FLAGS_REG))])]
12010 "operands[4] = gen_reg_rtx (<MODE>mode);")
12012 ;; Variant 3 of 4: Split ((A | B) ^ C) ^ A as (B & ~A) ^ C.
12014 [(set (match_operand:SWI48 0 "register_operand")
12017 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
12018 (match_operand:SWI48 2 "nonimmediate_operand"))
12019 (match_operand:SWI48 3 "nonimmediate_operand"))
12021 (clobber (reg:CC FLAGS_REG))]
12024 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 1)) (match_dup 2)))
12025 (clobber (reg:CC FLAGS_REG))])
12027 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
12028 (clobber (reg:CC FLAGS_REG))])]
12029 "operands[4] = gen_reg_rtx (<MODE>mode);")
12031 ;; Variant 4 of 4: Split ((A | B) ^ C) ^ B as (A & ~B) ^ C.
12033 [(set (match_operand:SWI48 0 "register_operand")
12036 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
12037 (match_operand:SWI48 2 "register_operand"))
12038 (match_operand:SWI48 3 "nonimmediate_operand"))
12040 (clobber (reg:CC FLAGS_REG))]
12043 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 2)) (match_dup 1)))
12044 (clobber (reg:CC FLAGS_REG))])
12046 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
12047 (clobber (reg:CC FLAGS_REG))])]
12048 "operands[4] = gen_reg_rtx (<MODE>mode);")
12050 ;; Logical inclusive and exclusive OR instructions
12052 ;; %%% This used to optimize known byte-wide and operations to memory.
12053 ;; If this is considered useful, it should be done with splitters.
12055 (define_expand "<code><mode>3"
12056 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
12057 (any_or:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
12058 (match_operand:SDWIM 2 "<general_operand>")))]
12061 if (GET_MODE_SIZE (<MODE>mode) > UNITS_PER_WORD
12062 && !x86_64_hilo_general_operand (operands[2], <MODE>mode))
12063 operands[2] = force_reg (<MODE>mode, operands[2]);
12065 ix86_expand_binary_operator (<CODE>, <MODE>mode, operands);
12069 (define_insn_and_split "*<code><dwi>3_doubleword"
12070 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
12072 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
12073 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
12074 (clobber (reg:CC FLAGS_REG))]
12075 "ix86_binary_operator_ok (<CODE>, <DWI>mode, operands)"
12077 "&& reload_completed"
12078 [(const_int:DWIH 0)]
12080 /* This insn may disappear completely when operands[2] == const0_rtx
12081 and operands[0] == operands[1], which requires a NOTE_INSN_DELETED. */
12082 bool emit_insn_deleted_note_p = false;
12084 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
12086 if (operands[2] == const0_rtx)
12087 emit_insn_deleted_note_p = true;
12088 else if (operands[2] == constm1_rtx)
12091 emit_move_insn (operands[0], constm1_rtx);
12093 ix86_expand_unary_operator (NOT, <MODE>mode, &operands[0]);
12096 ix86_expand_binary_operator (<CODE>, <MODE>mode, &operands[0]);
12098 if (operands[5] == const0_rtx)
12100 if (emit_insn_deleted_note_p)
12101 emit_note (NOTE_INSN_DELETED);
12103 else if (operands[5] == constm1_rtx)
12106 emit_move_insn (operands[3], constm1_rtx);
12108 ix86_expand_unary_operator (NOT, <MODE>mode, &operands[3]);
12111 ix86_expand_binary_operator (<CODE>, <MODE>mode, &operands[3]);
12116 (define_insn "*<code><mode>_1"
12117 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,?k")
12119 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,k")
12120 (match_operand:SWI248 2 "<general_operand>" "r<i>,<m>,k")))
12121 (clobber (reg:CC FLAGS_REG))]
12122 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
12124 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
12125 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
12127 [(set_attr "isa" "*,*,<kmov_isa>")
12128 (set_attr "type" "alu, alu, msklog")
12129 (set_attr "mode" "<MODE>")])
12131 (define_insn_and_split "*notxor<mode>_1"
12132 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,?k")
12135 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,k")
12136 (match_operand:SWI248 2 "<general_operand>" "r<i>,<m>,k"))))
12137 (clobber (reg:CC FLAGS_REG))]
12138 "ix86_binary_operator_ok (XOR, <MODE>mode, operands)"
12140 "&& reload_completed"
12142 [(set (match_dup 0)
12143 (xor:SWI248 (match_dup 1) (match_dup 2)))
12144 (clobber (reg:CC FLAGS_REG))])
12146 (not:SWI248 (match_dup 0)))]
12148 if (MASK_REG_P (operands[0]))
12150 emit_insn (gen_kxnor<mode> (operands[0], operands[1], operands[2]));
12154 [(set_attr "isa" "*,*,<kmov_isa>")
12155 (set_attr "type" "alu, alu, msklog")
12156 (set_attr "mode" "<MODE>")])
12158 (define_insn_and_split "*iordi_1_bts"
12159 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12161 (match_operand:DI 1 "nonimmediate_operand" "%0")
12162 (match_operand:DI 2 "const_int_operand" "n")))
12163 (clobber (reg:CC FLAGS_REG))]
12164 "TARGET_64BIT && TARGET_USE_BT
12165 && ix86_binary_operator_ok (IOR, DImode, operands)
12166 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
12168 "&& reload_completed"
12169 [(parallel [(set (zero_extract:DI (match_dup 0)
12173 (clobber (reg:CC FLAGS_REG))])]
12174 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
12175 [(set_attr "type" "alu1")
12176 (set_attr "prefix_0f" "1")
12177 (set_attr "znver1_decode" "double")
12178 (set_attr "mode" "DI")])
12180 (define_insn_and_split "*xordi_1_btc"
12181 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12183 (match_operand:DI 1 "nonimmediate_operand" "%0")
12184 (match_operand:DI 2 "const_int_operand" "n")))
12185 (clobber (reg:CC FLAGS_REG))]
12186 "TARGET_64BIT && TARGET_USE_BT
12187 && ix86_binary_operator_ok (XOR, DImode, operands)
12188 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
12190 "&& reload_completed"
12191 [(parallel [(set (zero_extract:DI (match_dup 0)
12194 (not:DI (zero_extract:DI (match_dup 0)
12197 (clobber (reg:CC FLAGS_REG))])]
12198 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
12199 [(set_attr "type" "alu1")
12200 (set_attr "prefix_0f" "1")
12201 (set_attr "znver1_decode" "double")
12202 (set_attr "mode" "DI")])
12204 ;; Optimize a ^ ((a ^ b) & mask) to (~mask & a) | (b & mask)
12205 (define_insn_and_split "*xor2andn"
12206 [(set (match_operand:SWI248 0 "register_operand")
12210 (match_operand:SWI248 1 "nonimmediate_operand")
12211 (match_operand:SWI248 2 "nonimmediate_operand"))
12212 (match_operand:SWI248 3 "nonimmediate_operand"))
12214 (clobber (reg:CC FLAGS_REG))]
12215 "TARGET_BMI && ix86_pre_reload_split ()"
12218 [(parallel [(set (match_dup 4)
12223 (clobber (reg:CC FLAGS_REG))])
12224 (parallel [(set (match_dup 5)
12228 (clobber (reg:CC FLAGS_REG))])
12229 (parallel [(set (match_dup 0)
12233 (clobber (reg:CC FLAGS_REG))])]
12235 operands[1] = force_reg (<MODE>mode, operands[1]);
12236 operands[3] = force_reg (<MODE>mode, operands[3]);
12237 operands[4] = gen_reg_rtx (<MODE>mode);
12238 operands[5] = gen_reg_rtx (<MODE>mode);
12241 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
12242 (define_insn "*<code>si_1_zext"
12243 [(set (match_operand:DI 0 "register_operand" "=r")
12245 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
12246 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
12247 (clobber (reg:CC FLAGS_REG))]
12248 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12249 "<logic>{l}\t{%2, %k0|%k0, %2}"
12250 [(set_attr "type" "alu")
12251 (set_attr "mode" "SI")])
12253 (define_insn "*<code>si_1_zext_imm"
12254 [(set (match_operand:DI 0 "register_operand" "=r")
12256 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
12257 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
12258 (clobber (reg:CC FLAGS_REG))]
12259 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12260 "<logic>{l}\t{%2, %k0|%k0, %2}"
12261 [(set_attr "type" "alu")
12262 (set_attr "mode" "SI")])
12264 (define_insn "*<code>qi_1"
12265 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,?k")
12266 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
12267 (match_operand:QI 2 "general_operand" "qn,m,rn,k")))
12268 (clobber (reg:CC FLAGS_REG))]
12269 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
12271 <logic>{b}\t{%2, %0|%0, %2}
12272 <logic>{b}\t{%2, %0|%0, %2}
12273 <logic>{l}\t{%k2, %k0|%k0, %k2}
12275 [(set_attr "isa" "*,*,*,avx512f")
12276 (set_attr "type" "alu,alu,alu,msklog")
12278 (cond [(eq_attr "alternative" "2")
12279 (const_string "SI")
12280 (and (eq_attr "alternative" "3")
12281 (match_test "!TARGET_AVX512DQ"))
12282 (const_string "HI")
12284 (const_string "QI")))
12285 ;; Potential partial reg stall on alternative 2.
12286 (set (attr "preferred_for_speed")
12287 (cond [(eq_attr "alternative" "2")
12288 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
12289 (symbol_ref "true")))])
12291 (define_insn_and_split "*notxorqi_1"
12292 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,?k")
12294 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
12295 (match_operand:QI 2 "general_operand" "qn,m,rn,k"))))
12296 (clobber (reg:CC FLAGS_REG))]
12297 "ix86_binary_operator_ok (XOR, QImode, operands)"
12299 "&& reload_completed"
12301 [(set (match_dup 0)
12302 (xor:QI (match_dup 1) (match_dup 2)))
12303 (clobber (reg:CC FLAGS_REG))])
12305 (not:QI (match_dup 0)))]
12307 if (mask_reg_operand (operands[0], QImode))
12309 emit_insn (gen_kxnorqi (operands[0], operands[1], operands[2]));
12313 [(set_attr "isa" "*,*,*,avx512f")
12314 (set_attr "type" "alu,alu,alu,msklog")
12316 (cond [(eq_attr "alternative" "2")
12317 (const_string "SI")
12318 (and (eq_attr "alternative" "3")
12319 (match_test "!TARGET_AVX512DQ"))
12320 (const_string "HI")
12322 (const_string "QI")))
12323 ;; Potential partial reg stall on alternative 2.
12324 (set (attr "preferred_for_speed")
12325 (cond [(eq_attr "alternative" "2")
12326 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
12327 (symbol_ref "true")))])
12329 ;; convert (sign_extend:WIDE (any_logic:NARROW (memory, immediate)))
12330 ;; to (any_logic:WIDE (sign_extend (memory)), (sign_extend (immediate))).
12331 ;; This eliminates sign extension after logic operation.
12334 [(set (match_operand:SWI248 0 "register_operand")
12335 (sign_extend:SWI248
12336 (any_logic:QI (match_operand:QI 1 "memory_operand")
12337 (match_operand:QI 2 "const_int_operand"))))]
12339 [(set (match_dup 3) (sign_extend:SWI248 (match_dup 1)))
12340 (set (match_dup 0) (any_logic:SWI248 (match_dup 3) (match_dup 2)))]
12341 "operands[3] = gen_reg_rtx (<MODE>mode);")
12344 [(set (match_operand:SWI48 0 "register_operand")
12346 (any_logic:HI (match_operand:HI 1 "memory_operand")
12347 (match_operand:HI 2 "const_int_operand"))))]
12349 [(set (match_dup 3) (sign_extend:SWI48 (match_dup 1)))
12350 (set (match_dup 0) (any_logic:SWI48 (match_dup 3) (match_dup 2)))]
12351 "operands[3] = gen_reg_rtx (<MODE>mode);")
12354 [(set (match_operand:DI 0 "register_operand")
12356 (any_logic:SI (match_operand:SI 1 "memory_operand")
12357 (match_operand:SI 2 "const_int_operand"))))]
12359 [(set (match_dup 3) (sign_extend:DI (match_dup 1)))
12360 (set (match_dup 0) (any_logic:DI (match_dup 3) (match_dup 2)))]
12361 "operands[3] = gen_reg_rtx (DImode);")
12363 (define_insn "*<code><mode>_2"
12364 [(set (reg FLAGS_REG)
12365 (compare (any_or:SWI
12366 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
12367 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
12369 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
12370 (any_or:SWI (match_dup 1) (match_dup 2)))]
12371 "ix86_match_ccmode (insn, CCNOmode)
12372 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
12373 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
12374 [(set_attr "type" "alu")
12375 (set_attr "mode" "<MODE>")])
12377 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
12378 ;; ??? Special case for immediate operand is missing - it is tricky.
12379 (define_insn "*<code>si_2_zext"
12380 [(set (reg FLAGS_REG)
12381 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
12382 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
12384 (set (match_operand:DI 0 "register_operand" "=r")
12385 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
12386 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
12387 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12388 "<logic>{l}\t{%2, %k0|%k0, %2}"
12389 [(set_attr "type" "alu")
12390 (set_attr "mode" "SI")])
12392 (define_insn "*<code>si_2_zext_imm"
12393 [(set (reg FLAGS_REG)
12394 (compare (any_or:SI
12395 (match_operand:SI 1 "nonimmediate_operand" "%0")
12396 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
12398 (set (match_operand:DI 0 "register_operand" "=r")
12399 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12400 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
12401 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12402 "<logic>{l}\t{%2, %k0|%k0, %2}"
12403 [(set_attr "type" "alu")
12404 (set_attr "mode" "SI")])
12406 (define_insn "*<code><mode>_3"
12407 [(set (reg FLAGS_REG)
12408 (compare (any_or:SWI
12409 (match_operand:SWI 1 "nonimmediate_operand" "%0")
12410 (match_operand:SWI 2 "<general_operand>" "<g>"))
12412 (clobber (match_scratch:SWI 0 "=<r>"))]
12413 "ix86_match_ccmode (insn, CCNOmode)
12414 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12415 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
12416 [(set_attr "type" "alu")
12417 (set_attr "mode" "<MODE>")])
12419 ;; Convert wide OR instructions with immediate operand to shorter QImode
12420 ;; equivalents when possible.
12421 ;; Don't do the splitting with memory operands, since it introduces risk
12422 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
12423 ;; for size, but that can (should?) be handled by generic code instead.
12425 [(set (match_operand:SWI248 0 "QIreg_operand")
12426 (any_or:SWI248 (match_operand:SWI248 1 "register_operand")
12427 (match_operand:SWI248 2 "const_int_operand")))
12428 (clobber (reg:CC FLAGS_REG))]
12430 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12431 && !(INTVAL (operands[2]) & ~(255 << 8))"
12433 [(set (zero_extract:HI (match_dup 0)
12439 (zero_extract:HI (match_dup 1)
12443 (clobber (reg:CC FLAGS_REG))])]
12445 /* Handle the case where INTVAL (operands[2]) == 0. */
12446 if (operands[2] == const0_rtx)
12448 if (!rtx_equal_p (operands[0], operands[1]))
12449 emit_move_insn (operands[0], operands[1]);
12451 emit_note (NOTE_INSN_DELETED);
12454 operands[0] = gen_lowpart (HImode, operands[0]);
12455 operands[1] = gen_lowpart (HImode, operands[1]);
12456 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
12459 ;; Since OR can be encoded with sign extended immediate, this is only
12460 ;; profitable when 7th bit is set.
12462 [(set (match_operand:SWI248 0 "any_QIreg_operand")
12463 (any_or:SWI248 (match_operand:SWI248 1 "general_operand")
12464 (match_operand:SWI248 2 "const_int_operand")))
12465 (clobber (reg:CC FLAGS_REG))]
12467 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12468 && !(INTVAL (operands[2]) & ~255)
12469 && (INTVAL (operands[2]) & 128)"
12470 [(parallel [(set (strict_low_part (match_dup 0))
12471 (any_or:QI (match_dup 1)
12473 (clobber (reg:CC FLAGS_REG))])]
12475 operands[0] = gen_lowpart (QImode, operands[0]);
12476 operands[1] = gen_lowpart (QImode, operands[1]);
12477 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
12480 (define_expand "xorqi_ext_1_cc"
12482 [(set (reg:CCNO FLAGS_REG)
12486 (zero_extract:HI (match_operand:HI 1 "register_operand")
12489 (match_operand:QI 2 "const_int_operand"))
12491 (set (zero_extract:HI (match_operand:HI 0 "register_operand")
12497 (zero_extract:HI (match_dup 1)
12500 (match_dup 2)) 0))])])
12502 ;; Peephole2 rega = 0; rega op= regb into rega = regb.
12504 [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
12506 (clobber (reg:CC FLAGS_REG))])
12507 (parallel [(set (match_dup 0)
12508 (any_or_plus:SWI (match_dup 0)
12509 (match_operand:SWI 1 "<general_operand>")))
12510 (clobber (reg:CC FLAGS_REG))])]
12511 "!reg_mentioned_p (operands[0], operands[1])"
12512 [(set (match_dup 0) (match_dup 1))])
12514 ;; Peephole2 dead instruction in rega = 0; rega op= rega.
12516 [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
12518 (clobber (reg:CC FLAGS_REG))])
12519 (parallel [(set (match_dup 0)
12520 (any_or_plus:SWI (match_dup 0) (match_dup 0)))
12521 (clobber (reg:CC FLAGS_REG))])]
12523 [(parallel [(set (match_dup 0) (const_int 0))
12524 (clobber (reg:CC FLAGS_REG))])])
12526 ;; Split DST = (HI<<32)|LO early to minimize register usage.
12527 (define_insn_and_split "*concat<mode><dwi>3_1"
12528 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
12530 (ashift:<DWI> (match_operand:<DWI> 1 "register_operand" "r,r")
12531 (match_operand:QI 2 "const_int_operand"))
12533 (match_operand:DWIH 3 "nonimmediate_operand" "r,m"))))]
12534 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT"
12536 "&& reload_completed"
12539 split_double_concat (<DWI>mode, operands[0], operands[3],
12540 gen_lowpart (<MODE>mode, operands[1]));
12544 (define_insn_and_split "*concat<mode><dwi>3_2"
12545 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
12548 (match_operand:DWIH 1 "nonimmediate_operand" "r,m"))
12549 (ashift:<DWI> (match_operand:<DWI> 2 "register_operand" "r,r")
12550 (match_operand:QI 3 "const_int_operand"))))]
12551 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12553 "&& reload_completed"
12556 split_double_concat (<DWI>mode, operands[0], operands[1],
12557 gen_lowpart (<MODE>mode, operands[2]));
12561 (define_insn_and_split "*concat<mode><dwi>3_3"
12562 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,r,&r,x")
12566 (match_operand:DWIH 1 "nonimmediate_operand" "r,m,r,m,x"))
12567 (match_operand:QI 2 "const_int_operand"))
12569 (match_operand:DWIH 3 "nonimmediate_operand" "r,r,m,m,0"))))]
12570 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT"
12572 "&& reload_completed"
12575 if (SSE_REG_P (operands[0]))
12577 rtx tmp = gen_rtx_REG (V2DImode, REGNO (operands[0]));
12578 emit_insn (gen_vec_concatv2di (tmp, operands[3], operands[1]));
12581 split_double_concat (<DWI>mode, operands[0], operands[3], operands[1]);
12584 [(set_attr "isa" "*,*,*,x64,x64")])
12586 (define_insn_and_split "*concat<mode><dwi>3_4"
12587 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,r,&r")
12590 (match_operand:DWIH 1 "nonimmediate_operand" "r,m,r,m"))
12593 (match_operand:DWIH 2 "nonimmediate_operand" "r,r,m,m"))
12594 (match_operand:QI 3 "const_int_operand"))))]
12595 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12597 "&& reload_completed"
12600 split_double_concat (<DWI>mode, operands[0], operands[1], operands[2]);
12603 [(set_attr "isa" "*,*,*,x64")])
12605 (define_insn_and_split "*concat<half><mode>3_5"
12606 [(set (match_operand:DWI 0 "nonimmediate_operand" "=r,o,o")
12608 (ashift:DWI (match_operand:DWI 1 "register_operand" "r,r,r")
12609 (match_operand:QI 2 "const_int_operand"))
12610 (match_operand:DWI 3 "const_scalar_int_operand" "n,n,Wd")))]
12611 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT / 2
12612 && (<MODE>mode == DImode
12613 ? CONST_INT_P (operands[3])
12614 && (UINTVAL (operands[3]) & ~GET_MODE_MASK (SImode)) == 0
12615 : CONST_INT_P (operands[3])
12616 ? INTVAL (operands[3]) >= 0
12617 : CONST_WIDE_INT_NUNITS (operands[3]) == 2
12618 && CONST_WIDE_INT_ELT (operands[3], 1) == 0)
12619 && !(CONST_INT_P (operands[3])
12620 ? ix86_endbr_immediate_operand (operands[3], VOIDmode)
12621 : ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[3],
12625 "&& reload_completed"
12628 rtx op3 = simplify_subreg (<HALF>mode, operands[3], <MODE>mode, 0);
12629 split_double_concat (<MODE>mode, operands[0], op3,
12630 gen_lowpart (<HALF>mode, operands[1]));
12633 [(set_attr "isa" "*,nox64,x64")])
12635 (define_insn_and_split "*concat<mode><dwi>3_6"
12636 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,o,r")
12640 (match_operand:DWIH 1 "nonimmediate_operand" "r,r,r,m"))
12641 (match_operand:QI 2 "const_int_operand"))
12642 (match_operand:<DWI> 3 "const_scalar_int_operand" "n,n,Wd,n")))]
12643 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT
12644 && (<DWI>mode == DImode
12645 ? CONST_INT_P (operands[3])
12646 && (UINTVAL (operands[3]) & ~GET_MODE_MASK (SImode)) == 0
12647 : CONST_INT_P (operands[3])
12648 ? INTVAL (operands[3]) >= 0
12649 : CONST_WIDE_INT_NUNITS (operands[3]) == 2
12650 && CONST_WIDE_INT_ELT (operands[3], 1) == 0)
12651 && !(CONST_INT_P (operands[3])
12652 ? ix86_endbr_immediate_operand (operands[3], VOIDmode)
12653 : ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[3],
12657 "&& reload_completed"
12660 rtx op3 = simplify_subreg (<MODE>mode, operands[3], <DWI>mode, 0);
12661 split_double_concat (<DWI>mode, operands[0], op3, operands[1]);
12664 [(set_attr "isa" "*,nox64,x64,*")])
12666 (define_insn_and_split "*concat<mode><dwi>3_7"
12667 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,o,r")
12670 (match_operand:DWIH 1 "nonimmediate_operand" "r,r,r,m"))
12671 (match_operand:<DWI> 2 "const_scalar_int_operand" "n,n,Wd,n")))]
12672 "<DWI>mode == DImode
12673 ? CONST_INT_P (operands[2])
12674 && (UINTVAL (operands[2]) & GET_MODE_MASK (SImode)) == 0
12675 && !ix86_endbr_immediate_operand (operands[2], VOIDmode)
12676 : CONST_WIDE_INT_P (operands[2])
12677 && CONST_WIDE_INT_NUNITS (operands[2]) == 2
12678 && CONST_WIDE_INT_ELT (operands[2], 0) == 0
12679 && !ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[2],
12683 "&& reload_completed"
12687 if (<DWI>mode == DImode)
12688 op2 = gen_int_mode (INTVAL (operands[2]) >> 32, <MODE>mode);
12690 op2 = gen_int_mode (CONST_WIDE_INT_ELT (operands[2], 1), <MODE>mode);
12691 split_double_concat (<DWI>mode, operands[0], operands[1], op2);
12694 [(set_attr "isa" "*,nox64,x64,*")])
12696 ;; Negation instructions
12698 (define_expand "neg<mode>2"
12699 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
12700 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
12702 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
12704 (define_insn_and_split "*neg<dwi>2_doubleword"
12705 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
12706 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
12707 (clobber (reg:CC FLAGS_REG))]
12708 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
12710 "&& reload_completed"
12712 [(set (reg:CCC FLAGS_REG)
12713 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
12714 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
12716 [(set (match_dup 2)
12717 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
12720 (clobber (reg:CC FLAGS_REG))])
12722 [(set (match_dup 2)
12723 (neg:DWIH (match_dup 2)))
12724 (clobber (reg:CC FLAGS_REG))])]
12725 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
12738 [(set (match_operand:SWI48 0 "general_reg_operand")
12739 (match_operand:SWI48 1 "nonimmediate_gr_operand"))
12741 [(set (reg:CCC FLAGS_REG)
12742 (unspec:CCC [(match_operand:SWI48 2 "general_reg_operand")
12743 (const_int 0)] UNSPEC_CC_NE))
12744 (set (match_dup 2) (neg:SWI48 (match_dup 2)))])
12746 [(set (match_dup 0)
12747 (plus:SWI48 (plus:SWI48
12748 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
12751 (clobber (reg:CC FLAGS_REG))])
12753 [(set (match_dup 0)
12754 (neg:SWI48 (match_dup 0)))
12755 (clobber (reg:CC FLAGS_REG))])]
12756 "REGNO (operands[0]) != REGNO (operands[2])
12757 && !reg_mentioned_p (operands[0], operands[1])
12758 && !reg_mentioned_p (operands[2], operands[1])"
12760 [(set (reg:CCC FLAGS_REG)
12761 (unspec:CCC [(match_dup 2) (const_int 0)] UNSPEC_CC_NE))
12762 (set (match_dup 2) (neg:SWI48 (match_dup 2)))])
12764 [(set (match_dup 0)
12765 (minus:SWI48 (minus:SWI48
12767 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0)))
12769 (clobber (reg:CC FLAGS_REG))])]
12770 "ix86_expand_clear (operands[0]);")
12779 ;; sbbl %edx, %edx // *x86_mov<mode>cc_0_m1
12783 [(set (match_operand:SWI48 0 "general_reg_operand") (const_int 0))
12784 (clobber (reg:CC FLAGS_REG))])
12786 [(set (reg:CCC FLAGS_REG)
12787 (unspec:CCC [(match_operand:SWI48 1 "general_reg_operand")
12788 (const_int 0)] UNSPEC_CC_NE))
12789 (set (match_dup 1) (neg:SWI48 (match_dup 1)))])
12791 [(set (match_dup 0)
12792 (plus:SWI48 (plus:SWI48
12793 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
12796 (clobber (reg:CC FLAGS_REG))])
12798 [(set (match_dup 0)
12799 (neg:SWI48 (match_dup 0)))
12800 (clobber (reg:CC FLAGS_REG))])]
12801 "REGNO (operands[0]) != REGNO (operands[1])"
12803 [(set (reg:CCC FLAGS_REG)
12804 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
12805 (set (match_dup 1) (neg:SWI48 (match_dup 1)))])
12807 [(set (match_dup 0)
12808 (if_then_else:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
12811 (clobber (reg:CC FLAGS_REG))])])
12813 (define_insn "*neg<mode>_1"
12814 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
12815 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
12816 (clobber (reg:CC FLAGS_REG))]
12817 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
12818 "neg{<imodesuffix>}\t%0"
12819 [(set_attr "type" "negnot")
12820 (set_attr "mode" "<MODE>")])
12822 (define_insn "*negsi_1_zext"
12823 [(set (match_operand:DI 0 "register_operand" "=r")
12825 (neg:SI (match_operand:SI 1 "register_operand" "0"))))
12826 (clobber (reg:CC FLAGS_REG))]
12827 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
12829 [(set_attr "type" "negnot")
12830 (set_attr "mode" "SI")])
12832 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
12833 (define_insn_and_split "*neg<mode>_1_slp"
12834 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
12835 (neg:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")))
12836 (clobber (reg:CC FLAGS_REG))]
12837 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
12839 neg{<imodesuffix>}\t%0
12841 "&& reload_completed
12842 && !(rtx_equal_p (operands[0], operands[1]))"
12843 [(set (strict_low_part (match_dup 0)) (match_dup 1))
12845 [(set (strict_low_part (match_dup 0))
12846 (neg:SWI12 (match_dup 0)))
12847 (clobber (reg:CC FLAGS_REG))])]
12849 [(set_attr "type" "negnot")
12850 (set_attr "mode" "<MODE>")])
12852 (define_insn "*neg<mode>_2"
12853 [(set (reg FLAGS_REG)
12855 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
12857 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
12858 (neg:SWI (match_dup 1)))]
12859 "ix86_match_ccmode (insn, CCGOCmode)
12860 && ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
12861 "neg{<imodesuffix>}\t%0"
12862 [(set_attr "type" "negnot")
12863 (set_attr "mode" "<MODE>")])
12865 (define_insn "*negsi_2_zext"
12866 [(set (reg FLAGS_REG)
12868 (neg:SI (match_operand:SI 1 "register_operand" "0"))
12870 (set (match_operand:DI 0 "register_operand" "=r")
12872 (neg:SI (match_dup 1))))]
12873 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12874 && ix86_unary_operator_ok (NEG, SImode, operands)"
12876 [(set_attr "type" "negnot")
12877 (set_attr "mode" "SI")])
12879 (define_insn "*neg<mode>_ccc_1"
12880 [(set (reg:CCC FLAGS_REG)
12882 [(match_operand:SWI 1 "nonimmediate_operand" "0")
12883 (const_int 0)] UNSPEC_CC_NE))
12884 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
12885 (neg:SWI (match_dup 1)))]
12887 "neg{<imodesuffix>}\t%0"
12888 [(set_attr "type" "negnot")
12889 (set_attr "mode" "<MODE>")])
12891 (define_insn "*neg<mode>_ccc_2"
12892 [(set (reg:CCC FLAGS_REG)
12894 [(match_operand:SWI 1 "nonimmediate_operand" "0")
12895 (const_int 0)] UNSPEC_CC_NE))
12896 (clobber (match_scratch:SWI 0 "=<r>"))]
12898 "neg{<imodesuffix>}\t%0"
12899 [(set_attr "type" "negnot")
12900 (set_attr "mode" "<MODE>")])
12902 (define_expand "x86_neg<mode>_ccc"
12904 [(set (reg:CCC FLAGS_REG)
12905 (unspec:CCC [(match_operand:SWI48 1 "register_operand")
12906 (const_int 0)] UNSPEC_CC_NE))
12907 (set (match_operand:SWI48 0 "register_operand")
12908 (neg:SWI48 (match_dup 1)))])])
12910 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
12911 (define_insn_and_split "*negqi_ext<mode>_1"
12912 [(set (zero_extract:SWI248
12913 (match_operand 0 "int248_register_operand" "+Q,&Q")
12919 (match_operator:SWI248 2 "extract_operator"
12920 [(match_operand 1 "int248_register_operand" "0,!Q")
12922 (const_int 8)]) 0)) 0))
12923 (clobber (reg:CC FLAGS_REG))]
12929 && !(rtx_equal_p (operands[0], operands[1]))"
12930 [(set (zero_extract:SWI248
12931 (match_dup 0) (const_int 8) (const_int 8))
12932 (zero_extract:SWI248
12933 (match_dup 1) (const_int 8) (const_int 8)))
12935 [(set (zero_extract:SWI248
12936 (match_dup 0) (const_int 8) (const_int 8))
12941 [(match_dup 0) (const_int 8) (const_int 8)]) 0)) 0))
12942 (clobber (reg:CC FLAGS_REG))])]
12944 [(set_attr "type" "negnot")
12945 (set_attr "mode" "QI")])
12947 ;; Negate with jump on overflow.
12948 (define_expand "negv<mode>3"
12949 [(parallel [(set (reg:CCO FLAGS_REG)
12951 [(match_operand:SWI 1 "register_operand")
12952 (match_dup 3)] UNSPEC_CC_NE))
12953 (set (match_operand:SWI 0 "register_operand")
12954 (neg:SWI (match_dup 1)))])
12955 (set (pc) (if_then_else
12956 (eq (reg:CCO FLAGS_REG) (const_int 0))
12957 (label_ref (match_operand 2))
12962 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
12966 (define_insn "*negv<mode>3"
12967 [(set (reg:CCO FLAGS_REG)
12968 (unspec:CCO [(match_operand:SWI 1 "nonimmediate_operand" "0")
12969 (match_operand:SWI 2 "const_int_operand")]
12971 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
12972 (neg:SWI (match_dup 1)))]
12973 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
12974 && mode_signbit_p (<MODE>mode, operands[2])"
12975 "neg{<imodesuffix>}\t%0"
12976 [(set_attr "type" "negnot")
12977 (set_attr "mode" "<MODE>")])
12979 ;; Optimize *negsi_1 followed by *cmpsi_ccno_1 (PR target/91384)
12981 [(set (match_operand:SWI 0 "general_reg_operand")
12982 (match_operand:SWI 1 "general_reg_operand"))
12983 (parallel [(set (match_dup 0) (neg:SWI (match_dup 0)))
12984 (clobber (reg:CC FLAGS_REG))])
12985 (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))]
12987 [(set (match_dup 0) (match_dup 1))
12988 (parallel [(set (reg:CCZ FLAGS_REG)
12989 (compare:CCZ (neg:SWI (match_dup 0)) (const_int 0)))
12990 (set (match_dup 0) (neg:SWI (match_dup 0)))])])
12992 ;; Special expand pattern to handle integer mode abs
12994 (define_expand "abs<mode>2"
12996 [(set (match_operand:SDWIM 0 "register_operand")
12998 (match_operand:SDWIM 1 "general_operand")))
12999 (clobber (reg:CC FLAGS_REG))])]
13001 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)"
13003 if (TARGET_EXPAND_ABS)
13005 machine_mode mode = <MODE>mode;
13006 operands[1] = force_reg (mode, operands[1]);
13008 /* Generate rtx abs using:
13009 abs (x) = (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)) */
13011 rtx shift_amount = gen_int_mode (GET_MODE_PRECISION (mode) - 1, QImode);
13012 rtx shift_dst = expand_simple_binop (mode, ASHIFTRT, operands[1],
13013 shift_amount, NULL_RTX,
13015 rtx xor_dst = expand_simple_binop (mode, XOR, shift_dst, operands[1],
13016 operands[0], 0, OPTAB_DIRECT);
13017 rtx minus_dst = expand_simple_binop (mode, MINUS, xor_dst, shift_dst,
13018 operands[0], 0, OPTAB_DIRECT);
13019 if (!rtx_equal_p (minus_dst, operands[0]))
13020 emit_move_insn (operands[0], minus_dst);
13025 (define_insn_and_split "*abs<dwi>2_doubleword"
13026 [(set (match_operand:<DWI> 0 "register_operand")
13028 (match_operand:<DWI> 1 "general_operand")))
13029 (clobber (reg:CC FLAGS_REG))]
13031 && ix86_pre_reload_split ()"
13035 [(set (reg:CCC FLAGS_REG)
13036 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
13037 (set (match_dup 2) (neg:DWIH (match_dup 1)))])
13039 [(set (match_dup 5)
13040 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
13043 (clobber (reg:CC FLAGS_REG))])
13045 [(set (reg:CCGOC FLAGS_REG)
13047 (neg:DWIH (match_dup 5))
13050 (neg:DWIH (match_dup 5)))])
13053 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
13058 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
13062 operands[1] = force_reg (<DWI>mode, operands[1]);
13063 operands[2] = gen_reg_rtx (<DWI>mode);
13065 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
13068 (define_insn_and_split "*nabs<dwi>2_doubleword"
13069 [(set (match_operand:<DWI> 0 "register_operand")
13072 (match_operand:<DWI> 1 "general_operand"))))
13073 (clobber (reg:CC FLAGS_REG))]
13075 && ix86_pre_reload_split ()"
13079 [(set (reg:CCC FLAGS_REG)
13080 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
13081 (set (match_dup 2) (neg:DWIH (match_dup 1)))])
13083 [(set (match_dup 5)
13084 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
13087 (clobber (reg:CC FLAGS_REG))])
13089 [(set (reg:CCGOC FLAGS_REG)
13091 (neg:DWIH (match_dup 5))
13094 (neg:DWIH (match_dup 5)))])
13097 (lt (reg:CCGOC FLAGS_REG) (const_int 0))
13102 (lt (reg:CCGOC FLAGS_REG) (const_int 0))
13106 operands[1] = force_reg (<DWI>mode, operands[1]);
13107 operands[2] = gen_reg_rtx (<DWI>mode);
13109 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
13112 (define_insn_and_split "*abs<mode>2_1"
13113 [(set (match_operand:SWI 0 "register_operand")
13115 (match_operand:SWI 1 "general_operand")))
13116 (clobber (reg:CC FLAGS_REG))]
13118 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
13119 && ix86_pre_reload_split ()"
13123 [(set (reg:CCGOC FLAGS_REG)
13125 (neg:SWI (match_dup 1))
13128 (neg:SWI (match_dup 1)))])
13131 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
13135 operands[1] = force_reg (<MODE>mode, operands[1]);
13136 operands[2] = gen_reg_rtx (<MODE>mode);
13139 (define_insn_and_split "*nabs<mode>2_1"
13140 [(set (match_operand:SWI 0 "register_operand")
13143 (match_operand:SWI 1 "general_operand"))))
13144 (clobber (reg:CC FLAGS_REG))]
13146 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
13147 && ix86_pre_reload_split ()"
13151 [(set (reg:CCGOC FLAGS_REG)
13153 (neg:SWI (match_dup 1))
13156 (neg:SWI (match_dup 1)))])
13159 (lt (reg:CCGOC FLAGS_REG) (const_int 0))
13163 operands[1] = force_reg (<MODE>mode, operands[1]);
13164 operands[2] = gen_reg_rtx (<MODE>mode);
13167 (define_expand "<code>tf2"
13168 [(set (match_operand:TF 0 "register_operand")
13169 (absneg:TF (match_operand:TF 1 "register_operand")))]
13171 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
13173 (define_insn_and_split "*<code>tf2_1"
13174 [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
13176 (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m")))
13177 (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))]
13180 "&& reload_completed"
13181 [(set (match_dup 0)
13182 (<absneg_op>:TF (match_dup 1) (match_dup 2)))]
13186 if (MEM_P (operands[1]))
13187 std::swap (operands[1], operands[2]);
13191 if (operands_match_p (operands[0], operands[2]))
13192 std::swap (operands[1], operands[2]);
13195 [(set_attr "isa" "noavx,noavx,avx,avx")])
13197 (define_insn_and_split "*nabstf2_1"
13198 [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
13201 (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m"))))
13202 (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))]
13205 "&& reload_completed"
13206 [(set (match_dup 0)
13207 (ior:TF (match_dup 1) (match_dup 2)))]
13211 if (MEM_P (operands[1]))
13212 std::swap (operands[1], operands[2]);
13216 if (operands_match_p (operands[0], operands[2]))
13217 std::swap (operands[1], operands[2]);
13220 [(set_attr "isa" "noavx,noavx,avx,avx")])
13222 (define_expand "<code>hf2"
13223 [(set (match_operand:HF 0 "register_operand")
13224 (absneg:HF (match_operand:HF 1 "register_operand")))]
13225 "TARGET_AVX512FP16"
13226 "ix86_expand_fp_absneg_operator (<CODE>, HFmode, operands); DONE;")
13228 (define_expand "<code><mode>2"
13229 [(set (match_operand:X87MODEF 0 "register_operand")
13230 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
13231 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13232 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
13234 ;; Changing of sign for FP values is doable using integer unit too.
13235 (define_insn "*<code><mode>2_i387_1"
13236 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
13238 (match_operand:X87MODEF 1 "register_operand" "0,0")))
13239 (clobber (reg:CC FLAGS_REG))]
13240 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13244 [(set (match_operand:X87MODEF 0 "fp_register_operand")
13245 (absneg:X87MODEF (match_operand:X87MODEF 1 "fp_register_operand")))
13246 (clobber (reg:CC FLAGS_REG))]
13247 "TARGET_80387 && reload_completed"
13248 [(set (match_dup 0) (absneg:X87MODEF (match_dup 1)))])
13251 [(set (match_operand:X87MODEF 0 "general_reg_operand")
13252 (absneg:X87MODEF (match_operand:X87MODEF 1 "general_reg_operand")))
13253 (clobber (reg:CC FLAGS_REG))]
13254 "TARGET_80387 && reload_completed"
13256 "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
13258 (define_insn_and_split "*<code>hf2_1"
13259 [(set (match_operand:HF 0 "register_operand" "=Yv")
13261 (match_operand:HF 1 "register_operand" "Yv")))
13262 (use (match_operand:V8HF 2 "vector_operand" "Yvm"))
13263 (clobber (reg:CC FLAGS_REG))]
13264 "TARGET_AVX512FP16"
13266 "&& reload_completed"
13267 [(set (match_dup 0)
13268 (<absneg_op>:V8HF (match_dup 1) (match_dup 2)))]
13270 operands[0] = lowpart_subreg (V8HFmode, operands[0], HFmode);
13271 operands[1] = lowpart_subreg (V8HFmode, operands[1], HFmode);
13274 (define_insn "*<code><mode>2_1"
13275 [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv,f,!r")
13277 (match_operand:MODEF 1 "register_operand" "0,x,Yv,0,0")))
13278 (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm,X,X"))
13279 (clobber (reg:CC FLAGS_REG))]
13280 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13282 [(set_attr "isa" "noavx,noavx,avx,*,*")
13283 (set (attr "enabled")
13285 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
13287 (eq_attr "alternative" "3,4")
13288 (symbol_ref "TARGET_MIX_SSE_I387")
13289 (const_string "*"))
13291 (eq_attr "alternative" "3,4")
13292 (symbol_ref "true")
13293 (symbol_ref "false"))))])
13296 [(set (match_operand:MODEF 0 "sse_reg_operand")
13298 (match_operand:MODEF 1 "sse_reg_operand")))
13299 (use (match_operand:<ssevecmodef> 2 "vector_operand"))
13300 (clobber (reg:CC FLAGS_REG))]
13301 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13302 && reload_completed"
13303 [(set (match_dup 0)
13304 (<absneg_op>:<ssevecmodef> (match_dup 1) (match_dup 2)))]
13306 machine_mode mode = <MODE>mode;
13307 machine_mode vmode = <ssevecmodef>mode;
13309 operands[0] = lowpart_subreg (vmode, operands[0], mode);
13310 operands[1] = lowpart_subreg (vmode, operands[1], mode);
13312 if (!TARGET_AVX && operands_match_p (operands[0], operands[2]))
13313 std::swap (operands[1], operands[2]);
13317 [(set (match_operand:MODEF 0 "fp_register_operand")
13318 (absneg:MODEF (match_operand:MODEF 1 "fp_register_operand")))
13319 (use (match_operand 2))
13320 (clobber (reg:CC FLAGS_REG))]
13321 "TARGET_80387 && reload_completed"
13322 [(set (match_dup 0) (absneg:MODEF (match_dup 1)))])
13325 [(set (match_operand:MODEF 0 "general_reg_operand")
13326 (absneg:MODEF (match_operand:MODEF 1 "general_reg_operand")))
13327 (use (match_operand 2))
13328 (clobber (reg:CC FLAGS_REG))]
13329 "TARGET_80387 && reload_completed"
13331 "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
13333 (define_insn_and_split "*nabs<mode>2_1"
13334 [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv")
13337 (match_operand:MODEF 1 "register_operand" "0,x,Yv"))))
13338 (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm"))]
13339 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13341 "&& reload_completed"
13342 [(set (match_dup 0)
13343 (ior:<ssevecmodef> (match_dup 1) (match_dup 2)))]
13345 machine_mode mode = <MODE>mode;
13346 machine_mode vmode = <ssevecmodef>mode;
13348 operands[0] = lowpart_subreg (vmode, operands[0], mode);
13349 operands[1] = lowpart_subreg (vmode, operands[1], mode);
13351 if (!TARGET_AVX && operands_match_p (operands[0], operands[2]))
13352 std::swap (operands[1], operands[2]);
13354 [(set_attr "isa" "noavx,noavx,avx")])
13356 ;; Conditionalize these after reload. If they match before reload, we
13357 ;; lose the clobber and ability to use integer instructions.
13359 (define_insn "*<code><mode>2_i387"
13360 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
13361 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
13362 "TARGET_80387 && reload_completed"
13363 "<absneg_mnemonic>"
13364 [(set_attr "type" "fsgn")
13365 (set_attr "mode" "<MODE>")])
13367 ;; Copysign instructions
13369 (define_expand "copysign<mode>3"
13370 [(match_operand:SSEMODEF 0 "register_operand")
13371 (match_operand:SSEMODEF 1 "nonmemory_operand")
13372 (match_operand:SSEMODEF 2 "register_operand")]
13373 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13374 || (TARGET_SSE && (<MODE>mode == TFmode))
13375 || (TARGET_AVX512FP16 && (<MODE>mode ==HFmode))"
13376 "ix86_expand_copysign (operands); DONE;")
13378 (define_expand "xorsign<mode>3"
13379 [(match_operand:MODEFH 0 "register_operand")
13380 (match_operand:MODEFH 1 "register_operand")
13381 (match_operand:MODEFH 2 "register_operand")]
13382 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13383 || <MODE>mode == HFmode"
13385 if (rtx_equal_p (operands[1], operands[2]))
13386 emit_insn (gen_abs<mode>2 (operands[0], operands[1]));
13388 ix86_expand_xorsign (operands);
13392 ;; One complement instructions
13394 (define_expand "one_cmpl<mode>2"
13395 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
13396 (not:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
13398 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
13400 (define_insn_and_split "*one_cmpl<dwi>2_doubleword"
13401 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
13402 (not:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))]
13403 "ix86_unary_operator_ok (NOT, <DWI>mode, operands)"
13405 "&& reload_completed"
13406 [(set (match_dup 0)
13407 (not:DWIH (match_dup 1)))
13409 (not:DWIH (match_dup 3)))]
13410 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
13412 (define_insn "*one_cmpl<mode>2_1"
13413 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,?k")
13414 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0,k")))]
13415 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
13417 not{<imodesuffix>}\t%0
13419 [(set_attr "isa" "*,<kmov_isa>")
13420 (set_attr "type" "negnot,msklog")
13421 (set_attr "mode" "<MODE>")])
13423 (define_insn "*one_cmplsi2_1_zext"
13424 [(set (match_operand:DI 0 "register_operand" "=r,?k")
13426 (not:SI (match_operand:SI 1 "register_operand" "0,k"))))]
13427 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
13431 [(set_attr "isa" "x64,avx512bw_512")
13432 (set_attr "type" "negnot,msklog")
13433 (set_attr "mode" "SI,SI")])
13435 (define_insn "*one_cmplqi2_1"
13436 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,?k")
13437 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
13438 "ix86_unary_operator_ok (NOT, QImode, operands)"
13443 [(set_attr "isa" "*,*,avx512f")
13444 (set_attr "type" "negnot,negnot,msklog")
13446 (cond [(eq_attr "alternative" "1")
13447 (const_string "SI")
13448 (and (eq_attr "alternative" "2")
13449 (match_test "!TARGET_AVX512DQ"))
13450 (const_string "HI")
13452 (const_string "QI")))
13453 ;; Potential partial reg stall on alternative 1.
13454 (set (attr "preferred_for_speed")
13455 (cond [(eq_attr "alternative" "1")
13456 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
13457 (symbol_ref "true")))])
13459 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
13460 (define_insn_and_split "*one_cmpl<mode>_1_slp"
13461 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
13462 (not:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")))]
13463 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
13465 not{<imodesuffix>}\t%0
13467 "&& reload_completed
13468 && !(rtx_equal_p (operands[0], operands[1]))"
13469 [(set (strict_low_part (match_dup 0)) (match_dup 1))
13470 (set (strict_low_part (match_dup 0))
13471 (not:SWI12 (match_dup 0)))]
13473 [(set_attr "type" "negnot")
13474 (set_attr "mode" "<MODE>")])
13476 (define_insn "*one_cmpl<mode>2_2"
13477 [(set (reg FLAGS_REG)
13478 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
13480 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
13481 (not:SWI (match_dup 1)))]
13482 "ix86_match_ccmode (insn, CCNOmode)
13483 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
13485 [(set_attr "type" "alu1")
13486 (set_attr "mode" "<MODE>")])
13489 [(set (match_operand 0 "flags_reg_operand")
13490 (match_operator 2 "compare_operator"
13491 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
13493 (set (match_operand:SWI 1 "nonimmediate_operand")
13494 (not:SWI (match_dup 3)))]
13495 "ix86_match_ccmode (insn, CCNOmode)"
13496 [(parallel [(set (match_dup 0)
13497 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
13500 (xor:SWI (match_dup 3) (const_int -1)))])])
13502 (define_insn "*one_cmplsi2_2_zext"
13503 [(set (reg FLAGS_REG)
13504 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
13506 (set (match_operand:DI 0 "register_operand" "=r")
13507 (zero_extend:DI (not:SI (match_dup 1))))]
13508 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
13509 && ix86_unary_operator_ok (NOT, SImode, operands)"
13511 [(set_attr "type" "alu1")
13512 (set_attr "mode" "SI")])
13515 [(set (match_operand 0 "flags_reg_operand")
13516 (match_operator 2 "compare_operator"
13517 [(not:SI (match_operand:SI 3 "register_operand"))
13519 (set (match_operand:DI 1 "register_operand")
13520 (zero_extend:DI (not:SI (match_dup 3))))]
13521 "ix86_match_ccmode (insn, CCNOmode)"
13522 [(parallel [(set (match_dup 0)
13523 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
13526 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
13528 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
13529 (define_insn_and_split "*one_cmplqi_ext<mode>_1"
13530 [(set (zero_extract:SWI248
13531 (match_operand 0 "int248_register_operand" "+Q,&Q")
13537 (match_operator:SWI248 2 "extract_operator"
13538 [(match_operand 1 "int248_register_operand" "0,!Q")
13540 (const_int 8)]) 0)) 0))]
13546 && !(rtx_equal_p (operands[0], operands[1]))"
13547 [(set (zero_extract:SWI248
13548 (match_dup 0) (const_int 8) (const_int 8))
13549 (zero_extract:SWI248
13550 (match_dup 1) (const_int 8) (const_int 8)))
13551 (set (zero_extract:SWI248
13552 (match_dup 0) (const_int 8) (const_int 8))
13557 [(match_dup 0) (const_int 8) (const_int 8)]) 0)) 0))]
13559 [(set_attr "type" "negnot")
13560 (set_attr "mode" "QI")])
13562 ;; Shift instructions
13564 ;; DImode shifts are implemented using the i386 "shift double" opcode,
13565 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
13566 ;; is variable, then the count is in %cl and the "imm" operand is dropped
13567 ;; from the assembler input.
13569 ;; This instruction shifts the target reg/mem as usual, but instead of
13570 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
13571 ;; is a left shift double, bits are taken from the high order bits of
13572 ;; reg, else if the insn is a shift right double, bits are taken from the
13573 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
13574 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
13576 ;; Since sh[lr]d does not change the `reg' operand, that is done
13577 ;; separately, making all shifts emit pairs of shift double and normal
13578 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
13579 ;; support a 63 bit shift, each shift where the count is in a reg expands
13580 ;; to a pair of shifts, a branch, a shift by 32 and a label.
13582 ;; If the shift count is a constant, we need never emit more than one
13583 ;; shift pair, instead using moves and sign extension for counts greater
13586 (define_expand "ashl<mode>3"
13587 [(set (match_operand:SDWIM 0 "<shift_operand>")
13588 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
13589 (match_operand:QI 2 "nonmemory_operand")))]
13591 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
13593 (define_insn_and_split "*ashl<dwi>3_doubleword_mask"
13594 [(set (match_operand:<DWI> 0 "register_operand")
13596 (match_operand:<DWI> 1 "register_operand")
13599 (match_operand 2 "int248_register_operand" "c")
13600 (match_operand 3 "const_int_operand")) 0)))
13601 (clobber (reg:CC FLAGS_REG))]
13602 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
13603 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
13604 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
13605 && ix86_pre_reload_split ()"
13609 [(set (match_dup 6)
13610 (ior:DWIH (ashift:DWIH (match_dup 6)
13611 (and:QI (match_dup 2) (match_dup 8)))
13613 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
13614 (minus:QI (match_dup 9)
13615 (and:QI (match_dup 2) (match_dup 8)))) 0)))
13616 (clobber (reg:CC FLAGS_REG))])
13618 [(set (match_dup 4)
13619 (ashift:DWIH (match_dup 5) (match_dup 2)))
13620 (clobber (reg:CC FLAGS_REG))])]
13622 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
13624 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
13625 operands[2] = gen_lowpart (QImode, operands[2]);
13626 emit_insn (gen_ashl<dwi>3_doubleword (operands[0], operands[1],
13631 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
13633 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
13634 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
13636 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13637 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13640 xops[0] = gen_reg_rtx (GET_MODE (operands[2]));
13641 xops[1] = operands[2];
13642 xops[2] = GEN_INT (INTVAL (operands[3])
13643 & ((<MODE_SIZE> * BITS_PER_UNIT) - 1));
13644 ix86_expand_binary_operator (AND, GET_MODE (operands[2]), xops);
13645 operands[2] = xops[0];
13648 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
13649 operands[2] = gen_lowpart (QImode, operands[2]);
13651 if (!rtx_equal_p (operands[6], operands[7]))
13652 emit_move_insn (operands[6], operands[7]);
13655 (define_insn_and_split "*ashl<dwi>3_doubleword_mask_1"
13656 [(set (match_operand:<DWI> 0 "register_operand")
13658 (match_operand:<DWI> 1 "register_operand")
13660 (match_operand:QI 2 "register_operand" "c")
13661 (match_operand:QI 3 "const_int_operand"))))
13662 (clobber (reg:CC FLAGS_REG))]
13663 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
13664 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
13665 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
13666 && ix86_pre_reload_split ()"
13670 [(set (match_dup 6)
13671 (ior:DWIH (ashift:DWIH (match_dup 6)
13672 (and:QI (match_dup 2) (match_dup 8)))
13674 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
13675 (minus:QI (match_dup 9)
13676 (and:QI (match_dup 2) (match_dup 8)))) 0)))
13677 (clobber (reg:CC FLAGS_REG))])
13679 [(set (match_dup 4)
13680 (ashift:DWIH (match_dup 5) (match_dup 2)))
13681 (clobber (reg:CC FLAGS_REG))])]
13683 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
13685 emit_insn (gen_ashl<dwi>3_doubleword (operands[0], operands[1],
13690 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
13692 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
13693 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
13695 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13696 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13698 rtx tem = gen_reg_rtx (QImode);
13699 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
13703 if (!rtx_equal_p (operands[6], operands[7]))
13704 emit_move_insn (operands[6], operands[7]);
13707 (define_insn "ashl<mode>3_doubleword"
13708 [(set (match_operand:DWI 0 "register_operand" "=&r")
13709 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n")
13710 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
13711 (clobber (reg:CC FLAGS_REG))]
13714 [(set_attr "type" "multi")])
13717 [(set (match_operand:DWI 0 "register_operand")
13718 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
13719 (match_operand:QI 2 "nonmemory_operand")))
13720 (clobber (reg:CC FLAGS_REG))]
13721 "epilogue_completed"
13723 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
13725 ;; By default we don't ask for a scratch register, because when DWImode
13726 ;; values are manipulated, registers are already at a premium. But if
13727 ;; we have one handy, we won't turn it away.
13730 [(match_scratch:DWIH 3 "r")
13731 (parallel [(set (match_operand:<DWI> 0 "register_operand")
13733 (match_operand:<DWI> 1 "nonmemory_operand")
13734 (match_operand:QI 2 "nonmemory_operand")))
13735 (clobber (reg:CC FLAGS_REG))])
13739 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
13741 (define_insn_and_split "*ashl<dwi>3_doubleword_highpart"
13742 [(set (match_operand:<DWI> 0 "register_operand" "=r")
13744 (any_extend:<DWI> (match_operand:DWIH 1 "nonimmediate_operand" "rm"))
13745 (match_operand:QI 2 "const_int_operand")))
13746 (clobber (reg:CC FLAGS_REG))]
13747 "INTVAL (operands[2]) >= <MODE_SIZE> * BITS_PER_UNIT
13748 && INTVAL (operands[2]) < <MODE_SIZE> * BITS_PER_UNIT * 2"
13750 "&& reload_completed"
13753 split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[3]);
13754 int bits = INTVAL (operands[2]) - (<MODE_SIZE> * BITS_PER_UNIT);
13755 if (!rtx_equal_p (operands[3], operands[1]))
13756 emit_move_insn (operands[3], operands[1]);
13758 emit_insn (gen_ashl<mode>3 (operands[3], operands[3], GEN_INT (bits)));
13759 ix86_expand_clear (operands[0]);
13763 (define_insn "x86_64_shld"
13764 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
13765 (ior:DI (ashift:DI (match_dup 0)
13766 (and:QI (match_operand:QI 2 "nonmemory_operand" "Jc")
13771 (match_operand:DI 1 "register_operand" "r"))
13772 (minus:QI (const_int 64)
13773 (and:QI (match_dup 2) (const_int 63)))) 0)))
13774 (clobber (reg:CC FLAGS_REG))]
13776 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
13777 [(set_attr "type" "ishift")
13778 (set_attr "prefix_0f" "1")
13779 (set_attr "mode" "DI")
13780 (set_attr "athlon_decode" "vector")
13781 (set_attr "amdfam10_decode" "vector")
13782 (set_attr "bdver1_decode" "vector")])
13784 (define_insn "x86_64_shld_1"
13785 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
13786 (ior:DI (ashift:DI (match_dup 0)
13787 (match_operand:QI 2 "const_0_to_63_operand"))
13791 (match_operand:DI 1 "register_operand" "r"))
13792 (match_operand:QI 3 "const_0_to_255_operand")) 0)))
13793 (clobber (reg:CC FLAGS_REG))]
13795 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])"
13796 "shld{q}\t{%2, %1, %0|%0, %1, %2}"
13797 [(set_attr "type" "ishift")
13798 (set_attr "prefix_0f" "1")
13799 (set_attr "mode" "DI")
13800 (set_attr "length_immediate" "1")
13801 (set_attr "athlon_decode" "vector")
13802 (set_attr "amdfam10_decode" "vector")
13803 (set_attr "bdver1_decode" "vector")])
13805 (define_insn_and_split "*x86_64_shld_shrd_1_nozext"
13806 [(set (match_operand:DI 0 "nonimmediate_operand")
13807 (ior:DI (ashift:DI (match_operand:DI 4 "nonimmediate_operand")
13808 (match_operand:QI 2 "const_0_to_63_operand"))
13810 (match_operand:DI 1 "nonimmediate_operand")
13811 (match_operand:QI 3 "const_0_to_63_operand"))))
13812 (clobber (reg:CC FLAGS_REG))]
13814 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])
13815 && ix86_pre_reload_split ()"
13820 if (rtx_equal_p (operands[4], operands[0]))
13822 operands[1] = force_reg (DImode, operands[1]);
13823 emit_insn (gen_x86_64_shld_1 (operands[0], operands[1], operands[2], operands[3]));
13825 else if (rtx_equal_p (operands[1], operands[0]))
13827 operands[4] = force_reg (DImode, operands[4]);
13828 emit_insn (gen_x86_64_shrd_1 (operands[0], operands[4], operands[3], operands[2]));
13832 operands[1] = force_reg (DImode, operands[1]);
13833 rtx tmp = gen_reg_rtx (DImode);
13834 emit_move_insn (tmp, operands[4]);
13835 emit_insn (gen_x86_64_shld_1 (tmp, operands[1], operands[2], operands[3]));
13836 emit_move_insn (operands[0], tmp);
13841 (define_insn_and_split "*x86_64_shld_2"
13842 [(set (match_operand:DI 0 "nonimmediate_operand")
13843 (ior:DI (ashift:DI (match_dup 0)
13844 (match_operand:QI 2 "nonmemory_operand"))
13845 (lshiftrt:DI (match_operand:DI 1 "register_operand")
13846 (minus:QI (const_int 64) (match_dup 2)))))
13847 (clobber (reg:CC FLAGS_REG))]
13848 "TARGET_64BIT && ix86_pre_reload_split ()"
13851 [(parallel [(set (match_dup 0)
13852 (ior:DI (ashift:DI (match_dup 0)
13853 (and:QI (match_dup 2) (const_int 63)))
13856 (zero_extend:TI (match_dup 1))
13857 (minus:QI (const_int 64)
13858 (and:QI (match_dup 2)
13859 (const_int 63)))) 0)))
13860 (clobber (reg:CC FLAGS_REG))])])
13862 (define_insn "x86_shld"
13863 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
13864 (ior:SI (ashift:SI (match_dup 0)
13865 (and:QI (match_operand:QI 2 "nonmemory_operand" "Ic")
13870 (match_operand:SI 1 "register_operand" "r"))
13871 (minus:QI (const_int 32)
13872 (and:QI (match_dup 2) (const_int 31)))) 0)))
13873 (clobber (reg:CC FLAGS_REG))]
13875 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
13876 [(set_attr "type" "ishift")
13877 (set_attr "prefix_0f" "1")
13878 (set_attr "mode" "SI")
13879 (set_attr "pent_pair" "np")
13880 (set_attr "athlon_decode" "vector")
13881 (set_attr "amdfam10_decode" "vector")
13882 (set_attr "bdver1_decode" "vector")])
13884 (define_insn "x86_shld_1"
13885 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
13886 (ior:SI (ashift:SI (match_dup 0)
13887 (match_operand:QI 2 "const_0_to_31_operand"))
13891 (match_operand:SI 1 "register_operand" "r"))
13892 (match_operand:QI 3 "const_0_to_63_operand")) 0)))
13893 (clobber (reg:CC FLAGS_REG))]
13894 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])"
13895 "shld{l}\t{%2, %1, %0|%0, %1, %2}"
13896 [(set_attr "type" "ishift")
13897 (set_attr "prefix_0f" "1")
13898 (set_attr "length_immediate" "1")
13899 (set_attr "mode" "SI")
13900 (set_attr "pent_pair" "np")
13901 (set_attr "athlon_decode" "vector")
13902 (set_attr "amdfam10_decode" "vector")
13903 (set_attr "bdver1_decode" "vector")])
13905 (define_insn_and_split "*x86_shld_shrd_1_nozext"
13906 [(set (match_operand:SI 0 "nonimmediate_operand")
13907 (ior:SI (ashift:SI (match_operand:SI 4 "nonimmediate_operand")
13908 (match_operand:QI 2 "const_0_to_31_operand"))
13910 (match_operand:SI 1 "nonimmediate_operand")
13911 (match_operand:QI 3 "const_0_to_31_operand"))))
13912 (clobber (reg:CC FLAGS_REG))]
13913 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])
13914 && ix86_pre_reload_split ()"
13919 if (rtx_equal_p (operands[4], operands[0]))
13921 operands[1] = force_reg (SImode, operands[1]);
13922 emit_insn (gen_x86_shld_1 (operands[0], operands[1], operands[2], operands[3]));
13924 else if (rtx_equal_p (operands[1], operands[0]))
13926 operands[4] = force_reg (SImode, operands[4]);
13927 emit_insn (gen_x86_shrd_1 (operands[0], operands[4], operands[3], operands[2]));
13931 operands[1] = force_reg (SImode, operands[1]);
13932 rtx tmp = gen_reg_rtx (SImode);
13933 emit_move_insn (tmp, operands[4]);
13934 emit_insn (gen_x86_shld_1 (tmp, operands[1], operands[2], operands[3]));
13935 emit_move_insn (operands[0], tmp);
13940 (define_insn_and_split "*x86_shld_2"
13941 [(set (match_operand:SI 0 "nonimmediate_operand")
13942 (ior:SI (ashift:SI (match_dup 0)
13943 (match_operand:QI 2 "nonmemory_operand"))
13944 (lshiftrt:SI (match_operand:SI 1 "register_operand")
13945 (minus:QI (const_int 32) (match_dup 2)))))
13946 (clobber (reg:CC FLAGS_REG))]
13947 "TARGET_64BIT && ix86_pre_reload_split ()"
13950 [(parallel [(set (match_dup 0)
13951 (ior:SI (ashift:SI (match_dup 0)
13952 (and:QI (match_dup 2) (const_int 31)))
13955 (zero_extend:DI (match_dup 1))
13956 (minus:QI (const_int 32)
13957 (and:QI (match_dup 2)
13958 (const_int 31)))) 0)))
13959 (clobber (reg:CC FLAGS_REG))])])
13961 (define_expand "@x86_shift<mode>_adj_1"
13962 [(set (reg:CCZ FLAGS_REG)
13963 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
13966 (set (match_operand:SWI48 0 "register_operand")
13967 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
13968 (match_operand:SWI48 1 "register_operand")
13971 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
13972 (match_operand:SWI48 3 "register_operand")
13975 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
13977 (define_expand "@x86_shift<mode>_adj_2"
13978 [(use (match_operand:SWI48 0 "register_operand"))
13979 (use (match_operand:SWI48 1 "register_operand"))
13980 (use (match_operand:QI 2 "register_operand"))]
13983 rtx_code_label *label = gen_label_rtx ();
13986 emit_insn (gen_testqi_ccz_1 (operands[2],
13987 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
13989 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
13990 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
13991 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
13992 gen_rtx_LABEL_REF (VOIDmode, label),
13994 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
13995 JUMP_LABEL (tmp) = label;
13997 emit_move_insn (operands[0], operands[1]);
13998 ix86_expand_clear (operands[1]);
14000 emit_label (label);
14001 LABEL_NUSES (label) = 1;
14006 ;; Avoid useless masking of count operand.
14007 (define_insn_and_split "*ashl<mode>3_mask"
14008 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14010 (match_operand:SWI48 1 "nonimmediate_operand")
14013 (match_operand 2 "int248_register_operand" "c,r")
14014 (match_operand 3 "const_int_operand")) 0)))
14015 (clobber (reg:CC FLAGS_REG))]
14016 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
14017 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
14018 == GET_MODE_BITSIZE (<MODE>mode)-1
14019 && ix86_pre_reload_split ()"
14023 [(set (match_dup 0)
14024 (ashift:SWI48 (match_dup 1)
14026 (clobber (reg:CC FLAGS_REG))])]
14028 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14029 operands[2] = gen_lowpart (QImode, operands[2]);
14031 [(set_attr "isa" "*,bmi2")])
14033 (define_insn_and_split "*ashl<mode>3_mask_1"
14034 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14036 (match_operand:SWI48 1 "nonimmediate_operand")
14038 (match_operand:QI 2 "register_operand" "c,r")
14039 (match_operand:QI 3 "const_int_operand"))))
14040 (clobber (reg:CC FLAGS_REG))]
14041 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
14042 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
14043 == GET_MODE_BITSIZE (<MODE>mode)-1
14044 && ix86_pre_reload_split ()"
14048 [(set (match_dup 0)
14049 (ashift:SWI48 (match_dup 1)
14051 (clobber (reg:CC FLAGS_REG))])]
14053 [(set_attr "isa" "*,bmi2")])
14055 (define_insn "*bmi2_ashl<mode>3_1"
14056 [(set (match_operand:SWI48 0 "register_operand" "=r")
14057 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14058 (match_operand:SWI48 2 "register_operand" "r")))]
14060 "shlx\t{%2, %1, %0|%0, %1, %2}"
14061 [(set_attr "type" "ishiftx")
14062 (set_attr "mode" "<MODE>")])
14064 (define_insn "*ashl<mode>3_1"
14065 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,?k")
14066 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm,k")
14067 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r,<KS>")))
14068 (clobber (reg:CC FLAGS_REG))]
14069 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
14071 switch (get_attr_type (insn))
14079 gcc_assert (operands[2] == const1_rtx);
14080 gcc_assert (rtx_equal_p (operands[0], operands[1]));
14081 return "add{<imodesuffix>}\t%0, %0";
14084 if (operands[2] == const1_rtx
14085 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14086 return "sal{<imodesuffix>}\t%0";
14088 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14091 [(set_attr "isa" "*,*,bmi2,<kmov_isa>")
14093 (cond [(eq_attr "alternative" "1")
14094 (const_string "lea")
14095 (eq_attr "alternative" "2")
14096 (const_string "ishiftx")
14097 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14098 (match_operand 0 "register_operand"))
14099 (match_operand 2 "const1_operand"))
14100 (const_string "alu")
14101 (eq_attr "alternative" "3")
14102 (const_string "msklog")
14104 (const_string "ishift")))
14105 (set (attr "length_immediate")
14107 (ior (eq_attr "type" "alu")
14108 (and (eq_attr "type" "ishift")
14109 (and (match_operand 2 "const1_operand")
14110 (ior (match_test "TARGET_SHIFT1")
14111 (match_test "optimize_function_for_size_p (cfun)")))))
14113 (const_string "*")))
14114 (set_attr "mode" "<MODE>")])
14116 ;; Convert shift to the shiftx pattern to avoid flags dependency.
14118 [(set (match_operand:SWI48 0 "register_operand")
14119 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
14120 (match_operand:QI 2 "register_operand")))
14121 (clobber (reg:CC FLAGS_REG))]
14122 "TARGET_BMI2 && reload_completed"
14123 [(set (match_dup 0)
14124 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
14125 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
14127 (define_insn "*bmi2_ashlsi3_1_zext"
14128 [(set (match_operand:DI 0 "register_operand" "=r")
14130 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
14131 (match_operand:SI 2 "register_operand" "r"))))]
14132 "TARGET_64BIT && TARGET_BMI2"
14133 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
14134 [(set_attr "type" "ishiftx")
14135 (set_attr "mode" "SI")])
14137 (define_insn "*ashlsi3_1_zext"
14138 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
14140 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
14141 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
14142 (clobber (reg:CC FLAGS_REG))]
14143 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
14145 switch (get_attr_type (insn))
14152 gcc_assert (operands[2] == const1_rtx);
14153 return "add{l}\t%k0, %k0";
14156 if (operands[2] == const1_rtx
14157 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14158 return "sal{l}\t%k0";
14160 return "sal{l}\t{%2, %k0|%k0, %2}";
14163 [(set_attr "isa" "*,*,bmi2")
14165 (cond [(eq_attr "alternative" "1")
14166 (const_string "lea")
14167 (eq_attr "alternative" "2")
14168 (const_string "ishiftx")
14169 (and (match_test "TARGET_DOUBLE_WITH_ADD")
14170 (match_operand 2 "const1_operand"))
14171 (const_string "alu")
14173 (const_string "ishift")))
14174 (set (attr "length_immediate")
14176 (ior (eq_attr "type" "alu")
14177 (and (eq_attr "type" "ishift")
14178 (and (match_operand 2 "const1_operand")
14179 (ior (match_test "TARGET_SHIFT1")
14180 (match_test "optimize_function_for_size_p (cfun)")))))
14182 (const_string "*")))
14183 (set_attr "mode" "SI")])
14185 ;; Convert shift to the shiftx pattern to avoid flags dependency.
14187 [(set (match_operand:DI 0 "register_operand")
14189 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
14190 (match_operand:QI 2 "register_operand"))))
14191 (clobber (reg:CC FLAGS_REG))]
14192 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
14193 [(set (match_dup 0)
14194 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
14195 "operands[2] = gen_lowpart (SImode, operands[2]);")
14197 (define_insn "*ashlhi3_1"
14198 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp,?k")
14199 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l,k")
14200 (match_operand:QI 2 "nonmemory_operand" "cI,M,Ww")))
14201 (clobber (reg:CC FLAGS_REG))]
14202 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
14204 switch (get_attr_type (insn))
14211 gcc_assert (operands[2] == const1_rtx);
14212 return "add{w}\t%0, %0";
14215 if (operands[2] == const1_rtx
14216 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14217 return "sal{w}\t%0";
14219 return "sal{w}\t{%2, %0|%0, %2}";
14222 [(set_attr "isa" "*,*,avx512f")
14224 (cond [(eq_attr "alternative" "1")
14225 (const_string "lea")
14226 (eq_attr "alternative" "2")
14227 (const_string "msklog")
14228 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14229 (match_operand 0 "register_operand"))
14230 (match_operand 2 "const1_operand"))
14231 (const_string "alu")
14233 (const_string "ishift")))
14234 (set (attr "length_immediate")
14236 (ior (eq_attr "type" "alu")
14237 (and (eq_attr "type" "ishift")
14238 (and (match_operand 2 "const1_operand")
14239 (ior (match_test "TARGET_SHIFT1")
14240 (match_test "optimize_function_for_size_p (cfun)")))))
14242 (const_string "*")))
14243 (set_attr "mode" "HI,SI,HI")])
14245 (define_insn "*ashlqi3_1"
14246 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp,?k")
14247 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l,k")
14248 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M,Wb")))
14249 (clobber (reg:CC FLAGS_REG))]
14250 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
14252 switch (get_attr_type (insn))
14259 gcc_assert (operands[2] == const1_rtx);
14260 if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
14261 return "add{l}\t%k0, %k0";
14263 return "add{b}\t%0, %0";
14266 if (operands[2] == const1_rtx
14267 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14269 if (get_attr_mode (insn) == MODE_SI)
14270 return "sal{l}\t%k0";
14272 return "sal{b}\t%0";
14276 if (get_attr_mode (insn) == MODE_SI)
14277 return "sal{l}\t{%2, %k0|%k0, %2}";
14279 return "sal{b}\t{%2, %0|%0, %2}";
14283 [(set_attr "isa" "*,*,*,avx512dq")
14285 (cond [(eq_attr "alternative" "2")
14286 (const_string "lea")
14287 (eq_attr "alternative" "3")
14288 (const_string "msklog")
14289 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14290 (match_operand 0 "register_operand"))
14291 (match_operand 2 "const1_operand"))
14292 (const_string "alu")
14294 (const_string "ishift")))
14295 (set (attr "length_immediate")
14297 (ior (eq_attr "type" "alu")
14298 (and (eq_attr "type" "ishift")
14299 (and (match_operand 2 "const1_operand")
14300 (ior (match_test "TARGET_SHIFT1")
14301 (match_test "optimize_function_for_size_p (cfun)")))))
14303 (const_string "*")))
14304 (set_attr "mode" "QI,SI,SI,QI")
14305 ;; Potential partial reg stall on alternative 1.
14306 (set (attr "preferred_for_speed")
14307 (cond [(eq_attr "alternative" "1")
14308 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
14309 (symbol_ref "true")))])
14311 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
14312 (define_insn_and_split "*ashl<mode>3_1_slp"
14313 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
14314 (ashift:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
14315 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
14316 (clobber (reg:CC FLAGS_REG))]
14317 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
14319 if (which_alternative)
14322 switch (get_attr_type (insn))
14325 gcc_assert (operands[2] == const1_rtx);
14326 return "add{<imodesuffix>}\t%0, %0";
14329 if (operands[2] == const1_rtx
14330 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14331 return "sal{<imodesuffix>}\t%0";
14333 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14336 "&& reload_completed
14337 && !(rtx_equal_p (operands[0], operands[1]))"
14338 [(set (strict_low_part (match_dup 0)) (match_dup 1))
14340 [(set (strict_low_part (match_dup 0))
14341 (ashift:SWI12 (match_dup 0) (match_dup 2)))
14342 (clobber (reg:CC FLAGS_REG))])]
14344 [(set (attr "type")
14345 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
14346 (match_operand 2 "const1_operand"))
14347 (const_string "alu")
14349 (const_string "ishift")))
14350 (set (attr "length_immediate")
14352 (ior (eq_attr "type" "alu")
14353 (and (eq_attr "type" "ishift")
14354 (and (match_operand 2 "const1_operand")
14355 (ior (match_test "TARGET_SHIFT1")
14356 (match_test "optimize_function_for_size_p (cfun)")))))
14358 (const_string "*")))
14359 (set_attr "mode" "<MODE>")])
14361 ;; Convert ashift to the lea pattern to avoid flags dependency.
14363 [(set (match_operand:SWI 0 "general_reg_operand")
14364 (ashift:SWI (match_operand:SWI 1 "index_reg_operand")
14365 (match_operand 2 "const_0_to_3_operand")))
14366 (clobber (reg:CC FLAGS_REG))]
14368 && REGNO (operands[0]) != REGNO (operands[1])"
14369 [(set (match_dup 0)
14370 (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
14372 if (<MODE>mode != <LEAMODE>mode)
14374 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
14375 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
14377 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
14380 ;; Convert ashift to the lea pattern to avoid flags dependency.
14382 [(set (match_operand:DI 0 "general_reg_operand")
14384 (ashift:SI (match_operand:SI 1 "index_reg_operand")
14385 (match_operand 2 "const_0_to_3_operand"))))
14386 (clobber (reg:CC FLAGS_REG))]
14387 "TARGET_64BIT && reload_completed
14388 && REGNO (operands[0]) != REGNO (operands[1])"
14389 [(set (match_dup 0)
14390 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
14392 operands[1] = gen_lowpart (SImode, operands[1]);
14393 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
14396 ;; This pattern can't accept a variable shift count, since shifts by
14397 ;; zero don't affect the flags. We assume that shifts by constant
14398 ;; zero are optimized away.
14399 (define_insn "*ashl<mode>3_cmp"
14400 [(set (reg FLAGS_REG)
14402 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
14403 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
14405 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
14406 (ashift:SWI (match_dup 1) (match_dup 2)))]
14407 "(optimize_function_for_size_p (cfun)
14408 || !TARGET_PARTIAL_FLAG_REG_STALL
14409 || (operands[2] == const1_rtx
14411 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
14412 && ix86_match_ccmode (insn, CCGOCmode)
14413 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
14415 switch (get_attr_type (insn))
14418 gcc_assert (operands[2] == const1_rtx);
14419 return "add{<imodesuffix>}\t%0, %0";
14422 if (operands[2] == const1_rtx
14423 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14424 return "sal{<imodesuffix>}\t%0";
14426 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14429 [(set (attr "type")
14430 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14431 (match_operand 0 "register_operand"))
14432 (match_operand 2 "const1_operand"))
14433 (const_string "alu")
14435 (const_string "ishift")))
14436 (set (attr "length_immediate")
14438 (ior (eq_attr "type" "alu")
14439 (and (eq_attr "type" "ishift")
14440 (and (match_operand 2 "const1_operand")
14441 (ior (match_test "TARGET_SHIFT1")
14442 (match_test "optimize_function_for_size_p (cfun)")))))
14444 (const_string "*")))
14445 (set_attr "mode" "<MODE>")])
14447 (define_insn "*ashlsi3_cmp_zext"
14448 [(set (reg FLAGS_REG)
14450 (ashift:SI (match_operand:SI 1 "register_operand" "0")
14451 (match_operand:QI 2 "const_1_to_31_operand"))
14453 (set (match_operand:DI 0 "register_operand" "=r")
14454 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
14456 && (optimize_function_for_size_p (cfun)
14457 || !TARGET_PARTIAL_FLAG_REG_STALL
14458 || (operands[2] == const1_rtx
14460 || TARGET_DOUBLE_WITH_ADD)))
14461 && ix86_match_ccmode (insn, CCGOCmode)
14462 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
14464 switch (get_attr_type (insn))
14467 gcc_assert (operands[2] == const1_rtx);
14468 return "add{l}\t%k0, %k0";
14471 if (operands[2] == const1_rtx
14472 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14473 return "sal{l}\t%k0";
14475 return "sal{l}\t{%2, %k0|%k0, %2}";
14478 [(set (attr "type")
14479 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
14480 (match_operand 2 "const1_operand"))
14481 (const_string "alu")
14483 (const_string "ishift")))
14484 (set (attr "length_immediate")
14486 (ior (eq_attr "type" "alu")
14487 (and (eq_attr "type" "ishift")
14488 (and (match_operand 2 "const1_operand")
14489 (ior (match_test "TARGET_SHIFT1")
14490 (match_test "optimize_function_for_size_p (cfun)")))))
14492 (const_string "*")))
14493 (set_attr "mode" "SI")])
14495 (define_insn "*ashl<mode>3_cconly"
14496 [(set (reg FLAGS_REG)
14498 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
14499 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
14501 (clobber (match_scratch:SWI 0 "=<r>"))]
14502 "(optimize_function_for_size_p (cfun)
14503 || !TARGET_PARTIAL_FLAG_REG_STALL
14504 || (operands[2] == const1_rtx
14506 || TARGET_DOUBLE_WITH_ADD)))
14507 && ix86_match_ccmode (insn, CCGOCmode)"
14509 switch (get_attr_type (insn))
14512 gcc_assert (operands[2] == const1_rtx);
14513 return "add{<imodesuffix>}\t%0, %0";
14516 if (operands[2] == const1_rtx
14517 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14518 return "sal{<imodesuffix>}\t%0";
14520 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14523 [(set (attr "type")
14524 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14525 (match_operand 0 "register_operand"))
14526 (match_operand 2 "const1_operand"))
14527 (const_string "alu")
14529 (const_string "ishift")))
14530 (set (attr "length_immediate")
14532 (ior (eq_attr "type" "alu")
14533 (and (eq_attr "type" "ishift")
14534 (and (match_operand 2 "const1_operand")
14535 (ior (match_test "TARGET_SHIFT1")
14536 (match_test "optimize_function_for_size_p (cfun)")))))
14538 (const_string "*")))
14539 (set_attr "mode" "<MODE>")])
14541 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
14542 (define_insn_and_split "*ashlqi_ext<mode>_1"
14543 [(set (zero_extract:SWI248
14544 (match_operand 0 "int248_register_operand" "+Q,&Q")
14550 (match_operator:SWI248 3 "extract_operator"
14551 [(match_operand 1 "int248_register_operand" "0,!Q")
14554 (match_operand:QI 2 "nonmemory_operand" "cI,cI")) 0))
14555 (clobber (reg:CC FLAGS_REG))]
14558 if (which_alternative)
14561 switch (get_attr_type (insn))
14564 gcc_assert (operands[2] == const1_rtx);
14565 return "add{b}\t%h0, %h0";
14568 if (operands[2] == const1_rtx
14569 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14570 return "sal{b}\t%h0";
14572 return "sal{b}\t{%2, %h0|%h0, %2}";
14576 && !(rtx_equal_p (operands[0], operands[1]))"
14577 [(set (zero_extract:SWI248
14578 (match_dup 0) (const_int 8) (const_int 8))
14581 [(set (zero_extract:SWI248
14582 (match_dup 0) (const_int 8) (const_int 8))
14587 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
14589 (clobber (reg:CC FLAGS_REG))])]
14591 [(set (attr "type")
14592 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
14593 (match_operand 2 "const1_operand"))
14594 (const_string "alu")
14596 (const_string "ishift")))
14597 (set (attr "length_immediate")
14599 (ior (eq_attr "type" "alu")
14600 (and (eq_attr "type" "ishift")
14601 (and (match_operand 2 "const1_operand")
14602 (ior (match_test "TARGET_SHIFT1")
14603 (match_test "optimize_function_for_size_p (cfun)")))))
14605 (const_string "*")))
14606 (set_attr "mode" "QI")])
14608 ;; See comment above `ashl<mode>3' about how this works.
14610 (define_expand "<insn><mode>3"
14611 [(set (match_operand:SDWIM 0 "<shift_operand>")
14612 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
14613 (match_operand:QI 2 "nonmemory_operand")))]
14615 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
14617 ;; Avoid useless masking of count operand.
14618 (define_insn_and_split "*<insn><mode>3_mask"
14619 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14621 (match_operand:SWI48 1 "nonimmediate_operand")
14624 (match_operand 2 "int248_register_operand" "c,r")
14625 (match_operand 3 "const_int_operand")) 0)))
14626 (clobber (reg:CC FLAGS_REG))]
14627 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
14628 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
14629 == GET_MODE_BITSIZE (<MODE>mode)-1
14630 && ix86_pre_reload_split ()"
14634 [(set (match_dup 0)
14635 (any_shiftrt:SWI48 (match_dup 1)
14637 (clobber (reg:CC FLAGS_REG))])]
14639 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14640 operands[2] = gen_lowpart (QImode, operands[2]);
14642 [(set_attr "isa" "*,bmi2")])
14644 (define_insn_and_split "*<insn><mode>3_mask_1"
14645 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14647 (match_operand:SWI48 1 "nonimmediate_operand")
14649 (match_operand:QI 2 "register_operand" "c,r")
14650 (match_operand:QI 3 "const_int_operand"))))
14651 (clobber (reg:CC FLAGS_REG))]
14652 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
14653 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
14654 == GET_MODE_BITSIZE (<MODE>mode)-1
14655 && ix86_pre_reload_split ()"
14659 [(set (match_dup 0)
14660 (any_shiftrt:SWI48 (match_dup 1)
14662 (clobber (reg:CC FLAGS_REG))])]
14664 [(set_attr "isa" "*,bmi2")])
14666 (define_insn_and_split "*<insn><dwi>3_doubleword_mask"
14667 [(set (match_operand:<DWI> 0 "register_operand")
14669 (match_operand:<DWI> 1 "register_operand")
14672 (match_operand 2 "int248_register_operand" "c")
14673 (match_operand 3 "const_int_operand")) 0)))
14674 (clobber (reg:CC FLAGS_REG))]
14675 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
14676 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
14677 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
14678 && ix86_pre_reload_split ()"
14682 [(set (match_dup 4)
14683 (ior:DWIH (lshiftrt:DWIH (match_dup 4)
14684 (and:QI (match_dup 2) (match_dup 8)))
14686 (ashift:<DWI> (zero_extend:<DWI> (match_dup 7))
14687 (minus:QI (match_dup 9)
14688 (and:QI (match_dup 2) (match_dup 8)))) 0)))
14689 (clobber (reg:CC FLAGS_REG))])
14691 [(set (match_dup 6)
14692 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
14693 (clobber (reg:CC FLAGS_REG))])]
14695 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
14697 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14698 operands[2] = gen_lowpart (QImode, operands[2]);
14699 emit_insn (gen_<insn><dwi>3_doubleword (operands[0], operands[1],
14704 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
14706 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
14707 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
14709 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14710 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14713 xops[0] = gen_reg_rtx (GET_MODE (operands[2]));
14714 xops[1] = operands[2];
14715 xops[2] = GEN_INT (INTVAL (operands[3])
14716 & ((<MODE_SIZE> * BITS_PER_UNIT) - 1));
14717 ix86_expand_binary_operator (AND, GET_MODE (operands[2]), xops);
14718 operands[2] = xops[0];
14721 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14722 operands[2] = gen_lowpart (QImode, operands[2]);
14724 if (!rtx_equal_p (operands[4], operands[5]))
14725 emit_move_insn (operands[4], operands[5]);
14728 (define_insn_and_split "*<insn><dwi>3_doubleword_mask_1"
14729 [(set (match_operand:<DWI> 0 "register_operand")
14731 (match_operand:<DWI> 1 "register_operand")
14733 (match_operand:QI 2 "register_operand" "c")
14734 (match_operand:QI 3 "const_int_operand"))))
14735 (clobber (reg:CC FLAGS_REG))]
14736 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
14737 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
14738 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
14739 && ix86_pre_reload_split ()"
14743 [(set (match_dup 4)
14744 (ior:DWIH (lshiftrt:DWIH (match_dup 4)
14745 (and:QI (match_dup 2) (match_dup 8)))
14747 (ashift:<DWI> (zero_extend:<DWI> (match_dup 7))
14748 (minus:QI (match_dup 9)
14749 (and:QI (match_dup 2) (match_dup 8)))) 0)))
14750 (clobber (reg:CC FLAGS_REG))])
14752 [(set (match_dup 6)
14753 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
14754 (clobber (reg:CC FLAGS_REG))])]
14756 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
14758 emit_insn (gen_<insn><dwi>3_doubleword (operands[0], operands[1],
14763 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
14765 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
14766 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
14768 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14769 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14771 rtx tem = gen_reg_rtx (QImode);
14772 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
14776 if (!rtx_equal_p (operands[4], operands[5]))
14777 emit_move_insn (operands[4], operands[5]);
14780 (define_insn_and_split "<insn><mode>3_doubleword"
14781 [(set (match_operand:DWI 0 "register_operand" "=&r")
14782 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
14783 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
14784 (clobber (reg:CC FLAGS_REG))]
14787 "epilogue_completed"
14789 "ix86_split_<insn> (operands, NULL_RTX, <MODE>mode); DONE;"
14790 [(set_attr "type" "multi")])
14792 ;; By default we don't ask for a scratch register, because when DWImode
14793 ;; values are manipulated, registers are already at a premium. But if
14794 ;; we have one handy, we won't turn it away.
14797 [(match_scratch:DWIH 3 "r")
14798 (parallel [(set (match_operand:<DWI> 0 "register_operand")
14800 (match_operand:<DWI> 1 "register_operand")
14801 (match_operand:QI 2 "nonmemory_operand")))
14802 (clobber (reg:CC FLAGS_REG))])
14806 "ix86_split_<insn> (operands, operands[3], <DWI>mode); DONE;")
14808 ;; Split truncations of double word right shifts into x86_shrd_1.
14809 (define_insn_and_split "<insn><dwi>3_doubleword_lowpart"
14810 [(set (match_operand:DWIH 0 "register_operand" "=&r")
14812 (any_shiftrt:<DWI> (match_operand:<DWI> 1 "register_operand" "r")
14813 (match_operand:QI 2 "const_int_operand")) 0))
14814 (clobber (reg:CC FLAGS_REG))]
14815 "UINTVAL (operands[2]) < <MODE_SIZE> * BITS_PER_UNIT"
14817 "&& reload_completed"
14819 [(set (match_dup 0)
14820 (ior:DWIH (lshiftrt:DWIH (match_dup 0) (match_dup 2))
14822 (ashift:<DWI> (zero_extend:<DWI> (match_dup 3))
14823 (match_dup 4)) 0)))
14824 (clobber (reg:CC FLAGS_REG))])]
14826 split_double_mode (<DWI>mode, &operands[1], 1, &operands[1], &operands[3]);
14827 operands[4] = GEN_INT ((<MODE_SIZE> * BITS_PER_UNIT) - INTVAL (operands[2]));
14828 if (!rtx_equal_p (operands[0], operands[3]))
14829 emit_move_insn (operands[0], operands[3]);
14832 (define_insn "x86_64_shrd"
14833 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
14834 (ior:DI (lshiftrt:DI (match_dup 0)
14835 (and:QI (match_operand:QI 2 "nonmemory_operand" "Jc")
14840 (match_operand:DI 1 "register_operand" "r"))
14841 (minus:QI (const_int 64)
14842 (and:QI (match_dup 2) (const_int 63)))) 0)))
14843 (clobber (reg:CC FLAGS_REG))]
14845 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
14846 [(set_attr "type" "ishift")
14847 (set_attr "prefix_0f" "1")
14848 (set_attr "mode" "DI")
14849 (set_attr "athlon_decode" "vector")
14850 (set_attr "amdfam10_decode" "vector")
14851 (set_attr "bdver1_decode" "vector")])
14853 (define_insn "x86_64_shrd_1"
14854 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
14855 (ior:DI (lshiftrt:DI (match_dup 0)
14856 (match_operand:QI 2 "const_0_to_63_operand"))
14860 (match_operand:DI 1 "register_operand" "r"))
14861 (match_operand:QI 3 "const_0_to_255_operand")) 0)))
14862 (clobber (reg:CC FLAGS_REG))]
14864 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])"
14865 "shrd{q}\t{%2, %1, %0|%0, %1, %2}"
14866 [(set_attr "type" "ishift")
14867 (set_attr "prefix_0f" "1")
14868 (set_attr "length_immediate" "1")
14869 (set_attr "mode" "DI")
14870 (set_attr "athlon_decode" "vector")
14871 (set_attr "amdfam10_decode" "vector")
14872 (set_attr "bdver1_decode" "vector")])
14874 (define_insn_and_split "*x86_64_shrd_shld_1_nozext"
14875 [(set (match_operand:DI 0 "nonimmediate_operand")
14876 (ior:DI (lshiftrt:DI (match_operand:DI 4 "nonimmediate_operand")
14877 (match_operand:QI 2 "const_0_to_63_operand"))
14879 (match_operand:DI 1 "nonimmediate_operand")
14880 (match_operand:QI 3 "const_0_to_63_operand"))))
14881 (clobber (reg:CC FLAGS_REG))]
14883 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])
14884 && ix86_pre_reload_split ()"
14889 if (rtx_equal_p (operands[4], operands[0]))
14891 operands[1] = force_reg (DImode, operands[1]);
14892 emit_insn (gen_x86_64_shrd_1 (operands[0], operands[1], operands[2], operands[3]));
14894 else if (rtx_equal_p (operands[1], operands[0]))
14896 operands[4] = force_reg (DImode, operands[4]);
14897 emit_insn (gen_x86_64_shld_1 (operands[0], operands[4], operands[3], operands[2]));
14901 operands[1] = force_reg (DImode, operands[1]);
14902 rtx tmp = gen_reg_rtx (DImode);
14903 emit_move_insn (tmp, operands[4]);
14904 emit_insn (gen_x86_64_shrd_1 (tmp, operands[1], operands[2], operands[3]));
14905 emit_move_insn (operands[0], tmp);
14910 (define_insn_and_split "*x86_64_shrd_2"
14911 [(set (match_operand:DI 0 "nonimmediate_operand")
14912 (ior:DI (lshiftrt:DI (match_dup 0)
14913 (match_operand:QI 2 "nonmemory_operand"))
14914 (ashift:DI (match_operand:DI 1 "register_operand")
14915 (minus:QI (const_int 64) (match_dup 2)))))
14916 (clobber (reg:CC FLAGS_REG))]
14917 "TARGET_64BIT && ix86_pre_reload_split ()"
14920 [(parallel [(set (match_dup 0)
14921 (ior:DI (lshiftrt:DI (match_dup 0)
14922 (and:QI (match_dup 2) (const_int 63)))
14925 (zero_extend:TI (match_dup 1))
14926 (minus:QI (const_int 64)
14927 (and:QI (match_dup 2)
14928 (const_int 63)))) 0)))
14929 (clobber (reg:CC FLAGS_REG))])])
14931 (define_insn "x86_shrd"
14932 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
14933 (ior:SI (lshiftrt:SI (match_dup 0)
14934 (and:QI (match_operand:QI 2 "nonmemory_operand" "Ic")
14939 (match_operand:SI 1 "register_operand" "r"))
14940 (minus:QI (const_int 32)
14941 (and:QI (match_dup 2) (const_int 31)))) 0)))
14942 (clobber (reg:CC FLAGS_REG))]
14944 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
14945 [(set_attr "type" "ishift")
14946 (set_attr "prefix_0f" "1")
14947 (set_attr "mode" "SI")
14948 (set_attr "pent_pair" "np")
14949 (set_attr "athlon_decode" "vector")
14950 (set_attr "amdfam10_decode" "vector")
14951 (set_attr "bdver1_decode" "vector")])
14953 (define_insn "x86_shrd_1"
14954 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
14955 (ior:SI (lshiftrt:SI (match_dup 0)
14956 (match_operand:QI 2 "const_0_to_31_operand"))
14960 (match_operand:SI 1 "register_operand" "r"))
14961 (match_operand:QI 3 "const_0_to_63_operand")) 0)))
14962 (clobber (reg:CC FLAGS_REG))]
14963 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])"
14964 "shrd{l}\t{%2, %1, %0|%0, %1, %2}"
14965 [(set_attr "type" "ishift")
14966 (set_attr "prefix_0f" "1")
14967 (set_attr "length_immediate" "1")
14968 (set_attr "mode" "SI")
14969 (set_attr "pent_pair" "np")
14970 (set_attr "athlon_decode" "vector")
14971 (set_attr "amdfam10_decode" "vector")
14972 (set_attr "bdver1_decode" "vector")])
14974 (define_insn_and_split "*x86_shrd_shld_1_nozext"
14975 [(set (match_operand:SI 0 "nonimmediate_operand")
14976 (ior:SI (lshiftrt:SI (match_operand:SI 4 "nonimmediate_operand")
14977 (match_operand:QI 2 "const_0_to_31_operand"))
14979 (match_operand:SI 1 "nonimmediate_operand")
14980 (match_operand:QI 3 "const_0_to_31_operand"))))
14981 (clobber (reg:CC FLAGS_REG))]
14982 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])
14983 && ix86_pre_reload_split ()"
14988 if (rtx_equal_p (operands[4], operands[0]))
14990 operands[1] = force_reg (SImode, operands[1]);
14991 emit_insn (gen_x86_shrd_1 (operands[0], operands[1], operands[2], operands[3]));
14993 else if (rtx_equal_p (operands[1], operands[0]))
14995 operands[4] = force_reg (SImode, operands[4]);
14996 emit_insn (gen_x86_shld_1 (operands[0], operands[4], operands[3], operands[2]));
15000 operands[1] = force_reg (SImode, operands[1]);
15001 rtx tmp = gen_reg_rtx (SImode);
15002 emit_move_insn (tmp, operands[4]);
15003 emit_insn (gen_x86_shrd_1 (tmp, operands[1], operands[2], operands[3]));
15004 emit_move_insn (operands[0], tmp);
15009 (define_insn_and_split "*x86_shrd_2"
15010 [(set (match_operand:SI 0 "nonimmediate_operand")
15011 (ior:SI (lshiftrt:SI (match_dup 0)
15012 (match_operand:QI 2 "nonmemory_operand"))
15013 (ashift:SI (match_operand:SI 1 "register_operand")
15014 (minus:QI (const_int 32) (match_dup 2)))))
15015 (clobber (reg:CC FLAGS_REG))]
15016 "TARGET_64BIT && ix86_pre_reload_split ()"
15019 [(parallel [(set (match_dup 0)
15020 (ior:SI (lshiftrt:SI (match_dup 0)
15021 (and:QI (match_dup 2) (const_int 31)))
15024 (zero_extend:DI (match_dup 1))
15025 (minus:QI (const_int 32)
15026 (and:QI (match_dup 2)
15027 (const_int 31)))) 0)))
15028 (clobber (reg:CC FLAGS_REG))])])
15030 ;; Base name for insn mnemonic.
15031 (define_mode_attr cvt_mnemonic
15032 [(SI "{cltd|cdq}") (DI "{cqto|cqo}")])
15034 (define_insn "ashr<mode>3_cvt"
15035 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=*d,rm")
15037 (match_operand:SWI48 1 "nonimmediate_operand" "*a,0")
15038 (match_operand:QI 2 "const_int_operand")))
15039 (clobber (reg:CC FLAGS_REG))]
15040 "INTVAL (operands[2]) == GET_MODE_BITSIZE (<MODE>mode)-1
15041 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
15042 && ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
15045 sar{<imodesuffix>}\t{%2, %0|%0, %2}"
15046 [(set_attr "type" "imovx,ishift")
15047 (set_attr "prefix_0f" "0,*")
15048 (set_attr "length_immediate" "0,*")
15049 (set_attr "modrm" "0,1")
15050 (set_attr "mode" "<MODE>")])
15052 (define_insn "*ashrsi3_cvt_zext"
15053 [(set (match_operand:DI 0 "register_operand" "=*d,r")
15055 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
15056 (match_operand:QI 2 "const_int_operand"))))
15057 (clobber (reg:CC FLAGS_REG))]
15058 "TARGET_64BIT && INTVAL (operands[2]) == 31
15059 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
15060 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
15063 sar{l}\t{%2, %k0|%k0, %2}"
15064 [(set_attr "type" "imovx,ishift")
15065 (set_attr "prefix_0f" "0,*")
15066 (set_attr "length_immediate" "0,*")
15067 (set_attr "modrm" "0,1")
15068 (set_attr "mode" "SI")])
15070 (define_expand "@x86_shift<mode>_adj_3"
15071 [(use (match_operand:SWI48 0 "register_operand"))
15072 (use (match_operand:SWI48 1 "register_operand"))
15073 (use (match_operand:QI 2 "register_operand"))]
15076 rtx_code_label *label = gen_label_rtx ();
15079 emit_insn (gen_testqi_ccz_1 (operands[2],
15080 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
15082 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
15083 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
15084 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
15085 gen_rtx_LABEL_REF (VOIDmode, label),
15087 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
15088 JUMP_LABEL (tmp) = label;
15090 emit_move_insn (operands[0], operands[1]);
15091 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
15092 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
15093 emit_label (label);
15094 LABEL_NUSES (label) = 1;
15099 (define_insn "*bmi2_<insn><mode>3_1"
15100 [(set (match_operand:SWI48 0 "register_operand" "=r")
15101 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
15102 (match_operand:SWI48 2 "register_operand" "r")))]
15104 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
15105 [(set_attr "type" "ishiftx")
15106 (set_attr "mode" "<MODE>")])
15108 (define_insn "*ashr<mode>3_1"
15109 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
15111 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
15112 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
15113 (clobber (reg:CC FLAGS_REG))]
15114 "ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
15116 switch (get_attr_type (insn))
15122 if (operands[2] == const1_rtx
15123 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15124 return "sar{<imodesuffix>}\t%0";
15126 return "sar{<imodesuffix>}\t{%2, %0|%0, %2}";
15129 [(set_attr "isa" "*,bmi2")
15130 (set_attr "type" "ishift,ishiftx")
15131 (set (attr "length_immediate")
15133 (and (match_operand 2 "const1_operand")
15134 (ior (match_test "TARGET_SHIFT1")
15135 (match_test "optimize_function_for_size_p (cfun)")))
15137 (const_string "*")))
15138 (set_attr "mode" "<MODE>")])
15140 ;; Specialization of *lshr<mode>3_1 below, extracting the SImode
15141 ;; highpart of a DI to be extracted, but allowing it to be clobbered.
15142 (define_insn_and_split "*highpartdisi2"
15143 [(set (subreg:DI (match_operand:SI 0 "register_operand" "=r,x,?k") 0)
15144 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0,k")
15146 (clobber (reg:CC FLAGS_REG))]
15149 "&& reload_completed"
15151 [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 32)))
15152 (clobber (reg:CC FLAGS_REG))])]
15154 if (SSE_REG_P (operands[0]))
15156 rtx tmp = gen_rtx_REG (V4SImode, REGNO (operands[0]));
15157 emit_insn (gen_sse_shufps_v4si (tmp, tmp, tmp,
15158 const1_rtx, const1_rtx,
15159 GEN_INT (5), GEN_INT (5)));
15162 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
15165 (define_insn "*lshr<mode>3_1"
15166 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,?k")
15168 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm,k")
15169 (match_operand:QI 2 "nonmemory_operand" "c<S>,r,<KS>")))
15170 (clobber (reg:CC FLAGS_REG))]
15171 "ix86_binary_operator_ok (LSHIFTRT, <MODE>mode, operands)"
15173 switch (get_attr_type (insn))
15180 if (operands[2] == const1_rtx
15181 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15182 return "shr{<imodesuffix>}\t%0";
15184 return "shr{<imodesuffix>}\t{%2, %0|%0, %2}";
15187 [(set_attr "isa" "*,bmi2,<kmov_isa>")
15188 (set_attr "type" "ishift,ishiftx,msklog")
15189 (set (attr "length_immediate")
15191 (and (and (match_operand 2 "const1_operand")
15192 (eq_attr "alternative" "0"))
15193 (ior (match_test "TARGET_SHIFT1")
15194 (match_test "optimize_function_for_size_p (cfun)")))
15196 (const_string "*")))
15197 (set_attr "mode" "<MODE>")])
15199 ;; Convert shift to the shiftx pattern to avoid flags dependency.
15201 [(set (match_operand:SWI48 0 "register_operand")
15202 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
15203 (match_operand:QI 2 "register_operand")))
15204 (clobber (reg:CC FLAGS_REG))]
15205 "TARGET_BMI2 && reload_completed"
15206 [(set (match_dup 0)
15207 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
15208 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
15210 (define_insn "*bmi2_<insn>si3_1_zext"
15211 [(set (match_operand:DI 0 "register_operand" "=r")
15213 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
15214 (match_operand:SI 2 "register_operand" "r"))))]
15215 "TARGET_64BIT && TARGET_BMI2"
15216 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
15217 [(set_attr "type" "ishiftx")
15218 (set_attr "mode" "SI")])
15220 (define_insn "*<insn>si3_1_zext"
15221 [(set (match_operand:DI 0 "register_operand" "=r,r")
15223 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
15224 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
15225 (clobber (reg:CC FLAGS_REG))]
15226 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
15228 switch (get_attr_type (insn))
15234 if (operands[2] == const1_rtx
15235 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15236 return "<shift>{l}\t%k0";
15238 return "<shift>{l}\t{%2, %k0|%k0, %2}";
15241 [(set_attr "isa" "*,bmi2")
15242 (set_attr "type" "ishift,ishiftx")
15243 (set (attr "length_immediate")
15245 (and (match_operand 2 "const1_operand")
15246 (ior (match_test "TARGET_SHIFT1")
15247 (match_test "optimize_function_for_size_p (cfun)")))
15249 (const_string "*")))
15250 (set_attr "mode" "SI")])
15252 ;; Convert shift to the shiftx pattern to avoid flags dependency.
15254 [(set (match_operand:DI 0 "register_operand")
15256 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
15257 (match_operand:QI 2 "register_operand"))))
15258 (clobber (reg:CC FLAGS_REG))]
15259 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
15260 [(set (match_dup 0)
15261 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
15262 "operands[2] = gen_lowpart (SImode, operands[2]);")
15264 (define_insn "*ashr<mode>3_1"
15265 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
15267 (match_operand:SWI12 1 "nonimmediate_operand" "0")
15268 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
15269 (clobber (reg:CC FLAGS_REG))]
15270 "ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
15272 if (operands[2] == const1_rtx
15273 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15274 return "sar{<imodesuffix>}\t%0";
15276 return "sar{<imodesuffix>}\t{%2, %0|%0, %2}";
15278 [(set_attr "type" "ishift")
15279 (set (attr "length_immediate")
15281 (and (match_operand 2 "const1_operand")
15282 (ior (match_test "TARGET_SHIFT1")
15283 (match_test "optimize_function_for_size_p (cfun)")))
15285 (const_string "*")))
15286 (set_attr "mode" "<MODE>")])
15288 (define_insn "*lshrqi3_1"
15289 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,?k")
15291 (match_operand:QI 1 "nonimmediate_operand" "0, k")
15292 (match_operand:QI 2 "nonmemory_operand" "cI,Wb")))
15293 (clobber (reg:CC FLAGS_REG))]
15294 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
15296 switch (get_attr_type (insn))
15299 if (operands[2] == const1_rtx
15300 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15301 return "shr{b}\t%0";
15303 return "shr{b}\t{%2, %0|%0, %2}";
15307 gcc_unreachable ();
15310 [(set_attr "isa" "*,avx512dq")
15311 (set_attr "type" "ishift,msklog")
15312 (set (attr "length_immediate")
15314 (and (and (match_operand 2 "const1_operand")
15315 (eq_attr "alternative" "0"))
15316 (ior (match_test "TARGET_SHIFT1")
15317 (match_test "optimize_function_for_size_p (cfun)")))
15319 (const_string "*")))
15320 (set_attr "mode" "QI")])
15322 (define_insn "*lshrhi3_1"
15323 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm, ?k")
15325 (match_operand:HI 1 "nonimmediate_operand" "0, k")
15326 (match_operand:QI 2 "nonmemory_operand" "cI, Ww")))
15327 (clobber (reg:CC FLAGS_REG))]
15328 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
15330 switch (get_attr_type (insn))
15333 if (operands[2] == const1_rtx
15334 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15335 return "shr{w}\t%0";
15337 return "shr{w}\t{%2, %0|%0, %2}";
15341 gcc_unreachable ();
15344 [(set_attr "isa" "*, avx512f")
15345 (set_attr "type" "ishift,msklog")
15346 (set (attr "length_immediate")
15348 (and (and (match_operand 2 "const1_operand")
15349 (eq_attr "alternative" "0"))
15350 (ior (match_test "TARGET_SHIFT1")
15351 (match_test "optimize_function_for_size_p (cfun)")))
15353 (const_string "*")))
15354 (set_attr "mode" "HI")])
15356 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
15357 (define_insn_and_split "*<insn><mode>3_1_slp"
15358 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
15359 (any_shiftrt:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
15360 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
15361 (clobber (reg:CC FLAGS_REG))]
15362 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
15364 if (which_alternative)
15367 if (operands[2] == const1_rtx
15368 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15369 return "<shift>{<imodesuffix>}\t%0";
15371 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
15373 "&& reload_completed
15374 && !(rtx_equal_p (operands[0], operands[1]))"
15375 [(set (strict_low_part (match_dup 0)) (match_dup 1))
15377 [(set (strict_low_part (match_dup 0))
15378 (any_shiftrt:SWI12 (match_dup 0) (match_dup 2)))
15379 (clobber (reg:CC FLAGS_REG))])]
15381 [(set_attr "type" "ishift")
15382 (set (attr "length_immediate")
15384 (and (match_operand 2 "const1_operand")
15385 (ior (match_test "TARGET_SHIFT1")
15386 (match_test "optimize_function_for_size_p (cfun)")))
15388 (const_string "*")))
15389 (set_attr "mode" "<MODE>")])
15391 ;; This pattern can't accept a variable shift count, since shifts by
15392 ;; zero don't affect the flags. We assume that shifts by constant
15393 ;; zero are optimized away.
15394 (define_insn "*<insn><mode>3_cmp"
15395 [(set (reg FLAGS_REG)
15398 (match_operand:SWI 1 "nonimmediate_operand" "0")
15399 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
15401 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
15402 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
15403 "(optimize_function_for_size_p (cfun)
15404 || !TARGET_PARTIAL_FLAG_REG_STALL
15405 || (operands[2] == const1_rtx
15407 && ix86_match_ccmode (insn, CCGOCmode)
15408 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
15410 if (operands[2] == const1_rtx
15411 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15412 return "<shift>{<imodesuffix>}\t%0";
15414 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
15416 [(set_attr "type" "ishift")
15417 (set (attr "length_immediate")
15419 (and (match_operand 2 "const1_operand")
15420 (ior (match_test "TARGET_SHIFT1")
15421 (match_test "optimize_function_for_size_p (cfun)")))
15423 (const_string "*")))
15424 (set_attr "mode" "<MODE>")])
15426 (define_insn "*<insn>si3_cmp_zext"
15427 [(set (reg FLAGS_REG)
15429 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
15430 (match_operand:QI 2 "const_1_to_31_operand"))
15432 (set (match_operand:DI 0 "register_operand" "=r")
15433 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
15435 && (optimize_function_for_size_p (cfun)
15436 || !TARGET_PARTIAL_FLAG_REG_STALL
15437 || (operands[2] == const1_rtx
15439 && ix86_match_ccmode (insn, CCGOCmode)
15440 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
15442 if (operands[2] == const1_rtx
15443 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15444 return "<shift>{l}\t%k0";
15446 return "<shift>{l}\t{%2, %k0|%k0, %2}";
15448 [(set_attr "type" "ishift")
15449 (set (attr "length_immediate")
15451 (and (match_operand 2 "const1_operand")
15452 (ior (match_test "TARGET_SHIFT1")
15453 (match_test "optimize_function_for_size_p (cfun)")))
15455 (const_string "*")))
15456 (set_attr "mode" "SI")])
15458 (define_insn "*<insn><mode>3_cconly"
15459 [(set (reg FLAGS_REG)
15462 (match_operand:SWI 1 "register_operand" "0")
15463 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
15465 (clobber (match_scratch:SWI 0 "=<r>"))]
15466 "(optimize_function_for_size_p (cfun)
15467 || !TARGET_PARTIAL_FLAG_REG_STALL
15468 || (operands[2] == const1_rtx
15470 && ix86_match_ccmode (insn, CCGOCmode)"
15472 if (operands[2] == const1_rtx
15473 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15474 return "<shift>{<imodesuffix>}\t%0";
15476 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
15478 [(set_attr "type" "ishift")
15479 (set (attr "length_immediate")
15481 (and (match_operand 2 "const1_operand")
15482 (ior (match_test "TARGET_SHIFT1")
15483 (match_test "optimize_function_for_size_p (cfun)")))
15485 (const_string "*")))
15486 (set_attr "mode" "<MODE>")])
15488 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
15489 (define_insn_and_split "*<insn>qi_ext<mode>_1"
15490 [(set (zero_extract:SWI248
15491 (match_operand 0 "int248_register_operand" "+Q,&Q")
15497 (match_operator:SWI248 3 "extract_operator"
15498 [(match_operand 1 "int248_register_operand" "0,!Q")
15501 (match_operand:QI 2 "nonmemory_operand" "cI,cI")) 0))
15502 (clobber (reg:CC FLAGS_REG))]
15505 if (which_alternative)
15508 if (operands[2] == const1_rtx
15509 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15510 return "<shift>{b}\t%h0";
15512 return "<shift>{b}\t{%2, %h0|%h0, %2}";
15515 && !(rtx_equal_p (operands[0], operands[1]))"
15516 [(set (zero_extract:SWI248
15517 (match_dup 0) (const_int 8) (const_int 8))
15520 [(set (zero_extract:SWI248
15521 (match_dup 0) (const_int 8) (const_int 8))
15526 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
15528 (clobber (reg:CC FLAGS_REG))])]
15530 [(set_attr "type" "ishift")
15531 (set (attr "length_immediate")
15533 (and (match_operand 2 "const1_operand")
15534 (ior (match_test "TARGET_SHIFT1")
15535 (match_test "optimize_function_for_size_p (cfun)")))
15537 (const_string "*")))
15538 (set_attr "mode" "QI")])
15540 (define_insn_and_split "*extend<dwi>2_doubleword_highpart"
15541 [(set (match_operand:<DWI> 0 "register_operand" "=r")
15543 (ashift:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")
15544 (match_operand:QI 2 "const_int_operand"))
15545 (match_operand:QI 3 "const_int_operand")))
15546 (clobber (reg:CC FLAGS_REG))]
15547 "INTVAL (operands[2]) == INTVAL (operands[3])
15548 && UINTVAL (operands[2]) < <MODE_SIZE> * BITS_PER_UNIT"
15550 "&& reload_completed"
15551 [(parallel [(set (match_dup 4)
15552 (ashift:DWIH (match_dup 4) (match_dup 2)))
15553 (clobber (reg:CC FLAGS_REG))])
15554 (parallel [(set (match_dup 4)
15555 (ashiftrt:DWIH (match_dup 4) (match_dup 2)))
15556 (clobber (reg:CC FLAGS_REG))])]
15557 "split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[4]);")
15559 (define_insn_and_split "*extendv2di2_highpart_stv"
15560 [(set (match_operand:V2DI 0 "register_operand" "=v")
15562 (ashift:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "vm")
15563 (match_operand:QI 2 "const_int_operand"))
15564 (match_operand:QI 3 "const_int_operand")))]
15565 "!TARGET_64BIT && TARGET_STV && TARGET_AVX512VL
15566 && INTVAL (operands[2]) == INTVAL (operands[3])
15567 && UINTVAL (operands[2]) < 32"
15569 "&& reload_completed"
15570 [(set (match_dup 0)
15571 (ashift:V2DI (match_dup 1) (match_dup 2)))
15573 (ashiftrt:V2DI (match_dup 0) (match_dup 2)))])
15575 ;; Rotate instructions
15577 (define_expand "<insn>ti3"
15578 [(set (match_operand:TI 0 "register_operand")
15579 (any_rotate:TI (match_operand:TI 1 "register_operand")
15580 (match_operand:QI 2 "nonmemory_operand")))]
15583 if (const_1_to_63_operand (operands[2], VOIDmode))
15584 emit_insn (gen_ix86_<insn>ti3_doubleword
15585 (operands[0], operands[1], operands[2]));
15586 else if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 64)
15588 operands[1] = force_reg (TImode, operands[1]);
15589 emit_insn (gen_<insn>64ti2_doubleword (operands[0], operands[1]));
15593 rtx amount = force_reg (QImode, operands[2]);
15594 rtx src_lo = gen_lowpart (DImode, operands[1]);
15595 rtx src_hi = gen_highpart (DImode, operands[1]);
15596 rtx tmp_lo = gen_reg_rtx (DImode);
15597 rtx tmp_hi = gen_reg_rtx (DImode);
15598 emit_move_insn (tmp_lo, src_lo);
15599 emit_move_insn (tmp_hi, src_hi);
15600 rtx (*shiftd) (rtx, rtx, rtx)
15601 = (<CODE> == ROTATE) ? gen_x86_64_shld : gen_x86_64_shrd;
15602 emit_insn (shiftd (tmp_lo, src_hi, amount));
15603 emit_insn (shiftd (tmp_hi, src_lo, amount));
15604 rtx dst_lo = gen_lowpart (DImode, operands[0]);
15605 rtx dst_hi = gen_highpart (DImode, operands[0]);
15606 emit_move_insn (dst_lo, tmp_lo);
15607 emit_move_insn (dst_hi, tmp_hi);
15608 emit_insn (gen_x86_shiftdi_adj_1 (dst_lo, dst_hi, amount, tmp_lo));
15613 (define_expand "<insn>di3"
15614 [(set (match_operand:DI 0 "shiftdi_operand")
15615 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
15616 (match_operand:QI 2 "nonmemory_operand")))]
15620 ix86_expand_binary_operator (<CODE>, DImode, operands);
15621 else if (const_1_to_31_operand (operands[2], VOIDmode))
15622 emit_insn (gen_ix86_<insn>di3_doubleword
15623 (operands[0], operands[1], operands[2]));
15624 else if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 32)
15626 operands[1] = force_reg (DImode, operands[1]);
15627 emit_insn (gen_<insn>32di2_doubleword (operands[0], operands[1]));
15635 (define_expand "<insn><mode>3"
15636 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
15637 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
15638 (match_operand:QI 2 "nonmemory_operand")))]
15640 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
15642 ;; Avoid useless masking of count operand.
15643 (define_insn_and_split "*<insn><mode>3_mask"
15644 [(set (match_operand:SWI 0 "nonimmediate_operand")
15646 (match_operand:SWI 1 "nonimmediate_operand")
15649 (match_operand 2 "int248_register_operand" "c")
15650 (match_operand 3 "const_int_operand")) 0)))
15651 (clobber (reg:CC FLAGS_REG))]
15652 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
15653 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15654 == GET_MODE_BITSIZE (<MODE>mode)-1
15655 && ix86_pre_reload_split ()"
15659 [(set (match_dup 0)
15660 (any_rotate:SWI (match_dup 1)
15662 (clobber (reg:CC FLAGS_REG))])]
15664 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
15665 operands[2] = gen_lowpart (QImode, operands[2]);
15669 [(set (match_operand:SWI 0 "register_operand")
15671 (match_operand:SWI 1 "const_int_operand")
15674 (match_operand 2 "int248_register_operand")
15675 (match_operand 3 "const_int_operand")) 0)))]
15676 "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode) - 1))
15677 == GET_MODE_BITSIZE (<MODE>mode) - 1"
15678 [(set (match_dup 4) (match_dup 1))
15680 (any_rotate:SWI (match_dup 4)
15681 (subreg:QI (match_dup 2) 0)))]
15682 "operands[4] = gen_reg_rtx (<MODE>mode);")
15684 (define_insn_and_split "*<insn><mode>3_mask_1"
15685 [(set (match_operand:SWI 0 "nonimmediate_operand")
15687 (match_operand:SWI 1 "nonimmediate_operand")
15689 (match_operand:QI 2 "register_operand" "c")
15690 (match_operand:QI 3 "const_int_operand"))))
15691 (clobber (reg:CC FLAGS_REG))]
15692 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
15693 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15694 == GET_MODE_BITSIZE (<MODE>mode)-1
15695 && ix86_pre_reload_split ()"
15699 [(set (match_dup 0)
15700 (any_rotate:SWI (match_dup 1)
15702 (clobber (reg:CC FLAGS_REG))])])
15705 [(set (match_operand:SWI 0 "register_operand")
15707 (match_operand:SWI 1 "const_int_operand")
15709 (match_operand:QI 2 "register_operand")
15710 (match_operand:QI 3 "const_int_operand"))))]
15711 "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode) - 1))
15712 == GET_MODE_BITSIZE (<MODE>mode) - 1"
15713 [(set (match_dup 4) (match_dup 1))
15715 (any_rotate:SWI (match_dup 4) (match_dup 2)))]
15716 "operands[4] = gen_reg_rtx (<MODE>mode);")
15718 ;; Implement rotation using two double-precision
15719 ;; shift instructions and a scratch register.
15721 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
15722 [(set (match_operand:<DWI> 0 "register_operand" "=r")
15723 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
15724 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
15725 (clobber (reg:CC FLAGS_REG))
15726 (clobber (match_scratch:DWIH 3 "=&r"))]
15730 [(set (match_dup 3) (match_dup 4))
15732 [(set (match_dup 4)
15733 (ior:DWIH (ashift:DWIH (match_dup 4)
15734 (and:QI (match_dup 2) (match_dup 6)))
15736 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
15737 (minus:QI (match_dup 7)
15738 (and:QI (match_dup 2)
15739 (match_dup 6)))) 0)))
15740 (clobber (reg:CC FLAGS_REG))])
15742 [(set (match_dup 5)
15743 (ior:DWIH (ashift:DWIH (match_dup 5)
15744 (and:QI (match_dup 2) (match_dup 6)))
15746 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 3))
15747 (minus:QI (match_dup 7)
15748 (and:QI (match_dup 2)
15749 (match_dup 6)))) 0)))
15750 (clobber (reg:CC FLAGS_REG))])]
15752 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
15753 operands[7] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
15755 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
15758 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
15759 [(set (match_operand:<DWI> 0 "register_operand" "=r")
15760 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
15761 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
15762 (clobber (reg:CC FLAGS_REG))
15763 (clobber (match_scratch:DWIH 3 "=&r"))]
15767 [(set (match_dup 3) (match_dup 4))
15769 [(set (match_dup 4)
15770 (ior:DWIH (lshiftrt:DWIH (match_dup 4)
15771 (and:QI (match_dup 2) (match_dup 6)))
15773 (ashift:<DWI> (zero_extend:<DWI> (match_dup 5))
15774 (minus:QI (match_dup 7)
15775 (and:QI (match_dup 2)
15776 (match_dup 6)))) 0)))
15777 (clobber (reg:CC FLAGS_REG))])
15779 [(set (match_dup 5)
15780 (ior:DWIH (lshiftrt:DWIH (match_dup 5)
15781 (and:QI (match_dup 2) (match_dup 6)))
15783 (ashift:<DWI> (zero_extend:<DWI> (match_dup 3))
15784 (minus:QI (match_dup 7)
15785 (and:QI (match_dup 2)
15786 (match_dup 6)))) 0)))
15787 (clobber (reg:CC FLAGS_REG))])]
15789 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
15790 operands[7] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
15792 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
15795 (define_insn_and_split "<insn>32di2_doubleword"
15796 [(set (match_operand:DI 0 "register_operand" "=r,r")
15797 (any_rotate:DI (match_operand:DI 1 "register_operand" "0,r")
15801 "&& reload_completed"
15802 [(set (match_dup 0) (match_dup 3))
15803 (set (match_dup 2) (match_dup 1))]
15805 split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);
15806 if (rtx_equal_p (operands[0], operands[1]))
15808 emit_insn (gen_swapsi (operands[0], operands[2]));
15813 (define_insn_and_split "<insn>64ti2_doubleword"
15814 [(set (match_operand:TI 0 "register_operand" "=r,r")
15815 (any_rotate:TI (match_operand:TI 1 "register_operand" "0,r")
15819 "&& reload_completed"
15820 [(set (match_dup 0) (match_dup 3))
15821 (set (match_dup 2) (match_dup 1))]
15823 split_double_mode (TImode, &operands[0], 2, &operands[0], &operands[2]);
15824 if (rtx_equal_p (operands[0], operands[1]))
15826 emit_insn (gen_swapdi (operands[0], operands[2]));
15831 (define_mode_attr rorx_immediate_operand
15832 [(SI "const_0_to_31_operand")
15833 (DI "const_0_to_63_operand")])
15835 (define_insn "*bmi2_rorx<mode>3_1"
15836 [(set (match_operand:SWI48 0 "register_operand" "=r")
15838 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
15839 (match_operand:QI 2 "<rorx_immediate_operand>" "<S>")))]
15840 "TARGET_BMI2 && !optimize_function_for_size_p (cfun)"
15841 "rorx\t{%2, %1, %0|%0, %1, %2}"
15842 [(set_attr "type" "rotatex")
15843 (set_attr "mode" "<MODE>")])
15845 (define_insn "*<insn><mode>3_1"
15846 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
15848 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
15849 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
15850 (clobber (reg:CC FLAGS_REG))]
15851 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
15853 switch (get_attr_type (insn))
15859 if (operands[2] == const1_rtx
15860 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15861 return "<rotate>{<imodesuffix>}\t%0";
15863 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
15866 [(set_attr "isa" "*,bmi2")
15867 (set_attr "type" "rotate,rotatex")
15868 (set (attr "preferred_for_size")
15869 (cond [(eq_attr "alternative" "0")
15870 (symbol_ref "true")]
15871 (symbol_ref "false")))
15872 (set (attr "length_immediate")
15874 (and (eq_attr "type" "rotate")
15875 (and (match_operand 2 "const1_operand")
15876 (ior (match_test "TARGET_SHIFT1")
15877 (match_test "optimize_function_for_size_p (cfun)"))))
15879 (const_string "*")))
15880 (set_attr "mode" "<MODE>")])
15882 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
15884 [(set (match_operand:SWI48 0 "register_operand")
15885 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
15886 (match_operand:QI 2 "const_int_operand")))
15887 (clobber (reg:CC FLAGS_REG))]
15888 "TARGET_BMI2 && reload_completed && !optimize_function_for_size_p (cfun)"
15889 [(set (match_dup 0)
15890 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
15892 int bitsize = GET_MODE_BITSIZE (<MODE>mode);
15894 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
15898 [(set (match_operand:SWI48 0 "register_operand")
15899 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
15900 (match_operand:QI 2 "const_int_operand")))
15901 (clobber (reg:CC FLAGS_REG))]
15902 "TARGET_BMI2 && reload_completed && !optimize_function_for_size_p (cfun)"
15903 [(set (match_dup 0)
15904 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
15906 (define_insn "*bmi2_rorxsi3_1_zext"
15907 [(set (match_operand:DI 0 "register_operand" "=r")
15909 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
15910 (match_operand:QI 2 "const_0_to_31_operand"))))]
15911 "TARGET_64BIT && TARGET_BMI2 && !optimize_function_for_size_p (cfun)"
15912 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
15913 [(set_attr "type" "rotatex")
15914 (set_attr "mode" "SI")])
15916 (define_insn "*<insn>si3_1_zext"
15917 [(set (match_operand:DI 0 "register_operand" "=r,r")
15919 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
15920 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
15921 (clobber (reg:CC FLAGS_REG))]
15922 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
15924 switch (get_attr_type (insn))
15930 if (operands[2] == const1_rtx
15931 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15932 return "<rotate>{l}\t%k0";
15934 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
15937 [(set_attr "isa" "*,bmi2")
15938 (set_attr "type" "rotate,rotatex")
15939 (set (attr "preferred_for_size")
15940 (cond [(eq_attr "alternative" "0")
15941 (symbol_ref "true")]
15942 (symbol_ref "false")))
15943 (set (attr "length_immediate")
15945 (and (eq_attr "type" "rotate")
15946 (and (match_operand 2 "const1_operand")
15947 (ior (match_test "TARGET_SHIFT1")
15948 (match_test "optimize_function_for_size_p (cfun)"))))
15950 (const_string "*")))
15951 (set_attr "mode" "SI")])
15953 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
15955 [(set (match_operand:DI 0 "register_operand")
15957 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
15958 (match_operand:QI 2 "const_int_operand"))))
15959 (clobber (reg:CC FLAGS_REG))]
15960 "TARGET_64BIT && TARGET_BMI2 && reload_completed
15961 && !optimize_function_for_size_p (cfun)"
15962 [(set (match_dup 0)
15963 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
15965 int bitsize = GET_MODE_BITSIZE (SImode);
15967 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
15971 [(set (match_operand:DI 0 "register_operand")
15973 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
15974 (match_operand:QI 2 "const_int_operand"))))
15975 (clobber (reg:CC FLAGS_REG))]
15976 "TARGET_64BIT && TARGET_BMI2 && reload_completed
15977 && !optimize_function_for_size_p (cfun)"
15978 [(set (match_dup 0)
15979 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
15981 (define_insn "*<insn><mode>3_1"
15982 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
15983 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
15984 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
15985 (clobber (reg:CC FLAGS_REG))]
15986 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
15988 if (operands[2] == const1_rtx
15989 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15990 return "<rotate>{<imodesuffix>}\t%0";
15992 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
15994 [(set_attr "type" "rotate")
15995 (set (attr "length_immediate")
15997 (and (match_operand 2 "const1_operand")
15998 (ior (match_test "TARGET_SHIFT1")
15999 (match_test "optimize_function_for_size_p (cfun)")))
16001 (const_string "*")))
16002 (set_attr "mode" "<MODE>")])
16004 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
16005 (define_insn_and_split "*<insn><mode>3_1_slp"
16006 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
16007 (any_rotate:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
16008 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
16009 (clobber (reg:CC FLAGS_REG))]
16010 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
16012 if (which_alternative)
16015 if (operands[2] == const1_rtx
16016 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
16017 return "<rotate>{<imodesuffix>}\t%0";
16019 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
16021 "&& reload_completed
16022 && !(rtx_equal_p (operands[0], operands[1]))"
16023 [(set (strict_low_part (match_dup 0)) (match_dup 1))
16025 [(set (strict_low_part (match_dup 0))
16026 (any_rotate:SWI12 (match_dup 0) (match_dup 2)))
16027 (clobber (reg:CC FLAGS_REG))])]
16029 [(set_attr "type" "rotate")
16030 (set (attr "length_immediate")
16032 (and (match_operand 2 "const1_operand")
16033 (ior (match_test "TARGET_SHIFT1")
16034 (match_test "optimize_function_for_size_p (cfun)")))
16036 (const_string "*")))
16037 (set_attr "mode" "<MODE>")])
16040 [(set (match_operand:HI 0 "QIreg_operand")
16041 (any_rotate:HI (match_dup 0) (const_int 8)))
16042 (clobber (reg:CC FLAGS_REG))]
16044 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
16045 [(parallel [(set (strict_low_part (match_dup 0))
16046 (bswap:HI (match_dup 0)))
16047 (clobber (reg:CC FLAGS_REG))])])
16049 ;; Rotations through carry flag
16050 (define_insn "rcrsi2"
16051 [(set (match_operand:SI 0 "register_operand" "=r")
16053 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
16055 (ashift:SI (ltu:SI (reg:CCC FLAGS_REG) (const_int 0))
16057 (clobber (reg:CC FLAGS_REG))]
16060 [(set_attr "type" "ishift1")
16061 (set_attr "memory" "none")
16062 (set_attr "length_immediate" "0")
16063 (set_attr "mode" "SI")])
16065 (define_insn "rcrdi2"
16066 [(set (match_operand:DI 0 "register_operand" "=r")
16068 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
16070 (ashift:DI (ltu:DI (reg:CCC FLAGS_REG) (const_int 0))
16072 (clobber (reg:CC FLAGS_REG))]
16075 [(set_attr "type" "ishift1")
16076 (set_attr "length_immediate" "0")
16077 (set_attr "mode" "DI")])
16079 ;; Versions of sar and shr that set the carry flag.
16080 (define_insn "<insn><mode>3_carry"
16081 [(set (reg:CCC FLAGS_REG)
16082 (unspec:CCC [(and:SWI48 (match_operand:SWI48 1 "register_operand" "0")
16084 (const_int 0)] UNSPEC_CC_NE))
16085 (set (match_operand:SWI48 0 "register_operand" "=r")
16086 (any_shiftrt:SWI48 (match_dup 1) (const_int 1)))]
16089 if (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
16090 return "<shift>{<imodesuffix>}\t%0";
16091 return "<shift>{<imodesuffix>}\t{1, %0|%0, 1}";
16093 [(set_attr "type" "ishift1")
16094 (set (attr "length_immediate")
16096 (ior (match_test "TARGET_SHIFT1")
16097 (match_test "optimize_function_for_size_p (cfun)"))
16099 (const_string "*")))
16100 (set_attr "mode" "<MODE>")])
16102 ;; Bit set / bit test instructions
16104 ;; %%% bts, btr, btc
16106 ;; These instructions are *slow* when applied to memory.
16108 (define_code_attr btsc [(ior "bts") (xor "btc")])
16110 (define_insn "*<btsc><mode>"
16111 [(set (match_operand:SWI48 0 "register_operand" "=r")
16113 (ashift:SWI48 (const_int 1)
16114 (match_operand:QI 2 "register_operand" "r"))
16115 (match_operand:SWI48 1 "register_operand" "0")))
16116 (clobber (reg:CC FLAGS_REG))]
16118 "<btsc>{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
16119 [(set_attr "type" "alu1")
16120 (set_attr "prefix_0f" "1")
16121 (set_attr "znver1_decode" "double")
16122 (set_attr "mode" "<MODE>")])
16124 ;; Avoid useless masking of count operand.
16125 (define_insn_and_split "*<btsc><mode>_mask"
16126 [(set (match_operand:SWI48 0 "register_operand")
16132 (match_operand 1 "int248_register_operand")
16133 (match_operand 2 "const_int_operand")) 0))
16134 (match_operand:SWI48 3 "register_operand")))
16135 (clobber (reg:CC FLAGS_REG))]
16137 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16138 == GET_MODE_BITSIZE (<MODE>mode)-1
16139 && ix86_pre_reload_split ()"
16143 [(set (match_dup 0)
16145 (ashift:SWI48 (const_int 1)
16148 (clobber (reg:CC FLAGS_REG))])]
16150 operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
16151 operands[1] = gen_lowpart (QImode, operands[1]);
16154 (define_insn_and_split "*<btsc><mode>_mask_1"
16155 [(set (match_operand:SWI48 0 "register_operand")
16160 (match_operand:QI 1 "register_operand")
16161 (match_operand:QI 2 "const_int_operand")))
16162 (match_operand:SWI48 3 "register_operand")))
16163 (clobber (reg:CC FLAGS_REG))]
16165 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16166 == GET_MODE_BITSIZE (<MODE>mode)-1
16167 && ix86_pre_reload_split ()"
16171 [(set (match_dup 0)
16173 (ashift:SWI48 (const_int 1)
16176 (clobber (reg:CC FLAGS_REG))])])
16178 (define_insn "*btr<mode>"
16179 [(set (match_operand:SWI48 0 "register_operand" "=r")
16181 (rotate:SWI48 (const_int -2)
16182 (match_operand:QI 2 "register_operand" "r"))
16183 (match_operand:SWI48 1 "register_operand" "0")))
16184 (clobber (reg:CC FLAGS_REG))]
16186 "btr{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
16187 [(set_attr "type" "alu1")
16188 (set_attr "prefix_0f" "1")
16189 (set_attr "znver1_decode" "double")
16190 (set_attr "mode" "<MODE>")])
16192 ;; Avoid useless masking of count operand.
16193 (define_insn_and_split "*btr<mode>_mask"
16194 [(set (match_operand:SWI48 0 "register_operand")
16200 (match_operand 1 "int248_register_operand")
16201 (match_operand 2 "const_int_operand")) 0))
16202 (match_operand:SWI48 3 "register_operand")))
16203 (clobber (reg:CC FLAGS_REG))]
16205 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16206 == GET_MODE_BITSIZE (<MODE>mode)-1
16207 && ix86_pre_reload_split ()"
16211 [(set (match_dup 0)
16213 (rotate:SWI48 (const_int -2)
16216 (clobber (reg:CC FLAGS_REG))])]
16218 operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
16219 operands[1] = gen_lowpart (QImode, operands[1]);
16222 (define_insn_and_split "*btr<mode>_mask_1"
16223 [(set (match_operand:SWI48 0 "register_operand")
16228 (match_operand:QI 1 "register_operand")
16229 (match_operand:QI 2 "const_int_operand")))
16230 (match_operand:SWI48 3 "register_operand")))
16231 (clobber (reg:CC FLAGS_REG))]
16233 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16234 == GET_MODE_BITSIZE (<MODE>mode)-1
16235 && ix86_pre_reload_split ()"
16239 [(set (match_dup 0)
16241 (rotate:SWI48 (const_int -2)
16244 (clobber (reg:CC FLAGS_REG))])])
16246 (define_insn_and_split "*btr<mode>_1"
16247 [(set (match_operand:SWI12 0 "register_operand")
16250 (rotate:SI (const_int -2)
16251 (match_operand:QI 2 "register_operand")) 0)
16252 (match_operand:SWI12 1 "nonimmediate_operand")))
16253 (clobber (reg:CC FLAGS_REG))]
16254 "TARGET_USE_BT && ix86_pre_reload_split ()"
16258 [(set (match_dup 0)
16259 (and:SI (rotate:SI (const_int -2) (match_dup 2))
16261 (clobber (reg:CC FLAGS_REG))])]
16263 operands[0] = lowpart_subreg (SImode, operands[0], <MODE>mode);
16264 operands[1] = force_reg (<MODE>mode, operands[1]);
16265 operands[1] = lowpart_subreg (SImode, operands[1], <MODE>mode);
16268 (define_insn_and_split "*btr<mode>_2"
16269 [(set (zero_extract:HI
16270 (match_operand:SWI12 0 "nonimmediate_operand")
16272 (match_operand:QI 1 "register_operand"))
16274 (clobber (reg:CC FLAGS_REG))]
16275 "TARGET_USE_BT && ix86_pre_reload_split ()"
16277 "&& MEM_P (operands[0])"
16278 [(set (match_dup 2) (match_dup 0))
16280 [(set (match_dup 3)
16281 (and:SI (rotate:SI (const_int -2) (match_dup 1))
16283 (clobber (reg:CC FLAGS_REG))])
16284 (set (match_dup 0) (match_dup 5))]
16286 operands[2] = gen_reg_rtx (<MODE>mode);
16287 operands[5] = gen_reg_rtx (<MODE>mode);
16288 operands[3] = lowpart_subreg (SImode, operands[5], <MODE>mode);
16289 operands[4] = lowpart_subreg (SImode, operands[2], <MODE>mode);
16293 [(set (zero_extract:HI
16294 (match_operand:SWI12 0 "register_operand")
16296 (match_operand:QI 1 "register_operand"))
16298 (clobber (reg:CC FLAGS_REG))]
16299 "TARGET_USE_BT && ix86_pre_reload_split ()"
16301 [(set (match_dup 0)
16302 (and:SI (rotate:SI (const_int -2) (match_dup 1))
16304 (clobber (reg:CC FLAGS_REG))])]
16306 operands[2] = lowpart_subreg (SImode, operands[0], <MODE>mode);
16307 operands[0] = lowpart_subreg (SImode, operands[0], <MODE>mode);
16310 ;; These instructions are never faster than the corresponding
16311 ;; and/ior/xor operations when using immediate operand, so with
16312 ;; 32-bit there's no point. But in 64-bit, we can't hold the
16313 ;; relevant immediates within the instruction itself, so operating
16314 ;; on bits in the high 32-bits of a register becomes easier.
16316 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
16317 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
16318 ;; negdf respectively, so they can never be disabled entirely.
16320 (define_insn "*btsq_imm"
16321 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
16323 (match_operand:QI 1 "const_0_to_63_operand"))
16325 (clobber (reg:CC FLAGS_REG))]
16326 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
16327 "bts{q}\t{%1, %0|%0, %1}"
16328 [(set_attr "type" "alu1")
16329 (set_attr "prefix_0f" "1")
16330 (set_attr "znver1_decode" "double")
16331 (set_attr "mode" "DI")])
16333 (define_insn "*btrq_imm"
16334 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
16336 (match_operand:QI 1 "const_0_to_63_operand"))
16338 (clobber (reg:CC FLAGS_REG))]
16339 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
16340 "btr{q}\t{%1, %0|%0, %1}"
16341 [(set_attr "type" "alu1")
16342 (set_attr "prefix_0f" "1")
16343 (set_attr "znver1_decode" "double")
16344 (set_attr "mode" "DI")])
16346 (define_insn "*btcq_imm"
16347 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
16349 (match_operand:QI 1 "const_0_to_63_operand"))
16350 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
16351 (clobber (reg:CC FLAGS_REG))]
16352 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
16353 "btc{q}\t{%1, %0|%0, %1}"
16354 [(set_attr "type" "alu1")
16355 (set_attr "prefix_0f" "1")
16356 (set_attr "znver1_decode" "double")
16357 (set_attr "mode" "DI")])
16359 ;; Allow Nocona to avoid these instructions if a register is available.
16362 [(match_scratch:DI 2 "r")
16363 (parallel [(set (zero_extract:DI
16364 (match_operand:DI 0 "nonimmediate_operand")
16366 (match_operand:QI 1 "const_0_to_63_operand"))
16368 (clobber (reg:CC FLAGS_REG))])]
16369 "TARGET_64BIT && !TARGET_USE_BT"
16370 [(parallel [(set (match_dup 0)
16371 (ior:DI (match_dup 0) (match_dup 3)))
16372 (clobber (reg:CC FLAGS_REG))])]
16374 int i = INTVAL (operands[1]);
16376 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
16378 if (!x86_64_immediate_operand (operands[3], DImode))
16380 emit_move_insn (operands[2], operands[3]);
16381 operands[3] = operands[2];
16386 [(match_scratch:DI 2 "r")
16387 (parallel [(set (zero_extract:DI
16388 (match_operand:DI 0 "nonimmediate_operand")
16390 (match_operand:QI 1 "const_0_to_63_operand"))
16392 (clobber (reg:CC FLAGS_REG))])]
16393 "TARGET_64BIT && !TARGET_USE_BT"
16394 [(parallel [(set (match_dup 0)
16395 (and:DI (match_dup 0) (match_dup 3)))
16396 (clobber (reg:CC FLAGS_REG))])]
16398 int i = INTVAL (operands[1]);
16400 operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
16402 if (!x86_64_immediate_operand (operands[3], DImode))
16404 emit_move_insn (operands[2], operands[3]);
16405 operands[3] = operands[2];
16410 [(match_scratch:DI 2 "r")
16411 (parallel [(set (zero_extract:DI
16412 (match_operand:DI 0 "nonimmediate_operand")
16414 (match_operand:QI 1 "const_0_to_63_operand"))
16415 (not:DI (zero_extract:DI
16416 (match_dup 0) (const_int 1) (match_dup 1))))
16417 (clobber (reg:CC FLAGS_REG))])]
16418 "TARGET_64BIT && !TARGET_USE_BT"
16419 [(parallel [(set (match_dup 0)
16420 (xor:DI (match_dup 0) (match_dup 3)))
16421 (clobber (reg:CC FLAGS_REG))])]
16423 int i = INTVAL (operands[1]);
16425 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
16427 if (!x86_64_immediate_operand (operands[3], DImode))
16429 emit_move_insn (operands[2], operands[3]);
16430 operands[3] = operands[2];
16436 (define_insn "*bt<mode>"
16437 [(set (reg:CCC FLAGS_REG)
16439 (zero_extract:SWI48
16440 (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
16442 (match_operand:QI 1 "nonmemory_operand" "q<S>,<S>"))
16446 switch (get_attr_mode (insn))
16449 return "bt{l}\t{%k1, %k0|%k0, %k1}";
16452 return "bt{q}\t{%q1, %0|%0, %q1}";
16455 gcc_unreachable ();
16458 [(set_attr "type" "alu1")
16459 (set_attr "prefix_0f" "1")
16462 (and (match_test "CONST_INT_P (operands[1])")
16463 (match_test "INTVAL (operands[1]) < 32"))
16464 (const_string "SI")
16465 (const_string "<MODE>")))])
16467 (define_insn_and_split "*bt<SWI48:mode>_mask"
16468 [(set (reg:CCC FLAGS_REG)
16470 (zero_extract:SWI48
16471 (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
16475 (match_operand:SWI248 1 "register_operand")
16476 (match_operand 2 "const_int_operand")) 0))
16479 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<SWI48:MODE>mode)-1))
16480 == GET_MODE_BITSIZE (<SWI48:MODE>mode)-1
16481 && ix86_pre_reload_split ()"
16484 [(set (reg:CCC FLAGS_REG)
16486 (zero_extract:SWI48 (match_dup 0) (const_int 1) (match_dup 1))
16488 "operands[1] = gen_lowpart (QImode, operands[1]);")
16490 (define_insn_and_split "*jcc_bt<mode>"
16492 (if_then_else (match_operator 0 "bt_comparison_operator"
16493 [(zero_extract:SWI48
16494 (match_operand:SWI48 1 "nonimmediate_operand")
16496 (match_operand:QI 2 "nonmemory_operand"))
16498 (label_ref (match_operand 3))
16500 (clobber (reg:CC FLAGS_REG))]
16501 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
16502 && (CONST_INT_P (operands[2])
16503 ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
16504 && INTVAL (operands[2])
16505 >= (optimize_function_for_size_p (cfun) ? 8 : 32))
16506 : !memory_operand (operands[1], <MODE>mode))
16507 && ix86_pre_reload_split ()"
16510 [(set (reg:CCC FLAGS_REG)
16512 (zero_extract:SWI48
16518 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16519 (label_ref (match_dup 3))
16522 operands[0] = shallow_copy_rtx (operands[0]);
16523 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16526 ;; Avoid useless masking of bit offset operand.
16527 (define_insn_and_split "*jcc_bt<mode>_mask"
16529 (if_then_else (match_operator 0 "bt_comparison_operator"
16530 [(zero_extract:SWI48
16531 (match_operand:SWI48 1 "register_operand")
16534 (match_operand:QI 2 "register_operand")
16535 (match_operand 3 "const_int_operand")))])
16536 (label_ref (match_operand 4))
16538 (clobber (reg:CC FLAGS_REG))]
16539 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
16540 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16541 == GET_MODE_BITSIZE (<MODE>mode)-1
16542 && ix86_pre_reload_split ()"
16545 [(set (reg:CCC FLAGS_REG)
16547 (zero_extract:SWI48
16553 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16554 (label_ref (match_dup 4))
16557 operands[0] = shallow_copy_rtx (operands[0]);
16558 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16561 ;; Avoid useless masking of bit offset operand.
16562 (define_insn_and_split "*jcc_bt<SWI48:mode>_mask_1"
16564 (if_then_else (match_operator 0 "bt_comparison_operator"
16565 [(zero_extract:SWI48
16566 (match_operand:SWI48 1 "register_operand")
16570 (match_operand:SWI248 2 "register_operand")
16571 (match_operand 3 "const_int_operand")) 0))])
16572 (label_ref (match_operand 4))
16574 (clobber (reg:CC FLAGS_REG))]
16575 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
16576 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<SWI48:MODE>mode)-1))
16577 == GET_MODE_BITSIZE (<SWI48:MODE>mode)-1
16578 && ix86_pre_reload_split ()"
16581 [(set (reg:CCC FLAGS_REG)
16583 (zero_extract:SWI48
16589 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16590 (label_ref (match_dup 4))
16593 operands[0] = shallow_copy_rtx (operands[0]);
16594 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16595 operands[2] = gen_lowpart (QImode, operands[2]);
16598 ;; Help combine recognize bt followed by cmov
16600 [(set (match_operand:SWI248 0 "register_operand")
16601 (if_then_else:SWI248
16602 (match_operator 5 "bt_comparison_operator"
16603 [(zero_extract:SWI48
16604 (match_operand:SWI48 1 "register_operand")
16606 (match_operand:QI 2 "register_operand"))
16608 (match_operand:SWI248 3 "nonimmediate_operand")
16609 (match_operand:SWI248 4 "nonimmediate_operand")))]
16610 "TARGET_USE_BT && TARGET_CMOVE
16611 && !(MEM_P (operands[3]) && MEM_P (operands[4]))
16612 && ix86_pre_reload_split ()"
16613 [(set (reg:CCC FLAGS_REG)
16615 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16618 (if_then_else:SWI248 (eq (reg:CCC FLAGS_REG) (const_int 0))
16622 if (GET_CODE (operands[5]) == EQ)
16623 std::swap (operands[3], operands[4]);
16626 ;; Help combine recognize bt followed by setc
16627 (define_insn_and_split "*bt<mode>_setcqi"
16628 [(set (subreg:SWI48 (match_operand:QI 0 "register_operand") 0)
16629 (zero_extract:SWI48
16630 (match_operand:SWI48 1 "register_operand")
16632 (match_operand:QI 2 "register_operand")))
16633 (clobber (reg:CC FLAGS_REG))]
16634 "TARGET_USE_BT && ix86_pre_reload_split ()"
16637 [(set (reg:CCC FLAGS_REG)
16639 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16642 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))])
16644 ;; Help combine recognize bt followed by setnc
16645 (define_insn_and_split "*bt<mode>_setncqi"
16646 [(set (match_operand:QI 0 "register_operand")
16650 (lshiftrt:SWI48 (match_operand:SWI48 1 "register_operand")
16651 (match_operand:QI 2 "register_operand")) 0))
16653 (clobber (reg:CC FLAGS_REG))]
16654 "TARGET_USE_BT && ix86_pre_reload_split ()"
16657 [(set (reg:CCC FLAGS_REG)
16659 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16662 (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))])
16664 (define_insn_and_split "*bt<mode>_setnc<mode>"
16665 [(set (match_operand:SWI48 0 "register_operand")
16668 (lshiftrt:SWI48 (match_operand:SWI48 1 "register_operand")
16669 (match_operand:QI 2 "register_operand")))
16671 (clobber (reg:CC FLAGS_REG))]
16672 "TARGET_USE_BT && ix86_pre_reload_split ()"
16675 [(set (reg:CCC FLAGS_REG)
16677 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16680 (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))
16681 (set (match_dup 0) (zero_extend:SWI48 (match_dup 3)))]
16682 "operands[3] = gen_reg_rtx (QImode);")
16684 ;; Help combine recognize bt followed by setnc (PR target/110588)
16685 (define_insn_and_split "*bt<mode>_setncqi_2"
16686 [(set (match_operand:QI 0 "register_operand")
16688 (zero_extract:SWI48
16689 (match_operand:SWI48 1 "register_operand")
16691 (match_operand:QI 2 "register_operand"))
16693 (clobber (reg:CC FLAGS_REG))]
16694 "TARGET_USE_BT && ix86_pre_reload_split ()"
16697 [(set (reg:CCC FLAGS_REG)
16699 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16702 (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))])
16704 ;; Help combine recognize bt followed by setc
16705 (define_insn_and_split "*bt<mode>_setc<mode>_mask"
16706 [(set (match_operand:SWI48 0 "register_operand")
16707 (zero_extract:SWI48
16708 (match_operand:SWI48 1 "register_operand")
16712 (match_operand:SWI48 2 "register_operand")
16713 (match_operand 3 "const_int_operand")) 0)))
16714 (clobber (reg:CC FLAGS_REG))]
16716 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16717 == GET_MODE_BITSIZE (<MODE>mode)-1
16718 && ix86_pre_reload_split ()"
16721 [(set (reg:CCC FLAGS_REG)
16723 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16726 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))
16727 (set (match_dup 0) (zero_extend:SWI48 (match_dup 3)))]
16729 operands[2] = gen_lowpart (QImode, operands[2]);
16730 operands[3] = gen_reg_rtx (QImode);
16733 ;; Store-flag instructions.
16736 [(set (match_operand:QI 0 "nonimmediate_operand")
16737 (match_operator:QI 1 "add_comparison_operator"
16738 [(not:SWI (match_operand:SWI 2 "register_operand"))
16739 (match_operand:SWI 3 "nonimmediate_operand")]))]
16741 [(set (reg:CCC FLAGS_REG)
16743 (plus:SWI (match_dup 2) (match_dup 3))
16746 (match_op_dup 1 [(reg:CCC FLAGS_REG) (const_int 0)]))])
16749 [(set (match_operand:QI 0 "nonimmediate_operand")
16750 (match_operator:QI 1 "shr_comparison_operator"
16751 [(match_operand:DI 2 "register_operand")
16752 (match_operand 3 "const_int_operand")]))]
16754 && IN_RANGE (exact_log2 (UINTVAL (operands[3]) + 1), 32, 63)"
16755 [(set (reg:CCZ FLAGS_REG)
16757 (lshiftrt:DI (match_dup 2) (match_dup 4))
16760 (match_op_dup 1 [(reg:CCZ FLAGS_REG) (const_int 0)]))]
16762 enum rtx_code new_code;
16764 operands[1] = shallow_copy_rtx (operands[1]);
16765 switch (GET_CODE (operands[1]))
16767 case GTU: new_code = NE; break;
16768 case LEU: new_code = EQ; break;
16769 default: gcc_unreachable ();
16771 PUT_CODE (operands[1], new_code);
16773 operands[4] = GEN_INT (exact_log2 (UINTVAL (operands[3]) + 1));
16776 ;; For all sCOND expanders, also expand the compare or test insn that
16777 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
16779 (define_insn_and_split "*setcc_di_1"
16780 [(set (match_operand:DI 0 "register_operand" "=q")
16781 (match_operator:DI 1 "ix86_comparison_operator"
16782 [(reg FLAGS_REG) (const_int 0)]))]
16783 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
16785 "&& reload_completed"
16786 [(set (match_dup 2) (match_dup 1))
16787 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
16789 operands[1] = shallow_copy_rtx (operands[1]);
16790 PUT_MODE (operands[1], QImode);
16791 operands[2] = gen_lowpart (QImode, operands[0]);
16794 (define_insn_and_split "*setcc_<mode>_1_and"
16795 [(set (match_operand:SWI24 0 "register_operand" "=q")
16796 (match_operator:SWI24 1 "ix86_comparison_operator"
16797 [(reg FLAGS_REG) (const_int 0)]))
16798 (clobber (reg:CC FLAGS_REG))]
16799 "!TARGET_PARTIAL_REG_STALL
16800 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
16802 "&& reload_completed"
16803 [(set (match_dup 2) (match_dup 1))
16804 (parallel [(set (match_dup 0) (zero_extend:SWI24 (match_dup 2)))
16805 (clobber (reg:CC FLAGS_REG))])]
16807 operands[1] = shallow_copy_rtx (operands[1]);
16808 PUT_MODE (operands[1], QImode);
16809 operands[2] = gen_lowpart (QImode, operands[0]);
16812 (define_insn_and_split "*setcc_<mode>_1_movzbl"
16813 [(set (match_operand:SWI24 0 "register_operand" "=q")
16814 (match_operator:SWI24 1 "ix86_comparison_operator"
16815 [(reg FLAGS_REG) (const_int 0)]))]
16816 "!TARGET_PARTIAL_REG_STALL
16817 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
16819 "&& reload_completed"
16820 [(set (match_dup 2) (match_dup 1))
16821 (set (match_dup 0) (zero_extend:SWI24 (match_dup 2)))]
16823 operands[1] = shallow_copy_rtx (operands[1]);
16824 PUT_MODE (operands[1], QImode);
16825 operands[2] = gen_lowpart (QImode, operands[0]);
16828 (define_insn "*setcc_qi"
16829 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
16830 (match_operator:QI 1 "ix86_comparison_operator"
16831 [(reg FLAGS_REG) (const_int 0)]))]
16834 [(set_attr "type" "setcc")
16835 (set_attr "mode" "QI")])
16837 (define_insn "*setcc_qi_slp"
16838 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+q"))
16839 (match_operator:QI 1 "ix86_comparison_operator"
16840 [(reg FLAGS_REG) (const_int 0)]))]
16843 [(set_attr "type" "setcc")
16844 (set_attr "mode" "QI")])
16846 ;; In general it is not safe to assume too much about CCmode registers,
16847 ;; so simplify-rtx stops when it sees a second one. Under certain
16848 ;; conditions this is safe on x86, so help combine not create
16855 [(set (match_operand:QI 0 "nonimmediate_operand")
16856 (ne:QI (match_operator 1 "ix86_comparison_operator"
16857 [(reg FLAGS_REG) (const_int 0)])
16860 [(set (match_dup 0) (match_dup 1))]
16862 operands[1] = shallow_copy_rtx (operands[1]);
16863 PUT_MODE (operands[1], QImode);
16867 [(set (strict_low_part (match_operand:QI 0 "register_operand"))
16868 (ne:QI (match_operator 1 "ix86_comparison_operator"
16869 [(reg FLAGS_REG) (const_int 0)])
16872 [(set (match_dup 0) (match_dup 1))]
16874 operands[1] = shallow_copy_rtx (operands[1]);
16875 PUT_MODE (operands[1], QImode);
16879 [(set (match_operand:QI 0 "nonimmediate_operand")
16880 (eq:QI (match_operator 1 "ix86_comparison_operator"
16881 [(reg FLAGS_REG) (const_int 0)])
16884 [(set (match_dup 0) (match_dup 1))]
16886 operands[1] = shallow_copy_rtx (operands[1]);
16887 PUT_MODE (operands[1], QImode);
16888 PUT_CODE (operands[1],
16889 ix86_reverse_condition (GET_CODE (operands[1]),
16890 GET_MODE (XEXP (operands[1], 0))));
16892 /* Make sure that (a) the CCmode we have for the flags is strong
16893 enough for the reversed compare or (b) we have a valid FP compare. */
16894 if (! ix86_comparison_operator (operands[1], VOIDmode))
16899 [(set (strict_low_part (match_operand:QI 0 "register_operand"))
16900 (eq:QI (match_operator 1 "ix86_comparison_operator"
16901 [(reg FLAGS_REG) (const_int 0)])
16904 [(set (match_dup 0) (match_dup 1))]
16906 operands[1] = shallow_copy_rtx (operands[1]);
16907 PUT_MODE (operands[1], QImode);
16908 PUT_CODE (operands[1],
16909 ix86_reverse_condition (GET_CODE (operands[1]),
16910 GET_MODE (XEXP (operands[1], 0))));
16912 /* Make sure that (a) the CCmode we have for the flags is strong
16913 enough for the reversed compare or (b) we have a valid FP compare. */
16914 if (! ix86_comparison_operator (operands[1], VOIDmode))
16918 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
16919 ;; subsequent logical operations are used to imitate conditional moves.
16920 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
16923 (define_insn "setcc_<mode>_sse"
16924 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16925 (match_operator:MODEF 3 "sse_comparison_operator"
16926 [(match_operand:MODEF 1 "register_operand" "0,x")
16927 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xjm")]))]
16928 "SSE_FLOAT_MODE_P (<MODE>mode)"
16930 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
16931 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16932 [(set_attr "isa" "noavx,avx")
16933 (set_attr "addr" "*,gpr16")
16934 (set_attr "type" "ssecmp")
16935 (set_attr "length_immediate" "1")
16936 (set_attr "prefix" "orig,vex")
16937 (set_attr "mode" "<MODE>")])
16939 (define_insn "setcc_hf_mask"
16940 [(set (match_operand:QI 0 "register_operand" "=k")
16942 [(match_operand:HF 1 "register_operand" "v")
16943 (match_operand:HF 2 "nonimmediate_operand" "vm")
16944 (match_operand:SI 3 "const_0_to_31_operand")]
16946 "TARGET_AVX512FP16"
16947 "vcmpsh\t{%3, %2, %1, %0|%0, %1, %2, %3}"
16948 [(set_attr "type" "ssecmp")
16949 (set_attr "prefix" "evex")
16950 (set_attr "mode" "HF")])
16953 ;; Basic conditional jump instructions.
16958 (match_operator 1 "add_comparison_operator"
16959 [(not:SWI (match_operand:SWI 2 "register_operand"))
16960 (match_operand:SWI 3 "nonimmediate_operand")])
16961 (label_ref (match_operand 0))
16964 [(set (reg:CCC FLAGS_REG)
16966 (plus:SWI (match_dup 2) (match_dup 3))
16969 (if_then_else (match_op_dup 1 [(reg:CCC FLAGS_REG) (const_int 0)])
16970 (label_ref (match_operand 0))
16976 (match_operator 1 "shr_comparison_operator"
16977 [(match_operand:DI 2 "register_operand")
16978 (match_operand 3 "const_int_operand")])
16979 (label_ref (match_operand 0))
16982 && IN_RANGE (exact_log2 (UINTVAL (operands[3]) + 1), 32, 63)"
16983 [(set (reg:CCZ FLAGS_REG)
16985 (lshiftrt:DI (match_dup 2) (match_dup 4))
16988 (if_then_else (match_op_dup 1 [(reg:CCZ FLAGS_REG) (const_int 0)])
16989 (label_ref (match_operand 0))
16992 enum rtx_code new_code;
16994 operands[1] = shallow_copy_rtx (operands[1]);
16995 switch (GET_CODE (operands[1]))
16997 case GTU: new_code = NE; break;
16998 case LEU: new_code = EQ; break;
16999 default: gcc_unreachable ();
17001 PUT_CODE (operands[1], new_code);
17003 operands[4] = GEN_INT (exact_log2 (UINTVAL (operands[3]) + 1));
17006 ;; We ignore the overflow flag for signed branch instructions.
17008 (define_insn "*jcc"
17010 (if_then_else (match_operator 1 "ix86_comparison_operator"
17011 [(reg FLAGS_REG) (const_int 0)])
17012 (label_ref (match_operand 0))
17016 [(set_attr "type" "ibr")
17017 (set_attr "modrm" "0")
17018 (set (attr "length")
17020 (and (ge (minus (match_dup 0) (pc))
17022 (lt (minus (match_dup 0) (pc))
17027 ;; In general it is not safe to assume too much about CCmode registers,
17028 ;; so simplify-rtx stops when it sees a second one. Under certain
17029 ;; conditions this is safe on x86, so help combine not create
17037 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
17038 [(reg FLAGS_REG) (const_int 0)])
17040 (label_ref (match_operand 1))
17044 (if_then_else (match_dup 0)
17045 (label_ref (match_dup 1))
17048 operands[0] = shallow_copy_rtx (operands[0]);
17049 PUT_MODE (operands[0], VOIDmode);
17054 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
17055 [(reg FLAGS_REG) (const_int 0)])
17057 (label_ref (match_operand 1))
17061 (if_then_else (match_dup 0)
17062 (label_ref (match_dup 1))
17065 operands[0] = shallow_copy_rtx (operands[0]);
17066 PUT_MODE (operands[0], VOIDmode);
17067 PUT_CODE (operands[0],
17068 ix86_reverse_condition (GET_CODE (operands[0]),
17069 GET_MODE (XEXP (operands[0], 0))));
17071 /* Make sure that (a) the CCmode we have for the flags is strong
17072 enough for the reversed compare or (b) we have a valid FP compare. */
17073 if (! ix86_comparison_operator (operands[0], VOIDmode))
17077 ;; Unconditional and other jump instructions
17079 (define_insn "jump"
17081 (label_ref (match_operand 0)))]
17084 [(set_attr "type" "ibr")
17085 (set_attr "modrm" "0")
17086 (set (attr "length")
17088 (and (ge (minus (match_dup 0) (pc))
17090 (lt (minus (match_dup 0) (pc))
17095 (define_expand "indirect_jump"
17096 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
17099 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
17100 operands[0] = convert_memory_address (word_mode, operands[0]);
17101 cfun->machine->has_local_indirect_jump = true;
17104 (define_insn "*indirect_jump"
17105 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
17107 "* return ix86_output_indirect_jmp (operands[0]);"
17108 [(set (attr "type")
17109 (if_then_else (match_test "(cfun->machine->indirect_branch_type
17110 != indirect_branch_keep)")
17111 (const_string "multi")
17112 (const_string "ibr")))
17113 (set_attr "length_immediate" "0")])
17115 (define_expand "tablejump"
17116 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
17117 (use (label_ref (match_operand 1)))])]
17120 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
17121 relative. Convert the relative address to an absolute address. */
17125 enum rtx_code code;
17127 /* We can't use @GOTOFF for text labels on VxWorks;
17128 see gotoff_operand. */
17129 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
17133 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
17135 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
17139 op1 = pic_offset_table_rtx;
17144 op0 = pic_offset_table_rtx;
17148 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
17152 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
17153 operands[0] = convert_memory_address (word_mode, operands[0]);
17154 cfun->machine->has_local_indirect_jump = true;
17157 (define_insn "*tablejump_1"
17158 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
17159 (use (label_ref (match_operand 1)))]
17161 "* return ix86_output_indirect_jmp (operands[0]);"
17162 [(set (attr "type")
17163 (if_then_else (match_test "(cfun->machine->indirect_branch_type
17164 != indirect_branch_keep)")
17165 (const_string "multi")
17166 (const_string "ibr")))
17167 (set_attr "length_immediate" "0")])
17169 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
17172 [(set (match_operand 4 "flags_reg_operand") (match_operand 0))
17173 (set (match_operand:QI 1 "register_operand")
17174 (match_operator:QI 2 "ix86_comparison_operator"
17175 [(reg FLAGS_REG) (const_int 0)]))
17176 (set (match_operand 3 "any_QIreg_operand")
17177 (zero_extend (match_dup 1)))]
17178 "(peep2_reg_dead_p (3, operands[1])
17179 || operands_match_p (operands[1], operands[3]))
17180 && ! reg_overlap_mentioned_p (operands[3], operands[0])
17181 && peep2_regno_dead_p (0, FLAGS_REG)"
17182 [(set (match_dup 4) (match_dup 0))
17183 (set (strict_low_part (match_dup 5))
17186 operands[5] = gen_lowpart (QImode, operands[3]);
17187 ix86_expand_clear (operands[3]);
17191 [(parallel [(set (match_operand 5 "flags_reg_operand") (match_operand 0))
17192 (match_operand 4)])
17193 (set (match_operand:QI 1 "register_operand")
17194 (match_operator:QI 2 "ix86_comparison_operator"
17195 [(reg FLAGS_REG) (const_int 0)]))
17196 (set (match_operand 3 "any_QIreg_operand")
17197 (zero_extend (match_dup 1)))]
17198 "(peep2_reg_dead_p (3, operands[1])
17199 || operands_match_p (operands[1], operands[3]))
17200 && ! reg_overlap_mentioned_p (operands[3], operands[0])
17201 && ! reg_overlap_mentioned_p (operands[3], operands[4])
17202 && ! reg_set_p (operands[3], operands[4])
17203 && peep2_regno_dead_p (0, FLAGS_REG)"
17204 [(parallel [(set (match_dup 5) (match_dup 0))
17206 (set (strict_low_part (match_dup 6))
17209 operands[6] = gen_lowpart (QImode, operands[3]);
17210 ix86_expand_clear (operands[3]);
17214 [(set (match_operand 6 "flags_reg_operand") (match_operand 0))
17215 (parallel [(set (match_operand 7 "flags_reg_operand") (match_operand 1))
17216 (match_operand 5)])
17217 (set (match_operand:QI 2 "register_operand")
17218 (match_operator:QI 3 "ix86_comparison_operator"
17219 [(reg FLAGS_REG) (const_int 0)]))
17220 (set (match_operand 4 "any_QIreg_operand")
17221 (zero_extend (match_dup 2)))]
17222 "(peep2_reg_dead_p (4, operands[2])
17223 || operands_match_p (operands[2], operands[4]))
17224 && ! reg_overlap_mentioned_p (operands[4], operands[0])
17225 && ! reg_overlap_mentioned_p (operands[4], operands[1])
17226 && ! reg_overlap_mentioned_p (operands[4], operands[5])
17227 && ! reg_set_p (operands[4], operands[5])
17228 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
17229 && peep2_regno_dead_p (0, FLAGS_REG)"
17230 [(set (match_dup 6) (match_dup 0))
17231 (parallel [(set (match_dup 7) (match_dup 1))
17233 (set (strict_low_part (match_dup 8))
17236 operands[8] = gen_lowpart (QImode, operands[4]);
17237 ix86_expand_clear (operands[4]);
17240 ;; Similar, but match zero extend with andsi3.
17243 [(set (match_operand 4 "flags_reg_operand") (match_operand 0))
17244 (set (match_operand:QI 1 "register_operand")
17245 (match_operator:QI 2 "ix86_comparison_operator"
17246 [(reg FLAGS_REG) (const_int 0)]))
17247 (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
17248 (and:SI (match_dup 3) (const_int 255)))
17249 (clobber (reg:CC FLAGS_REG))])]
17250 "REGNO (operands[1]) == REGNO (operands[3])
17251 && ! reg_overlap_mentioned_p (operands[3], operands[0])
17252 && peep2_regno_dead_p (0, FLAGS_REG)"
17253 [(set (match_dup 4) (match_dup 0))
17254 (set (strict_low_part (match_dup 5))
17257 operands[5] = gen_lowpart (QImode, operands[3]);
17258 ix86_expand_clear (operands[3]);
17262 [(parallel [(set (match_operand 5 "flags_reg_operand") (match_operand 0))
17263 (match_operand 4)])
17264 (set (match_operand:QI 1 "register_operand")
17265 (match_operator:QI 2 "ix86_comparison_operator"
17266 [(reg FLAGS_REG) (const_int 0)]))
17267 (parallel [(set (match_operand 3 "any_QIreg_operand")
17268 (zero_extend (match_dup 1)))
17269 (clobber (reg:CC FLAGS_REG))])]
17270 "(peep2_reg_dead_p (3, operands[1])
17271 || operands_match_p (operands[1], operands[3]))
17272 && ! reg_overlap_mentioned_p (operands[3], operands[0])
17273 && ! reg_overlap_mentioned_p (operands[3], operands[4])
17274 && ! reg_set_p (operands[3], operands[4])
17275 && peep2_regno_dead_p (0, FLAGS_REG)"
17276 [(parallel [(set (match_dup 5) (match_dup 0))
17278 (set (strict_low_part (match_dup 6))
17281 operands[6] = gen_lowpart (QImode, operands[3]);
17282 ix86_expand_clear (operands[3]);
17286 [(set (match_operand 6 "flags_reg_operand") (match_operand 0))
17287 (parallel [(set (match_operand 7 "flags_reg_operand") (match_operand 1))
17288 (match_operand 5)])
17289 (set (match_operand:QI 2 "register_operand")
17290 (match_operator:QI 3 "ix86_comparison_operator"
17291 [(reg FLAGS_REG) (const_int 0)]))
17292 (parallel [(set (match_operand 4 "any_QIreg_operand")
17293 (zero_extend (match_dup 2)))
17294 (clobber (reg:CC FLAGS_REG))])]
17295 "(peep2_reg_dead_p (4, operands[2])
17296 || operands_match_p (operands[2], operands[4]))
17297 && ! reg_overlap_mentioned_p (operands[4], operands[0])
17298 && ! reg_overlap_mentioned_p (operands[4], operands[1])
17299 && ! reg_overlap_mentioned_p (operands[4], operands[5])
17300 && ! reg_set_p (operands[4], operands[5])
17301 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
17302 && peep2_regno_dead_p (0, FLAGS_REG)"
17303 [(set (match_dup 6) (match_dup 0))
17304 (parallel [(set (match_dup 7) (match_dup 1))
17306 (set (strict_low_part (match_dup 8))
17309 operands[8] = gen_lowpart (QImode, operands[4]);
17310 ix86_expand_clear (operands[4]);
17313 ;; Call instructions.
17315 ;; The predicates normally associated with named expanders are not properly
17316 ;; checked for calls. This is a bug in the generic code, but it isn't that
17317 ;; easy to fix. Ignore it for now and be prepared to fix things up.
17319 ;; P6 processors will jump to the address after the decrement when %esp
17320 ;; is used as a call operand, so they will execute return address as a code.
17321 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
17323 ;; Register constraint for call instruction.
17324 (define_mode_attr c [(SI "l") (DI "r")])
17326 ;; Call subroutine returning no value.
17328 (define_expand "call"
17329 [(call (match_operand:QI 0)
17331 (use (match_operand 2))]
17334 ix86_expand_call (NULL, operands[0], operands[1],
17335 operands[2], NULL, false);
17339 (define_expand "sibcall"
17340 [(call (match_operand:QI 0)
17342 (use (match_operand 2))]
17345 ix86_expand_call (NULL, operands[0], operands[1],
17346 operands[2], NULL, true);
17350 (define_insn "*call"
17351 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
17352 (match_operand 1))]
17353 "!SIBLING_CALL_P (insn)"
17354 "* return ix86_output_call_insn (insn, operands[0]);"
17355 [(set_attr "type" "call")])
17357 ;; This covers both call and sibcall since only GOT slot is allowed.
17358 (define_insn "*call_got_x32"
17359 [(call (mem:QI (zero_extend:DI
17360 (match_operand:SI 0 "GOT_memory_operand" "Bg")))
17361 (match_operand 1))]
17364 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
17365 return ix86_output_call_insn (insn, fnaddr);
17367 [(set_attr "type" "call")])
17369 ;; Since sibcall never returns, we can only use call-clobbered register
17371 (define_insn "*sibcall_GOT_32"
17374 (match_operand:SI 0 "register_no_elim_operand" "U")
17375 (match_operand:SI 1 "GOT32_symbol_operand"))))
17376 (match_operand 2))]
17379 && !TARGET_INDIRECT_BRANCH_REGISTER
17380 && SIBLING_CALL_P (insn)"
17382 rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
17383 fnaddr = gen_const_mem (SImode, fnaddr);
17384 return ix86_output_call_insn (insn, fnaddr);
17386 [(set_attr "type" "call")])
17388 (define_insn "*sibcall"
17389 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
17390 (match_operand 1))]
17391 "SIBLING_CALL_P (insn)"
17392 "* return ix86_output_call_insn (insn, operands[0]);"
17393 [(set_attr "type" "call")])
17395 (define_insn "*sibcall_memory"
17396 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
17398 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17399 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
17400 "* return ix86_output_call_insn (insn, operands[0]);"
17401 [(set_attr "type" "call")])
17404 [(set (match_operand:W 0 "register_operand")
17405 (match_operand:W 1 "memory_operand"))
17406 (call (mem:QI (match_dup 0))
17407 (match_operand 3))]
17409 && !TARGET_INDIRECT_BRANCH_REGISTER
17410 && SIBLING_CALL_P (peep2_next_insn (1))
17411 && !reg_mentioned_p (operands[0],
17412 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17413 [(parallel [(call (mem:QI (match_dup 1))
17415 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17418 [(set (match_operand:W 0 "register_operand")
17419 (match_operand:W 1 "memory_operand"))
17420 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17421 (call (mem:QI (match_dup 0))
17422 (match_operand 3))]
17424 && !TARGET_INDIRECT_BRANCH_REGISTER
17425 && SIBLING_CALL_P (peep2_next_insn (2))
17426 && !reg_mentioned_p (operands[0],
17427 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17428 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17429 (parallel [(call (mem:QI (match_dup 1))
17431 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17433 (define_expand "call_pop"
17434 [(parallel [(call (match_operand:QI 0)
17435 (match_operand:SI 1))
17436 (set (reg:SI SP_REG)
17437 (plus:SI (reg:SI SP_REG)
17438 (match_operand:SI 3)))])]
17441 ix86_expand_call (NULL, operands[0], operands[1],
17442 operands[2], operands[3], false);
17446 (define_insn "*call_pop"
17447 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz"))
17449 (set (reg:SI SP_REG)
17450 (plus:SI (reg:SI SP_REG)
17451 (match_operand:SI 2 "immediate_operand" "i")))]
17452 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17453 "* return ix86_output_call_insn (insn, operands[0]);"
17454 [(set_attr "type" "call")])
17456 (define_insn "*sibcall_pop"
17457 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
17459 (set (reg:SI SP_REG)
17460 (plus:SI (reg:SI SP_REG)
17461 (match_operand:SI 2 "immediate_operand" "i")))]
17462 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17463 "* return ix86_output_call_insn (insn, operands[0]);"
17464 [(set_attr "type" "call")])
17466 (define_insn "*sibcall_pop_memory"
17467 [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs"))
17469 (set (reg:SI SP_REG)
17470 (plus:SI (reg:SI SP_REG)
17471 (match_operand:SI 2 "immediate_operand" "i")))
17472 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17474 "* return ix86_output_call_insn (insn, operands[0]);"
17475 [(set_attr "type" "call")])
17478 [(set (match_operand:SI 0 "register_operand")
17479 (match_operand:SI 1 "memory_operand"))
17480 (parallel [(call (mem:QI (match_dup 0))
17482 (set (reg:SI SP_REG)
17483 (plus:SI (reg:SI SP_REG)
17484 (match_operand:SI 4 "immediate_operand")))])]
17485 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
17486 && !reg_mentioned_p (operands[0],
17487 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17488 [(parallel [(call (mem:QI (match_dup 1))
17490 (set (reg:SI SP_REG)
17491 (plus:SI (reg:SI SP_REG)
17493 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17496 [(set (match_operand:SI 0 "register_operand")
17497 (match_operand:SI 1 "memory_operand"))
17498 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17499 (parallel [(call (mem:QI (match_dup 0))
17501 (set (reg:SI SP_REG)
17502 (plus:SI (reg:SI SP_REG)
17503 (match_operand:SI 4 "immediate_operand")))])]
17504 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
17505 && !reg_mentioned_p (operands[0],
17506 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17507 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17508 (parallel [(call (mem:QI (match_dup 1))
17510 (set (reg:SI SP_REG)
17511 (plus:SI (reg:SI SP_REG)
17513 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17515 ;; Combining simple memory jump instruction
17518 [(set (match_operand:W 0 "register_operand")
17519 (match_operand:W 1 "memory_operand"))
17520 (set (pc) (match_dup 0))]
17522 && !TARGET_INDIRECT_BRANCH_REGISTER
17523 && peep2_reg_dead_p (2, operands[0])"
17524 [(set (pc) (match_dup 1))])
17526 ;; Call subroutine, returning value in operand 0
17528 (define_expand "call_value"
17529 [(set (match_operand 0)
17530 (call (match_operand:QI 1)
17531 (match_operand 2)))
17532 (use (match_operand 3))]
17535 ix86_expand_call (operands[0], operands[1], operands[2],
17536 operands[3], NULL, false);
17540 (define_expand "sibcall_value"
17541 [(set (match_operand 0)
17542 (call (match_operand:QI 1)
17543 (match_operand 2)))
17544 (use (match_operand 3))]
17547 ix86_expand_call (operands[0], operands[1], operands[2],
17548 operands[3], NULL, true);
17552 (define_insn "*call_value"
17553 [(set (match_operand 0)
17554 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
17555 (match_operand 2)))]
17556 "!SIBLING_CALL_P (insn)"
17557 "* return ix86_output_call_insn (insn, operands[1]);"
17558 [(set_attr "type" "callv")])
17560 ;; This covers both call and sibcall since only GOT slot is allowed.
17561 (define_insn "*call_value_got_x32"
17562 [(set (match_operand 0)
17565 (match_operand:SI 1 "GOT_memory_operand" "Bg")))
17566 (match_operand 2)))]
17569 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
17570 return ix86_output_call_insn (insn, fnaddr);
17572 [(set_attr "type" "callv")])
17574 ;; Since sibcall never returns, we can only use call-clobbered register
17576 (define_insn "*sibcall_value_GOT_32"
17577 [(set (match_operand 0)
17580 (match_operand:SI 1 "register_no_elim_operand" "U")
17581 (match_operand:SI 2 "GOT32_symbol_operand"))))
17582 (match_operand 3)))]
17585 && !TARGET_INDIRECT_BRANCH_REGISTER
17586 && SIBLING_CALL_P (insn)"
17588 rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
17589 fnaddr = gen_const_mem (SImode, fnaddr);
17590 return ix86_output_call_insn (insn, fnaddr);
17592 [(set_attr "type" "callv")])
17594 (define_insn "*sibcall_value"
17595 [(set (match_operand 0)
17596 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
17597 (match_operand 2)))]
17598 "SIBLING_CALL_P (insn)"
17599 "* return ix86_output_call_insn (insn, operands[1]);"
17600 [(set_attr "type" "callv")])
17602 (define_insn "*sibcall_value_memory"
17603 [(set (match_operand 0)
17604 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
17605 (match_operand 2)))
17606 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17607 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
17608 "* return ix86_output_call_insn (insn, operands[1]);"
17609 [(set_attr "type" "callv")])
17612 [(set (match_operand:W 0 "register_operand")
17613 (match_operand:W 1 "memory_operand"))
17614 (set (match_operand 2)
17615 (call (mem:QI (match_dup 0))
17616 (match_operand 3)))]
17618 && !TARGET_INDIRECT_BRANCH_REGISTER
17619 && SIBLING_CALL_P (peep2_next_insn (1))
17620 && !reg_mentioned_p (operands[0],
17621 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17622 [(parallel [(set (match_dup 2)
17623 (call (mem:QI (match_dup 1))
17625 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17628 [(set (match_operand:W 0 "register_operand")
17629 (match_operand:W 1 "memory_operand"))
17630 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17631 (set (match_operand 2)
17632 (call (mem:QI (match_dup 0))
17633 (match_operand 3)))]
17635 && !TARGET_INDIRECT_BRANCH_REGISTER
17636 && SIBLING_CALL_P (peep2_next_insn (2))
17637 && !reg_mentioned_p (operands[0],
17638 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17639 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17640 (parallel [(set (match_dup 2)
17641 (call (mem:QI (match_dup 1))
17643 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17645 (define_expand "call_value_pop"
17646 [(parallel [(set (match_operand 0)
17647 (call (match_operand:QI 1)
17648 (match_operand:SI 2)))
17649 (set (reg:SI SP_REG)
17650 (plus:SI (reg:SI SP_REG)
17651 (match_operand:SI 4)))])]
17654 ix86_expand_call (operands[0], operands[1], operands[2],
17655 operands[3], operands[4], false);
17659 (define_insn "*call_value_pop"
17660 [(set (match_operand 0)
17661 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz"))
17662 (match_operand 2)))
17663 (set (reg:SI SP_REG)
17664 (plus:SI (reg:SI SP_REG)
17665 (match_operand:SI 3 "immediate_operand" "i")))]
17666 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17667 "* return ix86_output_call_insn (insn, operands[1]);"
17668 [(set_attr "type" "callv")])
17670 (define_insn "*sibcall_value_pop"
17671 [(set (match_operand 0)
17672 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
17673 (match_operand 2)))
17674 (set (reg:SI SP_REG)
17675 (plus:SI (reg:SI SP_REG)
17676 (match_operand:SI 3 "immediate_operand" "i")))]
17677 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17678 "* return ix86_output_call_insn (insn, operands[1]);"
17679 [(set_attr "type" "callv")])
17681 (define_insn "*sibcall_value_pop_memory"
17682 [(set (match_operand 0)
17683 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
17684 (match_operand 2)))
17685 (set (reg:SI SP_REG)
17686 (plus:SI (reg:SI SP_REG)
17687 (match_operand:SI 3 "immediate_operand" "i")))
17688 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17690 "* return ix86_output_call_insn (insn, operands[1]);"
17691 [(set_attr "type" "callv")])
17694 [(set (match_operand:SI 0 "register_operand")
17695 (match_operand:SI 1 "memory_operand"))
17696 (parallel [(set (match_operand 2)
17697 (call (mem:QI (match_dup 0))
17698 (match_operand 3)))
17699 (set (reg:SI SP_REG)
17700 (plus:SI (reg:SI SP_REG)
17701 (match_operand:SI 4 "immediate_operand")))])]
17702 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
17703 && !reg_mentioned_p (operands[0],
17704 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17705 [(parallel [(set (match_dup 2)
17706 (call (mem:QI (match_dup 1))
17708 (set (reg:SI SP_REG)
17709 (plus:SI (reg:SI SP_REG)
17711 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17714 [(set (match_operand:SI 0 "register_operand")
17715 (match_operand:SI 1 "memory_operand"))
17716 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17717 (parallel [(set (match_operand 2)
17718 (call (mem:QI (match_dup 0))
17719 (match_operand 3)))
17720 (set (reg:SI SP_REG)
17721 (plus:SI (reg:SI SP_REG)
17722 (match_operand:SI 4 "immediate_operand")))])]
17723 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
17724 && !reg_mentioned_p (operands[0],
17725 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17726 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17727 (parallel [(set (match_dup 2)
17728 (call (mem:QI (match_dup 1))
17730 (set (reg:SI SP_REG)
17731 (plus:SI (reg:SI SP_REG)
17733 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17735 ;; Call subroutine returning any type.
17737 (define_expand "untyped_call"
17738 [(parallel [(call (match_operand 0)
17741 (match_operand 2)])]
17746 /* In order to give reg-stack an easier job in validating two
17747 coprocessor registers as containing a possible return value,
17748 simply pretend the untyped call returns a complex long double
17751 We can't use SSE_REGPARM_MAX here since callee is unprototyped
17752 and should have the default ABI. */
17754 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
17755 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
17756 operands[0], const0_rtx,
17757 GEN_INT ((TARGET_64BIT
17758 ? (ix86_abi == SYSV_ABI
17759 ? X86_64_SSE_REGPARM_MAX
17760 : X86_64_MS_SSE_REGPARM_MAX)
17761 : X86_32_SSE_REGPARM_MAX)
17765 for (i = 0; i < XVECLEN (operands[2], 0); i++)
17767 rtx set = XVECEXP (operands[2], 0, i);
17768 emit_move_insn (SET_DEST (set), SET_SRC (set));
17771 /* The optimizer does not know that the call sets the function value
17772 registers we stored in the result block. We avoid problems by
17773 claiming that all hard registers are used and clobbered at this
17775 emit_insn (gen_blockage ());
17780 ;; Prologue and epilogue instructions
17782 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
17783 ;; all of memory. This blocks insns from being moved across this point.
17785 (define_insn "blockage"
17786 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
17789 [(set_attr "length" "0")])
17791 ;; Do not schedule instructions accessing memory across this point.
17793 (define_expand "memory_blockage"
17794 [(set (match_dup 0)
17795 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
17798 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
17799 MEM_VOLATILE_P (operands[0]) = 1;
17802 (define_insn "*memory_blockage"
17803 [(set (match_operand:BLK 0)
17804 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
17807 [(set_attr "length" "0")])
17809 ;; As USE insns aren't meaningful after reload, this is used instead
17810 ;; to prevent deleting instructions setting registers for PIC code
17811 (define_insn "prologue_use"
17812 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
17815 [(set_attr "length" "0")])
17817 ;; Insn emitted into the body of a function to return from a function.
17818 ;; This is only done if the function's epilogue is known to be simple.
17819 ;; See comments for ix86_can_use_return_insn_p in i386.cc.
17821 (define_expand "return"
17823 "ix86_can_use_return_insn_p ()"
17825 if (crtl->args.pops_args)
17827 rtx popc = GEN_INT (crtl->args.pops_args);
17828 emit_jump_insn (gen_simple_return_pop_internal (popc));
17833 ;; We need to disable this for TARGET_SEH, as otherwise
17834 ;; shrink-wrapped prologue gets enabled too. This might exceed
17835 ;; the maximum size of prologue in unwind information.
17836 ;; Also disallow shrink-wrapping if using stack slot to pass the
17837 ;; static chain pointer - the first instruction has to be pushl %esi
17838 ;; and it can't be moved around, as we use alternate entry points
17840 ;; Also disallow for ms_hook_prologue functions which have frame
17841 ;; pointer set up in function label which is correctly handled in
17842 ;; ix86_expand_{prologue|epligoue}() only.
17844 (define_expand "simple_return"
17846 "!TARGET_SEH && !ix86_static_chain_on_stack && !ix86_function_ms_hook_prologue (cfun->decl)"
17848 if (crtl->args.pops_args)
17850 rtx popc = GEN_INT (crtl->args.pops_args);
17851 emit_jump_insn (gen_simple_return_pop_internal (popc));
17856 (define_insn "simple_return_internal"
17859 "* return ix86_output_function_return (false);"
17860 [(set_attr "length" "1")
17861 (set_attr "atom_unit" "jeu")
17862 (set_attr "length_immediate" "0")
17863 (set_attr "modrm" "0")])
17865 (define_insn "interrupt_return"
17867 (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
17870 return TARGET_64BIT ? (TARGET_UINTR ? "uiret" : "iretq") : "iret";
17873 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
17874 ;; instruction Athlon and K8 have.
17876 (define_insn "simple_return_internal_long"
17878 (unspec [(const_int 0)] UNSPEC_REP)]
17880 "* return ix86_output_function_return (true);"
17881 [(set_attr "length" "2")
17882 (set_attr "atom_unit" "jeu")
17883 (set_attr "length_immediate" "0")
17884 (set_attr "prefix_rep" "1")
17885 (set_attr "modrm" "0")])
17887 (define_insn_and_split "simple_return_pop_internal"
17889 (use (match_operand:SI 0 "const_int_operand"))]
17892 "&& cfun->machine->function_return_type != indirect_branch_keep"
17894 "ix86_split_simple_return_pop_internal (operands[0]); DONE;"
17895 [(set_attr "length" "3")
17896 (set_attr "atom_unit" "jeu")
17897 (set_attr "length_immediate" "2")
17898 (set_attr "modrm" "0")])
17900 (define_expand "simple_return_indirect_internal"
17903 (use (match_operand 0 "register_operand"))])])
17905 (define_insn "*simple_return_indirect_internal<mode>"
17907 (use (match_operand:W 0 "register_operand" "r"))]
17909 "* return ix86_output_indirect_function_return (operands[0]);"
17910 [(set (attr "type")
17911 (if_then_else (match_test "(cfun->machine->indirect_branch_type
17912 != indirect_branch_keep)")
17913 (const_string "multi")
17914 (const_string "ibr")))
17915 (set_attr "length_immediate" "0")])
17921 [(set_attr "length" "1")
17922 (set_attr "length_immediate" "0")
17923 (set_attr "modrm" "0")])
17925 ;; Generate nops. Operand 0 is the number of nops, up to 8.
17926 (define_insn "nops"
17927 [(unspec_volatile [(match_operand 0 "const_int_operand")]
17931 int num = INTVAL (operands[0]);
17933 gcc_assert (IN_RANGE (num, 1, 8));
17936 fputs ("\tnop\n", asm_out_file);
17940 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
17941 (set_attr "length_immediate" "0")
17942 (set_attr "modrm" "0")])
17944 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
17945 ;; branch prediction penalty for the third jump in a 16-byte
17949 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
17952 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
17953 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
17955 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
17956 The align insn is used to avoid 3 jump instructions in the row to improve
17957 branch prediction and the benefits hardly outweigh the cost of extra 8
17958 nops on the average inserted by full alignment pseudo operation. */
17962 [(set_attr "length" "16")])
17964 (define_expand "prologue"
17967 "ix86_expand_prologue (); DONE;")
17969 (define_expand "set_got"
17971 [(set (match_operand:SI 0 "register_operand")
17972 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
17973 (clobber (reg:CC FLAGS_REG))])]
17976 if (flag_pic && !TARGET_VXWORKS_RTP)
17977 ix86_pc_thunk_call_expanded = true;
17980 (define_insn "*set_got"
17981 [(set (match_operand:SI 0 "register_operand" "=r")
17982 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
17983 (clobber (reg:CC FLAGS_REG))]
17985 "* return output_set_got (operands[0], NULL_RTX);"
17986 [(set_attr "type" "multi")
17987 (set_attr "length" "12")])
17989 (define_expand "set_got_labelled"
17991 [(set (match_operand:SI 0 "register_operand")
17992 (unspec:SI [(label_ref (match_operand 1))]
17994 (clobber (reg:CC FLAGS_REG))])]
17997 if (flag_pic && !TARGET_VXWORKS_RTP)
17998 ix86_pc_thunk_call_expanded = true;
18001 (define_insn "*set_got_labelled"
18002 [(set (match_operand:SI 0 "register_operand" "=r")
18003 (unspec:SI [(label_ref (match_operand 1))]
18005 (clobber (reg:CC FLAGS_REG))]
18007 "* return output_set_got (operands[0], operands[1]);"
18008 [(set_attr "type" "multi")
18009 (set_attr "length" "12")])
18011 (define_insn "set_got_rex64"
18012 [(set (match_operand:DI 0 "register_operand" "=r")
18013 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
18015 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
18016 [(set_attr "type" "lea")
18017 (set_attr "length_address" "4")
18018 (set_attr "mode" "DI")])
18020 (define_insn "set_rip_rex64"
18021 [(set (match_operand:DI 0 "register_operand" "=r")
18022 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
18024 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
18025 [(set_attr "type" "lea")
18026 (set_attr "length_address" "4")
18027 (set_attr "mode" "DI")])
18029 (define_insn "set_got_offset_rex64"
18030 [(set (match_operand:DI 0 "register_operand" "=r")
18032 [(label_ref (match_operand 1))]
18033 UNSPEC_SET_GOT_OFFSET))]
18035 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
18036 [(set_attr "type" "imov")
18037 (set_attr "length_immediate" "0")
18038 (set_attr "length_address" "8")
18039 (set_attr "mode" "DI")])
18041 (define_expand "epilogue"
18044 "ix86_expand_epilogue (1); DONE;")
18046 (define_expand "sibcall_epilogue"
18049 "ix86_expand_epilogue (0); DONE;")
18051 (define_expand "eh_return"
18052 [(use (match_operand 0 "register_operand"))]
18055 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
18057 /* Tricky bit: we write the address of the handler to which we will
18058 be returning into someone else's stack frame, one word below the
18059 stack address we wish to restore. */
18060 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
18061 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
18062 /* Return address is always in word_mode. */
18063 tmp = gen_rtx_MEM (word_mode, tmp);
18064 if (GET_MODE (ra) != word_mode)
18065 ra = convert_to_mode (word_mode, ra, 1);
18066 emit_move_insn (tmp, ra);
18068 emit_jump_insn (gen_eh_return_internal ());
18073 (define_insn_and_split "eh_return_internal"
18077 "epilogue_completed"
18079 "ix86_expand_epilogue (2); DONE;")
18081 (define_expand "@leave_<mode>"
18083 [(set (reg:W SP_REG) (plus:W (reg:W BP_REG) (match_dup 0)))
18084 (set (reg:W BP_REG) (mem:W (reg:W BP_REG)))
18085 (clobber (mem:BLK (scratch)))])]
18087 "operands[0] = GEN_INT (<MODE_SIZE>);")
18089 (define_insn "*leave"
18090 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
18091 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
18092 (clobber (mem:BLK (scratch)))]
18095 [(set_attr "type" "leave")])
18097 (define_insn "*leave_rex64"
18098 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
18099 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
18100 (clobber (mem:BLK (scratch)))]
18103 [(set_attr "type" "leave")])
18105 ;; Handle -fsplit-stack.
18107 (define_expand "split_stack_prologue"
18111 ix86_expand_split_stack_prologue ();
18115 ;; In order to support the call/return predictor, we use a return
18116 ;; instruction which the middle-end doesn't see.
18117 (define_insn "split_stack_return"
18118 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
18119 UNSPECV_SPLIT_STACK_RETURN)]
18122 if (operands[0] == const0_rtx)
18127 [(set_attr "atom_unit" "jeu")
18128 (set_attr "modrm" "0")
18129 (set (attr "length")
18130 (if_then_else (match_operand:SI 0 "const0_operand")
18133 (set (attr "length_immediate")
18134 (if_then_else (match_operand:SI 0 "const0_operand")
18138 ;; If there are operand 0 bytes available on the stack, jump to
18141 (define_expand "split_stack_space_check"
18142 [(set (pc) (if_then_else
18143 (ltu (minus (reg SP_REG)
18144 (match_operand 0 "register_operand"))
18146 (label_ref (match_operand 1))
18150 rtx reg = gen_reg_rtx (Pmode);
18152 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, operands[0]));
18154 operands[2] = ix86_split_stack_guard ();
18155 ix86_expand_branch (GEU, reg, operands[2], operands[1]);
18160 ;; Bit manipulation instructions.
18162 (define_expand "ffs<mode>2"
18163 [(set (match_dup 2) (const_int -1))
18164 (parallel [(set (match_dup 3) (match_dup 4))
18165 (set (match_operand:SWI48 0 "register_operand")
18167 (match_operand:SWI48 1 "nonimmediate_operand")))])
18168 (set (match_dup 0) (if_then_else:SWI48
18169 (eq (match_dup 3) (const_int 0))
18172 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
18173 (clobber (reg:CC FLAGS_REG))])]
18176 machine_mode flags_mode;
18178 if (<MODE>mode == SImode && !TARGET_CMOVE)
18180 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
18184 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
18186 operands[2] = gen_reg_rtx (<MODE>mode);
18187 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
18188 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
18191 (define_insn_and_split "ffssi2_no_cmove"
18192 [(set (match_operand:SI 0 "register_operand" "=r")
18193 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
18194 (clobber (match_scratch:SI 2 "=&q"))
18195 (clobber (reg:CC FLAGS_REG))]
18198 "&& reload_completed"
18199 [(parallel [(set (match_dup 4) (match_dup 5))
18200 (set (match_dup 0) (ctz:SI (match_dup 1)))])
18201 (set (strict_low_part (match_dup 3))
18202 (eq:QI (match_dup 4) (const_int 0)))
18203 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
18204 (clobber (reg:CC FLAGS_REG))])
18205 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
18206 (clobber (reg:CC FLAGS_REG))])
18207 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
18208 (clobber (reg:CC FLAGS_REG))])]
18210 machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
18212 operands[3] = gen_lowpart (QImode, operands[2]);
18213 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
18214 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
18216 ix86_expand_clear (operands[2]);
18219 (define_insn_and_split "*tzcnt<mode>_1"
18220 [(set (reg:CCC FLAGS_REG)
18221 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18223 (set (match_operand:SWI48 0 "register_operand" "=r")
18224 (ctz:SWI48 (match_dup 1)))]
18226 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
18227 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18228 && optimize_function_for_speed_p (cfun)
18229 && !reg_mentioned_p (operands[0], operands[1])"
18231 [(set (reg:CCC FLAGS_REG)
18232 (compare:CCC (match_dup 1) (const_int 0)))
18234 (ctz:SWI48 (match_dup 1)))
18235 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
18236 "ix86_expand_clear (operands[0]);"
18237 [(set_attr "type" "alu1")
18238 (set_attr "prefix_0f" "1")
18239 (set_attr "prefix_rep" "1")
18240 (set_attr "btver2_decode" "double")
18241 (set_attr "mode" "<MODE>")])
18243 ; False dependency happens when destination is only updated by tzcnt,
18244 ; lzcnt or popcnt. There is no false dependency when destination is
18245 ; also used in source.
18246 (define_insn "*tzcnt<mode>_1_falsedep"
18247 [(set (reg:CCC FLAGS_REG)
18248 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18250 (set (match_operand:SWI48 0 "register_operand" "=r")
18251 (ctz:SWI48 (match_dup 1)))
18252 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18253 UNSPEC_INSN_FALSE_DEP)]
18255 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
18256 [(set_attr "type" "alu1")
18257 (set_attr "prefix_0f" "1")
18258 (set_attr "prefix_rep" "1")
18259 (set_attr "btver2_decode" "double")
18260 (set_attr "mode" "<MODE>")])
18262 (define_insn "*bsf<mode>_1"
18263 [(set (reg:CCZ FLAGS_REG)
18264 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18266 (set (match_operand:SWI48 0 "register_operand" "=r")
18267 (ctz:SWI48 (match_dup 1)))]
18269 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
18270 [(set_attr "type" "alu1")
18271 (set_attr "prefix_0f" "1")
18272 (set_attr "btver2_decode" "double")
18273 (set_attr "znver1_decode" "vector")
18274 (set_attr "mode" "<MODE>")])
18276 (define_insn_and_split "ctz<mode>2"
18277 [(set (match_operand:SWI48 0 "register_operand" "=r")
18279 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18280 (clobber (reg:CC FLAGS_REG))]
18284 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
18285 else if (optimize_function_for_size_p (cfun))
18287 else if (TARGET_CPU_P (GENERIC))
18288 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
18289 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
18291 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
18293 "(TARGET_BMI || TARGET_CPU_P (GENERIC))
18294 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18295 && optimize_function_for_speed_p (cfun)
18296 && !reg_mentioned_p (operands[0], operands[1])"
18298 [(set (match_dup 0)
18299 (ctz:SWI48 (match_dup 1)))
18300 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18301 (clobber (reg:CC FLAGS_REG))])]
18302 "ix86_expand_clear (operands[0]);"
18303 [(set_attr "type" "alu1")
18304 (set_attr "prefix_0f" "1")
18305 (set (attr "prefix_rep")
18307 (ior (match_test "TARGET_BMI")
18308 (and (not (match_test "optimize_function_for_size_p (cfun)"))
18309 (match_test "TARGET_CPU_P (GENERIC)")))
18311 (const_string "0")))
18312 (set_attr "mode" "<MODE>")])
18314 ; False dependency happens when destination is only updated by tzcnt,
18315 ; lzcnt or popcnt. There is no false dependency when destination is
18316 ; also used in source.
18317 (define_insn "*ctz<mode>2_falsedep"
18318 [(set (match_operand:SWI48 0 "register_operand" "=r")
18320 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18321 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18322 UNSPEC_INSN_FALSE_DEP)
18323 (clobber (reg:CC FLAGS_REG))]
18327 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
18328 else if (TARGET_CPU_P (GENERIC))
18329 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
18330 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
18332 gcc_unreachable ();
18334 [(set_attr "type" "alu1")
18335 (set_attr "prefix_0f" "1")
18336 (set_attr "prefix_rep" "1")
18337 (set_attr "mode" "<MODE>")])
18339 (define_insn_and_split "*ctzsi2_zext"
18340 [(set (match_operand:DI 0 "register_operand" "=r")
18344 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
18346 (clobber (reg:CC FLAGS_REG))]
18347 "TARGET_BMI && TARGET_64BIT"
18348 "tzcnt{l}\t{%1, %k0|%k0, %1}"
18349 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18350 && optimize_function_for_speed_p (cfun)
18351 && !reg_mentioned_p (operands[0], operands[1])"
18353 [(set (match_dup 0)
18354 (and:DI (subreg:DI (ctz:SI (match_dup 1)) 0) (const_int 63)))
18355 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18356 (clobber (reg:CC FLAGS_REG))])]
18357 "ix86_expand_clear (operands[0]);"
18358 [(set_attr "type" "alu1")
18359 (set_attr "prefix_0f" "1")
18360 (set_attr "prefix_rep" "1")
18361 (set_attr "mode" "SI")])
18363 ; False dependency happens when destination is only updated by tzcnt,
18364 ; lzcnt or popcnt. There is no false dependency when destination is
18365 ; also used in source.
18366 (define_insn "*ctzsi2_zext_falsedep"
18367 [(set (match_operand:DI 0 "register_operand" "=r")
18371 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
18373 (unspec [(match_operand:DI 2 "register_operand" "0")]
18374 UNSPEC_INSN_FALSE_DEP)
18375 (clobber (reg:CC FLAGS_REG))]
18376 "TARGET_BMI && TARGET_64BIT"
18377 "tzcnt{l}\t{%1, %k0|%k0, %1}"
18378 [(set_attr "type" "alu1")
18379 (set_attr "prefix_0f" "1")
18380 (set_attr "prefix_rep" "1")
18381 (set_attr "mode" "SI")])
18383 (define_insn_and_split "*ctzsidi2_<s>ext"
18384 [(set (match_operand:DI 0 "register_operand" "=r")
18387 (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18388 (clobber (reg:CC FLAGS_REG))]
18392 return "tzcnt{l}\t{%1, %k0|%k0, %1}";
18393 else if (TARGET_CPU_P (GENERIC)
18394 && !optimize_function_for_size_p (cfun))
18395 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
18396 return "rep%; bsf{l}\t{%1, %k0|%k0, %1}";
18397 return "bsf{l}\t{%1, %k0|%k0, %1}";
18399 "(TARGET_BMI || TARGET_CPU_P (GENERIC))
18400 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18401 && optimize_function_for_speed_p (cfun)
18402 && !reg_mentioned_p (operands[0], operands[1])"
18404 [(set (match_dup 0)
18405 (any_extend:DI (ctz:SI (match_dup 1))))
18406 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18407 (clobber (reg:CC FLAGS_REG))])]
18408 "ix86_expand_clear (operands[0]);"
18409 [(set_attr "type" "alu1")
18410 (set_attr "prefix_0f" "1")
18411 (set (attr "prefix_rep")
18413 (ior (match_test "TARGET_BMI")
18414 (and (not (match_test "optimize_function_for_size_p (cfun)"))
18415 (match_test "TARGET_CPU_P (GENERIC)")))
18417 (const_string "0")))
18418 (set_attr "mode" "SI")])
18420 (define_insn "*ctzsidi2_<s>ext_falsedep"
18421 [(set (match_operand:DI 0 "register_operand" "=r")
18424 (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18425 (unspec [(match_operand:DI 2 "register_operand" "0")]
18426 UNSPEC_INSN_FALSE_DEP)
18427 (clobber (reg:CC FLAGS_REG))]
18431 return "tzcnt{l}\t{%1, %k0|%k0, %1}";
18432 else if (TARGET_CPU_P (GENERIC))
18433 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
18434 return "rep%; bsf{l}\t{%1, %k0|%k0, %1}";
18436 gcc_unreachable ();
18438 [(set_attr "type" "alu1")
18439 (set_attr "prefix_0f" "1")
18440 (set_attr "prefix_rep" "1")
18441 (set_attr "mode" "SI")])
18443 (define_insn "bsr_rex64"
18444 [(set (reg:CCZ FLAGS_REG)
18445 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
18447 (set (match_operand:DI 0 "register_operand" "=r")
18448 (minus:DI (const_int 63)
18449 (clz:DI (match_dup 1))))]
18451 "bsr{q}\t{%1, %0|%0, %1}"
18452 [(set_attr "type" "alu1")
18453 (set_attr "prefix_0f" "1")
18454 (set_attr "znver1_decode" "vector")
18455 (set_attr "mode" "DI")])
18457 (define_insn "bsr_rex64_1"
18458 [(set (match_operand:DI 0 "register_operand" "=r")
18459 (minus:DI (const_int 63)
18460 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
18461 (clobber (reg:CC FLAGS_REG))]
18462 "!TARGET_LZCNT && TARGET_64BIT"
18463 "bsr{q}\t{%1, %0|%0, %1}"
18464 [(set_attr "type" "alu1")
18465 (set_attr "prefix_0f" "1")
18466 (set_attr "znver1_decode" "vector")
18467 (set_attr "mode" "DI")])
18469 (define_insn "bsr_rex64_1_zext"
18470 [(set (match_operand:DI 0 "register_operand" "=r")
18472 (minus:SI (const_int 63)
18474 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
18476 (clobber (reg:CC FLAGS_REG))]
18477 "!TARGET_LZCNT && TARGET_64BIT"
18478 "bsr{q}\t{%1, %0|%0, %1}"
18479 [(set_attr "type" "alu1")
18480 (set_attr "prefix_0f" "1")
18481 (set_attr "znver1_decode" "vector")
18482 (set_attr "mode" "DI")])
18485 [(set (reg:CCZ FLAGS_REG)
18486 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
18488 (set (match_operand:SI 0 "register_operand" "=r")
18489 (minus:SI (const_int 31)
18490 (clz:SI (match_dup 1))))]
18492 "bsr{l}\t{%1, %0|%0, %1}"
18493 [(set_attr "type" "alu1")
18494 (set_attr "prefix_0f" "1")
18495 (set_attr "znver1_decode" "vector")
18496 (set_attr "mode" "SI")])
18498 (define_insn "bsr_1"
18499 [(set (match_operand:SI 0 "register_operand" "=r")
18500 (minus:SI (const_int 31)
18501 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18502 (clobber (reg:CC FLAGS_REG))]
18504 "bsr{l}\t{%1, %0|%0, %1}"
18505 [(set_attr "type" "alu1")
18506 (set_attr "prefix_0f" "1")
18507 (set_attr "znver1_decode" "vector")
18508 (set_attr "mode" "SI")])
18510 (define_insn "bsr_zext_1"
18511 [(set (match_operand:DI 0 "register_operand" "=r")
18515 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))))
18516 (clobber (reg:CC FLAGS_REG))]
18517 "!TARGET_LZCNT && TARGET_64BIT"
18518 "bsr{l}\t{%1, %k0|%k0, %1}"
18519 [(set_attr "type" "alu1")
18520 (set_attr "prefix_0f" "1")
18521 (set_attr "znver1_decode" "vector")
18522 (set_attr "mode" "SI")])
18524 ; As bsr is undefined behavior on zero and for other input
18525 ; values it is in range 0 to 63, we can optimize away sign-extends.
18526 (define_insn_and_split "*bsr_rex64_2"
18527 [(set (match_operand:DI 0 "register_operand")
18532 (subreg:SI (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
18535 (clobber (reg:CC FLAGS_REG))]
18536 "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
18539 [(parallel [(set (reg:CCZ FLAGS_REG)
18540 (compare:CCZ (match_dup 1) (const_int 0)))
18542 (minus:DI (const_int 63) (clz:DI (match_dup 1))))])
18543 (parallel [(set (match_dup 0)
18544 (zero_extend:DI (xor:SI (match_dup 3) (const_int 63))))
18545 (clobber (reg:CC FLAGS_REG))])]
18547 operands[2] = gen_reg_rtx (DImode);
18548 operands[3] = lowpart_subreg (SImode, operands[2], DImode);
18551 (define_insn_and_split "*bsr_2"
18552 [(set (match_operand:DI 0 "register_operand")
18557 (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
18559 (clobber (reg:CC FLAGS_REG))]
18560 "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
18563 [(parallel [(set (reg:CCZ FLAGS_REG)
18564 (compare:CCZ (match_dup 1) (const_int 0)))
18566 (minus:SI (const_int 31) (clz:SI (match_dup 1))))])
18567 (parallel [(set (match_dup 0)
18568 (zero_extend:DI (xor:SI (match_dup 2) (const_int 31))))
18569 (clobber (reg:CC FLAGS_REG))])]
18570 "operands[2] = gen_reg_rtx (SImode);")
18572 ; Splitters to optimize 64 - __builtin_clzl (x) or 32 - __builtin_clz (x).
18573 ; Again, as for !TARGET_LZCNT CLZ is UB at zero, CLZ is guaranteed to be
18574 ; in [0, 63] or [0, 31] range.
18576 [(set (match_operand:SI 0 "register_operand")
18578 (match_operand:SI 2 "const_int_operand")
18580 (minus:SI (const_int 63)
18582 (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
18585 "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
18586 [(set (match_dup 3)
18587 (minus:DI (const_int 63) (clz:DI (match_dup 1))))
18589 (plus:SI (match_dup 5) (match_dup 4)))]
18591 operands[3] = gen_reg_rtx (DImode);
18592 operands[5] = lowpart_subreg (SImode, operands[3], DImode);
18593 if (INTVAL (operands[2]) == 63)
18595 emit_insn (gen_bsr_rex64_1_zext (operands[3], operands[1]));
18596 emit_move_insn (operands[0], operands[5]);
18599 operands[4] = gen_int_mode (UINTVAL (operands[2]) - 63, SImode);
18603 [(set (match_operand:SI 0 "register_operand")
18605 (match_operand:SI 2 "const_int_operand")
18607 (minus:SI (const_int 31)
18608 (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
18610 "!TARGET_LZCNT && ix86_pre_reload_split ()"
18611 [(set (match_dup 3)
18612 (minus:SI (const_int 31) (clz:SI (match_dup 1))))
18614 (plus:SI (match_dup 3) (match_dup 4)))]
18616 if (INTVAL (operands[2]) == 31)
18618 emit_insn (gen_bsr_1 (operands[0], operands[1]));
18621 operands[3] = gen_reg_rtx (SImode);
18622 operands[4] = gen_int_mode (UINTVAL (operands[2]) - 31, SImode);
18626 [(set (match_operand:DI 0 "register_operand")
18628 (match_operand:DI 2 "const_int_operand")
18631 (minus:SI (const_int 63)
18633 (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
18638 && ix86_pre_reload_split ()
18639 && ((unsigned HOST_WIDE_INT)
18640 trunc_int_for_mode (UINTVAL (operands[2]) - 63, SImode)
18641 == UINTVAL (operands[2]) - 63)"
18642 [(set (match_dup 3)
18643 (minus:DI (const_int 63) (clz:DI (match_dup 1))))
18645 (plus:DI (match_dup 3) (match_dup 4)))]
18647 if (INTVAL (operands[2]) == 63)
18649 emit_insn (gen_bsr_rex64_1 (operands[0], operands[1]));
18652 operands[3] = gen_reg_rtx (DImode);
18653 operands[4] = GEN_INT (UINTVAL (operands[2]) - 63);
18657 [(set (match_operand:DI 0 "register_operand")
18659 (match_operand:DI 2 "const_int_operand")
18662 (minus:SI (const_int 31)
18663 (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
18664 (const_int 31)))))]
18667 && ix86_pre_reload_split ()
18668 && ((unsigned HOST_WIDE_INT)
18669 trunc_int_for_mode (UINTVAL (operands[2]) - 31, SImode)
18670 == UINTVAL (operands[2]) - 31)"
18671 [(set (match_dup 3)
18672 (zero_extend:DI (minus:SI (const_int 31) (clz:SI (match_dup 1)))))
18674 (plus:DI (match_dup 3) (match_dup 4)))]
18676 if (INTVAL (operands[2]) == 31)
18678 emit_insn (gen_bsr_zext_1 (operands[0], operands[1]));
18681 operands[3] = gen_reg_rtx (DImode);
18682 operands[4] = GEN_INT (UINTVAL (operands[2]) - 31);
18685 (define_expand "clz<mode>2"
18687 [(set (reg:CCZ FLAGS_REG)
18688 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18690 (set (match_dup 3) (minus:SWI48
18692 (clz:SWI48 (match_dup 1))))])
18694 [(set (match_operand:SWI48 0 "register_operand")
18695 (xor:SWI48 (match_dup 3) (match_dup 2)))
18696 (clobber (reg:CC FLAGS_REG))])]
18701 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
18704 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
18705 operands[3] = gen_reg_rtx (<MODE>mode);
18708 (define_insn_and_split "clz<mode>2_lzcnt"
18709 [(set (match_operand:SWI48 0 "register_operand" "=r")
18711 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18712 (clobber (reg:CC FLAGS_REG))]
18714 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
18715 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18716 && optimize_function_for_speed_p (cfun)
18717 && !reg_mentioned_p (operands[0], operands[1])"
18719 [(set (match_dup 0)
18720 (clz:SWI48 (match_dup 1)))
18721 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18722 (clobber (reg:CC FLAGS_REG))])]
18723 "ix86_expand_clear (operands[0]);"
18724 [(set_attr "prefix_rep" "1")
18725 (set_attr "type" "bitmanip")
18726 (set_attr "mode" "<MODE>")])
18728 ; False dependency happens when destination is only updated by tzcnt,
18729 ; lzcnt or popcnt. There is no false dependency when destination is
18730 ; also used in source.
18731 (define_insn "*clz<mode>2_lzcnt_falsedep"
18732 [(set (match_operand:SWI48 0 "register_operand" "=r")
18734 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18735 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18736 UNSPEC_INSN_FALSE_DEP)
18737 (clobber (reg:CC FLAGS_REG))]
18739 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
18740 [(set_attr "prefix_rep" "1")
18741 (set_attr "type" "bitmanip")
18742 (set_attr "mode" "<MODE>")])
18744 (define_insn_and_split "*clzsi2_lzcnt_zext"
18745 [(set (match_operand:DI 0 "register_operand" "=r")
18749 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
18751 (clobber (reg:CC FLAGS_REG))]
18752 "TARGET_LZCNT && TARGET_64BIT"
18753 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18754 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18755 && optimize_function_for_speed_p (cfun)
18756 && !reg_mentioned_p (operands[0], operands[1])"
18758 [(set (match_dup 0)
18759 (and:DI (subreg:DI (clz:SI (match_dup 1)) 0) (const_int 63)))
18760 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18761 (clobber (reg:CC FLAGS_REG))])]
18762 "ix86_expand_clear (operands[0]);"
18763 [(set_attr "prefix_rep" "1")
18764 (set_attr "type" "bitmanip")
18765 (set_attr "mode" "SI")])
18767 ; False dependency happens when destination is only updated by tzcnt,
18768 ; lzcnt or popcnt. There is no false dependency when destination is
18769 ; also used in source.
18770 (define_insn "*clzsi2_lzcnt_zext_falsedep"
18771 [(set (match_operand:DI 0 "register_operand" "=r")
18775 (match_operand:SWI48 1 "nonimmediate_operand" "rm")) 0)
18777 (unspec [(match_operand:DI 2 "register_operand" "0")]
18778 UNSPEC_INSN_FALSE_DEP)
18779 (clobber (reg:CC FLAGS_REG))]
18781 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18782 [(set_attr "prefix_rep" "1")
18783 (set_attr "type" "bitmanip")
18784 (set_attr "mode" "SI")])
18786 (define_insn_and_split "*clzsi2_lzcnt_zext_2"
18787 [(set (match_operand:DI 0 "register_operand" "=r")
18789 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18790 (clobber (reg:CC FLAGS_REG))]
18791 "TARGET_LZCNT && TARGET_64BIT"
18792 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18793 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18794 && optimize_function_for_speed_p (cfun)
18795 && !reg_mentioned_p (operands[0], operands[1])"
18797 [(set (match_dup 0)
18798 (zero_extend:DI (clz:SI (match_dup 1))))
18799 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18800 (clobber (reg:CC FLAGS_REG))])]
18801 "ix86_expand_clear (operands[0]);"
18802 [(set_attr "prefix_rep" "1")
18803 (set_attr "type" "bitmanip")
18804 (set_attr "mode" "SI")])
18806 ; False dependency happens when destination is only updated by tzcnt,
18807 ; lzcnt or popcnt. There is no false dependency when destination is
18808 ; also used in source.
18809 (define_insn "*clzsi2_lzcnt_zext_2_falsedep"
18810 [(set (match_operand:DI 0 "register_operand" "=r")
18812 (clz:SI (match_operand:SWI48 1 "nonimmediate_operand" "rm"))))
18813 (unspec [(match_operand:DI 2 "register_operand" "0")]
18814 UNSPEC_INSN_FALSE_DEP)
18815 (clobber (reg:CC FLAGS_REG))]
18817 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18818 [(set_attr "prefix_rep" "1")
18819 (set_attr "type" "bitmanip")
18820 (set_attr "mode" "SI")])
18822 (define_int_iterator LT_ZCNT
18823 [(UNSPEC_TZCNT "TARGET_BMI")
18824 (UNSPEC_LZCNT "TARGET_LZCNT")])
18826 (define_int_attr lt_zcnt
18827 [(UNSPEC_TZCNT "tzcnt")
18828 (UNSPEC_LZCNT "lzcnt")])
18830 (define_int_attr lt_zcnt_type
18831 [(UNSPEC_TZCNT "alu1")
18832 (UNSPEC_LZCNT "bitmanip")])
18834 ;; Version of lzcnt/tzcnt that is expanded from intrinsics. This version
18835 ;; provides operand size as output when source operand is zero.
18837 (define_insn_and_split "<lt_zcnt>_<mode>"
18838 [(set (match_operand:SWI48 0 "register_operand" "=r")
18840 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
18841 (clobber (reg:CC FLAGS_REG))]
18843 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %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 (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
18850 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18851 (clobber (reg:CC FLAGS_REG))])]
18852 "ix86_expand_clear (operands[0]);"
18853 [(set_attr "type" "<lt_zcnt_type>")
18854 (set_attr "prefix_0f" "1")
18855 (set_attr "prefix_rep" "1")
18856 (set_attr "mode" "<MODE>")])
18858 ; False dependency happens when destination is only updated by tzcnt,
18859 ; lzcnt or popcnt. There is no false dependency when destination is
18860 ; also used in source.
18861 (define_insn "*<lt_zcnt>_<mode>_falsedep"
18862 [(set (match_operand:SWI48 0 "register_operand" "=r")
18864 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
18865 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18866 UNSPEC_INSN_FALSE_DEP)
18867 (clobber (reg:CC FLAGS_REG))]
18869 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
18870 [(set_attr "type" "<lt_zcnt_type>")
18871 (set_attr "prefix_0f" "1")
18872 (set_attr "prefix_rep" "1")
18873 (set_attr "mode" "<MODE>")])
18875 (define_insn "<lt_zcnt>_hi"
18876 [(set (match_operand:HI 0 "register_operand" "=r")
18878 [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT))
18879 (clobber (reg:CC FLAGS_REG))]
18881 "<lt_zcnt>{w}\t{%1, %0|%0, %1}"
18882 [(set_attr "type" "<lt_zcnt_type>")
18883 (set_attr "prefix_0f" "1")
18884 (set_attr "prefix_rep" "1")
18885 (set_attr "mode" "HI")])
18887 ;; BMI instructions.
18889 (define_insn "bmi_bextr_<mode>"
18890 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
18891 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
18892 (match_operand:SWI48 2 "register_operand" "r,r")]
18894 (clobber (reg:CC FLAGS_REG))]
18896 "bextr\t{%2, %1, %0|%0, %1, %2}"
18897 [(set_attr "type" "bitmanip")
18898 (set_attr "btver2_decode" "direct, double")
18899 (set_attr "mode" "<MODE>")])
18901 (define_insn "*bmi_bextr_<mode>_ccz"
18902 [(set (reg:CCZ FLAGS_REG)
18904 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
18905 (match_operand:SWI48 2 "register_operand" "r,r")]
18908 (clobber (match_scratch:SWI48 0 "=r,r"))]
18910 "bextr\t{%2, %1, %0|%0, %1, %2}"
18911 [(set_attr "type" "bitmanip")
18912 (set_attr "btver2_decode" "direct, double")
18913 (set_attr "mode" "<MODE>")])
18915 (define_insn "*bmi_blsi_<mode>"
18916 [(set (match_operand:SWI48 0 "register_operand" "=r")
18919 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
18921 (clobber (reg:CC FLAGS_REG))]
18923 "blsi\t{%1, %0|%0, %1}"
18924 [(set_attr "type" "bitmanip")
18925 (set_attr "btver2_decode" "double")
18926 (set_attr "mode" "<MODE>")])
18928 (define_insn "*bmi_blsi_<mode>_cmp"
18929 [(set (reg FLAGS_REG)
18932 (neg:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
18935 (set (match_operand:SWI48 0 "register_operand" "=r")
18936 (and:SWI48 (neg:SWI48 (match_dup 1)) (match_dup 1)))]
18937 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
18938 "blsi\t{%1, %0|%0, %1}"
18939 [(set_attr "type" "bitmanip")
18940 (set_attr "btver2_decode" "double")
18941 (set_attr "mode" "<MODE>")])
18943 (define_insn "*bmi_blsi_<mode>_ccno"
18944 [(set (reg FLAGS_REG)
18947 (neg:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
18950 (clobber (match_scratch:SWI48 0 "=r"))]
18951 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
18952 "blsi\t{%1, %0|%0, %1}"
18953 [(set_attr "type" "bitmanip")
18954 (set_attr "btver2_decode" "double")
18955 (set_attr "mode" "<MODE>")])
18957 (define_insn "*bmi_blsmsk_<mode>"
18958 [(set (match_operand:SWI48 0 "register_operand" "=r")
18961 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18964 (clobber (reg:CC FLAGS_REG))]
18966 "blsmsk\t{%1, %0|%0, %1}"
18967 [(set_attr "type" "bitmanip")
18968 (set_attr "btver2_decode" "double")
18969 (set_attr "mode" "<MODE>")])
18971 (define_insn "*bmi_blsr_<mode>"
18972 [(set (match_operand:SWI48 0 "register_operand" "=r")
18975 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18978 (clobber (reg:CC FLAGS_REG))]
18980 "blsr\t{%1, %0|%0, %1}"
18981 [(set_attr "type" "bitmanip")
18982 (set_attr "btver2_decode" "double")
18983 (set_attr "mode" "<MODE>")])
18985 (define_insn "*bmi_blsr_<mode>_cmp"
18986 [(set (reg:CCZ FLAGS_REG)
18990 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18994 (set (match_operand:SWI48 0 "register_operand" "=r")
19001 "blsr\t{%1, %0|%0, %1}"
19002 [(set_attr "type" "bitmanip")
19003 (set_attr "btver2_decode" "double")
19004 (set_attr "mode" "<MODE>")])
19006 (define_insn "*bmi_blsr_<mode>_ccz"
19007 [(set (reg:CCZ FLAGS_REG)
19011 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19015 (clobber (match_scratch:SWI48 0 "=r"))]
19017 "blsr\t{%1, %0|%0, %1}"
19018 [(set_attr "type" "bitmanip")
19019 (set_attr "btver2_decode" "double")
19020 (set_attr "mode" "<MODE>")])
19022 ;; BMI2 instructions.
19023 (define_expand "bmi2_bzhi_<mode>3"
19025 [(set (match_operand:SWI48 0 "register_operand")
19026 (if_then_else:SWI48
19027 (ne:QI (match_operand:QI 2 "register_operand")
19029 (zero_extract:SWI48
19030 (match_operand:SWI48 1 "nonimmediate_operand")
19031 (umin:QI (match_dup 2) (match_dup 3))
19034 (clobber (reg:CC FLAGS_REG))])]
19037 operands[2] = gen_lowpart (QImode, operands[2]);
19038 operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
19041 (define_insn "*bmi2_bzhi_<mode>3"
19042 [(set (match_operand:SWI48 0 "register_operand" "=r")
19043 (if_then_else:SWI48
19044 (ne:QI (match_operand:QI 2 "register_operand" "q")
19046 (zero_extract:SWI48
19047 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19048 (umin:QI (match_dup 2)
19049 (match_operand:QI 3 "const_int_operand"))
19052 (clobber (reg:CC FLAGS_REG))]
19053 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
19054 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
19055 [(set_attr "type" "bitmanip")
19056 (set_attr "prefix" "vex")
19057 (set_attr "mode" "<MODE>")])
19059 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
19060 [(set (reg:CCZ FLAGS_REG)
19062 (if_then_else:SWI48
19063 (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0))
19064 (zero_extract:SWI48
19065 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19066 (umin:QI (match_dup 2)
19067 (match_operand:QI 3 "const_int_operand"))
19071 (clobber (match_scratch:SWI48 0 "=r"))]
19072 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
19073 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
19074 [(set_attr "type" "bitmanip")
19075 (set_attr "prefix" "vex")
19076 (set_attr "mode" "<MODE>")])
19078 (define_insn "*bmi2_bzhi_<mode>3_2"
19079 [(set (match_operand:SWI48 0 "register_operand" "=r")
19082 (ashift:SWI48 (const_int 1)
19083 (match_operand:QI 2 "register_operand" "r"))
19085 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
19086 (clobber (reg:CC FLAGS_REG))]
19088 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
19089 [(set_attr "type" "bitmanip")
19090 (set_attr "prefix" "vex")
19091 (set_attr "mode" "<MODE>")])
19093 (define_insn "*bmi2_bzhi_<mode>3_3"
19094 [(set (match_operand:SWI48 0 "register_operand" "=r")
19097 (ashift:SWI48 (const_int -1)
19098 (match_operand:QI 2 "register_operand" "r")))
19099 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
19100 (clobber (reg:CC FLAGS_REG))]
19102 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
19103 [(set_attr "type" "bitmanip")
19104 (set_attr "prefix" "vex")
19105 (set_attr "mode" "<MODE>")])
19107 (define_insn "*bmi2_bzhi_zero_extendsidi_4"
19108 [(set (match_operand:DI 0 "register_operand" "=r")
19112 (ashift:SI (const_int 1)
19113 (match_operand:QI 2 "register_operand" "r"))
19115 (match_operand:SI 1 "nonimmediate_operand" "rm"))))
19116 (clobber (reg:CC FLAGS_REG))]
19117 "TARGET_64BIT && TARGET_BMI2"
19118 "bzhi\t{%q2, %q1, %q0|%q0, %q1, %q2}"
19119 [(set_attr "type" "bitmanip")
19120 (set_attr "prefix" "vex")
19121 (set_attr "mode" "DI")])
19123 (define_insn "*bmi2_bzhi_zero_extendsidi_5"
19124 [(set (match_operand:DI 0 "register_operand" "=r")
19128 (ashift:SI (const_int 1)
19129 (match_operand:QI 2 "register_operand" "r"))
19131 (match_operand:DI 1 "nonimmediate_operand" "rm")))
19132 (clobber (reg:CC FLAGS_REG))]
19133 "TARGET_64BIT && TARGET_BMI2"
19134 "bzhi\t{%q2, %q1, %q0|%q0, %q1, %q2}"
19135 [(set_attr "type" "bitmanip")
19136 (set_attr "prefix" "vex")
19137 (set_attr "mode" "DI")])
19139 (define_insn "bmi2_pdep_<mode>3"
19140 [(set (match_operand:SWI48 0 "register_operand" "=r")
19141 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
19142 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
19145 "pdep\t{%2, %1, %0|%0, %1, %2}"
19146 [(set_attr "type" "bitmanip")
19147 (set_attr "prefix" "vex")
19148 (set_attr "mode" "<MODE>")])
19150 (define_insn "bmi2_pext_<mode>3"
19151 [(set (match_operand:SWI48 0 "register_operand" "=r")
19152 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
19153 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
19156 "pext\t{%2, %1, %0|%0, %1, %2}"
19157 [(set_attr "type" "bitmanip")
19158 (set_attr "prefix" "vex")
19159 (set_attr "mode" "<MODE>")])
19161 ;; TBM instructions.
19162 (define_insn "@tbm_bextri_<mode>"
19163 [(set (match_operand:SWI48 0 "register_operand" "=r")
19164 (zero_extract:SWI48
19165 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19166 (match_operand:QI 2 "const_0_to_255_operand")
19167 (match_operand:QI 3 "const_0_to_255_operand")))
19168 (clobber (reg:CC FLAGS_REG))]
19171 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
19172 return "bextr\t{%2, %1, %0|%0, %1, %2}";
19174 [(set_attr "type" "bitmanip")
19175 (set_attr "mode" "<MODE>")])
19177 (define_insn "*tbm_blcfill_<mode>"
19178 [(set (match_operand:SWI48 0 "register_operand" "=r")
19181 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19184 (clobber (reg:CC FLAGS_REG))]
19186 "blcfill\t{%1, %0|%0, %1}"
19187 [(set_attr "type" "bitmanip")
19188 (set_attr "mode" "<MODE>")])
19190 (define_insn "*tbm_blci_<mode>"
19191 [(set (match_operand:SWI48 0 "register_operand" "=r")
19195 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19198 (clobber (reg:CC FLAGS_REG))]
19200 "blci\t{%1, %0|%0, %1}"
19201 [(set_attr "type" "bitmanip")
19202 (set_attr "mode" "<MODE>")])
19204 (define_insn "*tbm_blcic_<mode>"
19205 [(set (match_operand:SWI48 0 "register_operand" "=r")
19208 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19212 (clobber (reg:CC FLAGS_REG))]
19214 "blcic\t{%1, %0|%0, %1}"
19215 [(set_attr "type" "bitmanip")
19216 (set_attr "mode" "<MODE>")])
19218 (define_insn "*tbm_blcmsk_<mode>"
19219 [(set (match_operand:SWI48 0 "register_operand" "=r")
19222 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19225 (clobber (reg:CC FLAGS_REG))]
19227 "blcmsk\t{%1, %0|%0, %1}"
19228 [(set_attr "type" "bitmanip")
19229 (set_attr "mode" "<MODE>")])
19231 (define_insn "*tbm_blcs_<mode>"
19232 [(set (match_operand:SWI48 0 "register_operand" "=r")
19235 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19238 (clobber (reg:CC FLAGS_REG))]
19240 "blcs\t{%1, %0|%0, %1}"
19241 [(set_attr "type" "bitmanip")
19242 (set_attr "mode" "<MODE>")])
19244 (define_insn "*tbm_blsfill_<mode>"
19245 [(set (match_operand:SWI48 0 "register_operand" "=r")
19248 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19251 (clobber (reg:CC FLAGS_REG))]
19253 "blsfill\t{%1, %0|%0, %1}"
19254 [(set_attr "type" "bitmanip")
19255 (set_attr "mode" "<MODE>")])
19257 (define_insn "*tbm_blsic_<mode>"
19258 [(set (match_operand:SWI48 0 "register_operand" "=r")
19261 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19265 (clobber (reg:CC FLAGS_REG))]
19267 "blsic\t{%1, %0|%0, %1}"
19268 [(set_attr "type" "bitmanip")
19269 (set_attr "mode" "<MODE>")])
19271 (define_insn "*tbm_t1mskc_<mode>"
19272 [(set (match_operand:SWI48 0 "register_operand" "=r")
19275 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19279 (clobber (reg:CC FLAGS_REG))]
19281 "t1mskc\t{%1, %0|%0, %1}"
19282 [(set_attr "type" "bitmanip")
19283 (set_attr "mode" "<MODE>")])
19285 (define_insn "*tbm_tzmsk_<mode>"
19286 [(set (match_operand:SWI48 0 "register_operand" "=r")
19289 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19293 (clobber (reg:CC FLAGS_REG))]
19295 "tzmsk\t{%1, %0|%0, %1}"
19296 [(set_attr "type" "bitmanip")
19297 (set_attr "mode" "<MODE>")])
19299 (define_insn_and_split "popcount<mode>2"
19300 [(set (match_operand:SWI48 0 "register_operand" "=r")
19302 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
19303 (clobber (reg:CC FLAGS_REG))]
19307 return "popcnt\t{%1, %0|%0, %1}";
19309 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
19312 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
19313 && optimize_function_for_speed_p (cfun)
19314 && !reg_mentioned_p (operands[0], operands[1])"
19316 [(set (match_dup 0)
19317 (popcount:SWI48 (match_dup 1)))
19318 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
19319 (clobber (reg:CC FLAGS_REG))])]
19320 "ix86_expand_clear (operands[0]);"
19321 [(set_attr "prefix_rep" "1")
19322 (set_attr "type" "bitmanip")
19323 (set_attr "mode" "<MODE>")])
19325 ; False dependency happens when destination is only updated by tzcnt,
19326 ; lzcnt or popcnt. There is no false dependency when destination is
19327 ; also used in source.
19328 (define_insn "*popcount<mode>2_falsedep"
19329 [(set (match_operand:SWI48 0 "register_operand" "=r")
19331 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
19332 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
19333 UNSPEC_INSN_FALSE_DEP)
19334 (clobber (reg:CC FLAGS_REG))]
19338 return "popcnt\t{%1, %0|%0, %1}";
19340 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
19343 [(set_attr "prefix_rep" "1")
19344 (set_attr "type" "bitmanip")
19345 (set_attr "mode" "<MODE>")])
19347 (define_insn_and_split "*popcountsi2_zext"
19348 [(set (match_operand:DI 0 "register_operand" "=r")
19352 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
19354 (clobber (reg:CC FLAGS_REG))]
19355 "TARGET_POPCNT && TARGET_64BIT"
19358 return "popcnt\t{%1, %k0|%k0, %1}";
19360 return "popcnt{l}\t{%1, %k0|%k0, %1}";
19363 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
19364 && optimize_function_for_speed_p (cfun)
19365 && !reg_mentioned_p (operands[0], operands[1])"
19367 [(set (match_dup 0)
19368 (and:DI (subreg:DI (popcount:SI (match_dup 1)) 0) (const_int 63)))
19369 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
19370 (clobber (reg:CC FLAGS_REG))])]
19371 "ix86_expand_clear (operands[0]);"
19372 [(set_attr "prefix_rep" "1")
19373 (set_attr "type" "bitmanip")
19374 (set_attr "mode" "SI")])
19376 ; False dependency happens when destination is only updated by tzcnt,
19377 ; lzcnt or popcnt. There is no false dependency when destination is
19378 ; also used in source.
19379 (define_insn "*popcountsi2_zext_falsedep"
19380 [(set (match_operand:DI 0 "register_operand" "=r")
19384 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
19386 (unspec [(match_operand:DI 2 "register_operand" "0")]
19387 UNSPEC_INSN_FALSE_DEP)
19388 (clobber (reg:CC FLAGS_REG))]
19389 "TARGET_POPCNT && TARGET_64BIT"
19392 return "popcnt\t{%1, %k0|%k0, %1}";
19394 return "popcnt{l}\t{%1, %k0|%k0, %1}";
19397 [(set_attr "prefix_rep" "1")
19398 (set_attr "type" "bitmanip")
19399 (set_attr "mode" "SI")])
19401 (define_insn_and_split "*popcountsi2_zext_2"
19402 [(set (match_operand:DI 0 "register_operand" "=r")
19404 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
19405 (clobber (reg:CC FLAGS_REG))]
19406 "TARGET_POPCNT && TARGET_64BIT"
19409 return "popcnt\t{%1, %k0|%k0, %1}";
19411 return "popcnt{l}\t{%1, %k0|%k0, %1}";
19414 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
19415 && optimize_function_for_speed_p (cfun)
19416 && !reg_mentioned_p (operands[0], operands[1])"
19418 [(set (match_dup 0)
19419 (zero_extend:DI (popcount:SI (match_dup 1))))
19420 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
19421 (clobber (reg:CC FLAGS_REG))])]
19422 "ix86_expand_clear (operands[0]);"
19423 [(set_attr "prefix_rep" "1")
19424 (set_attr "type" "bitmanip")
19425 (set_attr "mode" "SI")])
19427 ; False dependency happens when destination is only updated by tzcnt,
19428 ; lzcnt or popcnt. There is no false dependency when destination is
19429 ; also used in source.
19430 (define_insn "*popcountsi2_zext_2_falsedep"
19431 [(set (match_operand:DI 0 "register_operand" "=r")
19433 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
19434 (unspec [(match_operand:DI 2 "register_operand" "0")]
19435 UNSPEC_INSN_FALSE_DEP)
19436 (clobber (reg:CC FLAGS_REG))]
19437 "TARGET_POPCNT && TARGET_64BIT"
19440 return "popcnt\t{%1, %k0|%k0, %1}";
19442 return "popcnt{l}\t{%1, %k0|%k0, %1}";
19445 [(set_attr "prefix_rep" "1")
19446 (set_attr "type" "bitmanip")
19447 (set_attr "mode" "SI")])
19449 (define_insn_and_split "*popcounthi2_1"
19450 [(set (match_operand:SI 0 "register_operand")
19452 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
19453 (clobber (reg:CC FLAGS_REG))]
19455 && ix86_pre_reload_split ()"
19460 rtx tmp = gen_reg_rtx (HImode);
19462 emit_insn (gen_popcounthi2 (tmp, operands[1]));
19463 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
19467 (define_insn_and_split "*popcounthi2_2"
19468 [(set (match_operand:SI 0 "register_operand")
19470 (popcount:HI (match_operand:HI 1 "nonimmediate_operand"))))
19471 (clobber (reg:CC FLAGS_REG))]
19473 && ix86_pre_reload_split ()"
19478 rtx tmp = gen_reg_rtx (HImode);
19480 emit_insn (gen_popcounthi2 (tmp, operands[1]));
19481 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
19485 (define_insn "popcounthi2"
19486 [(set (match_operand:HI 0 "register_operand" "=r")
19488 (match_operand:HI 1 "nonimmediate_operand" "rm")))
19489 (clobber (reg:CC FLAGS_REG))]
19493 return "popcnt\t{%1, %0|%0, %1}";
19495 return "popcnt{w}\t{%1, %0|%0, %1}";
19498 [(set_attr "prefix_rep" "1")
19499 (set_attr "type" "bitmanip")
19500 (set_attr "mode" "HI")])
19502 (define_expand "bswapdi2"
19503 [(set (match_operand:DI 0 "register_operand")
19504 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
19508 operands[1] = force_reg (DImode, operands[1]);
19511 (define_expand "bswapsi2"
19512 [(set (match_operand:SI 0 "register_operand")
19513 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
19518 else if (TARGET_BSWAP)
19519 operands[1] = force_reg (SImode, operands[1]);
19522 rtx x = operands[0];
19524 emit_move_insn (x, operands[1]);
19525 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
19526 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
19527 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
19532 (define_insn "*bswap<mode>2_movbe"
19533 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
19534 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
19536 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
19539 movbe{<imodesuffix>}\t{%1, %0|%0, %1}
19540 movbe{<imodesuffix>}\t{%1, %0|%0, %1}"
19541 [(set_attr "type" "bitmanip,imov,imov")
19542 (set_attr "modrm" "0,1,1")
19543 (set_attr "prefix_0f" "*,1,1")
19544 (set_attr "prefix_extra" "*,1,1")
19545 (set_attr "mode" "<MODE>")])
19547 (define_insn "*bswap<mode>2"
19548 [(set (match_operand:SWI48 0 "register_operand" "=r")
19549 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
19552 [(set_attr "type" "bitmanip")
19553 (set_attr "modrm" "0")
19554 (set_attr "mode" "<MODE>")])
19556 (define_expand "bswaphi2"
19557 [(set (match_operand:HI 0 "register_operand")
19558 (bswap:HI (match_operand:HI 1 "nonimmediate_operand")))]
19561 (define_insn "*bswaphi2_movbe"
19562 [(set (match_operand:HI 0 "nonimmediate_operand" "=Q,r,m")
19563 (bswap:HI (match_operand:HI 1 "nonimmediate_operand" "0,m,r")))]
19565 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
19567 xchg{b}\t{%h0, %b0|%b0, %h0}
19568 movbe{w}\t{%1, %0|%0, %1}
19569 movbe{w}\t{%1, %0|%0, %1}"
19570 [(set_attr "type" "imov")
19571 (set_attr "modrm" "*,1,1")
19572 (set_attr "prefix_0f" "*,1,1")
19573 (set_attr "prefix_extra" "*,1,1")
19574 (set_attr "pent_pair" "np,*,*")
19575 (set_attr "athlon_decode" "vector,*,*")
19576 (set_attr "amdfam10_decode" "double,*,*")
19577 (set_attr "bdver1_decode" "double,*,*")
19578 (set_attr "mode" "QI,HI,HI")])
19581 [(set (match_operand:HI 0 "general_reg_operand")
19582 (bswap:HI (match_dup 0)))]
19584 && !(TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))
19585 && peep2_regno_dead_p (0, FLAGS_REG)"
19586 [(parallel [(set (match_dup 0) (rotate:HI (match_dup 0) (const_int 8)))
19587 (clobber (reg:CC FLAGS_REG))])])
19589 (define_insn "bswaphi_lowpart"
19590 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
19591 (bswap:HI (match_dup 0)))
19592 (clobber (reg:CC FLAGS_REG))]
19595 xchg{b}\t{%h0, %b0|%b0, %h0}
19596 rol{w}\t{$8, %0|%0, 8}"
19597 [(set (attr "preferred_for_size")
19598 (cond [(eq_attr "alternative" "0")
19599 (symbol_ref "true")]
19600 (symbol_ref "false")))
19601 (set (attr "preferred_for_speed")
19602 (cond [(eq_attr "alternative" "0")
19603 (symbol_ref "TARGET_USE_XCHGB")]
19604 (symbol_ref "!TARGET_USE_XCHGB")))
19605 (set_attr "length" "2,4")
19606 (set_attr "mode" "QI,HI")])
19608 (define_expand "paritydi2"
19609 [(set (match_operand:DI 0 "register_operand")
19610 (parity:DI (match_operand:DI 1 "register_operand")))]
19613 rtx scratch = gen_reg_rtx (QImode);
19614 rtx hipart1 = gen_reg_rtx (SImode);
19615 rtx lopart1 = gen_reg_rtx (SImode);
19616 rtx xor1 = gen_reg_rtx (SImode);
19617 rtx shift2 = gen_reg_rtx (SImode);
19618 rtx hipart2 = gen_reg_rtx (HImode);
19619 rtx lopart2 = gen_reg_rtx (HImode);
19620 rtx xor2 = gen_reg_rtx (HImode);
19624 rtx shift1 = gen_reg_rtx (DImode);
19625 emit_insn (gen_lshrdi3 (shift1, operands[1], GEN_INT (32)));
19626 emit_move_insn (hipart1, gen_lowpart (SImode, shift1));
19629 emit_move_insn (hipart1, gen_highpart (SImode, operands[1]));
19631 emit_move_insn (lopart1, gen_lowpart (SImode, operands[1]));
19632 emit_insn (gen_xorsi3 (xor1, hipart1, lopart1));
19634 emit_insn (gen_lshrsi3 (shift2, xor1, GEN_INT (16)));
19635 emit_move_insn (hipart2, gen_lowpart (HImode, shift2));
19636 emit_move_insn (lopart2, gen_lowpart (HImode, xor1));
19637 emit_insn (gen_xorhi3 (xor2, hipart2, lopart2));
19639 emit_insn (gen_parityhi2_cmp (xor2));
19641 ix86_expand_setcc (scratch, ORDERED,
19642 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19645 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
19648 rtx tmp = gen_reg_rtx (SImode);
19650 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
19651 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
19656 (define_expand "paritysi2"
19657 [(set (match_operand:SI 0 "register_operand")
19658 (parity:SI (match_operand:SI 1 "register_operand")))]
19661 rtx scratch = gen_reg_rtx (QImode);
19662 rtx shift = gen_reg_rtx (SImode);
19663 rtx hipart = gen_reg_rtx (HImode);
19664 rtx lopart = gen_reg_rtx (HImode);
19665 rtx tmp = gen_reg_rtx (HImode);
19667 emit_insn (gen_lshrsi3 (shift, operands[1], GEN_INT (16)));
19668 emit_move_insn (hipart, gen_lowpart (HImode, shift));
19669 emit_move_insn (lopart, gen_lowpart (HImode, operands[1]));
19670 emit_insn (gen_xorhi3 (tmp, hipart, lopart));
19672 emit_insn (gen_parityhi2_cmp (tmp));
19674 ix86_expand_setcc (scratch, ORDERED,
19675 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19677 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
19681 (define_expand "parityhi2"
19682 [(set (match_operand:HI 0 "register_operand")
19683 (parity:HI (match_operand:HI 1 "register_operand")))]
19686 rtx scratch = gen_reg_rtx (QImode);
19688 emit_insn (gen_parityhi2_cmp (operands[1]));
19690 ix86_expand_setcc (scratch, ORDERED,
19691 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19693 emit_insn (gen_zero_extendqihi2 (operands[0], scratch));
19697 (define_expand "parityqi2"
19698 [(set (match_operand:QI 0 "register_operand")
19699 (parity:QI (match_operand:QI 1 "register_operand")))]
19702 emit_insn (gen_parityqi2_cmp (operands[1]));
19704 ix86_expand_setcc (operands[0], ORDERED,
19705 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19709 (define_insn "parityhi2_cmp"
19710 [(set (reg:CC FLAGS_REG)
19711 (unspec:CC [(match_operand:HI 0 "register_operand" "+Q")]
19713 (clobber (match_dup 0))]
19715 "xor{b}\t{%h0, %b0|%b0, %h0}"
19716 [(set_attr "length" "2")
19717 (set_attr "mode" "QI")])
19719 (define_insn "parityqi2_cmp"
19720 [(set (reg:CC FLAGS_REG)
19721 (unspec:CC [(match_operand:QI 0 "register_operand" "q")]
19725 [(set_attr "mode" "QI")])
19727 ;; Replace zero_extend:HI followed by parityhi2_cmp with parityqi2_cmp
19729 [(set (match_operand:HI 0 "register_operand")
19730 (zero_extend:HI (match_operand:QI 1 "general_reg_operand")))
19731 (parallel [(set (reg:CC FLAGS_REG)
19732 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
19733 (clobber (match_dup 0))])]
19735 [(set (reg:CC FLAGS_REG)
19736 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))])
19738 ;; Eliminate QImode popcount&1 using parity flag
19740 [(set (match_operand:SI 0 "register_operand")
19741 (zero_extend:SI (match_operand:QI 1 "general_reg_operand")))
19742 (parallel [(set (match_operand:SI 2 "register_operand")
19743 (popcount:SI (match_dup 0)))
19744 (clobber (reg:CC FLAGS_REG))])
19745 (set (reg:CCZ FLAGS_REG)
19746 (compare:CCZ (and:QI (match_operand:QI 3 "register_operand")
19749 (set (pc) (if_then_else (match_operator 4 "bt_comparison_operator"
19750 [(reg:CCZ FLAGS_REG)
19752 (label_ref (match_operand 5))
19754 "REGNO (operands[2]) == REGNO (operands[3])
19755 && peep2_reg_dead_p (3, operands[0])
19756 && peep2_reg_dead_p (3, operands[2])
19757 && peep2_regno_dead_p (4, FLAGS_REG)"
19758 [(set (reg:CC FLAGS_REG)
19759 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
19760 (set (pc) (if_then_else (match_op_dup 4 [(reg:CC FLAGS_REG)
19762 (label_ref (match_dup 5))
19765 operands[4] = shallow_copy_rtx (operands[4]);
19766 PUT_CODE (operands[4], GET_CODE (operands[4]) == EQ ? UNORDERED : ORDERED);
19769 ;; Eliminate HImode popcount&1 using parity flag
19771 [(match_scratch:HI 0 "Q")
19772 (parallel [(set (match_operand:HI 1 "register_operand")
19774 (match_operand:HI 2 "nonimmediate_operand")))
19775 (clobber (reg:CC FLAGS_REG))])
19776 (set (match_operand 3 "register_operand")
19777 (zero_extend (match_dup 1)))
19778 (set (reg:CCZ FLAGS_REG)
19779 (compare:CCZ (and:QI (match_operand:QI 4 "register_operand")
19782 (set (pc) (if_then_else (match_operator 5 "bt_comparison_operator"
19783 [(reg:CCZ FLAGS_REG)
19785 (label_ref (match_operand 6))
19787 "REGNO (operands[3]) == REGNO (operands[4])
19788 && peep2_reg_dead_p (3, operands[1])
19789 && peep2_reg_dead_p (3, operands[3])
19790 && peep2_regno_dead_p (4, FLAGS_REG)"
19791 [(set (match_dup 0) (match_dup 2))
19792 (parallel [(set (reg:CC FLAGS_REG)
19793 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
19794 (clobber (match_dup 0))])
19795 (set (pc) (if_then_else (match_op_dup 5 [(reg:CC FLAGS_REG)
19797 (label_ref (match_dup 6))
19800 operands[5] = shallow_copy_rtx (operands[5]);
19801 PUT_CODE (operands[5], GET_CODE (operands[5]) == EQ ? UNORDERED : ORDERED);
19804 ;; Eliminate HImode popcount&1 using parity flag (variant 2)
19806 [(match_scratch:HI 0 "Q")
19807 (parallel [(set (match_operand:HI 1 "register_operand")
19809 (match_operand:HI 2 "nonimmediate_operand")))
19810 (clobber (reg:CC FLAGS_REG))])
19811 (set (reg:CCZ FLAGS_REG)
19812 (compare:CCZ (and:QI (match_operand:QI 3 "register_operand")
19815 (set (pc) (if_then_else (match_operator 4 "bt_comparison_operator"
19816 [(reg:CCZ FLAGS_REG)
19818 (label_ref (match_operand 5))
19820 "REGNO (operands[1]) == REGNO (operands[3])
19821 && peep2_reg_dead_p (2, operands[1])
19822 && peep2_reg_dead_p (2, operands[3])
19823 && peep2_regno_dead_p (3, FLAGS_REG)"
19824 [(set (match_dup 0) (match_dup 2))
19825 (parallel [(set (reg:CC FLAGS_REG)
19826 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
19827 (clobber (match_dup 0))])
19828 (set (pc) (if_then_else (match_op_dup 4 [(reg:CC FLAGS_REG)
19830 (label_ref (match_dup 5))
19833 operands[4] = shallow_copy_rtx (operands[4]);
19834 PUT_CODE (operands[4], GET_CODE (operands[4]) == EQ ? UNORDERED : ORDERED);
19838 ;; Thread-local storage patterns for ELF.
19840 ;; Note that these code sequences must appear exactly as shown
19841 ;; in order to allow linker relaxation.
19843 (define_insn "*tls_global_dynamic_32_gnu"
19844 [(set (match_operand:SI 0 "register_operand" "=a")
19846 [(match_operand:SI 1 "register_operand" "Yb")
19847 (match_operand 2 "tls_symbolic_operand")
19848 (match_operand 3 "constant_call_address_operand" "Bz")
19851 (clobber (match_scratch:SI 4 "=d"))
19852 (clobber (match_scratch:SI 5 "=c"))
19853 (clobber (reg:CC FLAGS_REG))]
19854 "!TARGET_64BIT && TARGET_GNU_TLS"
19856 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19858 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
19861 ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
19862 if (TARGET_SUN_TLS)
19863 #ifdef HAVE_AS_IX86_TLSGDPLT
19864 return "call\t%a2@tlsgdplt";
19866 return "call\t%p3@plt";
19868 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19869 return "call\t%P3";
19870 return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
19872 [(set_attr "type" "multi")
19873 (set_attr "length" "12")])
19875 (define_expand "tls_global_dynamic_32"
19877 [(set (match_operand:SI 0 "register_operand")
19878 (unspec:SI [(match_operand:SI 2 "register_operand")
19879 (match_operand 1 "tls_symbolic_operand")
19880 (match_operand 3 "constant_call_address_operand")
19883 (clobber (scratch:SI))
19884 (clobber (scratch:SI))
19885 (clobber (reg:CC FLAGS_REG))])]
19887 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
19889 (define_insn "*tls_global_dynamic_64_<mode>"
19890 [(set (match_operand:P 0 "register_operand" "=a")
19892 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
19893 (match_operand 3)))
19894 (unspec:P [(match_operand 1 "tls_symbolic_operand")
19900 /* The .loc directive has effect for 'the immediately following assembly
19901 instruction'. So for a sequence:
19905 the 'immediately following assembly instruction' is insn1.
19906 We want to emit an insn prefix here, but if we use .byte (as shown in
19907 'ELF Handling For Thread-Local Storage'), a preceding .loc will point
19908 inside the insn sequence, rather than to the start. After relaxation
19909 of the sequence by the linker, the .loc might point inside an insn.
19910 Use data16 prefix instead, which doesn't have this problem. */
19911 fputs ("\tdata16", asm_out_file);
19913 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
19914 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19915 fputs (ASM_SHORT "0x6666\n", asm_out_file);
19917 fputs (ASM_BYTE "0x66\n", asm_out_file);
19918 fputs ("\trex64\n", asm_out_file);
19919 if (TARGET_SUN_TLS)
19920 return "call\t%p2@plt";
19921 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19922 return "call\t%P2";
19923 return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
19925 [(set_attr "type" "multi")
19926 (set (attr "length")
19927 (symbol_ref "TARGET_X32 ? 15 : 16"))])
19929 (define_insn "*tls_global_dynamic_64_largepic"
19930 [(set (match_operand:DI 0 "register_operand" "=a")
19932 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
19933 (match_operand:DI 3 "immediate_operand" "i")))
19934 (match_operand 4)))
19935 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
19938 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
19939 && GET_CODE (operands[3]) == CONST
19940 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
19941 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
19944 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
19945 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
19946 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
19947 return "call\t{*%%rax|rax}";
19949 [(set_attr "type" "multi")
19950 (set_attr "length" "22")])
19952 (define_expand "@tls_global_dynamic_64_<mode>"
19954 [(set (match_operand:P 0 "register_operand")
19956 (mem:QI (match_operand 2))
19958 (unspec:P [(match_operand 1 "tls_symbolic_operand")
19962 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
19964 (define_insn "*tls_local_dynamic_base_32_gnu"
19965 [(set (match_operand:SI 0 "register_operand" "=a")
19967 [(match_operand:SI 1 "register_operand" "Yb")
19968 (match_operand 2 "constant_call_address_operand" "Bz")
19970 UNSPEC_TLS_LD_BASE))
19971 (clobber (match_scratch:SI 3 "=d"))
19972 (clobber (match_scratch:SI 4 "=c"))
19973 (clobber (reg:CC FLAGS_REG))]
19974 "!TARGET_64BIT && TARGET_GNU_TLS"
19977 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
19978 if (TARGET_SUN_TLS)
19980 if (HAVE_AS_IX86_TLSLDMPLT)
19981 return "call\t%&@tlsldmplt";
19983 return "call\t%p2@plt";
19985 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19986 return "call\t%P2";
19987 return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
19989 [(set_attr "type" "multi")
19990 (set_attr "length" "11")])
19992 (define_expand "tls_local_dynamic_base_32"
19994 [(set (match_operand:SI 0 "register_operand")
19996 [(match_operand:SI 1 "register_operand")
19997 (match_operand 2 "constant_call_address_operand")
19999 UNSPEC_TLS_LD_BASE))
20000 (clobber (scratch:SI))
20001 (clobber (scratch:SI))
20002 (clobber (reg:CC FLAGS_REG))])]
20004 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
20006 (define_insn "*tls_local_dynamic_base_64_<mode>"
20007 [(set (match_operand:P 0 "register_operand" "=a")
20009 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
20010 (match_operand 2)))
20011 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
20015 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
20016 if (TARGET_SUN_TLS)
20017 return "call\t%p1@plt";
20018 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
20019 return "call\t%P1";
20020 return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
20022 [(set_attr "type" "multi")
20023 (set_attr "length" "12")])
20025 (define_insn "*tls_local_dynamic_base_64_largepic"
20026 [(set (match_operand:DI 0 "register_operand" "=a")
20028 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
20029 (match_operand:DI 2 "immediate_operand" "i")))
20030 (match_operand 3)))
20031 (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
20032 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
20033 && GET_CODE (operands[2]) == CONST
20034 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
20035 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
20038 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
20039 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
20040 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
20041 return "call\t{*%%rax|rax}";
20043 [(set_attr "type" "multi")
20044 (set_attr "length" "22")])
20046 (define_expand "@tls_local_dynamic_base_64_<mode>"
20048 [(set (match_operand:P 0 "register_operand")
20050 (mem:QI (match_operand 1))
20052 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
20054 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
20056 ;; Local dynamic of a single variable is a lose. Show combine how
20057 ;; to convert that back to global dynamic.
20059 (define_insn_and_split "*tls_local_dynamic_32_once"
20060 [(set (match_operand:SI 0 "register_operand" "=a")
20062 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
20063 (match_operand 2 "constant_call_address_operand" "Bz")
20065 UNSPEC_TLS_LD_BASE)
20066 (const:SI (unspec:SI
20067 [(match_operand 3 "tls_symbolic_operand")]
20069 (clobber (match_scratch:SI 4 "=d"))
20070 (clobber (match_scratch:SI 5 "=c"))
20071 (clobber (reg:CC FLAGS_REG))]
20076 [(set (match_dup 0)
20077 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
20080 (clobber (match_dup 4))
20081 (clobber (match_dup 5))
20082 (clobber (reg:CC FLAGS_REG))])])
20084 ;; Load and add the thread base pointer from %<tp_seg>:0.
20085 (define_expand "get_thread_pointer<mode>"
20086 [(set (match_operand:PTR 0 "register_operand")
20087 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
20090 /* targetm is not visible in the scope of the condition. */
20091 if (!targetm.have_tls)
20092 error ("%<__builtin_thread_pointer%> is not supported on this target");
20095 (define_insn_and_split "*load_tp_<mode>"
20096 [(set (match_operand:PTR 0 "register_operand" "=r")
20097 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
20101 [(set (match_dup 0)
20104 addr_space_t as = DEFAULT_TLS_SEG_REG;
20106 operands[1] = gen_const_mem (<MODE>mode, const0_rtx);
20107 set_mem_addr_space (operands[1], as);
20110 (define_insn_and_split "*load_tp_x32_zext"
20111 [(set (match_operand:DI 0 "register_operand" "=r")
20113 (unspec:SI [(const_int 0)] UNSPEC_TP)))]
20117 [(set (match_dup 0)
20118 (zero_extend:DI (match_dup 1)))]
20120 addr_space_t as = DEFAULT_TLS_SEG_REG;
20122 operands[1] = gen_const_mem (SImode, const0_rtx);
20123 set_mem_addr_space (operands[1], as);
20126 (define_insn_and_split "*add_tp_<mode>"
20127 [(set (match_operand:PTR 0 "register_operand" "=r")
20129 (unspec:PTR [(const_int 0)] UNSPEC_TP)
20130 (match_operand:PTR 1 "register_operand" "0")))
20131 (clobber (reg:CC FLAGS_REG))]
20136 [(set (match_dup 0)
20137 (plus:PTR (match_dup 1) (match_dup 2)))
20138 (clobber (reg:CC FLAGS_REG))])]
20140 addr_space_t as = DEFAULT_TLS_SEG_REG;
20142 operands[2] = gen_const_mem (<MODE>mode, const0_rtx);
20143 set_mem_addr_space (operands[2], as);
20146 (define_insn_and_split "*add_tp_x32_zext"
20147 [(set (match_operand:DI 0 "register_operand" "=r")
20149 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
20150 (match_operand:SI 1 "register_operand" "0"))))
20151 (clobber (reg:CC FLAGS_REG))]
20156 [(set (match_dup 0)
20158 (plus:SI (match_dup 1) (match_dup 2))))
20159 (clobber (reg:CC FLAGS_REG))])]
20161 addr_space_t as = DEFAULT_TLS_SEG_REG;
20163 operands[2] = gen_const_mem (SImode, const0_rtx);
20164 set_mem_addr_space (operands[2], as);
20167 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
20168 ;; %rax as destination of the initial executable code sequence.
20169 (define_insn "tls_initial_exec_64_sun"
20170 [(set (match_operand:DI 0 "register_operand" "=a")
20172 [(match_operand 1 "tls_symbolic_operand")]
20173 UNSPEC_TLS_IE_SUN))
20174 (clobber (reg:CC FLAGS_REG))]
20175 "TARGET_64BIT && TARGET_SUN_TLS"
20178 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
20179 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
20181 [(set_attr "type" "multi")])
20183 ;; GNU2 TLS patterns can be split.
20185 (define_expand "tls_dynamic_gnu2_32"
20186 [(set (match_dup 3)
20187 (plus:SI (match_operand:SI 2 "register_operand")
20189 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
20192 [(set (match_operand:SI 0 "register_operand")
20193 (unspec:SI [(match_dup 1) (match_dup 3)
20194 (match_dup 2) (reg:SI SP_REG)]
20196 (clobber (reg:CC FLAGS_REG))])]
20197 "!TARGET_64BIT && TARGET_GNU2_TLS"
20199 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
20200 ix86_tls_descriptor_calls_expanded_in_cfun = true;
20203 (define_insn "*tls_dynamic_gnu2_lea_32"
20204 [(set (match_operand:SI 0 "register_operand" "=r")
20205 (plus:SI (match_operand:SI 1 "register_operand" "b")
20207 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
20208 UNSPEC_TLSDESC))))]
20209 "!TARGET_64BIT && TARGET_GNU2_TLS"
20210 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
20211 [(set_attr "type" "lea")
20212 (set_attr "mode" "SI")
20213 (set_attr "length" "6")
20214 (set_attr "length_address" "4")])
20216 (define_insn "*tls_dynamic_gnu2_call_32"
20217 [(set (match_operand:SI 0 "register_operand" "=a")
20218 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
20219 (match_operand:SI 2 "register_operand" "0")
20220 ;; we have to make sure %ebx still points to the GOT
20221 (match_operand:SI 3 "register_operand" "b")
20224 (clobber (reg:CC FLAGS_REG))]
20225 "!TARGET_64BIT && TARGET_GNU2_TLS"
20226 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
20227 [(set_attr "type" "call")
20228 (set_attr "length" "2")
20229 (set_attr "length_address" "0")])
20231 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
20232 [(set (match_operand:SI 0 "register_operand" "=&a")
20234 (unspec:SI [(match_operand 3 "tls_modbase_operand")
20235 (match_operand:SI 4)
20236 (match_operand:SI 2 "register_operand" "b")
20239 (const:SI (unspec:SI
20240 [(match_operand 1 "tls_symbolic_operand")]
20242 (clobber (reg:CC FLAGS_REG))]
20243 "!TARGET_64BIT && TARGET_GNU2_TLS"
20246 [(set (match_dup 0) (match_dup 5))]
20248 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
20249 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
20252 (define_expand "@tls_dynamic_gnu2_64_<mode>"
20253 [(set (match_dup 2)
20254 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")]
20257 [(set (match_operand:PTR 0 "register_operand")
20258 (unspec:PTR [(match_dup 1) (match_dup 2) (reg:PTR SP_REG)]
20260 (clobber (reg:CC FLAGS_REG))])]
20261 "TARGET_64BIT && TARGET_GNU2_TLS"
20263 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (ptr_mode) : operands[0];
20264 ix86_tls_descriptor_calls_expanded_in_cfun = true;
20267 (define_insn "*tls_dynamic_gnu2_lea_64_<mode>"
20268 [(set (match_operand:PTR 0 "register_operand" "=r")
20269 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")]
20271 "TARGET_64BIT && TARGET_GNU2_TLS"
20272 "lea%z0\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
20273 [(set_attr "type" "lea")
20274 (set_attr "mode" "<MODE>")
20275 (set_attr "length" "7")
20276 (set_attr "length_address" "4")])
20278 (define_insn "*tls_dynamic_gnu2_call_64_<mode>"
20279 [(set (match_operand:PTR 0 "register_operand" "=a")
20280 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")
20281 (match_operand:PTR 2 "register_operand" "0")
20284 (clobber (reg:CC FLAGS_REG))]
20285 "TARGET_64BIT && TARGET_GNU2_TLS"
20286 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
20287 [(set_attr "type" "call")
20288 (set_attr "length" "2")
20289 (set_attr "length_address" "0")])
20291 (define_insn_and_split "*tls_dynamic_gnu2_combine_64_<mode>"
20292 [(set (match_operand:PTR 0 "register_operand" "=&a")
20294 (unspec:PTR [(match_operand 2 "tls_modbase_operand")
20295 (match_operand:PTR 3)
20298 (const:PTR (unspec:PTR
20299 [(match_operand 1 "tls_symbolic_operand")]
20301 (clobber (reg:CC FLAGS_REG))]
20302 "TARGET_64BIT && TARGET_GNU2_TLS"
20305 [(set (match_dup 0) (match_dup 4))]
20307 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (ptr_mode) : operands[0];
20308 emit_insn (gen_tls_dynamic_gnu2_64 (ptr_mode, operands[4], operands[1]));
20312 [(match_operand 0 "tls_address_pattern")]
20313 "TARGET_TLS_DIRECT_SEG_REFS"
20315 "operands[0] = ix86_rewrite_tls_address (operands[0]);")
20318 ;; These patterns match the binary 387 instructions for addM3, subM3,
20319 ;; mulM3 and divM3. There are three patterns for each of DFmode and
20320 ;; SFmode. The first is the normal insn, the second the same insn but
20321 ;; with one operand a conversion, and the third the same insn but with
20322 ;; the other operand a conversion. The conversion may be SFmode or
20323 ;; SImode if the target mode DFmode, but only SImode if the target mode
20326 ;; Gcc is slightly more smart about handling normal two address instructions
20327 ;; so use special patterns for add and mull.
20329 (define_insn "*fop_xf_comm_i387"
20330 [(set (match_operand:XF 0 "register_operand" "=f")
20331 (match_operator:XF 3 "binary_fp_operator"
20332 [(match_operand:XF 1 "register_operand" "%0")
20333 (match_operand:XF 2 "register_operand" "f")]))]
20335 && COMMUTATIVE_ARITH_P (operands[3])"
20336 "* return output_387_binary_op (insn, operands);"
20337 [(set (attr "type")
20338 (if_then_else (match_operand:XF 3 "mult_operator")
20339 (const_string "fmul")
20340 (const_string "fop")))
20341 (set_attr "mode" "XF")])
20343 (define_insn "*fop_<mode>_comm"
20344 [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
20345 (match_operator:MODEF 3 "binary_fp_operator"
20346 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
20347 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
20348 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20349 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
20350 && COMMUTATIVE_ARITH_P (operands[3])
20351 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
20352 "* return output_387_binary_op (insn, operands);"
20353 [(set (attr "type")
20354 (if_then_else (eq_attr "alternative" "1,2")
20355 (if_then_else (match_operand:MODEF 3 "mult_operator")
20356 (const_string "ssemul")
20357 (const_string "sseadd"))
20358 (if_then_else (match_operand:MODEF 3 "mult_operator")
20359 (const_string "fmul")
20360 (const_string "fop"))))
20361 (set_attr "isa" "*,noavx,avx")
20362 (set_attr "prefix" "orig,orig,vex")
20363 (set_attr "mode" "<MODE>")
20364 (set (attr "enabled")
20366 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
20368 (eq_attr "alternative" "0")
20369 (symbol_ref "TARGET_MIX_SSE_I387
20370 && X87_ENABLE_ARITH (<MODE>mode)")
20371 (const_string "*"))
20373 (eq_attr "alternative" "0")
20374 (symbol_ref "true")
20375 (symbol_ref "false"))))])
20377 (define_insn "*<insn>hf"
20378 [(set (match_operand:HF 0 "register_operand" "=v")
20379 (plusminusmultdiv:HF
20380 (match_operand:HF 1 "nonimmediate_operand" "<comm>v")
20381 (match_operand:HF 2 "nonimmediate_operand" "vm")))]
20383 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
20384 "v<insn>sh\t{%2, %1, %0|%0, %1, %2}"
20385 [(set_attr "prefix" "evex")
20386 (set_attr "mode" "HF")])
20388 (define_insn "*rcpsf2_sse"
20389 [(set (match_operand:SF 0 "register_operand" "=x,x,x,x")
20390 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m,ja")]
20392 "TARGET_SSE && TARGET_SSE_MATH"
20394 %vrcpss\t{%d1, %0|%0, %d1}
20395 %vrcpss\t{%d1, %0|%0, %d1}
20396 rcpss\t{%1, %d0|%d0, %1}
20397 vrcpss\t{%1, %d0|%d0, %1}"
20398 [(set_attr "isa" "*,*,noavx,avx")
20399 (set_attr "addr" "*,*,*,gpr16")
20400 (set_attr "type" "sse")
20401 (set_attr "atom_sse_attr" "rcp")
20402 (set_attr "btver2_sse_attr" "rcp")
20403 (set_attr "prefix" "maybe_vex")
20404 (set_attr "mode" "SF")
20405 (set_attr "avx_partial_xmm_update" "false,false,true,true")
20406 (set (attr "preferred_for_speed")
20407 (cond [(match_test "TARGET_AVX")
20408 (symbol_ref "true")
20409 (eq_attr "alternative" "1,2,3")
20410 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
20412 (symbol_ref "true")))])
20414 (define_insn "rcphf2"
20415 [(set (match_operand:HF 0 "register_operand" "=v,v")
20416 (unspec:HF [(match_operand:HF 1 "nonimmediate_operand" "v,m")]
20418 "TARGET_AVX512FP16"
20420 vrcpsh\t{%d1, %0|%0, %d1}
20421 vrcpsh\t{%1, %d0|%d0, %1}"
20422 [(set_attr "type" "sse")
20423 (set_attr "prefix" "evex")
20424 (set_attr "mode" "HF")
20425 (set_attr "avx_partial_xmm_update" "false,true")])
20427 (define_insn "*fop_xf_1_i387"
20428 [(set (match_operand:XF 0 "register_operand" "=f,f")
20429 (match_operator:XF 3 "binary_fp_operator"
20430 [(match_operand:XF 1 "register_operand" "0,f")
20431 (match_operand:XF 2 "register_operand" "f,0")]))]
20433 && !COMMUTATIVE_ARITH_P (operands[3])"
20434 "* return output_387_binary_op (insn, operands);"
20435 [(set (attr "type")
20436 (if_then_else (match_operand:XF 3 "div_operator")
20437 (const_string "fdiv")
20438 (const_string "fop")))
20439 (set_attr "mode" "XF")])
20441 (define_insn "*fop_<mode>_1"
20442 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
20443 (match_operator:MODEF 3 "binary_fp_operator"
20444 [(match_operand:MODEF 1
20445 "x87nonimm_ssenomem_operand" "0,fm,0,v")
20446 (match_operand:MODEF 2
20447 "nonimmediate_operand" "fm,0,xm,vm")]))]
20448 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20449 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
20450 && !COMMUTATIVE_ARITH_P (operands[3])
20451 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
20452 "* return output_387_binary_op (insn, operands);"
20453 [(set (attr "type")
20454 (if_then_else (eq_attr "alternative" "2,3")
20455 (if_then_else (match_operand:MODEF 3 "div_operator")
20456 (const_string "ssediv")
20457 (const_string "sseadd"))
20458 (if_then_else (match_operand:MODEF 3 "div_operator")
20459 (const_string "fdiv")
20460 (const_string "fop"))))
20461 (set_attr "isa" "*,*,noavx,avx")
20462 (set_attr "prefix" "orig,orig,orig,vex")
20463 (set_attr "mode" "<MODE>")
20464 (set (attr "enabled")
20466 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
20468 (eq_attr "alternative" "0,1")
20469 (symbol_ref "TARGET_MIX_SSE_I387
20470 && X87_ENABLE_ARITH (<MODE>mode)")
20471 (const_string "*"))
20473 (eq_attr "alternative" "0,1")
20474 (symbol_ref "true")
20475 (symbol_ref "false"))))])
20477 (define_insn "*fop_<X87MODEF:mode>_2_i387"
20478 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
20479 (match_operator:X87MODEF 3 "binary_fp_operator"
20481 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
20482 (match_operand:X87MODEF 2 "register_operand" "0")]))]
20483 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
20484 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
20485 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
20486 || optimize_function_for_size_p (cfun))"
20487 "* return output_387_binary_op (insn, operands);"
20488 [(set (attr "type")
20489 (cond [(match_operand:X87MODEF 3 "mult_operator")
20490 (const_string "fmul")
20491 (match_operand:X87MODEF 3 "div_operator")
20492 (const_string "fdiv")
20494 (const_string "fop")))
20495 (set_attr "fp_int_src" "true")
20496 (set_attr "mode" "<SWI24:MODE>")])
20498 (define_insn "*fop_<X87MODEF:mode>_3_i387"
20499 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
20500 (match_operator:X87MODEF 3 "binary_fp_operator"
20501 [(match_operand:X87MODEF 1 "register_operand" "0")
20503 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
20504 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
20505 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
20506 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
20507 || optimize_function_for_size_p (cfun))"
20508 "* return output_387_binary_op (insn, operands);"
20509 [(set (attr "type")
20510 (cond [(match_operand:X87MODEF 3 "mult_operator")
20511 (const_string "fmul")
20512 (match_operand:X87MODEF 3 "div_operator")
20513 (const_string "fdiv")
20515 (const_string "fop")))
20516 (set_attr "fp_int_src" "true")
20517 (set_attr "mode" "<SWI24:MODE>")])
20519 (define_insn "*fop_xf_4_i387"
20520 [(set (match_operand:XF 0 "register_operand" "=f,f")
20521 (match_operator:XF 3 "binary_fp_operator"
20523 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
20524 (match_operand:XF 2 "register_operand" "0,f")]))]
20526 "* return output_387_binary_op (insn, operands);"
20527 [(set (attr "type")
20528 (cond [(match_operand:XF 3 "mult_operator")
20529 (const_string "fmul")
20530 (match_operand:XF 3 "div_operator")
20531 (const_string "fdiv")
20533 (const_string "fop")))
20534 (set_attr "mode" "<MODE>")])
20536 (define_insn "*fop_df_4_i387"
20537 [(set (match_operand:DF 0 "register_operand" "=f,f")
20538 (match_operator:DF 3 "binary_fp_operator"
20540 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
20541 (match_operand:DF 2 "register_operand" "0,f")]))]
20542 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
20543 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
20544 "* return output_387_binary_op (insn, operands);"
20545 [(set (attr "type")
20546 (cond [(match_operand:DF 3 "mult_operator")
20547 (const_string "fmul")
20548 (match_operand:DF 3 "div_operator")
20549 (const_string "fdiv")
20551 (const_string "fop")))
20552 (set_attr "mode" "SF")])
20554 (define_insn "*fop_xf_5_i387"
20555 [(set (match_operand:XF 0 "register_operand" "=f,f")
20556 (match_operator:XF 3 "binary_fp_operator"
20557 [(match_operand:XF 1 "register_operand" "0,f")
20559 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
20561 "* return output_387_binary_op (insn, operands);"
20562 [(set (attr "type")
20563 (cond [(match_operand:XF 3 "mult_operator")
20564 (const_string "fmul")
20565 (match_operand:XF 3 "div_operator")
20566 (const_string "fdiv")
20568 (const_string "fop")))
20569 (set_attr "mode" "<MODE>")])
20571 (define_insn "*fop_df_5_i387"
20572 [(set (match_operand:DF 0 "register_operand" "=f,f")
20573 (match_operator:DF 3 "binary_fp_operator"
20574 [(match_operand:DF 1 "register_operand" "0,f")
20576 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
20577 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
20578 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
20579 "* return output_387_binary_op (insn, operands);"
20580 [(set (attr "type")
20581 (cond [(match_operand:DF 3 "mult_operator")
20582 (const_string "fmul")
20583 (match_operand:DF 3 "div_operator")
20584 (const_string "fdiv")
20586 (const_string "fop")))
20587 (set_attr "mode" "SF")])
20589 (define_insn "*fop_xf_6_i387"
20590 [(set (match_operand:XF 0 "register_operand" "=f,f")
20591 (match_operator:XF 3 "binary_fp_operator"
20593 (match_operand:MODEF 1 "register_operand" "0,f"))
20595 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
20597 "* return output_387_binary_op (insn, operands);"
20598 [(set (attr "type")
20599 (cond [(match_operand:XF 3 "mult_operator")
20600 (const_string "fmul")
20601 (match_operand:XF 3 "div_operator")
20602 (const_string "fdiv")
20604 (const_string "fop")))
20605 (set_attr "mode" "<MODE>")])
20607 (define_insn "*fop_df_6_i387"
20608 [(set (match_operand:DF 0 "register_operand" "=f,f")
20609 (match_operator:DF 3 "binary_fp_operator"
20611 (match_operand:SF 1 "register_operand" "0,f"))
20613 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
20614 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
20615 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
20616 "* return output_387_binary_op (insn, operands);"
20617 [(set (attr "type")
20618 (cond [(match_operand:DF 3 "mult_operator")
20619 (const_string "fmul")
20620 (match_operand:DF 3 "div_operator")
20621 (const_string "fdiv")
20623 (const_string "fop")))
20624 (set_attr "mode" "SF")])
20626 ;; FPU special functions.
20628 ;; This pattern implements a no-op XFmode truncation for
20629 ;; all fancy i386 XFmode math functions.
20631 (define_insn "truncxf<mode>2_i387_noop_unspec"
20632 [(set (match_operand:MODEF 0 "nonimmediate_operand" "=mf")
20633 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
20634 UNSPEC_TRUNC_NOOP))]
20635 "TARGET_USE_FANCY_MATH_387"
20636 "* return output_387_reg_move (insn, operands);"
20637 [(set_attr "type" "fmov")
20638 (set_attr "mode" "<MODE>")])
20640 (define_insn "sqrtxf2"
20641 [(set (match_operand:XF 0 "register_operand" "=f")
20642 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
20643 "TARGET_USE_FANCY_MATH_387"
20645 [(set_attr "type" "fpspc")
20646 (set_attr "mode" "XF")
20647 (set_attr "athlon_decode" "direct")
20648 (set_attr "amdfam10_decode" "direct")
20649 (set_attr "bdver1_decode" "direct")])
20651 (define_insn "*rsqrtsf2_sse"
20652 [(set (match_operand:SF 0 "register_operand" "=x,x,x,x")
20653 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m,ja")]
20655 "TARGET_SSE && TARGET_SSE_MATH"
20657 %vrsqrtss\t{%d1, %0|%0, %d1}
20658 %vrsqrtss\t{%d1, %0|%0, %d1}
20659 rsqrtss\t{%1, %d0|%d0, %1}
20660 vrsqrtss\t{%1, %d0|%d0, %1}"
20661 [(set_attr "isa" "*,*,noavx,avx")
20662 (set_attr "addr" "*,*,*,gpr16")
20663 (set_attr "type" "sse")
20664 (set_attr "atom_sse_attr" "rcp")
20665 (set_attr "btver2_sse_attr" "rcp")
20666 (set_attr "prefix" "maybe_vex")
20667 (set_attr "mode" "SF")
20668 (set_attr "avx_partial_xmm_update" "false,false,true,true")
20669 (set (attr "preferred_for_speed")
20670 (cond [(match_test "TARGET_AVX")
20671 (symbol_ref "true")
20672 (eq_attr "alternative" "1,2,3")
20673 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
20675 (symbol_ref "true")))])
20677 (define_expand "rsqrtsf2"
20678 [(set (match_operand:SF 0 "register_operand")
20679 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
20681 "TARGET_SSE && TARGET_SSE_MATH"
20683 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
20687 (define_insn "rsqrthf2"
20688 [(set (match_operand:HF 0 "register_operand" "=v,v")
20689 (unspec:HF [(match_operand:HF 1 "nonimmediate_operand" "v,m")]
20691 "TARGET_AVX512FP16"
20693 vrsqrtsh\t{%d1, %0|%0, %d1}
20694 vrsqrtsh\t{%1, %d0|%d0, %1}"
20695 [(set_attr "type" "sse")
20696 (set_attr "prefix" "evex")
20697 (set_attr "avx_partial_xmm_update" "false,true")
20698 (set_attr "mode" "HF")])
20700 (define_insn "sqrthf2"
20701 [(set (match_operand:HF 0 "register_operand" "=v,v")
20703 (match_operand:HF 1 "nonimmediate_operand" "v,m")))]
20704 "TARGET_AVX512FP16"
20706 vsqrtsh\t{%d1, %0|%0, %d1}
20707 vsqrtsh\t{%1, %d0|%d0, %1}"
20708 [(set_attr "type" "sse")
20709 (set_attr "prefix" "evex")
20710 (set_attr "avx_partial_xmm_update" "false,true")
20711 (set_attr "mode" "HF")])
20713 (define_insn "*sqrt<mode>2_sse"
20714 [(set (match_operand:MODEF 0 "register_operand" "=v,v,v")
20716 (match_operand:MODEF 1 "nonimmediate_operand" "0,v,m")))]
20717 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20719 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
20720 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
20721 %vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
20722 [(set_attr "type" "sse")
20723 (set_attr "atom_sse_attr" "sqrt")
20724 (set_attr "btver2_sse_attr" "sqrt")
20725 (set_attr "prefix" "maybe_vex")
20726 (set_attr "avx_partial_xmm_update" "false,false,true")
20727 (set_attr "mode" "<MODE>")
20728 (set (attr "preferred_for_speed")
20729 (cond [(match_test "TARGET_AVX")
20730 (symbol_ref "true")
20731 (eq_attr "alternative" "1,2")
20732 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
20734 (symbol_ref "true")))])
20736 (define_expand "sqrt<mode>2"
20737 [(set (match_operand:MODEF 0 "register_operand")
20739 (match_operand:MODEF 1 "nonimmediate_operand")))]
20740 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
20741 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
20743 if (<MODE>mode == SFmode
20744 && TARGET_SSE && TARGET_SSE_MATH
20745 && TARGET_RECIP_SQRT
20746 && !optimize_function_for_size_p (cfun)
20747 && flag_finite_math_only && !flag_trapping_math
20748 && flag_unsafe_math_optimizations)
20750 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
20754 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
20756 rtx op0 = gen_reg_rtx (XFmode);
20757 rtx op1 = gen_reg_rtx (XFmode);
20759 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20760 emit_insn (gen_sqrtxf2 (op0, op1));
20761 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
20766 (define_expand "hypot<mode>3"
20767 [(use (match_operand:MODEF 0 "register_operand"))
20768 (use (match_operand:MODEF 1 "general_operand"))
20769 (use (match_operand:MODEF 2 "general_operand"))]
20770 "TARGET_USE_FANCY_MATH_387
20771 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20772 || TARGET_MIX_SSE_I387)
20773 && flag_finite_math_only
20774 && flag_unsafe_math_optimizations"
20776 rtx op0 = gen_reg_rtx (XFmode);
20777 rtx op1 = gen_reg_rtx (XFmode);
20778 rtx op2 = gen_reg_rtx (XFmode);
20780 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20781 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20783 emit_insn (gen_mulxf3 (op1, op1, op1));
20784 emit_insn (gen_mulxf3 (op2, op2, op2));
20785 emit_insn (gen_addxf3 (op0, op2, op1));
20786 emit_insn (gen_sqrtxf2 (op0, op0));
20788 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20792 (define_insn "x86_fnstsw_1"
20793 [(set (match_operand:HI 0 "register_operand" "=a")
20794 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
20797 [(set_attr "length" "2")
20798 (set_attr "mode" "SI")
20799 (set_attr "unit" "i387")])
20801 (define_insn "fpremxf4_i387"
20802 [(set (match_operand:XF 0 "register_operand" "=f")
20803 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
20804 (match_operand:XF 3 "register_operand" "1")]
20806 (set (match_operand:XF 1 "register_operand" "=f")
20807 (unspec:XF [(match_dup 2) (match_dup 3)]
20809 (set (reg:CCFP FPSR_REG)
20810 (unspec:CCFP [(match_dup 2) (match_dup 3)]
20812 "TARGET_USE_FANCY_MATH_387"
20814 [(set_attr "type" "fpspc")
20815 (set_attr "znver1_decode" "vector")
20816 (set_attr "mode" "XF")])
20818 (define_expand "fmodxf3"
20819 [(use (match_operand:XF 0 "register_operand"))
20820 (use (match_operand:XF 1 "general_operand"))
20821 (use (match_operand:XF 2 "general_operand"))]
20822 "TARGET_USE_FANCY_MATH_387"
20824 rtx_code_label *label = gen_label_rtx ();
20826 rtx op1 = gen_reg_rtx (XFmode);
20827 rtx op2 = gen_reg_rtx (XFmode);
20829 emit_move_insn (op2, operands[2]);
20830 emit_move_insn (op1, operands[1]);
20832 emit_label (label);
20833 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
20834 ix86_emit_fp_unordered_jump (label);
20835 LABEL_NUSES (label) = 1;
20837 emit_move_insn (operands[0], op1);
20841 (define_expand "fmod<mode>3"
20842 [(use (match_operand:MODEF 0 "register_operand"))
20843 (use (match_operand:MODEF 1 "general_operand"))
20844 (use (match_operand:MODEF 2 "general_operand"))]
20845 "TARGET_USE_FANCY_MATH_387"
20847 rtx (*gen_truncxf) (rtx, rtx);
20849 rtx_code_label *label = gen_label_rtx ();
20851 rtx op1 = gen_reg_rtx (XFmode);
20852 rtx op2 = gen_reg_rtx (XFmode);
20854 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20855 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20857 emit_label (label);
20858 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
20859 ix86_emit_fp_unordered_jump (label);
20860 LABEL_NUSES (label) = 1;
20862 /* Truncate the result properly for strict SSE math. */
20863 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
20864 && !TARGET_MIX_SSE_I387)
20865 gen_truncxf = gen_truncxf<mode>2;
20867 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
20869 emit_insn (gen_truncxf (operands[0], op1));
20873 (define_insn "fprem1xf4_i387"
20874 [(set (match_operand:XF 0 "register_operand" "=f")
20875 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
20876 (match_operand:XF 3 "register_operand" "1")]
20878 (set (match_operand:XF 1 "register_operand" "=f")
20879 (unspec:XF [(match_dup 2) (match_dup 3)]
20881 (set (reg:CCFP FPSR_REG)
20882 (unspec:CCFP [(match_dup 2) (match_dup 3)]
20884 "TARGET_USE_FANCY_MATH_387"
20886 [(set_attr "type" "fpspc")
20887 (set_attr "znver1_decode" "vector")
20888 (set_attr "mode" "XF")])
20890 (define_expand "remainderxf3"
20891 [(use (match_operand:XF 0 "register_operand"))
20892 (use (match_operand:XF 1 "general_operand"))
20893 (use (match_operand:XF 2 "general_operand"))]
20894 "TARGET_USE_FANCY_MATH_387"
20896 rtx_code_label *label = gen_label_rtx ();
20898 rtx op1 = gen_reg_rtx (XFmode);
20899 rtx op2 = gen_reg_rtx (XFmode);
20901 emit_move_insn (op2, operands[2]);
20902 emit_move_insn (op1, operands[1]);
20904 emit_label (label);
20905 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
20906 ix86_emit_fp_unordered_jump (label);
20907 LABEL_NUSES (label) = 1;
20909 emit_move_insn (operands[0], op1);
20913 (define_expand "remainder<mode>3"
20914 [(use (match_operand:MODEF 0 "register_operand"))
20915 (use (match_operand:MODEF 1 "general_operand"))
20916 (use (match_operand:MODEF 2 "general_operand"))]
20917 "TARGET_USE_FANCY_MATH_387"
20919 rtx (*gen_truncxf) (rtx, rtx);
20921 rtx_code_label *label = gen_label_rtx ();
20923 rtx op1 = gen_reg_rtx (XFmode);
20924 rtx op2 = gen_reg_rtx (XFmode);
20926 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20927 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20929 emit_label (label);
20931 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
20932 ix86_emit_fp_unordered_jump (label);
20933 LABEL_NUSES (label) = 1;
20935 /* Truncate the result properly for strict SSE math. */
20936 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
20937 && !TARGET_MIX_SSE_I387)
20938 gen_truncxf = gen_truncxf<mode>2;
20940 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
20942 emit_insn (gen_truncxf (operands[0], op1));
20946 (define_int_iterator SINCOS
20950 (define_int_attr sincos
20951 [(UNSPEC_SIN "sin")
20952 (UNSPEC_COS "cos")])
20954 (define_insn "<sincos>xf2"
20955 [(set (match_operand:XF 0 "register_operand" "=f")
20956 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
20958 "TARGET_USE_FANCY_MATH_387
20959 && flag_unsafe_math_optimizations"
20961 [(set_attr "type" "fpspc")
20962 (set_attr "znver1_decode" "vector")
20963 (set_attr "mode" "XF")])
20965 (define_expand "<sincos><mode>2"
20966 [(set (match_operand:MODEF 0 "register_operand")
20967 (unspec:MODEF [(match_operand:MODEF 1 "general_operand")]
20969 "TARGET_USE_FANCY_MATH_387
20970 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20971 || TARGET_MIX_SSE_I387)
20972 && flag_unsafe_math_optimizations"
20974 rtx op0 = gen_reg_rtx (XFmode);
20975 rtx op1 = gen_reg_rtx (XFmode);
20977 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20978 emit_insn (gen_<sincos>xf2 (op0, op1));
20979 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20983 (define_insn "sincosxf3"
20984 [(set (match_operand:XF 0 "register_operand" "=f")
20985 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
20986 UNSPEC_SINCOS_COS))
20987 (set (match_operand:XF 1 "register_operand" "=f")
20988 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
20989 "TARGET_USE_FANCY_MATH_387
20990 && flag_unsafe_math_optimizations"
20992 [(set_attr "type" "fpspc")
20993 (set_attr "znver1_decode" "vector")
20994 (set_attr "mode" "XF")])
20996 (define_expand "sincos<mode>3"
20997 [(use (match_operand:MODEF 0 "register_operand"))
20998 (use (match_operand:MODEF 1 "register_operand"))
20999 (use (match_operand:MODEF 2 "general_operand"))]
21000 "TARGET_USE_FANCY_MATH_387
21001 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21002 || TARGET_MIX_SSE_I387)
21003 && flag_unsafe_math_optimizations"
21005 rtx op0 = gen_reg_rtx (XFmode);
21006 rtx op1 = gen_reg_rtx (XFmode);
21007 rtx op2 = gen_reg_rtx (XFmode);
21009 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
21010 emit_insn (gen_sincosxf3 (op0, op1, op2));
21011 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21012 emit_insn (gen_truncxf<mode>2 (operands[1], op1));
21016 (define_insn "fptanxf4_i387"
21017 [(set (match_operand:SF 0 "register_operand" "=f")
21018 (match_operand:SF 3 "const1_operand"))
21019 (set (match_operand:XF 1 "register_operand" "=f")
21020 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
21022 "TARGET_USE_FANCY_MATH_387
21023 && flag_unsafe_math_optimizations"
21025 [(set_attr "type" "fpspc")
21026 (set_attr "znver1_decode" "vector")
21027 (set_attr "mode" "XF")])
21029 (define_expand "tanxf2"
21030 [(use (match_operand:XF 0 "register_operand"))
21031 (use (match_operand:XF 1 "register_operand"))]
21032 "TARGET_USE_FANCY_MATH_387
21033 && flag_unsafe_math_optimizations"
21035 rtx one = gen_reg_rtx (SFmode);
21036 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1],
21037 CONST1_RTX (SFmode)));
21041 (define_expand "tan<mode>2"
21042 [(use (match_operand:MODEF 0 "register_operand"))
21043 (use (match_operand:MODEF 1 "general_operand"))]
21044 "TARGET_USE_FANCY_MATH_387
21045 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21046 || TARGET_MIX_SSE_I387)
21047 && flag_unsafe_math_optimizations"
21049 rtx op0 = gen_reg_rtx (XFmode);
21050 rtx op1 = gen_reg_rtx (XFmode);
21052 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21053 emit_insn (gen_tanxf2 (op0, op1));
21054 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21058 (define_insn "atan2xf3"
21059 [(set (match_operand:XF 0 "register_operand" "=f")
21060 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
21061 (match_operand:XF 1 "register_operand" "f")]
21063 (clobber (match_scratch:XF 3 "=1"))]
21064 "TARGET_USE_FANCY_MATH_387
21065 && flag_unsafe_math_optimizations"
21067 [(set_attr "type" "fpspc")
21068 (set_attr "znver1_decode" "vector")
21069 (set_attr "mode" "XF")])
21071 (define_expand "atan2<mode>3"
21072 [(use (match_operand:MODEF 0 "register_operand"))
21073 (use (match_operand:MODEF 1 "general_operand"))
21074 (use (match_operand:MODEF 2 "general_operand"))]
21075 "TARGET_USE_FANCY_MATH_387
21076 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21077 || TARGET_MIX_SSE_I387)
21078 && flag_unsafe_math_optimizations"
21080 rtx op0 = gen_reg_rtx (XFmode);
21081 rtx op1 = gen_reg_rtx (XFmode);
21082 rtx op2 = gen_reg_rtx (XFmode);
21084 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
21085 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21087 emit_insn (gen_atan2xf3 (op0, op1, op2));
21088 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21092 (define_expand "atanxf2"
21093 [(parallel [(set (match_operand:XF 0 "register_operand")
21094 (unspec:XF [(match_dup 2)
21095 (match_operand:XF 1 "register_operand")]
21097 (clobber (scratch:XF))])]
21098 "TARGET_USE_FANCY_MATH_387
21099 && flag_unsafe_math_optimizations"
21100 "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
21102 (define_expand "atan<mode>2"
21103 [(use (match_operand:MODEF 0 "register_operand"))
21104 (use (match_operand:MODEF 1 "general_operand"))]
21105 "TARGET_USE_FANCY_MATH_387
21106 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21107 || TARGET_MIX_SSE_I387)
21108 && flag_unsafe_math_optimizations"
21110 rtx op0 = gen_reg_rtx (XFmode);
21111 rtx op1 = gen_reg_rtx (XFmode);
21113 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21114 emit_insn (gen_atanxf2 (op0, op1));
21115 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21119 (define_expand "asinxf2"
21120 [(set (match_dup 2)
21121 (mult:XF (match_operand:XF 1 "register_operand")
21123 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
21124 (set (match_dup 5) (sqrt:XF (match_dup 4)))
21125 (parallel [(set (match_operand:XF 0 "register_operand")
21126 (unspec:XF [(match_dup 5) (match_dup 1)]
21128 (clobber (scratch:XF))])]
21129 "TARGET_USE_FANCY_MATH_387
21130 && flag_unsafe_math_optimizations"
21134 for (i = 2; i < 6; i++)
21135 operands[i] = gen_reg_rtx (XFmode);
21137 emit_move_insn (operands[3], CONST1_RTX (XFmode));
21140 (define_expand "asin<mode>2"
21141 [(use (match_operand:MODEF 0 "register_operand"))
21142 (use (match_operand:MODEF 1 "general_operand"))]
21143 "TARGET_USE_FANCY_MATH_387
21144 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21145 || TARGET_MIX_SSE_I387)
21146 && flag_unsafe_math_optimizations"
21148 rtx op0 = gen_reg_rtx (XFmode);
21149 rtx op1 = gen_reg_rtx (XFmode);
21151 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21152 emit_insn (gen_asinxf2 (op0, op1));
21153 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21157 (define_expand "acosxf2"
21158 [(set (match_dup 2)
21159 (mult:XF (match_operand:XF 1 "register_operand")
21161 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
21162 (set (match_dup 5) (sqrt:XF (match_dup 4)))
21163 (parallel [(set (match_operand:XF 0 "register_operand")
21164 (unspec:XF [(match_dup 1) (match_dup 5)]
21166 (clobber (scratch:XF))])]
21167 "TARGET_USE_FANCY_MATH_387
21168 && flag_unsafe_math_optimizations"
21172 for (i = 2; i < 6; i++)
21173 operands[i] = gen_reg_rtx (XFmode);
21175 emit_move_insn (operands[3], CONST1_RTX (XFmode));
21178 (define_expand "acos<mode>2"
21179 [(use (match_operand:MODEF 0 "register_operand"))
21180 (use (match_operand:MODEF 1 "general_operand"))]
21181 "TARGET_USE_FANCY_MATH_387
21182 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21183 || TARGET_MIX_SSE_I387)
21184 && flag_unsafe_math_optimizations"
21186 rtx op0 = gen_reg_rtx (XFmode);
21187 rtx op1 = gen_reg_rtx (XFmode);
21189 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21190 emit_insn (gen_acosxf2 (op0, op1));
21191 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21195 (define_expand "sinhxf2"
21196 [(use (match_operand:XF 0 "register_operand"))
21197 (use (match_operand:XF 1 "register_operand"))]
21198 "TARGET_USE_FANCY_MATH_387
21199 && flag_finite_math_only
21200 && flag_unsafe_math_optimizations"
21202 ix86_emit_i387_sinh (operands[0], operands[1]);
21206 (define_expand "sinh<mode>2"
21207 [(use (match_operand:MODEF 0 "register_operand"))
21208 (use (match_operand:MODEF 1 "general_operand"))]
21209 "TARGET_USE_FANCY_MATH_387
21210 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21211 || TARGET_MIX_SSE_I387)
21212 && flag_finite_math_only
21213 && flag_unsafe_math_optimizations"
21215 rtx op0 = gen_reg_rtx (XFmode);
21216 rtx op1 = gen_reg_rtx (XFmode);
21218 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21219 emit_insn (gen_sinhxf2 (op0, op1));
21220 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21224 (define_expand "coshxf2"
21225 [(use (match_operand:XF 0 "register_operand"))
21226 (use (match_operand:XF 1 "register_operand"))]
21227 "TARGET_USE_FANCY_MATH_387
21228 && flag_unsafe_math_optimizations"
21230 ix86_emit_i387_cosh (operands[0], operands[1]);
21234 (define_expand "cosh<mode>2"
21235 [(use (match_operand:MODEF 0 "register_operand"))
21236 (use (match_operand:MODEF 1 "general_operand"))]
21237 "TARGET_USE_FANCY_MATH_387
21238 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21239 || TARGET_MIX_SSE_I387)
21240 && flag_unsafe_math_optimizations"
21242 rtx op0 = gen_reg_rtx (XFmode);
21243 rtx op1 = gen_reg_rtx (XFmode);
21245 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21246 emit_insn (gen_coshxf2 (op0, op1));
21247 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21251 (define_expand "tanhxf2"
21252 [(use (match_operand:XF 0 "register_operand"))
21253 (use (match_operand:XF 1 "register_operand"))]
21254 "TARGET_USE_FANCY_MATH_387
21255 && flag_unsafe_math_optimizations"
21257 ix86_emit_i387_tanh (operands[0], operands[1]);
21261 (define_expand "tanh<mode>2"
21262 [(use (match_operand:MODEF 0 "register_operand"))
21263 (use (match_operand:MODEF 1 "general_operand"))]
21264 "TARGET_USE_FANCY_MATH_387
21265 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21266 || TARGET_MIX_SSE_I387)
21267 && flag_unsafe_math_optimizations"
21269 rtx op0 = gen_reg_rtx (XFmode);
21270 rtx op1 = gen_reg_rtx (XFmode);
21272 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21273 emit_insn (gen_tanhxf2 (op0, op1));
21274 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21278 (define_expand "asinhxf2"
21279 [(use (match_operand:XF 0 "register_operand"))
21280 (use (match_operand:XF 1 "register_operand"))]
21281 "TARGET_USE_FANCY_MATH_387
21282 && flag_finite_math_only
21283 && flag_unsafe_math_optimizations"
21285 ix86_emit_i387_asinh (operands[0], operands[1]);
21289 (define_expand "asinh<mode>2"
21290 [(use (match_operand:MODEF 0 "register_operand"))
21291 (use (match_operand:MODEF 1 "general_operand"))]
21292 "TARGET_USE_FANCY_MATH_387
21293 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21294 || TARGET_MIX_SSE_I387)
21295 && flag_finite_math_only
21296 && flag_unsafe_math_optimizations"
21298 rtx op0 = gen_reg_rtx (XFmode);
21299 rtx op1 = gen_reg_rtx (XFmode);
21301 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21302 emit_insn (gen_asinhxf2 (op0, op1));
21303 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21307 (define_expand "acoshxf2"
21308 [(use (match_operand:XF 0 "register_operand"))
21309 (use (match_operand:XF 1 "register_operand"))]
21310 "TARGET_USE_FANCY_MATH_387
21311 && flag_unsafe_math_optimizations"
21313 ix86_emit_i387_acosh (operands[0], operands[1]);
21317 (define_expand "acosh<mode>2"
21318 [(use (match_operand:MODEF 0 "register_operand"))
21319 (use (match_operand:MODEF 1 "general_operand"))]
21320 "TARGET_USE_FANCY_MATH_387
21321 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21322 || TARGET_MIX_SSE_I387)
21323 && flag_unsafe_math_optimizations"
21325 rtx op0 = gen_reg_rtx (XFmode);
21326 rtx op1 = gen_reg_rtx (XFmode);
21328 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21329 emit_insn (gen_acoshxf2 (op0, op1));
21330 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21334 (define_expand "atanhxf2"
21335 [(use (match_operand:XF 0 "register_operand"))
21336 (use (match_operand:XF 1 "register_operand"))]
21337 "TARGET_USE_FANCY_MATH_387
21338 && flag_unsafe_math_optimizations"
21340 ix86_emit_i387_atanh (operands[0], operands[1]);
21344 (define_expand "atanh<mode>2"
21345 [(use (match_operand:MODEF 0 "register_operand"))
21346 (use (match_operand:MODEF 1 "general_operand"))]
21347 "TARGET_USE_FANCY_MATH_387
21348 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21349 || TARGET_MIX_SSE_I387)
21350 && flag_unsafe_math_optimizations"
21352 rtx op0 = gen_reg_rtx (XFmode);
21353 rtx op1 = gen_reg_rtx (XFmode);
21355 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21356 emit_insn (gen_atanhxf2 (op0, op1));
21357 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21361 (define_insn "fyl2xxf3_i387"
21362 [(set (match_operand:XF 0 "register_operand" "=f")
21363 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
21364 (match_operand:XF 2 "register_operand" "f")]
21366 (clobber (match_scratch:XF 3 "=2"))]
21367 "TARGET_USE_FANCY_MATH_387
21368 && flag_unsafe_math_optimizations"
21370 [(set_attr "type" "fpspc")
21371 (set_attr "znver1_decode" "vector")
21372 (set_attr "mode" "XF")])
21374 (define_expand "logxf2"
21375 [(parallel [(set (match_operand:XF 0 "register_operand")
21376 (unspec:XF [(match_operand:XF 1 "register_operand")
21377 (match_dup 2)] UNSPEC_FYL2X))
21378 (clobber (scratch:XF))])]
21379 "TARGET_USE_FANCY_MATH_387
21380 && flag_unsafe_math_optimizations"
21383 = force_reg (XFmode, standard_80387_constant_rtx (4)); /* fldln2 */
21386 (define_expand "log<mode>2"
21387 [(use (match_operand:MODEF 0 "register_operand"))
21388 (use (match_operand:MODEF 1 "general_operand"))]
21389 "TARGET_USE_FANCY_MATH_387
21390 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21391 || TARGET_MIX_SSE_I387)
21392 && flag_unsafe_math_optimizations"
21394 rtx op0 = gen_reg_rtx (XFmode);
21395 rtx op1 = gen_reg_rtx (XFmode);
21397 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21398 emit_insn (gen_logxf2 (op0, op1));
21399 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21403 (define_expand "log10xf2"
21404 [(parallel [(set (match_operand:XF 0 "register_operand")
21405 (unspec:XF [(match_operand:XF 1 "register_operand")
21406 (match_dup 2)] UNSPEC_FYL2X))
21407 (clobber (scratch:XF))])]
21408 "TARGET_USE_FANCY_MATH_387
21409 && flag_unsafe_math_optimizations"
21412 = force_reg (XFmode, standard_80387_constant_rtx (3)); /* fldlg2 */
21415 (define_expand "log10<mode>2"
21416 [(use (match_operand:MODEF 0 "register_operand"))
21417 (use (match_operand:MODEF 1 "general_operand"))]
21418 "TARGET_USE_FANCY_MATH_387
21419 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21420 || TARGET_MIX_SSE_I387)
21421 && flag_unsafe_math_optimizations"
21423 rtx op0 = gen_reg_rtx (XFmode);
21424 rtx op1 = gen_reg_rtx (XFmode);
21426 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21427 emit_insn (gen_log10xf2 (op0, op1));
21428 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21432 (define_expand "log2xf2"
21433 [(parallel [(set (match_operand:XF 0 "register_operand")
21434 (unspec:XF [(match_operand:XF 1 "register_operand")
21435 (match_dup 2)] UNSPEC_FYL2X))
21436 (clobber (scratch:XF))])]
21437 "TARGET_USE_FANCY_MATH_387
21438 && flag_unsafe_math_optimizations"
21439 "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
21441 (define_expand "log2<mode>2"
21442 [(use (match_operand:MODEF 0 "register_operand"))
21443 (use (match_operand:MODEF 1 "general_operand"))]
21444 "TARGET_USE_FANCY_MATH_387
21445 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21446 || TARGET_MIX_SSE_I387)
21447 && flag_unsafe_math_optimizations"
21449 rtx op0 = gen_reg_rtx (XFmode);
21450 rtx op1 = gen_reg_rtx (XFmode);
21452 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21453 emit_insn (gen_log2xf2 (op0, op1));
21454 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21458 (define_insn "fyl2xp1xf3_i387"
21459 [(set (match_operand:XF 0 "register_operand" "=f")
21460 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
21461 (match_operand:XF 2 "register_operand" "f")]
21463 (clobber (match_scratch:XF 3 "=2"))]
21464 "TARGET_USE_FANCY_MATH_387
21465 && flag_unsafe_math_optimizations"
21467 [(set_attr "type" "fpspc")
21468 (set_attr "znver1_decode" "vector")
21469 (set_attr "mode" "XF")])
21471 (define_expand "log1pxf2"
21472 [(use (match_operand:XF 0 "register_operand"))
21473 (use (match_operand:XF 1 "register_operand"))]
21474 "TARGET_USE_FANCY_MATH_387
21475 && flag_unsafe_math_optimizations"
21477 ix86_emit_i387_log1p (operands[0], operands[1]);
21481 (define_expand "log1p<mode>2"
21482 [(use (match_operand:MODEF 0 "register_operand"))
21483 (use (match_operand:MODEF 1 "general_operand"))]
21484 "TARGET_USE_FANCY_MATH_387
21485 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21486 || TARGET_MIX_SSE_I387)
21487 && flag_unsafe_math_optimizations"
21489 rtx op0 = gen_reg_rtx (XFmode);
21490 rtx op1 = gen_reg_rtx (XFmode);
21492 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21493 emit_insn (gen_log1pxf2 (op0, op1));
21494 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21498 (define_insn "fxtractxf3_i387"
21499 [(set (match_operand:XF 0 "register_operand" "=f")
21500 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
21501 UNSPEC_XTRACT_FRACT))
21502 (set (match_operand:XF 1 "register_operand" "=f")
21503 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
21504 "TARGET_USE_FANCY_MATH_387
21505 && flag_unsafe_math_optimizations"
21507 [(set_attr "type" "fpspc")
21508 (set_attr "znver1_decode" "vector")
21509 (set_attr "mode" "XF")])
21511 (define_expand "logbxf2"
21512 [(parallel [(set (match_dup 2)
21513 (unspec:XF [(match_operand:XF 1 "register_operand")]
21514 UNSPEC_XTRACT_FRACT))
21515 (set (match_operand:XF 0 "register_operand")
21516 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
21517 "TARGET_USE_FANCY_MATH_387
21518 && flag_unsafe_math_optimizations"
21519 "operands[2] = gen_reg_rtx (XFmode);")
21521 (define_expand "logb<mode>2"
21522 [(use (match_operand:MODEF 0 "register_operand"))
21523 (use (match_operand:MODEF 1 "general_operand"))]
21524 "TARGET_USE_FANCY_MATH_387
21525 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21526 || TARGET_MIX_SSE_I387)
21527 && flag_unsafe_math_optimizations"
21529 rtx op0 = gen_reg_rtx (XFmode);
21530 rtx op1 = gen_reg_rtx (XFmode);
21532 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21533 emit_insn (gen_logbxf2 (op0, op1));
21534 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
21538 (define_expand "ilogbxf2"
21539 [(use (match_operand:SI 0 "register_operand"))
21540 (use (match_operand:XF 1 "register_operand"))]
21541 "TARGET_USE_FANCY_MATH_387
21542 && flag_unsafe_math_optimizations"
21546 if (optimize_insn_for_size_p ())
21549 op0 = gen_reg_rtx (XFmode);
21550 op1 = gen_reg_rtx (XFmode);
21552 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
21553 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
21557 (define_expand "ilogb<mode>2"
21558 [(use (match_operand:SI 0 "register_operand"))
21559 (use (match_operand:MODEF 1 "general_operand"))]
21560 "TARGET_USE_FANCY_MATH_387
21561 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21562 || TARGET_MIX_SSE_I387)
21563 && flag_unsafe_math_optimizations"
21567 if (optimize_insn_for_size_p ())
21570 op0 = gen_reg_rtx (XFmode);
21571 op1 = gen_reg_rtx (XFmode);
21572 op2 = gen_reg_rtx (XFmode);
21574 emit_insn (gen_extend<mode>xf2 (op2, operands[1]));
21575 emit_insn (gen_fxtractxf3_i387 (op0, op1, op2));
21576 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
21580 (define_insn "*f2xm1xf2_i387"
21581 [(set (match_operand:XF 0 "register_operand" "=f")
21582 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
21584 "TARGET_USE_FANCY_MATH_387
21585 && flag_unsafe_math_optimizations"
21587 [(set_attr "type" "fpspc")
21588 (set_attr "znver1_decode" "vector")
21589 (set_attr "mode" "XF")])
21591 (define_insn "fscalexf4_i387"
21592 [(set (match_operand:XF 0 "register_operand" "=f")
21593 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
21594 (match_operand:XF 3 "register_operand" "1")]
21595 UNSPEC_FSCALE_FRACT))
21596 (set (match_operand:XF 1 "register_operand" "=f")
21597 (unspec:XF [(match_dup 2) (match_dup 3)]
21598 UNSPEC_FSCALE_EXP))]
21599 "TARGET_USE_FANCY_MATH_387
21600 && flag_unsafe_math_optimizations"
21602 [(set_attr "type" "fpspc")
21603 (set_attr "znver1_decode" "vector")
21604 (set_attr "mode" "XF")])
21606 (define_expand "expNcorexf3"
21607 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
21608 (match_operand:XF 2 "register_operand")))
21609 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
21610 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
21611 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
21612 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
21613 (parallel [(set (match_operand:XF 0 "register_operand")
21614 (unspec:XF [(match_dup 8) (match_dup 4)]
21615 UNSPEC_FSCALE_FRACT))
21617 (unspec:XF [(match_dup 8) (match_dup 4)]
21618 UNSPEC_FSCALE_EXP))])]
21619 "TARGET_USE_FANCY_MATH_387
21620 && flag_unsafe_math_optimizations"
21624 for (i = 3; i < 10; i++)
21625 operands[i] = gen_reg_rtx (XFmode);
21627 emit_move_insn (operands[7], CONST1_RTX (XFmode));
21630 (define_expand "expxf2"
21631 [(use (match_operand:XF 0 "register_operand"))
21632 (use (match_operand:XF 1 "register_operand"))]
21633 "TARGET_USE_FANCY_MATH_387
21634 && flag_unsafe_math_optimizations"
21636 rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (5)); /* fldl2e */
21638 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
21642 (define_expand "exp<mode>2"
21643 [(use (match_operand:MODEF 0 "register_operand"))
21644 (use (match_operand:MODEF 1 "general_operand"))]
21645 "TARGET_USE_FANCY_MATH_387
21646 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21647 || TARGET_MIX_SSE_I387)
21648 && flag_unsafe_math_optimizations"
21650 rtx op0 = gen_reg_rtx (XFmode);
21651 rtx op1 = gen_reg_rtx (XFmode);
21653 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21654 emit_insn (gen_expxf2 (op0, op1));
21655 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21659 (define_expand "exp10xf2"
21660 [(use (match_operand:XF 0 "register_operand"))
21661 (use (match_operand:XF 1 "register_operand"))]
21662 "TARGET_USE_FANCY_MATH_387
21663 && flag_unsafe_math_optimizations"
21665 rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (6)); /* fldl2t */
21667 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
21671 (define_expand "exp10<mode>2"
21672 [(use (match_operand:MODEF 0 "register_operand"))
21673 (use (match_operand:MODEF 1 "general_operand"))]
21674 "TARGET_USE_FANCY_MATH_387
21675 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21676 || TARGET_MIX_SSE_I387)
21677 && flag_unsafe_math_optimizations"
21679 rtx op0 = gen_reg_rtx (XFmode);
21680 rtx op1 = gen_reg_rtx (XFmode);
21682 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21683 emit_insn (gen_exp10xf2 (op0, op1));
21684 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21688 (define_expand "exp2xf2"
21689 [(use (match_operand:XF 0 "register_operand"))
21690 (use (match_operand:XF 1 "register_operand"))]
21691 "TARGET_USE_FANCY_MATH_387
21692 && flag_unsafe_math_optimizations"
21694 rtx op2 = force_reg (XFmode, CONST1_RTX (XFmode));
21696 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
21700 (define_expand "exp2<mode>2"
21701 [(use (match_operand:MODEF 0 "register_operand"))
21702 (use (match_operand:MODEF 1 "general_operand"))]
21703 "TARGET_USE_FANCY_MATH_387
21704 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21705 || TARGET_MIX_SSE_I387)
21706 && flag_unsafe_math_optimizations"
21708 rtx op0 = gen_reg_rtx (XFmode);
21709 rtx op1 = gen_reg_rtx (XFmode);
21711 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21712 emit_insn (gen_exp2xf2 (op0, op1));
21713 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21717 (define_expand "expm1xf2"
21718 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
21720 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
21721 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
21722 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
21723 (parallel [(set (match_dup 7)
21724 (unspec:XF [(match_dup 6) (match_dup 4)]
21725 UNSPEC_FSCALE_FRACT))
21727 (unspec:XF [(match_dup 6) (match_dup 4)]
21728 UNSPEC_FSCALE_EXP))])
21729 (parallel [(set (match_dup 10)
21730 (unspec:XF [(match_dup 9) (match_dup 8)]
21731 UNSPEC_FSCALE_FRACT))
21732 (set (match_dup 11)
21733 (unspec:XF [(match_dup 9) (match_dup 8)]
21734 UNSPEC_FSCALE_EXP))])
21735 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
21736 (set (match_operand:XF 0 "register_operand")
21737 (plus:XF (match_dup 12) (match_dup 7)))]
21738 "TARGET_USE_FANCY_MATH_387
21739 && flag_unsafe_math_optimizations"
21743 for (i = 2; i < 13; i++)
21744 operands[i] = gen_reg_rtx (XFmode);
21746 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
21747 emit_move_insn (operands[9], CONST1_RTX (XFmode));
21750 (define_expand "expm1<mode>2"
21751 [(use (match_operand:MODEF 0 "register_operand"))
21752 (use (match_operand:MODEF 1 "general_operand"))]
21753 "TARGET_USE_FANCY_MATH_387
21754 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21755 || TARGET_MIX_SSE_I387)
21756 && flag_unsafe_math_optimizations"
21758 rtx op0 = gen_reg_rtx (XFmode);
21759 rtx op1 = gen_reg_rtx (XFmode);
21761 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21762 emit_insn (gen_expm1xf2 (op0, op1));
21763 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21767 (define_insn "avx512f_scalef<mode>2"
21768 [(set (match_operand:MODEF 0 "register_operand" "=v")
21770 [(match_operand:MODEF 1 "register_operand" "v")
21771 (match_operand:MODEF 2 "nonimmediate_operand" "vm")]
21774 "vscalef<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
21775 [(set_attr "prefix" "evex")
21776 (set_attr "mode" "<MODE>")])
21778 (define_expand "ldexpxf3"
21779 [(match_operand:XF 0 "register_operand")
21780 (match_operand:XF 1 "register_operand")
21781 (match_operand:SI 2 "register_operand")]
21782 "TARGET_USE_FANCY_MATH_387
21783 && flag_unsafe_math_optimizations"
21785 rtx tmp1 = gen_reg_rtx (XFmode);
21786 rtx tmp2 = gen_reg_rtx (XFmode);
21788 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
21789 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
21790 operands[1], tmp1));
21794 (define_expand "ldexp<mode>3"
21795 [(use (match_operand:MODEF 0 "register_operand"))
21796 (use (match_operand:MODEF 1 "general_operand"))
21797 (use (match_operand:SI 2 "register_operand"))]
21798 "((TARGET_USE_FANCY_MATH_387
21799 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21800 || TARGET_MIX_SSE_I387))
21801 || (TARGET_AVX512F && TARGET_SSE_MATH))
21802 && flag_unsafe_math_optimizations"
21804 /* Prefer avx512f version. */
21805 if (TARGET_AVX512F && TARGET_SSE_MATH)
21807 rtx op2 = gen_reg_rtx (<MODE>mode);
21808 operands[1] = force_reg (<MODE>mode, operands[1]);
21810 emit_insn (gen_floatsi<mode>2 (op2, operands[2]));
21811 emit_insn (gen_avx512f_scalef<mode>2 (operands[0], operands[1], op2));
21815 rtx op0 = gen_reg_rtx (XFmode);
21816 rtx op1 = gen_reg_rtx (XFmode);
21818 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21819 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
21820 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21825 (define_expand "scalbxf3"
21826 [(parallel [(set (match_operand:XF 0 " register_operand")
21827 (unspec:XF [(match_operand:XF 1 "register_operand")
21828 (match_operand:XF 2 "register_operand")]
21829 UNSPEC_FSCALE_FRACT))
21831 (unspec:XF [(match_dup 1) (match_dup 2)]
21832 UNSPEC_FSCALE_EXP))])]
21833 "TARGET_USE_FANCY_MATH_387
21834 && flag_unsafe_math_optimizations"
21835 "operands[3] = gen_reg_rtx (XFmode);")
21837 (define_expand "scalb<mode>3"
21838 [(use (match_operand:MODEF 0 "register_operand"))
21839 (use (match_operand:MODEF 1 "general_operand"))
21840 (use (match_operand:MODEF 2 "general_operand"))]
21841 "TARGET_USE_FANCY_MATH_387
21842 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21843 || TARGET_MIX_SSE_I387)
21844 && flag_unsafe_math_optimizations"
21846 rtx op0 = gen_reg_rtx (XFmode);
21847 rtx op1 = gen_reg_rtx (XFmode);
21848 rtx op2 = gen_reg_rtx (XFmode);
21850 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21851 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
21852 emit_insn (gen_scalbxf3 (op0, op1, op2));
21853 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21857 (define_expand "significandxf2"
21858 [(parallel [(set (match_operand:XF 0 "register_operand")
21859 (unspec:XF [(match_operand:XF 1 "register_operand")]
21860 UNSPEC_XTRACT_FRACT))
21862 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
21863 "TARGET_USE_FANCY_MATH_387
21864 && flag_unsafe_math_optimizations"
21865 "operands[2] = gen_reg_rtx (XFmode);")
21867 (define_expand "significand<mode>2"
21868 [(use (match_operand:MODEF 0 "register_operand"))
21869 (use (match_operand:MODEF 1 "general_operand"))]
21870 "TARGET_USE_FANCY_MATH_387
21871 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21872 || TARGET_MIX_SSE_I387)
21873 && flag_unsafe_math_optimizations"
21875 rtx op0 = gen_reg_rtx (XFmode);
21876 rtx op1 = gen_reg_rtx (XFmode);
21878 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21879 emit_insn (gen_significandxf2 (op0, op1));
21880 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21885 (define_insn "sse4_1_round<mode>2"
21886 [(set (match_operand:MODEFH 0 "register_operand" "=x,x,x,v,v")
21888 [(match_operand:MODEFH 1 "nonimmediate_operand" "0,x,jm,v,m")
21889 (match_operand:SI 2 "const_0_to_15_operand")]
21893 %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
21894 %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
21895 %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
21896 vrndscale<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
21897 vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
21898 [(set_attr "type" "ssecvt")
21899 (set_attr "prefix_extra" "1,1,1,*,*")
21900 (set_attr "length_immediate" "1")
21901 (set_attr "addr" "*,*,gpr16,*,*")
21902 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,evex,evex")
21903 (set_attr "isa" "noavx512f,noavx512f,noavx512f,avx512f,avx512f")
21904 (set_attr "avx_partial_xmm_update" "false,false,true,false,true")
21905 (set_attr "mode" "<MODE>")
21906 (set (attr "preferred_for_speed")
21907 (cond [(match_test "TARGET_AVX")
21908 (symbol_ref "true")
21909 (eq_attr "alternative" "1,2")
21910 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
21912 (symbol_ref "true")))])
21914 (define_insn "rintxf2"
21915 [(set (match_operand:XF 0 "register_operand" "=f")
21916 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
21918 "TARGET_USE_FANCY_MATH_387"
21920 [(set_attr "type" "fpspc")
21921 (set_attr "znver1_decode" "vector")
21922 (set_attr "mode" "XF")])
21924 (define_expand "rinthf2"
21925 [(match_operand:HF 0 "register_operand")
21926 (match_operand:HF 1 "nonimmediate_operand")]
21927 "TARGET_AVX512FP16"
21929 emit_insn (gen_sse4_1_roundhf2 (operands[0],
21931 GEN_INT (ROUND_MXCSR)));
21935 (define_expand "rint<mode>2"
21936 [(use (match_operand:MODEF 0 "register_operand"))
21937 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
21938 "TARGET_USE_FANCY_MATH_387
21939 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
21941 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21944 emit_insn (gen_sse4_1_round<mode>2
21945 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
21947 ix86_expand_rint (operands[0], operands[1]);
21951 rtx op0 = gen_reg_rtx (XFmode);
21952 rtx op1 = gen_reg_rtx (XFmode);
21954 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21955 emit_insn (gen_rintxf2 (op0, op1));
21956 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
21961 (define_expand "nearbyintxf2"
21962 [(set (match_operand:XF 0 "register_operand")
21963 (unspec:XF [(match_operand:XF 1 "register_operand")]
21965 "TARGET_USE_FANCY_MATH_387
21966 && !flag_trapping_math")
21968 (define_expand "nearbyinthf2"
21969 [(match_operand:HF 0 "register_operand")
21970 (match_operand:HF 1 "nonimmediate_operand")]
21971 "TARGET_AVX512FP16"
21973 emit_insn (gen_sse4_1_roundhf2 (operands[0],
21975 GEN_INT (ROUND_MXCSR | ROUND_NO_EXC)));
21979 (define_expand "nearbyint<mode>2"
21980 [(use (match_operand:MODEF 0 "register_operand"))
21981 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
21982 "(TARGET_USE_FANCY_MATH_387
21983 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21984 || TARGET_MIX_SSE_I387)
21985 && !flag_trapping_math)
21986 || (TARGET_SSE4_1 && TARGET_SSE_MATH)"
21988 if (TARGET_SSE4_1 && TARGET_SSE_MATH)
21989 emit_insn (gen_sse4_1_round<mode>2
21990 (operands[0], operands[1], GEN_INT (ROUND_MXCSR
21994 rtx op0 = gen_reg_rtx (XFmode);
21995 rtx op1 = gen_reg_rtx (XFmode);
21997 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21998 emit_insn (gen_nearbyintxf2 (op0, op1));
21999 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
22004 (define_expand "roundhf2"
22005 [(match_operand:HF 0 "register_operand")
22006 (match_operand:HF 1 "register_operand")]
22007 "TARGET_AVX512FP16 && !flag_trapping_math && !flag_rounding_math"
22009 ix86_expand_round_sse4 (operands[0], operands[1]);
22013 (define_expand "round<mode>2"
22014 [(match_operand:X87MODEF 0 "register_operand")
22015 (match_operand:X87MODEF 1 "nonimmediate_operand")]
22016 "(TARGET_USE_FANCY_MATH_387
22017 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22018 || TARGET_MIX_SSE_I387)
22019 && flag_unsafe_math_optimizations
22020 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
22021 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
22022 && !flag_trapping_math && !flag_rounding_math)"
22024 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
22025 && !flag_trapping_math && !flag_rounding_math)
22029 operands[1] = force_reg (<MODE>mode, operands[1]);
22030 ix86_expand_round_sse4 (operands[0], operands[1]);
22032 else if (TARGET_64BIT || (<MODE>mode != DFmode))
22033 ix86_expand_round (operands[0], operands[1]);
22035 ix86_expand_rounddf_32 (operands[0], operands[1]);
22039 operands[1] = force_reg (<MODE>mode, operands[1]);
22040 ix86_emit_i387_round (operands[0], operands[1]);
22045 (define_insn "lrintxfdi2"
22046 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
22047 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
22049 (clobber (match_scratch:XF 2 "=&f"))]
22050 "TARGET_USE_FANCY_MATH_387"
22051 "* return output_fix_trunc (insn, operands, false);"
22052 [(set_attr "type" "fpspc")
22053 (set_attr "mode" "DI")])
22055 (define_insn "lrintxf<mode>2"
22056 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
22057 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
22059 "TARGET_USE_FANCY_MATH_387"
22060 "* return output_fix_trunc (insn, operands, false);"
22061 [(set_attr "type" "fpspc")
22062 (set_attr "mode" "<MODE>")])
22064 (define_expand "lroundhf<mode>2"
22065 [(set (match_operand:SWI248 0 "register_operand")
22066 (unspec:SWI248 [(match_operand:HF 1 "nonimmediate_operand")]
22067 UNSPEC_FIX_NOTRUNC))]
22068 "TARGET_AVX512FP16 && !flag_trapping_math && !flag_rounding_math"
22070 ix86_expand_lround (operands[0], operands[1]);
22074 (define_expand "lrinthf<mode>2"
22075 [(set (match_operand:SWI48 0 "register_operand")
22076 (unspec:SWI48 [(match_operand:HF 1 "nonimmediate_operand")]
22077 UNSPEC_FIX_NOTRUNC))]
22078 "TARGET_AVX512FP16")
22080 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
22081 [(set (match_operand:SWI48 0 "register_operand")
22082 (unspec:SWI48 [(match_operand:MODEF 1 "nonimmediate_operand")]
22083 UNSPEC_FIX_NOTRUNC))]
22084 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
22086 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
22087 [(match_operand:SWI248x 0 "nonimmediate_operand")
22088 (match_operand:X87MODEF 1 "register_operand")]
22089 "(TARGET_USE_FANCY_MATH_387
22090 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
22091 || TARGET_MIX_SSE_I387)
22092 && flag_unsafe_math_optimizations)
22093 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
22094 && <SWI248x:MODE>mode != HImode
22095 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
22096 && !flag_trapping_math && !flag_rounding_math)"
22098 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
22099 && <SWI248x:MODE>mode != HImode
22100 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
22101 && !flag_trapping_math && !flag_rounding_math)
22102 ix86_expand_lround (operands[0], operands[1]);
22104 ix86_emit_i387_round (operands[0], operands[1]);
22108 (define_int_iterator FRNDINT_ROUNDING
22109 [UNSPEC_FRNDINT_ROUNDEVEN
22110 UNSPEC_FRNDINT_FLOOR
22111 UNSPEC_FRNDINT_CEIL
22112 UNSPEC_FRNDINT_TRUNC])
22114 (define_int_iterator FIST_ROUNDING
22118 ;; Base name for define_insn
22119 (define_int_attr rounding_insn
22120 [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven")
22121 (UNSPEC_FRNDINT_FLOOR "floor")
22122 (UNSPEC_FRNDINT_CEIL "ceil")
22123 (UNSPEC_FRNDINT_TRUNC "btrunc")
22124 (UNSPEC_FIST_FLOOR "floor")
22125 (UNSPEC_FIST_CEIL "ceil")])
22127 (define_int_attr rounding
22128 [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven")
22129 (UNSPEC_FRNDINT_FLOOR "floor")
22130 (UNSPEC_FRNDINT_CEIL "ceil")
22131 (UNSPEC_FRNDINT_TRUNC "trunc")
22132 (UNSPEC_FIST_FLOOR "floor")
22133 (UNSPEC_FIST_CEIL "ceil")])
22135 (define_int_attr ROUNDING
22136 [(UNSPEC_FRNDINT_ROUNDEVEN "ROUNDEVEN")
22137 (UNSPEC_FRNDINT_FLOOR "FLOOR")
22138 (UNSPEC_FRNDINT_CEIL "CEIL")
22139 (UNSPEC_FRNDINT_TRUNC "TRUNC")
22140 (UNSPEC_FIST_FLOOR "FLOOR")
22141 (UNSPEC_FIST_CEIL "CEIL")])
22143 ;; Rounding mode control word calculation could clobber FLAGS_REG.
22144 (define_insn_and_split "frndintxf2_<rounding>"
22145 [(set (match_operand:XF 0 "register_operand")
22146 (unspec:XF [(match_operand:XF 1 "register_operand")]
22148 (clobber (reg:CC FLAGS_REG))]
22149 "TARGET_USE_FANCY_MATH_387
22150 && (flag_fp_int_builtin_inexact || !flag_trapping_math)
22151 && ix86_pre_reload_split ()"
22156 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
22158 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
22159 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
22161 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
22162 operands[2], operands[3]));
22165 [(set_attr "type" "frndint")
22166 (set_attr "i387_cw" "<rounding>")
22167 (set_attr "mode" "XF")])
22169 (define_insn "frndintxf2_<rounding>_i387"
22170 [(set (match_operand:XF 0 "register_operand" "=f")
22171 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
22173 (use (match_operand:HI 2 "memory_operand" "m"))
22174 (use (match_operand:HI 3 "memory_operand" "m"))]
22175 "TARGET_USE_FANCY_MATH_387
22176 && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
22177 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
22178 [(set_attr "type" "frndint")
22179 (set_attr "i387_cw" "<rounding>")
22180 (set_attr "mode" "XF")])
22182 (define_expand "<rounding_insn>xf2"
22183 [(parallel [(set (match_operand:XF 0 "register_operand")
22184 (unspec:XF [(match_operand:XF 1 "register_operand")]
22186 (clobber (reg:CC FLAGS_REG))])]
22187 "TARGET_USE_FANCY_MATH_387
22188 && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
22190 (define_expand "<rounding_insn>hf2"
22191 [(parallel [(set (match_operand:HF 0 "register_operand")
22192 (unspec:HF [(match_operand:HF 1 "register_operand")]
22194 (clobber (reg:CC FLAGS_REG))])]
22195 "TARGET_AVX512FP16"
22197 emit_insn (gen_sse4_1_roundhf2 (operands[0], operands[1],
22198 GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
22202 (define_expand "<rounding_insn><mode>2"
22203 [(parallel [(set (match_operand:MODEF 0 "register_operand")
22204 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
22206 (clobber (reg:CC FLAGS_REG))])]
22207 "(TARGET_USE_FANCY_MATH_387
22208 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22209 || TARGET_MIX_SSE_I387)
22210 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
22211 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
22213 || (ROUND_<ROUNDING> != ROUND_ROUNDEVEN
22214 && (flag_fp_int_builtin_inexact || !flag_trapping_math))))"
22216 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
22218 || (ROUND_<ROUNDING> != ROUND_ROUNDEVEN
22219 && (flag_fp_int_builtin_inexact || !flag_trapping_math))))
22222 emit_insn (gen_sse4_1_round<mode>2
22223 (operands[0], operands[1],
22224 GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
22225 else if (TARGET_64BIT || (<MODE>mode != DFmode))
22227 if (ROUND_<ROUNDING> == ROUND_FLOOR)
22228 ix86_expand_floorceil (operands[0], operands[1], true);
22229 else if (ROUND_<ROUNDING> == ROUND_CEIL)
22230 ix86_expand_floorceil (operands[0], operands[1], false);
22231 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
22232 ix86_expand_trunc (operands[0], operands[1]);
22234 gcc_unreachable ();
22238 if (ROUND_<ROUNDING> == ROUND_FLOOR)
22239 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
22240 else if (ROUND_<ROUNDING> == ROUND_CEIL)
22241 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
22242 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
22243 ix86_expand_truncdf_32 (operands[0], operands[1]);
22245 gcc_unreachable ();
22250 rtx op0 = gen_reg_rtx (XFmode);
22251 rtx op1 = gen_reg_rtx (XFmode);
22253 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22254 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
22255 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
22260 ;; Rounding mode control word calculation could clobber FLAGS_REG.
22261 (define_insn_and_split "*fist<mode>2_<rounding>_1"
22262 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
22263 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
22265 (clobber (reg:CC FLAGS_REG))]
22266 "TARGET_USE_FANCY_MATH_387
22267 && flag_unsafe_math_optimizations
22268 && ix86_pre_reload_split ()"
22273 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
22275 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
22276 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
22278 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
22279 operands[2], operands[3]));
22282 [(set_attr "type" "fistp")
22283 (set_attr "i387_cw" "<rounding>")
22284 (set_attr "mode" "<MODE>")])
22286 (define_insn "fistdi2_<rounding>"
22287 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
22288 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
22290 (use (match_operand:HI 2 "memory_operand" "m"))
22291 (use (match_operand:HI 3 "memory_operand" "m"))
22292 (clobber (match_scratch:XF 4 "=&f"))]
22293 "TARGET_USE_FANCY_MATH_387
22294 && flag_unsafe_math_optimizations"
22295 "* return output_fix_trunc (insn, operands, false);"
22296 [(set_attr "type" "fistp")
22297 (set_attr "i387_cw" "<rounding>")
22298 (set_attr "mode" "DI")])
22300 (define_insn "fist<mode>2_<rounding>"
22301 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
22302 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
22304 (use (match_operand:HI 2 "memory_operand" "m"))
22305 (use (match_operand:HI 3 "memory_operand" "m"))]
22306 "TARGET_USE_FANCY_MATH_387
22307 && flag_unsafe_math_optimizations"
22308 "* return output_fix_trunc (insn, operands, false);"
22309 [(set_attr "type" "fistp")
22310 (set_attr "i387_cw" "<rounding>")
22311 (set_attr "mode" "<MODE>")])
22313 (define_expand "l<rounding_insn>xf<mode>2"
22314 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
22315 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
22317 (clobber (reg:CC FLAGS_REG))])]
22318 "TARGET_USE_FANCY_MATH_387
22319 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
22320 && flag_unsafe_math_optimizations")
22322 (define_expand "l<rounding_insn>hf<mode>2"
22323 [(set (match_operand:SWI48 0 "nonimmediate_operand")
22324 (unspec:SWI48 [(match_operand:HF 1 "register_operand")]
22326 "TARGET_AVX512FP16"
22328 rtx tmp = gen_reg_rtx (HFmode);
22329 emit_insn (gen_sse4_1_roundhf2 (tmp, operands[1],
22330 GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
22331 emit_insn (gen_fix_trunchf<mode>2 (operands[0], tmp));
22335 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
22336 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
22337 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
22339 (clobber (reg:CC FLAGS_REG))])]
22340 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
22341 && (TARGET_SSE4_1 || !flag_trapping_math)"
22345 rtx tmp = gen_reg_rtx (<MODEF:MODE>mode);
22347 emit_insn (gen_sse4_1_round<MODEF:mode>2
22348 (tmp, operands[1], GEN_INT (ROUND_<ROUNDING>
22350 emit_insn (gen_fix_trunc<MODEF:mode><SWI48:mode>2
22351 (operands[0], tmp));
22353 else if (ROUND_<ROUNDING> == ROUND_FLOOR)
22354 ix86_expand_lfloorceil (operands[0], operands[1], true);
22355 else if (ROUND_<ROUNDING> == ROUND_CEIL)
22356 ix86_expand_lfloorceil (operands[0], operands[1], false);
22358 gcc_unreachable ();
22363 (define_insn "fxam<mode>2_i387"
22364 [(set (match_operand:HI 0 "register_operand" "=a")
22366 [(match_operand:X87MODEF 1 "register_operand" "f")]
22368 "TARGET_USE_FANCY_MATH_387"
22369 "fxam\n\tfnstsw\t%0"
22370 [(set_attr "type" "multi")
22371 (set_attr "length" "4")
22372 (set_attr "unit" "i387")
22373 (set_attr "mode" "<MODE>")])
22375 (define_expand "signbittf2"
22376 [(use (match_operand:SI 0 "register_operand"))
22377 (use (match_operand:TF 1 "register_operand"))]
22382 rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
22383 rtx scratch = gen_reg_rtx (QImode);
22385 emit_insn (gen_ptesttf2 (operands[1], mask));
22386 ix86_expand_setcc (scratch, NE,
22387 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
22389 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
22393 emit_insn (gen_sse_movmskps (operands[0],
22394 gen_lowpart (V4SFmode, operands[1])));
22395 emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8)));
22400 (define_expand "signbitxf2"
22401 [(use (match_operand:SI 0 "register_operand"))
22402 (use (match_operand:XF 1 "register_operand"))]
22403 "TARGET_USE_FANCY_MATH_387"
22405 rtx scratch = gen_reg_rtx (HImode);
22407 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
22408 emit_insn (gen_andsi3 (operands[0],
22409 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
22413 (define_insn "movmsk_df"
22414 [(set (match_operand:SI 0 "register_operand" "=r,jr")
22416 [(match_operand:DF 1 "register_operand" "x,x")]
22418 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
22419 "%vmovmskpd\t{%1, %0|%0, %1}"
22420 [(set_attr "isa" "noavx,avx")
22421 (set_attr "type" "ssemov")
22422 (set_attr "prefix" "maybe_evex")
22423 (set_attr "mode" "DF")])
22425 ;; Use movmskpd in SSE mode to avoid store forwarding stall
22426 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
22427 (define_expand "signbitdf2"
22428 [(use (match_operand:SI 0 "register_operand"))
22429 (use (match_operand:DF 1 "register_operand"))]
22430 "TARGET_USE_FANCY_MATH_387
22431 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
22433 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
22435 emit_insn (gen_movmsk_df (operands[0], operands[1]));
22436 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
22440 rtx scratch = gen_reg_rtx (HImode);
22442 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
22443 emit_insn (gen_andsi3 (operands[0],
22444 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
22449 (define_expand "signbitsf2"
22450 [(use (match_operand:SI 0 "register_operand"))
22451 (use (match_operand:SF 1 "register_operand"))]
22452 "TARGET_USE_FANCY_MATH_387
22453 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
22455 rtx scratch = gen_reg_rtx (HImode);
22457 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
22458 emit_insn (gen_andsi3 (operands[0],
22459 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
22463 ;; Block operation instructions
22466 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
22469 [(set_attr "length" "1")
22470 (set_attr "length_immediate" "0")
22471 (set_attr "modrm" "0")])
22473 (define_expand "cpymem<mode>"
22474 [(use (match_operand:BLK 0 "memory_operand"))
22475 (use (match_operand:BLK 1 "memory_operand"))
22476 (use (match_operand:SWI48 2 "nonmemory_operand"))
22477 (use (match_operand:SWI48 3 "const_int_operand"))
22478 (use (match_operand:SI 4 "const_int_operand"))
22479 (use (match_operand:SI 5 "const_int_operand"))
22480 (use (match_operand:SI 6 ""))
22481 (use (match_operand:SI 7 ""))
22482 (use (match_operand:SI 8 ""))]
22485 if (ix86_expand_set_or_cpymem (operands[0], operands[1],
22486 operands[2], NULL, operands[3],
22487 operands[4], operands[5],
22488 operands[6], operands[7],
22489 operands[8], false))
22495 ;; Most CPUs don't like single string operations
22496 ;; Handle this case here to simplify previous expander.
22498 (define_expand "strmov"
22499 [(set (match_dup 4) (match_operand 3 "memory_operand"))
22500 (set (match_operand 1 "memory_operand") (match_dup 4))
22501 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
22502 (clobber (reg:CC FLAGS_REG))])
22503 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
22504 (clobber (reg:CC FLAGS_REG))])]
22507 /* Can't use this for non-default address spaces. */
22508 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
22511 int piece_size = GET_MODE_SIZE (GET_MODE (operands[1]));
22513 /* If .md ever supports :P for Pmode, these can be directly
22514 in the pattern above. */
22515 operands[5] = plus_constant (Pmode, operands[0], piece_size);
22516 operands[6] = plus_constant (Pmode, operands[2], piece_size);
22518 /* Can't use this if the user has appropriated esi or edi. */
22519 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
22520 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
22522 emit_insn (gen_strmov_singleop (operands[0], operands[1],
22523 operands[2], operands[3],
22524 operands[5], operands[6]));
22528 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
22531 (define_expand "strmov_singleop"
22532 [(parallel [(set (match_operand 1 "memory_operand")
22533 (match_operand 3 "memory_operand"))
22534 (set (match_operand 0 "register_operand")
22536 (set (match_operand 2 "register_operand")
22537 (match_operand 5))])]
22541 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22544 (define_insn "*strmovdi_rex_1"
22545 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
22546 (mem:DI (match_operand:P 3 "register_operand" "1")))
22547 (set (match_operand:P 0 "register_operand" "=D")
22548 (plus:P (match_dup 2)
22550 (set (match_operand:P 1 "register_operand" "=S")
22551 (plus:P (match_dup 3)
22554 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22555 && ix86_check_no_addr_space (insn)"
22557 [(set_attr "type" "str")
22558 (set_attr "memory" "both")
22559 (set_attr "mode" "DI")])
22561 (define_insn "*strmovsi_1"
22562 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
22563 (mem:SI (match_operand:P 3 "register_operand" "1")))
22564 (set (match_operand:P 0 "register_operand" "=D")
22565 (plus:P (match_dup 2)
22567 (set (match_operand:P 1 "register_operand" "=S")
22568 (plus:P (match_dup 3)
22570 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22571 && ix86_check_no_addr_space (insn)"
22573 [(set_attr "type" "str")
22574 (set_attr "memory" "both")
22575 (set_attr "mode" "SI")])
22577 (define_insn "*strmovhi_1"
22578 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
22579 (mem:HI (match_operand:P 3 "register_operand" "1")))
22580 (set (match_operand:P 0 "register_operand" "=D")
22581 (plus:P (match_dup 2)
22583 (set (match_operand:P 1 "register_operand" "=S")
22584 (plus:P (match_dup 3)
22586 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22587 && ix86_check_no_addr_space (insn)"
22589 [(set_attr "type" "str")
22590 (set_attr "memory" "both")
22591 (set_attr "mode" "HI")])
22593 (define_insn "*strmovqi_1"
22594 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
22595 (mem:QI (match_operand:P 3 "register_operand" "1")))
22596 (set (match_operand:P 0 "register_operand" "=D")
22597 (plus:P (match_dup 2)
22599 (set (match_operand:P 1 "register_operand" "=S")
22600 (plus:P (match_dup 3)
22602 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22603 && ix86_check_no_addr_space (insn)"
22605 [(set_attr "type" "str")
22606 (set_attr "memory" "both")
22607 (set (attr "prefix_rex")
22609 (match_test "<P:MODE>mode == DImode")
22611 (const_string "*")))
22612 (set_attr "mode" "QI")])
22614 (define_expand "rep_mov"
22615 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
22616 (set (match_operand 0 "register_operand")
22618 (set (match_operand 2 "register_operand")
22620 (set (match_operand 1 "memory_operand")
22621 (match_operand 3 "memory_operand"))
22622 (use (match_dup 4))])]
22626 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22629 (define_insn "*rep_movdi_rex64"
22630 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
22631 (set (match_operand:P 0 "register_operand" "=D")
22632 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
22634 (match_operand:P 3 "register_operand" "0")))
22635 (set (match_operand:P 1 "register_operand" "=S")
22636 (plus:P (ashift:P (match_dup 5) (const_int 3))
22637 (match_operand:P 4 "register_operand" "1")))
22638 (set (mem:BLK (match_dup 3))
22639 (mem:BLK (match_dup 4)))
22640 (use (match_dup 5))]
22642 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22643 && ix86_check_no_addr_space (insn)"
22645 [(set_attr "type" "str")
22646 (set_attr "prefix_rep" "1")
22647 (set_attr "memory" "both")
22648 (set_attr "mode" "DI")])
22650 (define_insn "*rep_movsi"
22651 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
22652 (set (match_operand:P 0 "register_operand" "=D")
22653 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
22655 (match_operand:P 3 "register_operand" "0")))
22656 (set (match_operand:P 1 "register_operand" "=S")
22657 (plus:P (ashift:P (match_dup 5) (const_int 2))
22658 (match_operand:P 4 "register_operand" "1")))
22659 (set (mem:BLK (match_dup 3))
22660 (mem:BLK (match_dup 4)))
22661 (use (match_dup 5))]
22662 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22663 && ix86_check_no_addr_space (insn)"
22664 "%^rep{%;} movs{l|d}"
22665 [(set_attr "type" "str")
22666 (set_attr "prefix_rep" "1")
22667 (set_attr "memory" "both")
22668 (set_attr "mode" "SI")])
22670 (define_insn "*rep_movqi"
22671 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
22672 (set (match_operand:P 0 "register_operand" "=D")
22673 (plus:P (match_operand:P 3 "register_operand" "0")
22674 (match_operand:P 5 "register_operand" "2")))
22675 (set (match_operand:P 1 "register_operand" "=S")
22676 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
22677 (set (mem:BLK (match_dup 3))
22678 (mem:BLK (match_dup 4)))
22679 (use (match_dup 5))]
22680 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22681 && ix86_check_no_addr_space (insn)"
22683 [(set_attr "type" "str")
22684 (set_attr "prefix_rep" "1")
22685 (set_attr "memory" "both")
22686 (set_attr "mode" "QI")])
22688 (define_expand "setmem<mode>"
22689 [(use (match_operand:BLK 0 "memory_operand"))
22690 (use (match_operand:SWI48 1 "nonmemory_operand"))
22691 (use (match_operand:QI 2 "nonmemory_operand"))
22692 (use (match_operand 3 "const_int_operand"))
22693 (use (match_operand:SI 4 "const_int_operand"))
22694 (use (match_operand:SI 5 "const_int_operand"))
22695 (use (match_operand:SI 6 ""))
22696 (use (match_operand:SI 7 ""))
22697 (use (match_operand:SI 8 ""))]
22700 if (ix86_expand_set_or_cpymem (operands[0], NULL,
22701 operands[1], operands[2],
22702 operands[3], operands[4],
22703 operands[5], operands[6],
22704 operands[7], operands[8], true))
22710 ;; Most CPUs don't like single string operations
22711 ;; Handle this case here to simplify previous expander.
22713 (define_expand "strset"
22714 [(set (match_operand 1 "memory_operand")
22715 (match_operand 2 "register_operand"))
22716 (parallel [(set (match_operand 0 "register_operand")
22718 (clobber (reg:CC FLAGS_REG))])]
22721 /* Can't use this for non-default address spaces. */
22722 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
22725 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
22726 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
22728 /* If .md ever supports :P for Pmode, this can be directly
22729 in the pattern above. */
22730 operands[3] = plus_constant (Pmode, operands[0],
22731 GET_MODE_SIZE (GET_MODE (operands[2])));
22733 /* Can't use this if the user has appropriated eax or edi. */
22734 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
22735 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
22737 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
22743 (define_expand "strset_singleop"
22744 [(parallel [(set (match_operand 1 "memory_operand")
22745 (match_operand 2 "register_operand"))
22746 (set (match_operand 0 "register_operand")
22748 (unspec [(const_int 0)] UNSPEC_STOS)])]
22752 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22755 (define_insn "*strsetdi_rex_1"
22756 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
22757 (match_operand:DI 2 "register_operand" "a"))
22758 (set (match_operand:P 0 "register_operand" "=D")
22759 (plus:P (match_dup 1)
22761 (unspec [(const_int 0)] UNSPEC_STOS)]
22763 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22764 && ix86_check_no_addr_space (insn)"
22766 [(set_attr "type" "str")
22767 (set_attr "memory" "store")
22768 (set_attr "mode" "DI")])
22770 (define_insn "*strsetsi_1"
22771 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
22772 (match_operand:SI 2 "register_operand" "a"))
22773 (set (match_operand:P 0 "register_operand" "=D")
22774 (plus:P (match_dup 1)
22776 (unspec [(const_int 0)] UNSPEC_STOS)]
22777 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22778 && ix86_check_no_addr_space (insn)"
22780 [(set_attr "type" "str")
22781 (set_attr "memory" "store")
22782 (set_attr "mode" "SI")])
22784 (define_insn "*strsethi_1"
22785 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
22786 (match_operand:HI 2 "register_operand" "a"))
22787 (set (match_operand:P 0 "register_operand" "=D")
22788 (plus:P (match_dup 1)
22790 (unspec [(const_int 0)] UNSPEC_STOS)]
22791 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22792 && ix86_check_no_addr_space (insn)"
22794 [(set_attr "type" "str")
22795 (set_attr "memory" "store")
22796 (set_attr "mode" "HI")])
22798 (define_insn "*strsetqi_1"
22799 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
22800 (match_operand:QI 2 "register_operand" "a"))
22801 (set (match_operand:P 0 "register_operand" "=D")
22802 (plus:P (match_dup 1)
22804 (unspec [(const_int 0)] UNSPEC_STOS)]
22805 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22806 && ix86_check_no_addr_space (insn)"
22808 [(set_attr "type" "str")
22809 (set_attr "memory" "store")
22810 (set (attr "prefix_rex")
22812 (match_test "<P:MODE>mode == DImode")
22814 (const_string "*")))
22815 (set_attr "mode" "QI")])
22817 (define_expand "rep_stos"
22818 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
22819 (set (match_operand 0 "register_operand")
22821 (set (match_operand 2 "memory_operand") (const_int 0))
22822 (use (match_operand 3 "register_operand"))
22823 (use (match_dup 1))])]
22827 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22830 (define_insn "*rep_stosdi_rex64"
22831 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
22832 (set (match_operand:P 0 "register_operand" "=D")
22833 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
22835 (match_operand:P 3 "register_operand" "0")))
22836 (set (mem:BLK (match_dup 3))
22838 (use (match_operand:DI 2 "register_operand" "a"))
22839 (use (match_dup 4))]
22841 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
22842 && ix86_check_no_addr_space (insn)"
22844 [(set_attr "type" "str")
22845 (set_attr "prefix_rep" "1")
22846 (set_attr "memory" "store")
22847 (set_attr "mode" "DI")])
22849 (define_insn "*rep_stossi"
22850 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
22851 (set (match_operand:P 0 "register_operand" "=D")
22852 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
22854 (match_operand:P 3 "register_operand" "0")))
22855 (set (mem:BLK (match_dup 3))
22857 (use (match_operand:SI 2 "register_operand" "a"))
22858 (use (match_dup 4))]
22859 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
22860 && ix86_check_no_addr_space (insn)"
22861 "%^rep{%;} stos{l|d}"
22862 [(set_attr "type" "str")
22863 (set_attr "prefix_rep" "1")
22864 (set_attr "memory" "store")
22865 (set_attr "mode" "SI")])
22867 (define_insn "*rep_stosqi"
22868 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
22869 (set (match_operand:P 0 "register_operand" "=D")
22870 (plus:P (match_operand:P 3 "register_operand" "0")
22871 (match_operand:P 4 "register_operand" "1")))
22872 (set (mem:BLK (match_dup 3))
22874 (use (match_operand:QI 2 "register_operand" "a"))
22875 (use (match_dup 4))]
22876 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
22877 && ix86_check_no_addr_space (insn)"
22879 [(set_attr "type" "str")
22880 (set_attr "prefix_rep" "1")
22881 (set_attr "memory" "store")
22882 (set (attr "prefix_rex")
22884 (match_test "<P:MODE>mode == DImode")
22886 (const_string "*")))
22887 (set_attr "mode" "QI")])
22889 (define_expand "cmpmemsi"
22890 [(set (match_operand:SI 0 "register_operand" "")
22891 (compare:SI (match_operand:BLK 1 "memory_operand" "")
22892 (match_operand:BLK 2 "memory_operand" "") ) )
22893 (use (match_operand 3 "general_operand"))
22894 (use (match_operand 4 "immediate_operand"))]
22897 if (ix86_expand_cmpstrn_or_cmpmem (operands[0], operands[1],
22898 operands[2], operands[3],
22899 operands[4], false))
22905 (define_expand "cmpstrnsi"
22906 [(set (match_operand:SI 0 "register_operand")
22907 (compare:SI (match_operand:BLK 1 "general_operand")
22908 (match_operand:BLK 2 "general_operand")))
22909 (use (match_operand 3 "general_operand"))
22910 (use (match_operand 4 "immediate_operand"))]
22913 if (ix86_expand_cmpstrn_or_cmpmem (operands[0], operands[1],
22914 operands[2], operands[3],
22915 operands[4], true))
22921 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
22923 (define_expand "cmpintqi"
22924 [(set (match_dup 1)
22925 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
22927 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
22928 (parallel [(set (match_operand:QI 0 "register_operand")
22929 (minus:QI (match_dup 1)
22931 (clobber (reg:CC FLAGS_REG))])]
22934 operands[1] = gen_reg_rtx (QImode);
22935 operands[2] = gen_reg_rtx (QImode);
22938 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
22939 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
22941 (define_expand "cmpstrnqi_nz_1"
22942 [(parallel [(set (reg:CC FLAGS_REG)
22943 (compare:CC (match_operand 4 "memory_operand")
22944 (match_operand 5 "memory_operand")))
22945 (use (match_operand 2 "register_operand"))
22946 (use (match_operand:SI 3 "immediate_operand"))
22947 (clobber (match_operand 0 "register_operand"))
22948 (clobber (match_operand 1 "register_operand"))
22949 (clobber (match_dup 2))])]
22953 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22956 (define_insn "*cmpstrnqi_nz_1"
22957 [(set (reg:CC FLAGS_REG)
22958 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
22959 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
22960 (use (match_operand:P 6 "register_operand" "2"))
22961 (use (match_operand:SI 3 "immediate_operand" "i"))
22962 (clobber (match_operand:P 0 "register_operand" "=S"))
22963 (clobber (match_operand:P 1 "register_operand" "=D"))
22964 (clobber (match_operand:P 2 "register_operand" "=c"))]
22965 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22966 && ix86_check_no_addr_space (insn)"
22968 [(set_attr "type" "str")
22969 (set_attr "mode" "QI")
22970 (set (attr "prefix_rex")
22972 (match_test "<P:MODE>mode == DImode")
22974 (const_string "*")))
22975 (set_attr "prefix_rep" "1")])
22977 ;; The same, but the count is not known to not be zero.
22979 (define_expand "cmpstrnqi_1"
22980 [(parallel [(set (reg:CC FLAGS_REG)
22981 (if_then_else:CC (ne (match_operand 2 "register_operand")
22983 (compare:CC (match_operand 4 "memory_operand")
22984 (match_operand 5 "memory_operand"))
22986 (use (match_operand:SI 3 "immediate_operand"))
22987 (use (reg:CC FLAGS_REG))
22988 (clobber (match_operand 0 "register_operand"))
22989 (clobber (match_operand 1 "register_operand"))
22990 (clobber (match_dup 2))])]
22994 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22997 (define_insn "*cmpstrnqi_1"
22998 [(set (reg:CC FLAGS_REG)
22999 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
23001 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
23002 (mem:BLK (match_operand:P 5 "register_operand" "1")))
23004 (use (match_operand:SI 3 "immediate_operand" "i"))
23005 (use (reg:CC FLAGS_REG))
23006 (clobber (match_operand:P 0 "register_operand" "=S"))
23007 (clobber (match_operand:P 1 "register_operand" "=D"))
23008 (clobber (match_operand:P 2 "register_operand" "=c"))]
23009 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
23010 && ix86_check_no_addr_space (insn)"
23012 [(set_attr "type" "str")
23013 (set_attr "mode" "QI")
23014 (set (attr "prefix_rex")
23016 (match_test "<P:MODE>mode == DImode")
23018 (const_string "*")))
23019 (set_attr "prefix_rep" "1")])
23021 (define_expand "strlen<mode>"
23022 [(set (match_operand:P 0 "register_operand")
23023 (unspec:P [(match_operand:BLK 1 "general_operand")
23024 (match_operand:QI 2 "immediate_operand")
23025 (match_operand 3 "immediate_operand")]
23029 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
23035 (define_expand "strlenqi_1"
23036 [(parallel [(set (match_operand 0 "register_operand")
23038 (clobber (match_operand 1 "register_operand"))
23039 (clobber (reg:CC FLAGS_REG))])]
23043 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
23046 (define_insn "*strlenqi_1"
23047 [(set (match_operand:P 0 "register_operand" "=&c")
23048 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
23049 (match_operand:QI 2 "register_operand" "a")
23050 (match_operand:P 3 "immediate_operand" "i")
23051 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
23052 (clobber (match_operand:P 1 "register_operand" "=D"))
23053 (clobber (reg:CC FLAGS_REG))]
23054 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
23055 && ix86_check_no_addr_space (insn)"
23056 "%^repnz{%;} scasb"
23057 [(set_attr "type" "str")
23058 (set_attr "mode" "QI")
23059 (set (attr "prefix_rex")
23061 (match_test "<P:MODE>mode == DImode")
23063 (const_string "*")))
23064 (set_attr "prefix_rep" "1")])
23066 ;; Peephole optimizations to clean up after cmpstrn*. This should be
23067 ;; handled in combine, but it is not currently up to the task.
23068 ;; When used for their truth value, the cmpstrn* expanders generate
23077 ;; The intermediate three instructions are unnecessary.
23079 ;; This one handles cmpstrn*_nz_1...
23082 (set (reg:CC FLAGS_REG)
23083 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
23084 (mem:BLK (match_operand 5 "register_operand"))))
23085 (use (match_operand 6 "register_operand"))
23086 (use (match_operand:SI 3 "immediate_operand"))
23087 (clobber (match_operand 0 "register_operand"))
23088 (clobber (match_operand 1 "register_operand"))
23089 (clobber (match_operand 2 "register_operand"))])
23090 (set (match_operand:QI 7 "register_operand")
23091 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
23092 (set (match_operand:QI 8 "register_operand")
23093 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
23094 (set (reg FLAGS_REG)
23095 (compare (match_dup 7) (match_dup 8)))
23097 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
23099 (set (reg:CC FLAGS_REG)
23100 (compare:CC (mem:BLK (match_dup 4))
23101 (mem:BLK (match_dup 5))))
23102 (use (match_dup 6))
23103 (use (match_dup 3))
23104 (clobber (match_dup 0))
23105 (clobber (match_dup 1))
23106 (clobber (match_dup 2))])])
23108 ;; ...and this one handles cmpstrn*_1.
23111 (set (reg:CC FLAGS_REG)
23112 (if_then_else:CC (ne (match_operand 6 "register_operand")
23114 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
23115 (mem:BLK (match_operand 5 "register_operand")))
23117 (use (match_operand:SI 3 "immediate_operand"))
23118 (use (reg:CC FLAGS_REG))
23119 (clobber (match_operand 0 "register_operand"))
23120 (clobber (match_operand 1 "register_operand"))
23121 (clobber (match_operand 2 "register_operand"))])
23122 (set (match_operand:QI 7 "register_operand")
23123 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
23124 (set (match_operand:QI 8 "register_operand")
23125 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
23126 (set (reg FLAGS_REG)
23127 (compare (match_dup 7) (match_dup 8)))
23129 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
23131 (set (reg:CC FLAGS_REG)
23132 (if_then_else:CC (ne (match_dup 6)
23134 (compare:CC (mem:BLK (match_dup 4))
23135 (mem:BLK (match_dup 5)))
23137 (use (match_dup 3))
23138 (use (reg:CC FLAGS_REG))
23139 (clobber (match_dup 0))
23140 (clobber (match_dup 1))
23141 (clobber (match_dup 2))])])
23143 ;; Conditional move instructions.
23145 (define_expand "mov<mode>cc"
23146 [(set (match_operand:SWIM 0 "register_operand")
23147 (if_then_else:SWIM (match_operand 1 "comparison_operator")
23148 (match_operand:SWIM 2 "<general_operand>")
23149 (match_operand:SWIM 3 "<general_operand>")))]
23151 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
23153 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
23154 ;; the register first winds up with `sbbl $0,reg', which is also weird.
23155 ;; So just document what we're doing explicitly.
23157 (define_expand "x86_mov<mode>cc_0_m1"
23159 [(set (match_operand:SWI48 0 "register_operand")
23160 (if_then_else:SWI48
23161 (match_operator:SWI48 2 "ix86_carry_flag_operator"
23162 [(match_operand 1 "flags_reg_operand")
23166 (clobber (reg:CC FLAGS_REG))])])
23168 (define_insn "*x86_mov<mode>cc_0_m1"
23169 [(set (match_operand:SWI48 0 "register_operand" "=r")
23170 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
23171 [(reg FLAGS_REG) (const_int 0)])
23174 (clobber (reg:CC FLAGS_REG))]
23176 "sbb{<imodesuffix>}\t%0, %0"
23177 [(set_attr "type" "alu1")
23178 (set_attr "use_carry" "1")
23179 (set_attr "pent_pair" "pu")
23180 (set_attr "mode" "<MODE>")
23181 (set_attr "length_immediate" "0")])
23183 (define_insn "*x86_mov<mode>cc_0_m1_se"
23184 [(set (match_operand:SWI48 0 "register_operand" "=r")
23185 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
23186 [(reg FLAGS_REG) (const_int 0)])
23189 (clobber (reg:CC FLAGS_REG))]
23191 "sbb{<imodesuffix>}\t%0, %0"
23192 [(set_attr "type" "alu1")
23193 (set_attr "use_carry" "1")
23194 (set_attr "pent_pair" "pu")
23195 (set_attr "mode" "<MODE>")
23196 (set_attr "length_immediate" "0")])
23198 (define_insn "*x86_mov<mode>cc_0_m1_neg"
23199 [(set (match_operand:SWI 0 "register_operand" "=<r>")
23200 (neg:SWI (match_operator 1 "ix86_carry_flag_operator"
23201 [(reg FLAGS_REG) (const_int 0)])))
23202 (clobber (reg:CC FLAGS_REG))]
23204 "sbb{<imodesuffix>}\t%0, %0"
23205 [(set_attr "type" "alu1")
23206 (set_attr "use_carry" "1")
23207 (set_attr "pent_pair" "pu")
23208 (set_attr "mode" "<MODE>")
23209 (set_attr "length_immediate" "0")])
23211 (define_expand "x86_mov<mode>cc_0_m1_neg"
23213 [(set (match_operand:SWI48 0 "register_operand")
23214 (neg:SWI48 (ltu:SWI48 (reg:CCC FLAGS_REG) (const_int 0))))
23215 (clobber (reg:CC FLAGS_REG))])])
23218 [(set (match_operand:SWI48 0 "register_operand")
23221 (match_operand 1 "int_nonimmediate_operand")
23222 (match_operand 2 "const_int_operand"))))]
23223 "x86_64_immediate_operand (operands[2], VOIDmode)
23224 && INTVAL (operands[2]) != -1
23225 && INTVAL (operands[2]) != 2147483647"
23226 [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
23228 (neg:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))))]
23229 "operands[2] = GEN_INT (INTVAL (operands[2]) + 1);")
23232 [(set (match_operand:SWI 0 "register_operand")
23235 (match_operand 1 "int_nonimmediate_operand")
23238 [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (const_int 1)))
23240 (neg:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))))])
23243 [(set (match_operand:SWI 0 "register_operand")
23246 (match_operand 1 "int_nonimmediate_operand")
23249 [(set (reg:CCC FLAGS_REG)
23250 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
23252 (neg:SWI (ltu:SWI (reg:CCC FLAGS_REG) (const_int 0))))])
23254 (define_insn "*mov<mode>cc_noc"
23255 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
23256 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
23257 [(reg FLAGS_REG) (const_int 0)])
23258 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
23259 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
23260 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23262 cmov%O2%C1\t{%2, %0|%0, %2}
23263 cmov%O2%c1\t{%3, %0|%0, %3}"
23264 [(set_attr "type" "icmov")
23265 (set_attr "mode" "<MODE>")])
23267 (define_insn "*movsicc_noc_zext"
23268 [(set (match_operand:DI 0 "register_operand" "=r,r")
23269 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
23270 [(reg FLAGS_REG) (const_int 0)])
23272 (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
23274 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
23276 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23278 cmov%O2%C1\t{%2, %k0|%k0, %2}
23279 cmov%O2%c1\t{%3, %k0|%k0, %3}"
23280 [(set_attr "type" "icmov")
23281 (set_attr "mode" "SI")])
23283 (define_insn "*movsicc_noc_zext_1"
23284 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r")
23286 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
23287 [(reg FLAGS_REG) (const_int 0)])
23288 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
23289 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
23291 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23293 cmov%O2%C1\t{%2, %k0|%k0, %2}
23294 cmov%O2%c1\t{%3, %k0|%k0, %3}"
23295 [(set_attr "type" "icmov")
23296 (set_attr "mode" "SI")])
23299 ;; Don't do conditional moves with memory inputs. This splitter helps
23300 ;; register starved x86_32 by forcing inputs into registers before reload.
23302 [(set (match_operand:SWI248 0 "register_operand")
23303 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
23304 [(reg FLAGS_REG) (const_int 0)])
23305 (match_operand:SWI248 2 "nonimmediate_operand")
23306 (match_operand:SWI248 3 "nonimmediate_operand")))]
23307 "!TARGET_64BIT && TARGET_CMOVE
23308 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23309 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23310 && can_create_pseudo_p ()
23311 && optimize_insn_for_speed_p ()"
23312 [(set (match_dup 0)
23313 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
23315 operands[2] = force_reg (<MODE>mode, operands[2]);
23316 operands[3] = force_reg (<MODE>mode, operands[3]);
23319 (define_insn "*movqicc_noc"
23320 [(set (match_operand:QI 0 "register_operand" "=r,r")
23321 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
23322 [(reg FLAGS_REG) (const_int 0)])
23323 (match_operand:QI 2 "register_operand" "r,0")
23324 (match_operand:QI 3 "register_operand" "0,r")))]
23325 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
23327 [(set_attr "type" "icmov")
23328 (set_attr "mode" "QI")])
23331 [(set (match_operand:SWI12 0 "register_operand")
23332 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
23333 [(reg FLAGS_REG) (const_int 0)])
23334 (match_operand:SWI12 2 "register_operand")
23335 (match_operand:SWI12 3 "register_operand")))]
23336 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
23337 && reload_completed"
23338 [(set (match_dup 0)
23339 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
23341 operands[0] = gen_lowpart (SImode, operands[0]);
23342 operands[2] = gen_lowpart (SImode, operands[2]);
23343 operands[3] = gen_lowpart (SImode, operands[3]);
23346 ;; Don't do conditional moves with memory inputs
23348 [(match_scratch:SWI248 4 "r")
23349 (set (match_operand:SWI248 0 "register_operand")
23350 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
23351 [(reg FLAGS_REG) (const_int 0)])
23352 (match_operand:SWI248 2 "nonimmediate_operand")
23353 (match_operand:SWI248 3 "nonimmediate_operand")))]
23354 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23355 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23356 && optimize_insn_for_speed_p ()"
23357 [(set (match_dup 4) (match_dup 5))
23359 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
23361 if (MEM_P (operands[2]))
23363 operands[5] = operands[2];
23364 operands[2] = operands[4];
23366 else if (MEM_P (operands[3]))
23368 operands[5] = operands[3];
23369 operands[3] = operands[4];
23372 gcc_unreachable ();
23376 [(match_scratch:SI 4 "r")
23377 (set (match_operand:DI 0 "register_operand")
23378 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
23379 [(reg FLAGS_REG) (const_int 0)])
23381 (match_operand:SI 2 "nonimmediate_operand"))
23383 (match_operand:SI 3 "nonimmediate_operand"))))]
23385 && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23386 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23387 && optimize_insn_for_speed_p ()"
23388 [(set (match_dup 4) (match_dup 5))
23390 (if_then_else:DI (match_dup 1)
23391 (zero_extend:DI (match_dup 2))
23392 (zero_extend:DI (match_dup 3))))]
23394 if (MEM_P (operands[2]))
23396 operands[5] = operands[2];
23397 operands[2] = operands[4];
23399 else if (MEM_P (operands[3]))
23401 operands[5] = operands[3];
23402 operands[3] = operands[4];
23405 gcc_unreachable ();
23408 ;; Eliminate a reg-reg mov by inverting the condition of a cmov (#1).
23409 ;; mov r0,r1; dec r0; mov r2,r3; cmov r0,r2 -> dec r1; mov r0,r3; cmov r0, r1
23411 [(set (match_operand:SWI248 0 "general_reg_operand")
23412 (match_operand:SWI248 1 "general_reg_operand"))
23413 (parallel [(set (reg FLAGS_REG) (match_operand 5))
23414 (set (match_dup 0) (match_operand:SWI248 6))])
23415 (set (match_operand:SWI248 2 "general_reg_operand")
23416 (match_operand:SWI248 3 "general_gr_operand"))
23418 (if_then_else:SWI248 (match_operator 4 "ix86_comparison_operator"
23419 [(reg FLAGS_REG) (const_int 0)])
23423 && REGNO (operands[2]) != REGNO (operands[0])
23424 && REGNO (operands[2]) != REGNO (operands[1])
23425 && peep2_reg_dead_p (1, operands[1])
23426 && peep2_reg_dead_p (4, operands[2])
23427 && !reg_overlap_mentioned_p (operands[0], operands[3])"
23428 [(parallel [(set (match_dup 7) (match_dup 8))
23429 (set (match_dup 1) (match_dup 9))])
23430 (set (match_dup 0) (match_dup 3))
23431 (set (match_dup 0) (if_then_else:SWI248 (match_dup 4)
23435 operands[7] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
23437 = ix86_replace_reg_with_reg (operands[5], operands[0], operands[1]);
23439 = ix86_replace_reg_with_reg (operands[6], operands[0], operands[1]);
23442 ;; Eliminate a reg-reg mov by inverting the condition of a cmov (#2).
23443 ;; mov r2,r3; mov r0,r1; dec r0; cmov r0,r2 -> dec r1; mov r0,r3; cmov r0, r1
23445 [(set (match_operand:SWI248 2 "general_reg_operand")
23446 (match_operand:SWI248 3 "general_gr_operand"))
23447 (set (match_operand:SWI248 0 "general_reg_operand")
23448 (match_operand:SWI248 1 "general_reg_operand"))
23449 (parallel [(set (reg FLAGS_REG) (match_operand 5))
23450 (set (match_dup 0) (match_operand:SWI248 6))])
23452 (if_then_else:SWI248 (match_operator 4 "ix86_comparison_operator"
23453 [(reg FLAGS_REG) (const_int 0)])
23457 && REGNO (operands[2]) != REGNO (operands[0])
23458 && REGNO (operands[2]) != REGNO (operands[1])
23459 && peep2_reg_dead_p (2, operands[1])
23460 && peep2_reg_dead_p (4, operands[2])
23461 && !reg_overlap_mentioned_p (operands[0], operands[3])
23462 && !reg_mentioned_p (operands[2], operands[6])"
23463 [(parallel [(set (match_dup 7) (match_dup 8))
23464 (set (match_dup 1) (match_dup 9))])
23465 (set (match_dup 0) (match_dup 3))
23466 (set (match_dup 0) (if_then_else:SWI248 (match_dup 4)
23470 operands[7] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (2)), 0, 0));
23472 = ix86_replace_reg_with_reg (operands[5], operands[0], operands[1]);
23474 = ix86_replace_reg_with_reg (operands[6], operands[0], operands[1]);
23477 (define_insn "movhf_mask"
23478 [(set (match_operand:HF 0 "nonimmediate_operand" "=v,m,v")
23480 [(match_operand:HF 1 "nonimmediate_operand" "m,v,v")
23481 (match_operand:HF 2 "nonimm_or_0_operand" "0C,0C,0C")
23482 (match_operand:QI 3 "register_operand" "Yk,Yk,Yk")]
23483 UNSPEC_MOVCC_MASK))]
23484 "TARGET_AVX512FP16"
23486 vmovsh\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}
23487 vmovsh\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}
23488 vmovsh\t{%d1, %0%{%3%}%N2|%0%{%3%}%N2, %d1}"
23489 [(set_attr "type" "ssemov")
23490 (set_attr "prefix" "evex")
23491 (set_attr "mode" "HF")])
23493 (define_expand "movhfcc"
23494 [(set (match_operand:HF 0 "register_operand")
23496 (match_operand 1 "comparison_operator")
23497 (match_operand:HF 2 "register_operand")
23498 (match_operand:HF 3 "register_operand")))]
23499 "TARGET_AVX512FP16"
23500 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
23502 (define_expand "mov<mode>cc"
23503 [(set (match_operand:X87MODEF 0 "register_operand")
23504 (if_then_else:X87MODEF
23505 (match_operand 1 "comparison_operator")
23506 (match_operand:X87MODEF 2 "register_operand")
23507 (match_operand:X87MODEF 3 "register_operand")))]
23508 "(TARGET_80387 && TARGET_CMOVE)
23509 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
23510 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
23512 (define_insn "*movxfcc_1"
23513 [(set (match_operand:XF 0 "register_operand" "=f,f")
23514 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
23515 [(reg FLAGS_REG) (const_int 0)])
23516 (match_operand:XF 2 "register_operand" "f,0")
23517 (match_operand:XF 3 "register_operand" "0,f")))]
23518 "TARGET_80387 && TARGET_CMOVE"
23520 fcmov%F1\t{%2, %0|%0, %2}
23521 fcmov%f1\t{%3, %0|%0, %3}"
23522 [(set_attr "type" "fcmov")
23523 (set_attr "mode" "XF")])
23525 (define_insn "*movdfcc_1"
23526 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
23527 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
23528 [(reg FLAGS_REG) (const_int 0)])
23529 (match_operand:DF 2 "nonimmediate_operand"
23531 (match_operand:DF 3 "nonimmediate_operand"
23532 "0 ,f,0 ,rm,0, rm")))]
23533 "TARGET_80387 && TARGET_CMOVE
23534 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23536 fcmov%F1\t{%2, %0|%0, %2}
23537 fcmov%f1\t{%3, %0|%0, %3}
23540 cmov%O2%C1\t{%2, %0|%0, %2}
23541 cmov%O2%c1\t{%3, %0|%0, %3}"
23542 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
23543 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
23544 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
23547 [(set (match_operand:DF 0 "general_reg_operand")
23548 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
23549 [(reg FLAGS_REG) (const_int 0)])
23550 (match_operand:DF 2 "nonimmediate_operand")
23551 (match_operand:DF 3 "nonimmediate_operand")))]
23552 "!TARGET_64BIT && reload_completed"
23553 [(set (match_dup 2)
23554 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
23556 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
23558 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
23559 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
23562 (define_insn "*movsfcc_1_387"
23563 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
23564 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
23565 [(reg FLAGS_REG) (const_int 0)])
23566 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
23567 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
23568 "TARGET_80387 && TARGET_CMOVE
23569 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23571 fcmov%F1\t{%2, %0|%0, %2}
23572 fcmov%f1\t{%3, %0|%0, %3}
23573 cmov%O2%C1\t{%2, %0|%0, %2}
23574 cmov%O2%c1\t{%3, %0|%0, %3}"
23575 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
23576 (set_attr "mode" "SF,SF,SI,SI")])
23578 ;; Don't do conditional moves with memory inputs. This splitter helps
23579 ;; register starved x86_32 by forcing inputs into registers before reload.
23581 [(set (match_operand:MODEF 0 "register_operand")
23582 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
23583 [(reg FLAGS_REG) (const_int 0)])
23584 (match_operand:MODEF 2 "nonimmediate_operand")
23585 (match_operand:MODEF 3 "nonimmediate_operand")))]
23586 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
23587 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23588 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23589 && can_create_pseudo_p ()
23590 && optimize_insn_for_speed_p ()"
23591 [(set (match_dup 0)
23592 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
23594 operands[2] = force_reg (<MODE>mode, operands[2]);
23595 operands[3] = force_reg (<MODE>mode, operands[3]);
23598 ;; Don't do conditional moves with memory inputs
23600 [(match_scratch:MODEF 4 "r")
23601 (set (match_operand:MODEF 0 "general_reg_operand")
23602 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
23603 [(reg FLAGS_REG) (const_int 0)])
23604 (match_operand:MODEF 2 "nonimmediate_operand")
23605 (match_operand:MODEF 3 "nonimmediate_operand")))]
23606 "(<MODE>mode != DFmode || TARGET_64BIT)
23607 && TARGET_80387 && TARGET_CMOVE
23608 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23609 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23610 && optimize_insn_for_speed_p ()"
23611 [(set (match_dup 4) (match_dup 5))
23613 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
23615 if (MEM_P (operands[2]))
23617 operands[5] = operands[2];
23618 operands[2] = operands[4];
23620 else if (MEM_P (operands[3]))
23622 operands[5] = operands[3];
23623 operands[3] = operands[4];
23626 gcc_unreachable ();
23629 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
23630 ;; the scalar versions to have only XMM registers as operands.
23632 ;; XOP conditional move
23633 (define_insn "*xop_pcmov_<mode>"
23634 [(set (match_operand:MODEF 0 "register_operand" "=x")
23635 (if_then_else:MODEF
23636 (match_operand:MODEF 1 "register_operand" "x")
23637 (match_operand:MODEF 2 "register_operand" "x")
23638 (match_operand:MODEF 3 "register_operand" "x")))]
23640 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
23641 [(set_attr "type" "sse4arg")
23642 (set_attr "mode" "TI")])
23644 ;; These versions of the min/max patterns are intentionally ignorant of
23645 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
23646 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
23647 ;; are undefined in this condition, we're certain this is correct.
23649 (define_insn "<code><mode>3"
23650 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
23652 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
23653 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
23654 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
23656 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
23657 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
23658 [(set_attr "isa" "noavx,avx")
23659 (set_attr "prefix" "orig,vex")
23660 (set_attr "type" "sseadd")
23661 (set_attr "mode" "<MODE>")])
23663 (define_insn "<code>hf3"
23664 [(set (match_operand:HF 0 "register_operand" "=v")
23666 (match_operand:HF 1 "nonimmediate_operand" "%v")
23667 (match_operand:HF 2 "nonimmediate_operand" "vm")))]
23668 "TARGET_AVX512FP16"
23669 "v<maxmin_float>sh\t{%2, %1, %0|%0, %1, %2}"
23670 [(set_attr "prefix" "evex")
23671 (set_attr "type" "sseadd")
23672 (set_attr "mode" "HF")])
23674 ;; These versions of the min/max patterns implement exactly the operations
23675 ;; min = (op1 < op2 ? op1 : op2)
23676 ;; max = (!(op1 < op2) ? op1 : op2)
23677 ;; Their operands are not commutative, and thus they may be used in the
23678 ;; presence of -0.0 and NaN.
23680 (define_insn "*ieee_s<ieee_maxmin>hf3"
23681 [(set (match_operand:HF 0 "register_operand" "=v")
23683 [(match_operand:HF 1 "register_operand" "v")
23684 (match_operand:HF 2 "nonimmediate_operand" "vm")]
23686 "TARGET_AVX512FP16"
23687 "v<ieee_maxmin>sh\t{%2, %1, %0|%0, %1, %2}"
23688 [(set_attr "prefix" "evex")
23689 (set_attr "type" "sseadd")
23690 (set_attr "mode" "HF")])
23692 (define_insn "*ieee_s<ieee_maxmin><mode>3"
23693 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
23695 [(match_operand:MODEF 1 "register_operand" "0,v")
23696 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
23698 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
23700 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
23701 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
23702 [(set_attr "isa" "noavx,avx")
23703 (set_attr "prefix" "orig,maybe_evex")
23704 (set_attr "type" "sseadd")
23705 (set_attr "mode" "<MODE>")])
23707 ;; Operands order in min/max instruction matters for signed zero and NANs.
23708 (define_insn_and_split "*ieee_max<mode>3_1"
23709 [(set (match_operand:MODEF 0 "register_operand")
23711 [(match_operand:MODEF 1 "register_operand")
23712 (match_operand:MODEF 2 "register_operand")
23714 (match_operand:MODEF 3 "register_operand")
23715 (match_operand:MODEF 4 "register_operand"))]
23717 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
23718 && (rtx_equal_p (operands[1], operands[3])
23719 && rtx_equal_p (operands[2], operands[4]))
23720 && ix86_pre_reload_split ()"
23723 [(set (match_dup 0)
23727 UNSPEC_IEEE_MAX))])
23729 (define_insn_and_split "*ieee_min<mode>3_1"
23730 [(set (match_operand:MODEF 0 "register_operand")
23732 [(match_operand:MODEF 1 "register_operand")
23733 (match_operand:MODEF 2 "register_operand")
23735 (match_operand:MODEF 3 "register_operand")
23736 (match_operand:MODEF 4 "register_operand"))]
23738 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
23739 && (rtx_equal_p (operands[1], operands[4])
23740 && rtx_equal_p (operands[2], operands[3]))
23741 && ix86_pre_reload_split ()"
23744 [(set (match_dup 0)
23748 UNSPEC_IEEE_MIN))])
23750 ;; Make two stack loads independent:
23752 ;; fld %st(0) -> fld bb
23753 ;; fmul bb fmul %st(1), %st
23755 ;; Actually we only match the last two instructions for simplicity.
23758 [(set (match_operand 0 "fp_register_operand")
23759 (match_operand 1 "fp_register_operand"))
23761 (match_operator 2 "binary_fp_operator"
23763 (match_operand 3 "memory_operand")]))]
23764 "REGNO (operands[0]) != REGNO (operands[1])"
23765 [(set (match_dup 0) (match_dup 3))
23768 [(match_dup 5) (match_dup 4)]))]
23770 operands[4] = operands[0];
23771 operands[5] = operands[1];
23773 /* The % modifier is not operational anymore in peephole2's, so we have to
23774 swap the operands manually in the case of addition and multiplication. */
23775 if (COMMUTATIVE_ARITH_P (operands[2]))
23776 std::swap (operands[4], operands[5]);
23780 [(set (match_operand 0 "fp_register_operand")
23781 (match_operand 1 "fp_register_operand"))
23783 (match_operator 2 "binary_fp_operator"
23784 [(match_operand 3 "memory_operand")
23786 "REGNO (operands[0]) != REGNO (operands[1])"
23787 [(set (match_dup 0) (match_dup 3))
23790 [(match_dup 4) (match_dup 5)]))]
23792 operands[4] = operands[0];
23793 operands[5] = operands[1];
23795 /* The % modifier is not operational anymore in peephole2's, so we have to
23796 swap the operands manually in the case of addition and multiplication. */
23797 if (COMMUTATIVE_ARITH_P (operands[2]))
23798 std::swap (operands[4], operands[5]);
23801 ;; Conditional addition patterns
23802 (define_expand "add<mode>cc"
23803 [(match_operand:SWI 0 "register_operand")
23804 (match_operand 1 "ordered_comparison_operator")
23805 (match_operand:SWI 2 "register_operand")
23806 (match_operand:SWI 3 "const_int_operand")]
23808 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
23810 ;; min/max patterns
23812 (define_code_attr maxmin_rel
23813 [(smax "GE") (smin "LE") (umax "GEU") (umin "LEU")])
23815 (define_expand "<code><mode>3"
23817 [(set (match_operand:SDWIM 0 "register_operand")
23819 (match_operand:SDWIM 1 "register_operand")
23820 (match_operand:SDWIM 2 "general_operand")))
23821 (clobber (reg:CC FLAGS_REG))])]
23823 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)")
23825 (define_insn_and_split "*<code><dwi>3_doubleword"
23826 [(set (match_operand:<DWI> 0 "register_operand")
23828 (match_operand:<DWI> 1 "register_operand")
23829 (match_operand:<DWI> 2 "general_operand")))
23830 (clobber (reg:CC FLAGS_REG))]
23832 && ix86_pre_reload_split ()"
23835 [(set (match_dup 0)
23836 (if_then_else:DWIH (match_dup 6)
23840 (if_then_else:DWIH (match_dup 6)
23844 operands[2] = force_reg (<DWI>mode, operands[2]);
23846 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
23848 rtx cmplo[2] = { operands[1], operands[2] };
23849 rtx cmphi[2] = { operands[4], operands[5] };
23851 enum rtx_code code = <maxmin_rel>;
23856 std::swap (cmplo[0], cmplo[1]);
23857 std::swap (cmphi[0], cmphi[1]);
23858 code = swap_condition (code);
23863 bool uns = (code == GEU);
23864 rtx (*sbb_insn) (machine_mode, rtx, rtx, rtx)
23865 = uns ? gen_sub3_carry_ccc : gen_sub3_carry_ccgz;
23867 emit_insn (gen_cmp_1 (<MODE>mode, cmplo[0], cmplo[1]));
23869 rtx tmp = gen_rtx_SCRATCH (<MODE>mode);
23870 emit_insn (sbb_insn (<MODE>mode, tmp, cmphi[0], cmphi[1]));
23872 rtx flags = gen_rtx_REG (uns ? CCCmode : CCGZmode, FLAGS_REG);
23873 operands[6] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
23879 gcc_unreachable ();
23883 (define_insn_and_split "*<code><mode>3_1"
23884 [(set (match_operand:SWI 0 "register_operand")
23886 (match_operand:SWI 1 "register_operand")
23887 (match_operand:SWI 2 "general_operand")))
23888 (clobber (reg:CC FLAGS_REG))]
23890 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
23891 && ix86_pre_reload_split ()"
23894 [(set (match_dup 0)
23895 (if_then_else:SWI (match_dup 3)
23899 machine_mode mode = <MODE>mode;
23900 rtx cmp_op = operands[2];
23902 operands[2] = force_reg (mode, cmp_op);
23904 enum rtx_code code = <maxmin_rel>;
23906 if (cmp_op == const1_rtx)
23908 /* Convert smax (x, 1) into (x > 0 ? x : 1).
23909 Convert umax (x, 1) into (x != 0 ? x : 1).
23910 Convert ?min (x, 1) into (x <= 0 ? x : 1). */
23911 cmp_op = const0_rtx;
23914 else if (code == GEU)
23917 /* Convert smin (x, -1) into (x < 0 ? x : -1). */
23918 else if (cmp_op == constm1_rtx && code == LE)
23920 cmp_op = const0_rtx;
23923 /* Convert smax (x, -1) into (x >= 0 ? x : -1). */
23924 else if (cmp_op == constm1_rtx && code == GE)
23925 cmp_op = const0_rtx;
23926 else if (cmp_op != const0_rtx)
23927 cmp_op = operands[2];
23929 machine_mode cmpmode = SELECT_CC_MODE (code, operands[1], cmp_op);
23930 rtx flags = gen_rtx_REG (cmpmode, FLAGS_REG);
23932 rtx tmp = gen_rtx_COMPARE (cmpmode, operands[1], cmp_op);
23933 emit_insn (gen_rtx_SET (flags, tmp));
23935 operands[3] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
23938 ;; Avoid clearing a register between a flags setting comparison and its use,
23939 ;; i.e. prefer "xorl %eax,%eax; test/cmp" over "test/cmp; movl $0, %eax".
23941 [(set (reg FLAGS_REG) (match_operand 0))
23942 (set (match_operand:SWI 1 "general_reg_operand") (const_int 0))]
23943 "peep2_regno_dead_p (0, FLAGS_REG)
23944 && !reg_overlap_mentioned_p (operands[1], operands[0])"
23945 [(set (match_dup 2) (match_dup 0))]
23947 operands[2] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
23948 ix86_expand_clear (operands[1]);
23951 ;; When optimizing for size, zeroing memory should use a register.
23953 [(match_scratch:SWI48 0 "r")
23954 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
23955 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))
23956 (set (match_operand:SWI48 3 "memory_operand") (const_int 0))
23957 (set (match_operand:SWI48 4 "memory_operand") (const_int 0))]
23958 "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
23961 ix86_expand_clear (operands[0]);
23962 emit_move_insn (operands[1], operands[0]);
23963 emit_move_insn (operands[2], operands[0]);
23964 emit_move_insn (operands[3], operands[0]);
23965 ix86_last_zero_store_uid
23966 = INSN_UID (emit_move_insn (operands[4], operands[0]));
23971 [(match_scratch:SWI48 0 "r")
23972 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
23973 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))]
23974 "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
23977 ix86_expand_clear (operands[0]);
23978 emit_move_insn (operands[1], operands[0]);
23979 ix86_last_zero_store_uid
23980 = INSN_UID (emit_move_insn (operands[2], operands[0]));
23985 [(match_scratch:SWI48 0 "r")
23986 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))]
23987 "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
23990 ix86_expand_clear (operands[0]);
23991 ix86_last_zero_store_uid
23992 = INSN_UID (emit_move_insn (operands[1], operands[0]));
23997 [(set (match_operand:SWI48 5 "memory_operand")
23998 (match_operand:SWI48 0 "general_reg_operand"))
23999 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
24000 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))
24001 (set (match_operand:SWI48 3 "memory_operand") (const_int 0))
24002 (set (match_operand:SWI48 4 "memory_operand") (const_int 0))]
24003 "optimize_insn_for_size_p ()
24004 && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
24007 emit_move_insn (operands[5], operands[0]);
24008 emit_move_insn (operands[1], operands[0]);
24009 emit_move_insn (operands[2], operands[0]);
24010 emit_move_insn (operands[3], operands[0]);
24011 ix86_last_zero_store_uid
24012 = INSN_UID (emit_move_insn (operands[4], operands[0]));
24017 [(set (match_operand:SWI48 3 "memory_operand")
24018 (match_operand:SWI48 0 "general_reg_operand"))
24019 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
24020 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))]
24021 "optimize_insn_for_size_p ()
24022 && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
24025 emit_move_insn (operands[3], operands[0]);
24026 emit_move_insn (operands[1], operands[0]);
24027 ix86_last_zero_store_uid
24028 = INSN_UID (emit_move_insn (operands[2], operands[0]));
24033 [(set (match_operand:SWI48 2 "memory_operand")
24034 (match_operand:SWI48 0 "general_reg_operand"))
24035 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))]
24036 "optimize_insn_for_size_p ()
24037 && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
24040 emit_move_insn (operands[2], operands[0]);
24041 ix86_last_zero_store_uid
24042 = INSN_UID (emit_move_insn (operands[1], operands[0]));
24046 ;; Reload dislikes loading constants directly into class_likely_spilled
24047 ;; hard registers. Try to tidy things up here.
24049 [(set (match_operand:SWI 0 "general_reg_operand")
24050 (match_operand:SWI 1 "x86_64_general_operand"))
24051 (set (match_operand:SWI 2 "general_reg_operand")
24053 "peep2_reg_dead_p (2, operands[0])"
24054 [(set (match_dup 2) (match_dup 1))])
24056 ;; Misc patterns (?)
24058 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
24059 ;; Otherwise there will be nothing to keep
24061 ;; [(set (reg ebp) (reg esp))]
24062 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
24063 ;; (clobber (eflags)]
24064 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
24066 ;; in proper program order.
24068 (define_insn "@pro_epilogue_adjust_stack_add_<mode>"
24069 [(set (match_operand:P 0 "register_operand" "=r,r")
24070 (plus:P (match_operand:P 1 "register_operand" "0,r")
24071 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
24072 (clobber (reg:CC FLAGS_REG))
24073 (clobber (mem:BLK (scratch)))]
24076 switch (get_attr_type (insn))
24079 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
24082 gcc_assert (rtx_equal_p (operands[0], operands[1]));
24083 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
24084 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
24086 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
24089 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
24090 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
24093 [(set (attr "type")
24094 (cond [(and (eq_attr "alternative" "0")
24095 (not (match_test "TARGET_OPT_AGU")))
24096 (const_string "alu")
24097 (match_operand:<MODE> 2 "const0_operand")
24098 (const_string "imov")
24100 (const_string "lea")))
24101 (set (attr "length_immediate")
24102 (cond [(eq_attr "type" "imov")
24104 (and (eq_attr "type" "alu")
24105 (match_operand 2 "const128_operand"))
24108 (const_string "*")))
24109 (set_attr "mode" "<MODE>")])
24111 (define_insn "@pro_epilogue_adjust_stack_sub_<mode>"
24112 [(set (match_operand:P 0 "register_operand" "=r")
24113 (minus:P (match_operand:P 1 "register_operand" "0")
24114 (match_operand:P 2 "register_operand" "r")))
24115 (clobber (reg:CC FLAGS_REG))
24116 (clobber (mem:BLK (scratch)))]
24118 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
24119 [(set_attr "type" "alu")
24120 (set_attr "mode" "<MODE>")])
24122 (define_insn "@allocate_stack_worker_probe_<mode>"
24123 [(set (match_operand:P 0 "register_operand" "=a")
24124 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
24125 UNSPECV_STACK_PROBE))
24126 (clobber (reg:CC FLAGS_REG))]
24127 "ix86_target_stack_probe ()"
24128 "call\t___chkstk_ms"
24129 [(set_attr "type" "multi")
24130 (set_attr "length" "5")])
24132 (define_expand "allocate_stack"
24133 [(match_operand 0 "register_operand")
24134 (match_operand 1 "general_operand")]
24135 "ix86_target_stack_probe ()"
24139 #ifndef CHECK_STACK_LIMIT
24140 #define CHECK_STACK_LIMIT 0
24143 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
24144 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
24148 x = copy_to_mode_reg (Pmode, operands[1]);
24150 emit_insn (gen_allocate_stack_worker_probe (Pmode, x, x));
24153 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
24154 stack_pointer_rtx, 0, OPTAB_DIRECT);
24156 if (x != stack_pointer_rtx)
24157 emit_move_insn (stack_pointer_rtx, x);
24159 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
24163 (define_expand "probe_stack"
24164 [(match_operand 0 "memory_operand")]
24167 emit_insn (gen_probe_stack_1
24168 (word_mode, operands[0], const0_rtx));
24172 ;; Use OR for stack probes, this is shorter.
24173 (define_insn "@probe_stack_1_<mode>"
24174 [(set (match_operand:W 0 "memory_operand" "=m")
24175 (unspec:W [(match_operand:W 1 "const0_operand")]
24176 UNSPEC_PROBE_STACK))
24177 (clobber (reg:CC FLAGS_REG))]
24179 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
24180 [(set_attr "type" "alu1")
24181 (set_attr "mode" "<MODE>")
24182 (set_attr "length_immediate" "1")])
24184 (define_insn "@adjust_stack_and_probe_<mode>"
24185 [(set (match_operand:P 0 "register_operand" "=r")
24186 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
24187 UNSPECV_PROBE_STACK_RANGE))
24188 (set (reg:P SP_REG)
24189 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand")))
24190 (clobber (reg:CC FLAGS_REG))
24191 (clobber (mem:BLK (scratch)))]
24193 "* return output_adjust_stack_and_probe (operands[0]);"
24194 [(set_attr "type" "multi")])
24196 (define_insn "@probe_stack_range_<mode>"
24197 [(set (match_operand:P 0 "register_operand" "=r")
24198 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
24199 (match_operand:P 2 "const_int_operand")]
24200 UNSPECV_PROBE_STACK_RANGE))
24201 (clobber (reg:CC FLAGS_REG))]
24203 "* return output_probe_stack_range (operands[0], operands[2]);"
24204 [(set_attr "type" "multi")])
24206 (define_expand "builtin_setjmp_receiver"
24207 [(label_ref (match_operand 0))]
24208 "!TARGET_64BIT && flag_pic"
24214 rtx_code_label *label_rtx = gen_label_rtx ();
24215 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
24216 xops[0] = xops[1] = pic_offset_table_rtx;
24217 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
24218 ix86_expand_binary_operator (MINUS, SImode, xops);
24222 emit_insn (gen_set_got (pic_offset_table_rtx));
24226 (define_expand "save_stack_nonlocal"
24227 [(set (match_operand 0 "memory_operand")
24228 (match_operand 1 "register_operand"))]
24233 if (flag_cf_protection & CF_RETURN)
24235 /* Copy shadow stack pointer to the first slot
24236 and stack pointer to the second slot. */
24237 rtx ssp_slot = adjust_address (operands[0], word_mode, 0);
24238 stack_slot = adjust_address (operands[0], Pmode, UNITS_PER_WORD);
24240 rtx reg_ssp = force_reg (word_mode, const0_rtx);
24241 emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
24242 emit_move_insn (ssp_slot, reg_ssp);
24245 stack_slot = adjust_address (operands[0], Pmode, 0);
24246 emit_move_insn (stack_slot, operands[1]);
24250 (define_expand "restore_stack_nonlocal"
24251 [(set (match_operand 0 "register_operand" "")
24252 (match_operand 1 "memory_operand" ""))]
24257 if (flag_cf_protection & CF_RETURN)
24259 /* Restore shadow stack pointer from the first slot
24260 and stack pointer from the second slot. */
24261 rtx ssp_slot = adjust_address (operands[1], word_mode, 0);
24262 stack_slot = adjust_address (operands[1], Pmode, UNITS_PER_WORD);
24264 /* Get the current shadow stack pointer. The code below will check if
24265 SHSTK feature is enabled. If it is not enabled the RDSSP instruction
24267 rtx reg_ssp = force_reg (word_mode, const0_rtx);
24268 emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
24270 /* Compare through subtraction the saved and the current ssp
24271 to decide if ssp has to be adjusted. */
24272 reg_ssp = expand_simple_binop (word_mode, MINUS,
24274 reg_ssp, 1, OPTAB_DIRECT);
24276 /* Compare and jump over adjustment code. */
24277 rtx noadj_label = gen_label_rtx ();
24278 emit_cmp_and_jump_insns (reg_ssp, const0_rtx, EQ, NULL_RTX,
24279 word_mode, 1, noadj_label);
24281 /* Compute the number of frames to adjust. */
24282 rtx reg_adj = gen_lowpart (ptr_mode, reg_ssp);
24283 rtx reg_adj_neg = expand_simple_unop (ptr_mode, NEG, reg_adj,
24286 reg_adj = expand_simple_binop (ptr_mode, LSHIFTRT, reg_adj_neg,
24287 GEN_INT (exact_log2 (UNITS_PER_WORD)),
24288 reg_adj, 1, OPTAB_DIRECT);
24290 /* Check if number of frames <= 255 so no loop is needed. */
24291 rtx inc_label = gen_label_rtx ();
24292 emit_cmp_and_jump_insns (reg_adj, GEN_INT (255), LEU, NULL_RTX,
24293 ptr_mode, 1, inc_label);
24295 /* Adjust the ssp in a loop. */
24296 rtx loop_label = gen_label_rtx ();
24297 emit_label (loop_label);
24298 LABEL_NUSES (loop_label) = 1;
24300 rtx reg_255 = force_reg (word_mode, GEN_INT (255));
24301 emit_insn (gen_incssp (word_mode, reg_255));
24303 reg_adj = expand_simple_binop (ptr_mode, MINUS,
24304 reg_adj, GEN_INT (255),
24305 reg_adj, 1, OPTAB_DIRECT);
24307 /* Compare and jump to the loop label. */
24308 emit_cmp_and_jump_insns (reg_adj, GEN_INT (255), GTU, NULL_RTX,
24309 ptr_mode, 1, loop_label);
24311 emit_label (inc_label);
24312 LABEL_NUSES (inc_label) = 1;
24314 emit_insn (gen_incssp (word_mode, reg_ssp));
24316 emit_label (noadj_label);
24317 LABEL_NUSES (noadj_label) = 1;
24320 stack_slot = adjust_address (operands[1], Pmode, 0);
24321 emit_move_insn (operands[0], stack_slot);
24325 (define_expand "stack_protect_set"
24326 [(match_operand 0 "memory_operand")
24327 (match_operand 1 "memory_operand")]
24330 rtx scratch = gen_reg_rtx (word_mode);
24332 emit_insn (gen_stack_protect_set_1
24333 (ptr_mode, word_mode, operands[0], operands[1], scratch));
24337 (define_insn "@stack_protect_set_1_<PTR:mode>_<W:mode>"
24338 [(set (match_operand:PTR 0 "memory_operand" "=m")
24339 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
24341 (set (match_operand:W 2 "register_operand" "=&r") (const_int 0))
24342 (clobber (reg:CC FLAGS_REG))]
24345 output_asm_insn ("mov{<PTR:imodesuffix>}\t{%1, %<PTR:k>2|%<PTR:k>2, %1}",
24347 output_asm_insn ("mov{<PTR:imodesuffix>}\t{%<PTR:k>2, %0|%0, %<PTR:k>2}",
24349 if (!TARGET_USE_MOV0 || optimize_insn_for_size_p ())
24350 return "xor{l}\t%k2, %k2";
24352 return "mov{l}\t{$0, %k2|%k2, 0}";
24354 [(set_attr "type" "multi")])
24356 ;; Patterns and peephole2s to optimize stack_protect_set_1_<mode>
24357 ;; immediately followed by *mov{s,d}i_internal, where we can avoid
24358 ;; the xor{l} above. We don't split this, so that scheduling or
24359 ;; anything else doesn't separate the *stack_protect_set* pattern from
24360 ;; the set of the register that overwrites the register with a new value.
24363 [(parallel [(set (match_operand:PTR 0 "memory_operand")
24364 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
24366 (set (match_operand 2 "general_reg_operand") (const_int 0))
24367 (clobber (reg:CC FLAGS_REG))])
24368 (set (match_operand 3 "general_reg_operand")
24369 (match_operand 4 "const0_operand"))]
24370 "GET_MODE (operands[2]) == word_mode
24371 && GET_MODE_SIZE (GET_MODE (operands[3])) <= UNITS_PER_WORD
24372 && peep2_reg_dead_p (0, operands[3])
24373 && peep2_reg_dead_p (1, operands[2])"
24374 [(parallel [(set (match_dup 0)
24375 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
24376 (set (match_dup 3) (const_int 0))
24377 (clobber (reg:CC FLAGS_REG))])]
24378 "operands[3] = gen_lowpart (word_mode, operands[3]);")
24380 (define_insn "*stack_protect_set_2_<mode>_si"
24381 [(set (match_operand:PTR 0 "memory_operand" "=m")
24382 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
24384 (set (match_operand:SI 1 "register_operand" "=&r")
24385 (match_operand:SI 2 "general_operand" "g"))]
24388 output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
24389 output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
24390 if (pic_32bit_operand (operands[2], SImode)
24391 || ix86_use_lea_for_mov (insn, operands + 1))
24392 return "lea{l}\t{%E2, %1|%1, %E2}";
24394 return "mov{l}\t{%2, %1|%1, %2}";
24396 [(set_attr "type" "multi")
24397 (set_attr "length" "24")])
24399 (define_insn "*stack_protect_set_2_<mode>_di"
24400 [(set (match_operand:PTR 0 "memory_operand" "=m,m,m")
24401 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m,m,m")]
24403 (set (match_operand:DI 1 "register_operand" "=&r,&r,&r")
24404 (match_operand:DI 2 "general_operand" "Z,rem,i"))]
24405 "TARGET_64BIT && reload_completed"
24407 output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
24408 output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
24409 if (pic_32bit_operand (operands[2], DImode))
24410 return "lea{q}\t{%E2, %1|%1, %E2}";
24411 else if (which_alternative == 0)
24412 return "mov{l}\t{%k2, %k1|%k1, %k2}";
24413 else if (which_alternative == 2)
24414 return "movabs{q}\t{%2, %1|%1, %2}";
24415 else if (ix86_use_lea_for_mov (insn, operands + 1))
24416 return "lea{q}\t{%E2, %1|%1, %E2}";
24418 return "mov{q}\t{%2, %1|%1, %2}";
24420 [(set_attr "type" "multi")
24421 (set_attr "length" "24")])
24424 [(parallel [(set (match_operand:PTR 0 "memory_operand")
24425 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
24427 (set (match_operand 2 "general_reg_operand") (const_int 0))
24428 (clobber (reg:CC FLAGS_REG))])
24429 (set (match_operand:SWI48 3 "general_reg_operand")
24430 (match_operand:SWI48 4 "general_gr_operand"))]
24431 "GET_MODE (operands[2]) == word_mode
24432 && peep2_reg_dead_p (0, operands[3])
24433 && peep2_reg_dead_p (1, operands[2])"
24434 [(parallel [(set (match_dup 0)
24435 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
24436 (set (match_dup 3) (match_dup 4))])])
24439 [(set (match_operand:SWI48 3 "general_reg_operand")
24440 (match_operand:SWI48 4 "general_gr_operand"))
24441 (parallel [(set (match_operand:PTR 0 "memory_operand")
24442 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
24444 (set (match_operand 2 "general_reg_operand") (const_int 0))
24445 (clobber (reg:CC FLAGS_REG))])]
24446 "GET_MODE (operands[2]) == word_mode
24447 && peep2_reg_dead_p (0, operands[3])
24448 && peep2_reg_dead_p (2, operands[2])
24449 && !reg_mentioned_p (operands[3], operands[0])
24450 && !reg_mentioned_p (operands[3], operands[1])"
24451 [(parallel [(set (match_dup 0)
24452 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
24453 (set (match_dup 3) (match_dup 4))])])
24455 (define_insn "*stack_protect_set_3_<PTR:mode>_<SWI48:mode>"
24456 [(set (match_operand:PTR 0 "memory_operand" "=m")
24457 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
24459 (set (match_operand:SWI48 1 "register_operand" "=&r")
24460 (match_operand:SWI48 2 "address_no_seg_operand" "Ts"))]
24463 output_asm_insn ("mov{<PTR:imodesuffix>}\t{%3, %<PTR:k>1|%<PTR:k>1, %3}",
24465 output_asm_insn ("mov{<PTR:imodesuffix>}\t{%<PTR:k>1, %0|%0, %<PTR:k>1}",
24467 if (SImode_address_operand (operands[2], VOIDmode))
24469 gcc_assert (TARGET_64BIT);
24470 return "lea{l}\t{%E2, %k1|%k1, %E2}";
24473 return "lea{<SWI48:imodesuffix>}\t{%E2, %1|%1, %E2}";
24475 [(set_attr "type" "multi")
24476 (set_attr "length" "24")])
24479 [(parallel [(set (match_operand:PTR 0 "memory_operand")
24480 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
24482 (set (match_operand 2 "general_reg_operand") (const_int 0))
24483 (clobber (reg:CC FLAGS_REG))])
24484 (set (match_operand:SWI48 3 "general_reg_operand")
24485 (match_operand:SWI48 4 "address_no_seg_operand"))]
24486 "GET_MODE (operands[2]) == word_mode
24487 && peep2_reg_dead_p (0, operands[3])
24488 && peep2_reg_dead_p (1, operands[2])"
24489 [(parallel [(set (match_dup 0)
24490 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
24491 (set (match_dup 3) (match_dup 4))])])
24493 (define_insn "*stack_protect_set_4z_<mode>_di"
24494 [(set (match_operand:PTR 0 "memory_operand" "=m")
24495 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
24497 (set (match_operand:DI 1 "register_operand" "=&r")
24498 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))]
24499 "TARGET_64BIT && reload_completed"
24501 output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
24502 output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
24503 if (ix86_use_lea_for_mov (insn, operands + 1))
24504 return "lea{l}\t{%E2, %k1|%k1, %E2}";
24506 return "mov{l}\t{%2, %k1|%k1, %2}";
24508 [(set_attr "type" "multi")
24509 (set_attr "length" "24")])
24511 (define_insn "*stack_protect_set_4s_<mode>_di"
24512 [(set (match_operand:PTR 0 "memory_operand" "=m")
24513 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
24515 (set (match_operand:DI 1 "register_operand" "=&r")
24516 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))]
24517 "TARGET_64BIT && reload_completed"
24519 output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
24520 output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
24521 return "movs{lq|x}\t{%2, %1|%1, %2}";
24523 [(set_attr "type" "multi")
24524 (set_attr "length" "24")])
24527 [(parallel [(set (match_operand:PTR 0 "memory_operand")
24528 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
24530 (set (match_operand 2 "general_reg_operand") (const_int 0))
24531 (clobber (reg:CC FLAGS_REG))])
24532 (set (match_operand:DI 3 "general_reg_operand")
24534 (match_operand:SI 4 "nonimmediate_gr_operand")))]
24536 && GET_MODE (operands[2]) == word_mode
24537 && peep2_reg_dead_p (0, operands[3])
24538 && peep2_reg_dead_p (1, operands[2])"
24539 [(parallel [(set (match_dup 0)
24540 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
24542 (any_extend:DI (match_dup 4)))])])
24544 (define_expand "stack_protect_test"
24545 [(match_operand 0 "memory_operand")
24546 (match_operand 1 "memory_operand")
24550 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
24552 emit_insn (gen_stack_protect_test_1
24553 (ptr_mode, flags, operands[0], operands[1]));
24555 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
24556 flags, const0_rtx, operands[2]));
24560 (define_insn "@stack_protect_test_1_<mode>"
24561 [(set (match_operand:CCZ 0 "flags_reg_operand")
24562 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
24563 (match_operand:PTR 2 "memory_operand" "m")]
24565 (clobber (match_scratch:PTR 3 "=&r"))]
24568 output_asm_insn ("mov{<imodesuffix>}\t{%1, %3|%3, %1}", operands);
24569 return "sub{<imodesuffix>}\t{%2, %3|%3, %2}";
24571 [(set_attr "type" "multi")])
24573 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
24574 ;; Do not split instructions with mask registers.
24576 [(set (match_operand 0 "general_reg_operand")
24577 (match_operator 3 "promotable_binary_operator"
24578 [(match_operand 1 "general_reg_operand")
24579 (match_operand 2 "aligned_operand")]))
24580 (clobber (reg:CC FLAGS_REG))]
24581 "! TARGET_PARTIAL_REG_STALL && reload_completed
24582 && ((GET_MODE (operands[0]) == HImode
24583 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
24584 /* ??? next two lines just !satisfies_constraint_K (...) */
24585 || !CONST_INT_P (operands[2])
24586 || satisfies_constraint_K (operands[2])))
24587 || (GET_MODE (operands[0]) == QImode
24588 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
24589 [(parallel [(set (match_dup 0)
24590 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
24591 (clobber (reg:CC FLAGS_REG))])]
24593 operands[0] = gen_lowpart (SImode, operands[0]);
24594 operands[1] = gen_lowpart (SImode, operands[1]);
24595 if (GET_CODE (operands[3]) != ASHIFT)
24596 operands[2] = gen_lowpart (SImode, operands[2]);
24597 operands[3] = shallow_copy_rtx (operands[3]);
24598 PUT_MODE (operands[3], SImode);
24601 ; Promote the QImode tests, as i386 has encoding of the AND
24602 ; instruction with 32-bit sign-extended immediate and thus the
24603 ; instruction size is unchanged, except in the %eax case for
24604 ; which it is increased by one byte, hence the ! optimize_size.
24606 [(set (match_operand 0 "flags_reg_operand")
24607 (match_operator 2 "compare_operator"
24608 [(and (match_operand 3 "aligned_operand")
24609 (match_operand 4 "const_int_operand"))
24611 (set (match_operand 1 "register_operand")
24612 (and (match_dup 3) (match_dup 4)))]
24613 "! TARGET_PARTIAL_REG_STALL && reload_completed
24614 && optimize_insn_for_speed_p ()
24615 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
24616 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
24617 /* Ensure that the operand will remain sign-extended immediate. */
24618 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
24619 [(parallel [(set (match_dup 0)
24620 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
24623 (and:SI (match_dup 3) (match_dup 4)))])]
24626 = gen_int_mode (INTVAL (operands[4])
24627 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
24628 operands[1] = gen_lowpart (SImode, operands[1]);
24629 operands[3] = gen_lowpart (SImode, operands[3]);
24632 ; Don't promote the QImode tests, as i386 doesn't have encoding of
24633 ; the TEST instruction with 32-bit sign-extended immediate and thus
24634 ; the instruction size would at least double, which is not what we
24635 ; want even with ! optimize_size.
24637 [(set (match_operand 0 "flags_reg_operand")
24638 (match_operator 1 "compare_operator"
24639 [(and (match_operand:HI 2 "aligned_operand")
24640 (match_operand:HI 3 "const_int_operand"))
24642 "! TARGET_PARTIAL_REG_STALL && reload_completed
24643 && ! TARGET_FAST_PREFIX
24644 && optimize_insn_for_speed_p ()
24645 /* Ensure that the operand will remain sign-extended immediate. */
24646 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
24647 [(set (match_dup 0)
24648 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
24652 = gen_int_mode (INTVAL (operands[3])
24653 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
24654 operands[2] = gen_lowpart (SImode, operands[2]);
24658 [(set (match_operand 0 "register_operand")
24659 (neg (match_operand 1 "register_operand")))
24660 (clobber (reg:CC FLAGS_REG))]
24661 "! TARGET_PARTIAL_REG_STALL && reload_completed
24662 && (GET_MODE (operands[0]) == HImode
24663 || (GET_MODE (operands[0]) == QImode
24664 && (TARGET_PROMOTE_QImode
24665 || optimize_insn_for_size_p ())))"
24666 [(parallel [(set (match_dup 0)
24667 (neg:SI (match_dup 1)))
24668 (clobber (reg:CC FLAGS_REG))])]
24670 operands[0] = gen_lowpart (SImode, operands[0]);
24671 operands[1] = gen_lowpart (SImode, operands[1]);
24674 ;; Do not split instructions with mask regs.
24676 [(set (match_operand 0 "general_reg_operand")
24677 (not (match_operand 1 "general_reg_operand")))]
24678 "! TARGET_PARTIAL_REG_STALL && reload_completed
24679 && (GET_MODE (operands[0]) == HImode
24680 || (GET_MODE (operands[0]) == QImode
24681 && (TARGET_PROMOTE_QImode
24682 || optimize_insn_for_size_p ())))"
24683 [(set (match_dup 0)
24684 (not:SI (match_dup 1)))]
24686 operands[0] = gen_lowpart (SImode, operands[0]);
24687 operands[1] = gen_lowpart (SImode, operands[1]);
24690 ;; RTL Peephole optimizations, run before sched2. These primarily look to
24691 ;; transform a complex memory operation into two memory to register operations.
24693 ;; Don't push memory operands
24695 [(set (match_operand:SWI 0 "push_operand")
24696 (match_operand:SWI 1 "memory_operand"))
24697 (match_scratch:SWI 2 "<r>")]
24698 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
24699 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
24700 [(set (match_dup 2) (match_dup 1))
24701 (set (match_dup 0) (match_dup 2))])
24703 ;; We need to handle SFmode only, because DFmode and XFmode are split to
24706 [(set (match_operand:SF 0 "push_operand")
24707 (match_operand:SF 1 "memory_operand"))
24708 (match_scratch:SF 2 "r")]
24709 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
24710 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
24711 [(set (match_dup 2) (match_dup 1))
24712 (set (match_dup 0) (match_dup 2))])
24714 ;; Don't move an immediate directly to memory when the instruction
24715 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
24717 [(match_scratch:SWI124 1 "<r>")
24718 (set (match_operand:SWI124 0 "memory_operand")
24720 "optimize_insn_for_speed_p ()
24721 && ((<MODE>mode == HImode
24722 && TARGET_LCP_STALL)
24723 || (!TARGET_USE_MOV0
24724 && TARGET_SPLIT_LONG_MOVES
24725 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
24726 && peep2_regno_dead_p (0, FLAGS_REG)"
24727 [(parallel [(set (match_dup 2) (const_int 0))
24728 (clobber (reg:CC FLAGS_REG))])
24729 (set (match_dup 0) (match_dup 1))]
24730 "operands[2] = gen_lowpart (SImode, operands[1]);")
24733 [(match_scratch:SWI124 2 "<r>")
24734 (set (match_operand:SWI124 0 "memory_operand")
24735 (match_operand:SWI124 1 "immediate_operand"))]
24736 "optimize_insn_for_speed_p ()
24737 && ((<MODE>mode == HImode
24738 && TARGET_LCP_STALL)
24739 || (TARGET_SPLIT_LONG_MOVES
24740 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
24741 [(set (match_dup 2) (match_dup 1))
24742 (set (match_dup 0) (match_dup 2))])
24744 ;; Don't compare memory with zero, load and use a test instead.
24746 [(set (match_operand 0 "flags_reg_operand")
24747 (match_operator 1 "compare_operator"
24748 [(match_operand:SI 2 "memory_operand")
24750 (match_scratch:SI 3 "r")]
24751 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
24752 [(set (match_dup 3) (match_dup 2))
24753 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
24755 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
24756 ;; Don't split NOTs with a displacement operand, because resulting XOR
24757 ;; will not be pairable anyway.
24759 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
24760 ;; represented using a modRM byte. The XOR replacement is long decoded,
24761 ;; so this split helps here as well.
24763 ;; Note: Can't do this as a regular split because we can't get proper
24764 ;; lifetime information then.
24767 [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
24768 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
24769 "optimize_insn_for_speed_p ()
24770 && ((TARGET_NOT_UNPAIRABLE
24771 && (!MEM_P (operands[0])
24772 || !memory_displacement_operand (operands[0], <MODE>mode)))
24773 || (TARGET_NOT_VECTORMODE
24774 && long_memory_operand (operands[0], <MODE>mode)))
24775 && peep2_regno_dead_p (0, FLAGS_REG)"
24776 [(parallel [(set (match_dup 0)
24777 (xor:SWI124 (match_dup 1) (const_int -1)))
24778 (clobber (reg:CC FLAGS_REG))])])
24780 ;; Non pairable "test imm, reg" instructions can be translated to
24781 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
24782 ;; byte opcode instead of two, have a short form for byte operands),
24783 ;; so do it for other CPUs as well. Given that the value was dead,
24784 ;; this should not create any new dependencies. Pass on the sub-word
24785 ;; versions if we're concerned about partial register stalls.
24788 [(set (match_operand 0 "flags_reg_operand")
24789 (match_operator 1 "compare_operator"
24790 [(and:SI (match_operand:SI 2 "register_operand")
24791 (match_operand:SI 3 "immediate_operand"))
24793 "ix86_match_ccmode (insn, CCNOmode)
24794 && (REGNO (operands[2]) != AX_REG
24795 || satisfies_constraint_K (operands[3]))
24796 && peep2_reg_dead_p (1, operands[2])"
24798 [(set (match_dup 0)
24799 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
24802 (and:SI (match_dup 2) (match_dup 3)))])])
24804 ;; We don't need to handle HImode case, because it will be promoted to SImode
24805 ;; on ! TARGET_PARTIAL_REG_STALL
24808 [(set (match_operand 0 "flags_reg_operand")
24809 (match_operator 1 "compare_operator"
24810 [(and:QI (match_operand:QI 2 "register_operand")
24811 (match_operand:QI 3 "immediate_operand"))
24813 "! TARGET_PARTIAL_REG_STALL
24814 && ix86_match_ccmode (insn, CCNOmode)
24815 && REGNO (operands[2]) != AX_REG
24816 && peep2_reg_dead_p (1, operands[2])"
24818 [(set (match_dup 0)
24819 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
24822 (and:QI (match_dup 2) (match_dup 3)))])])
24825 [(set (match_operand 0 "flags_reg_operand")
24826 (match_operator 1 "compare_operator"
24829 (match_operator:SWI248 4 "extract_operator"
24830 [(match_operand 2 "int248_register_operand")
24833 (match_operand 3 "const_int_operand"))
24835 "! TARGET_PARTIAL_REG_STALL
24836 && ix86_match_ccmode (insn, CCNOmode)
24837 && REGNO (operands[2]) != AX_REG
24838 && peep2_reg_dead_p (1, operands[2])"
24840 [(set (match_dup 0)
24844 (match_op_dup 4 [(match_dup 2)
24849 (set (zero_extract:SWI248 (match_dup 2)
24855 (match_op_dup 4 [(match_dup 2)
24858 (match_dup 3)) 0))])])
24860 ;; Don't do logical operations with memory inputs.
24862 [(match_scratch:SWI 2 "<r>")
24863 (parallel [(set (match_operand:SWI 0 "register_operand")
24864 (match_operator:SWI 3 "arith_or_logical_operator"
24866 (match_operand:SWI 1 "memory_operand")]))
24867 (clobber (reg:CC FLAGS_REG))])]
24868 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
24869 [(set (match_dup 2) (match_dup 1))
24870 (parallel [(set (match_dup 0)
24871 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
24872 (clobber (reg:CC FLAGS_REG))])])
24875 [(match_scratch:SWI 2 "<r>")
24876 (parallel [(set (match_operand:SWI 0 "register_operand")
24877 (match_operator:SWI 3 "arith_or_logical_operator"
24878 [(match_operand:SWI 1 "memory_operand")
24880 (clobber (reg:CC FLAGS_REG))])]
24881 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
24882 [(set (match_dup 2) (match_dup 1))
24883 (parallel [(set (match_dup 0)
24884 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
24885 (clobber (reg:CC FLAGS_REG))])])
24887 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when
24888 ;; the memory address refers to the destination of the load!
24891 [(set (match_operand:SWI 0 "general_reg_operand")
24892 (match_operand:SWI 1 "general_reg_operand"))
24893 (parallel [(set (match_dup 0)
24894 (match_operator:SWI 3 "commutative_operator"
24896 (match_operand:SWI 2 "memory_operand")]))
24897 (clobber (reg:CC FLAGS_REG))])]
24898 "REGNO (operands[0]) != REGNO (operands[1])
24899 && (<MODE>mode != QImode
24900 || any_QIreg_operand (operands[1], QImode))"
24901 [(set (match_dup 0) (match_dup 4))
24902 (parallel [(set (match_dup 0)
24903 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
24904 (clobber (reg:CC FLAGS_REG))])]
24907 = ix86_replace_reg_with_reg (operands[2], operands[0], operands[1]);
24911 [(set (match_operand 0 "mmx_reg_operand")
24912 (match_operand 1 "mmx_reg_operand"))
24914 (match_operator 3 "commutative_operator"
24916 (match_operand 2 "memory_operand")]))]
24917 "REGNO (operands[0]) != REGNO (operands[1])"
24918 [(set (match_dup 0) (match_dup 2))
24920 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
24923 [(set (match_operand 0 "sse_reg_operand")
24924 (match_operand 1 "sse_reg_operand"))
24926 (match_operator 3 "commutative_operator"
24928 (match_operand 2 "memory_operand")]))]
24929 "REGNO (operands[0]) != REGNO (operands[1])
24930 /* Punt if operands[1] is %[xy]mm16+ and AVX512BW is not enabled,
24931 as EVEX encoded vpadd[bw], vpmullw, vpmin[su][bw] and vpmax[su][bw]
24932 instructions require AVX512BW and AVX512VL, but with the original
24933 instructions it might require just AVX512VL.
24934 AVX512VL is implied from TARGET_HARD_REGNO_MODE_OK. */
24935 && (!EXT_REX_SSE_REGNO_P (REGNO (operands[1]))
24937 || GET_MODE_SIZE (GET_MODE_INNER (GET_MODE (operands[0]))) > 2
24938 || logic_operator (operands[3], VOIDmode))"
24939 [(set (match_dup 0) (match_dup 2))
24941 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
24943 ; Don't do logical operations with memory outputs
24945 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
24946 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
24947 ; the same decoder scheduling characteristics as the original.
24950 [(match_scratch:SWI 2 "<r>")
24951 (parallel [(set (match_operand:SWI 0 "memory_operand")
24952 (match_operator:SWI 3 "arith_or_logical_operator"
24954 (match_operand:SWI 1 "<nonmemory_operand>")]))
24955 (clobber (reg:CC FLAGS_REG))])]
24956 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
24957 [(set (match_dup 2) (match_dup 0))
24958 (parallel [(set (match_dup 2)
24959 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
24960 (clobber (reg:CC FLAGS_REG))])
24961 (set (match_dup 0) (match_dup 2))])
24964 [(match_scratch:SWI 2 "<r>")
24965 (parallel [(set (match_operand:SWI 0 "memory_operand")
24966 (match_operator:SWI 3 "arith_or_logical_operator"
24967 [(match_operand:SWI 1 "<nonmemory_operand>")
24969 (clobber (reg:CC FLAGS_REG))])]
24970 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
24971 [(set (match_dup 2) (match_dup 0))
24972 (parallel [(set (match_dup 2)
24973 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
24974 (clobber (reg:CC FLAGS_REG))])
24975 (set (match_dup 0) (match_dup 2))])
24977 ;; Attempt to use arith or logical operations with memory outputs with
24978 ;; setting of flags.
24980 [(set (match_operand:SWI 0 "register_operand")
24981 (match_operand:SWI 1 "memory_operand"))
24982 (parallel [(set (match_dup 0)
24983 (match_operator:SWI 3 "plusminuslogic_operator"
24985 (match_operand:SWI 2 "<nonmemory_operand>")]))
24986 (clobber (reg:CC FLAGS_REG))])
24987 (set (match_dup 1) (match_dup 0))
24988 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
24989 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24990 && peep2_reg_dead_p (4, operands[0])
24991 && !reg_overlap_mentioned_p (operands[0], operands[1])
24992 && !reg_overlap_mentioned_p (operands[0], operands[2])
24993 && (<MODE>mode != QImode
24994 || immediate_operand (operands[2], QImode)
24995 || any_QIreg_operand (operands[2], QImode))
24996 && ix86_match_ccmode (peep2_next_insn (3),
24997 (GET_CODE (operands[3]) == PLUS
24998 || GET_CODE (operands[3]) == MINUS)
24999 ? CCGOCmode : CCNOmode)"
25000 [(parallel [(set (match_dup 4) (match_dup 6))
25001 (set (match_dup 1) (match_dup 5))])]
25003 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
25005 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
25006 copy_rtx (operands[1]),
25009 = gen_rtx_COMPARE (GET_MODE (operands[4]),
25010 copy_rtx (operands[5]),
25014 ;; Likewise for cmpelim optimized pattern.
25016 [(set (match_operand:SWI 0 "register_operand")
25017 (match_operand:SWI 1 "memory_operand"))
25018 (parallel [(set (reg FLAGS_REG)
25019 (compare (match_operator:SWI 3 "plusminuslogic_operator"
25021 (match_operand:SWI 2 "<nonmemory_operand>")])
25023 (set (match_dup 0) (match_dup 3))])
25024 (set (match_dup 1) (match_dup 0))]
25025 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25026 && peep2_reg_dead_p (3, operands[0])
25027 && !reg_overlap_mentioned_p (operands[0], operands[1])
25028 && !reg_overlap_mentioned_p (operands[0], operands[2])
25029 && ix86_match_ccmode (peep2_next_insn (1),
25030 (GET_CODE (operands[3]) == PLUS
25031 || GET_CODE (operands[3]) == MINUS)
25032 ? CCGOCmode : CCNOmode)"
25033 [(parallel [(set (match_dup 4) (match_dup 6))
25034 (set (match_dup 1) (match_dup 5))])]
25036 operands[4] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
25038 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
25039 copy_rtx (operands[1]), operands[2]);
25041 = gen_rtx_COMPARE (GET_MODE (operands[4]), copy_rtx (operands[5]),
25045 ;; Likewise for instances where we have a lea pattern.
25047 [(set (match_operand:SWI 0 "register_operand")
25048 (match_operand:SWI 1 "memory_operand"))
25049 (set (match_operand:<LEAMODE> 3 "register_operand")
25050 (plus:<LEAMODE> (match_operand:<LEAMODE> 4 "register_operand")
25051 (match_operand:<LEAMODE> 2 "<nonmemory_operand>")))
25052 (set (match_dup 1) (match_operand:SWI 5 "register_operand"))
25053 (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
25054 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25055 && REGNO (operands[4]) == REGNO (operands[0])
25056 && REGNO (operands[5]) == REGNO (operands[3])
25057 && peep2_reg_dead_p (4, operands[3])
25058 && ((REGNO (operands[0]) == REGNO (operands[3]))
25059 || peep2_reg_dead_p (2, operands[0]))
25060 && !reg_overlap_mentioned_p (operands[0], operands[1])
25061 && !reg_overlap_mentioned_p (operands[3], operands[1])
25062 && !reg_overlap_mentioned_p (operands[0], operands[2])
25063 && (<MODE>mode != QImode
25064 || immediate_operand (operands[2], QImode)
25065 || any_QIreg_operand (operands[2], QImode))
25066 && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
25067 [(parallel [(set (match_dup 6) (match_dup 8))
25068 (set (match_dup 1) (match_dup 7))])]
25070 operands[6] = SET_DEST (PATTERN (peep2_next_insn (3)));
25072 = gen_rtx_PLUS (<MODE>mode,
25073 copy_rtx (operands[1]),
25074 gen_lowpart (<MODE>mode, operands[2]));
25076 = gen_rtx_COMPARE (GET_MODE (operands[6]),
25077 copy_rtx (operands[7]),
25082 [(parallel [(set (match_operand:SWI 0 "register_operand")
25083 (match_operator:SWI 2 "plusminuslogic_operator"
25085 (match_operand:SWI 1 "memory_operand")]))
25086 (clobber (reg:CC FLAGS_REG))])
25087 (set (match_dup 1) (match_dup 0))
25088 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
25089 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25090 && COMMUTATIVE_ARITH_P (operands[2])
25091 && peep2_reg_dead_p (3, operands[0])
25092 && !reg_overlap_mentioned_p (operands[0], operands[1])
25093 && ix86_match_ccmode (peep2_next_insn (2),
25094 GET_CODE (operands[2]) == PLUS
25095 ? CCGOCmode : CCNOmode)"
25096 [(parallel [(set (match_dup 3) (match_dup 5))
25097 (set (match_dup 1) (match_dup 4))])]
25099 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
25101 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
25102 copy_rtx (operands[1]),
25105 = gen_rtx_COMPARE (GET_MODE (operands[3]),
25106 copy_rtx (operands[4]),
25110 ;; Likewise for cmpelim optimized pattern.
25112 [(parallel [(set (reg FLAGS_REG)
25113 (compare (match_operator:SWI 2 "plusminuslogic_operator"
25114 [(match_operand:SWI 0 "register_operand")
25115 (match_operand:SWI 1 "memory_operand")])
25117 (set (match_dup 0) (match_dup 2))])
25118 (set (match_dup 1) (match_dup 0))]
25119 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25120 && COMMUTATIVE_ARITH_P (operands[2])
25121 && peep2_reg_dead_p (2, operands[0])
25122 && !reg_overlap_mentioned_p (operands[0], operands[1])
25123 && ix86_match_ccmode (peep2_next_insn (0),
25124 GET_CODE (operands[2]) == PLUS
25125 ? CCGOCmode : CCNOmode)"
25126 [(parallel [(set (match_dup 3) (match_dup 5))
25127 (set (match_dup 1) (match_dup 4))])]
25129 operands[3] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (0)), 0, 0));
25131 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
25132 copy_rtx (operands[1]), operands[0]);
25134 = gen_rtx_COMPARE (GET_MODE (operands[3]), copy_rtx (operands[4]),
25139 [(set (match_operand:SWI12 0 "register_operand")
25140 (match_operand:SWI12 1 "memory_operand"))
25141 (parallel [(set (match_operand:SI 4 "register_operand")
25142 (match_operator:SI 3 "plusminuslogic_operator"
25144 (match_operand:SI 2 "nonmemory_operand")]))
25145 (clobber (reg:CC FLAGS_REG))])
25146 (set (match_dup 1) (match_dup 0))
25147 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
25148 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25149 && REGNO (operands[0]) == REGNO (operands[4])
25150 && peep2_reg_dead_p (4, operands[0])
25151 && (<MODE>mode != QImode
25152 || immediate_operand (operands[2], SImode)
25153 || any_QIreg_operand (operands[2], SImode))
25154 && !reg_overlap_mentioned_p (operands[0], operands[1])
25155 && !reg_overlap_mentioned_p (operands[0], operands[2])
25156 && ix86_match_ccmode (peep2_next_insn (3),
25157 (GET_CODE (operands[3]) == PLUS
25158 || GET_CODE (operands[3]) == MINUS)
25159 ? CCGOCmode : CCNOmode)"
25160 [(parallel [(set (match_dup 5) (match_dup 7))
25161 (set (match_dup 1) (match_dup 6))])]
25163 operands[5] = SET_DEST (PATTERN (peep2_next_insn (3)));
25165 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
25166 copy_rtx (operands[1]),
25167 gen_lowpart (<MODE>mode, operands[2]));
25169 = gen_rtx_COMPARE (GET_MODE (operands[5]),
25170 copy_rtx (operands[6]),
25174 ;; peephole2 comes before regcprop, so deal also with a case that
25175 ;; would be cleaned up by regcprop.
25177 [(set (match_operand:SWI 0 "register_operand")
25178 (match_operand:SWI 1 "memory_operand"))
25179 (parallel [(set (match_dup 0)
25180 (match_operator:SWI 3 "plusminuslogic_operator"
25182 (match_operand:SWI 2 "<nonmemory_operand>")]))
25183 (clobber (reg:CC FLAGS_REG))])
25184 (set (match_operand:SWI 4 "register_operand") (match_dup 0))
25185 (set (match_dup 1) (match_dup 4))
25186 (set (reg FLAGS_REG) (compare (match_dup 4) (const_int 0)))]
25187 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25188 && peep2_reg_dead_p (3, operands[0])
25189 && peep2_reg_dead_p (5, operands[4])
25190 && !reg_overlap_mentioned_p (operands[0], operands[1])
25191 && !reg_overlap_mentioned_p (operands[0], operands[2])
25192 && !reg_overlap_mentioned_p (operands[4], operands[1])
25193 && (<MODE>mode != QImode
25194 || immediate_operand (operands[2], QImode)
25195 || any_QIreg_operand (operands[2], QImode))
25196 && ix86_match_ccmode (peep2_next_insn (4),
25197 (GET_CODE (operands[3]) == PLUS
25198 || GET_CODE (operands[3]) == MINUS)
25199 ? CCGOCmode : CCNOmode)"
25200 [(parallel [(set (match_dup 5) (match_dup 7))
25201 (set (match_dup 1) (match_dup 6))])]
25203 operands[5] = SET_DEST (PATTERN (peep2_next_insn (4)));
25205 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
25206 copy_rtx (operands[1]),
25209 = gen_rtx_COMPARE (GET_MODE (operands[5]),
25210 copy_rtx (operands[6]),
25215 [(set (match_operand:SWI12 0 "register_operand")
25216 (match_operand:SWI12 1 "memory_operand"))
25217 (parallel [(set (match_operand:SI 4 "register_operand")
25218 (match_operator:SI 3 "plusminuslogic_operator"
25220 (match_operand:SI 2 "nonmemory_operand")]))
25221 (clobber (reg:CC FLAGS_REG))])
25222 (set (match_operand:SWI12 5 "register_operand") (match_dup 0))
25223 (set (match_dup 1) (match_dup 5))
25224 (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
25225 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25226 && REGNO (operands[0]) == REGNO (operands[4])
25227 && peep2_reg_dead_p (3, operands[0])
25228 && peep2_reg_dead_p (5, operands[5])
25229 && (<MODE>mode != QImode
25230 || immediate_operand (operands[2], SImode)
25231 || any_QIreg_operand (operands[2], SImode))
25232 && !reg_overlap_mentioned_p (operands[0], operands[1])
25233 && !reg_overlap_mentioned_p (operands[0], operands[2])
25234 && !reg_overlap_mentioned_p (operands[5], operands[1])
25235 && ix86_match_ccmode (peep2_next_insn (4),
25236 (GET_CODE (operands[3]) == PLUS
25237 || GET_CODE (operands[3]) == MINUS)
25238 ? CCGOCmode : CCNOmode)"
25239 [(parallel [(set (match_dup 6) (match_dup 8))
25240 (set (match_dup 1) (match_dup 7))])]
25242 operands[6] = SET_DEST (PATTERN (peep2_next_insn (4)));
25244 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
25245 copy_rtx (operands[1]),
25246 gen_lowpart (<MODE>mode, operands[2]));
25248 = gen_rtx_COMPARE (GET_MODE (operands[6]),
25249 copy_rtx (operands[7]),
25253 ;; Likewise for cmpelim optimized pattern.
25255 [(set (match_operand:SWI 0 "register_operand")
25256 (match_operand:SWI 1 "memory_operand"))
25257 (parallel [(set (reg FLAGS_REG)
25258 (compare (match_operator:SWI 3 "plusminuslogic_operator"
25260 (match_operand:SWI 2 "<nonmemory_operand>")])
25262 (set (match_dup 0) (match_dup 3))])
25263 (set (match_operand:SWI 4 "register_operand") (match_dup 0))
25264 (set (match_dup 1) (match_dup 4))]
25265 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25266 && peep2_reg_dead_p (3, operands[0])
25267 && peep2_reg_dead_p (4, operands[4])
25268 && !reg_overlap_mentioned_p (operands[0], operands[1])
25269 && !reg_overlap_mentioned_p (operands[0], operands[2])
25270 && !reg_overlap_mentioned_p (operands[4], operands[1])
25271 && ix86_match_ccmode (peep2_next_insn (1),
25272 (GET_CODE (operands[3]) == PLUS
25273 || GET_CODE (operands[3]) == MINUS)
25274 ? CCGOCmode : CCNOmode)"
25275 [(parallel [(set (match_dup 5) (match_dup 7))
25276 (set (match_dup 1) (match_dup 6))])]
25278 operands[5] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
25280 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
25281 copy_rtx (operands[1]), operands[2]);
25283 = gen_rtx_COMPARE (GET_MODE (operands[5]), copy_rtx (operands[6]),
25287 ;; Special cases for xor, where (x ^= y) != 0 is (misoptimized)
25288 ;; into x = z; x ^= y; x != z
25290 [(set (match_operand:SWI 0 "register_operand")
25291 (match_operand:SWI 1 "memory_operand"))
25292 (set (match_operand:SWI 3 "register_operand") (match_dup 0))
25293 (parallel [(set (match_operand:SWI 4 "register_operand")
25294 (xor:SWI (match_dup 4)
25295 (match_operand:SWI 2 "<nonmemory_operand>")))
25296 (clobber (reg:CC FLAGS_REG))])
25297 (set (match_dup 1) (match_dup 4))
25298 (set (reg:CCZ FLAGS_REG)
25299 (compare:CCZ (match_operand:SWI 5 "register_operand")
25300 (match_operand:SWI 6 "<nonmemory_operand>")))]
25301 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25302 && (REGNO (operands[4]) == REGNO (operands[0])
25303 || REGNO (operands[4]) == REGNO (operands[3]))
25304 && (rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
25305 ? 3 : 0], operands[5])
25306 ? rtx_equal_p (operands[2], operands[6])
25307 : rtx_equal_p (operands[2], operands[5])
25308 && rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
25309 ? 3 : 0], operands[6]))
25310 && peep2_reg_dead_p (4, operands[4])
25311 && peep2_reg_dead_p (5, operands[REGNO (operands[4]) == REGNO (operands[0])
25313 && !reg_overlap_mentioned_p (operands[0], operands[1])
25314 && !reg_overlap_mentioned_p (operands[0], operands[2])
25315 && !reg_overlap_mentioned_p (operands[3], operands[0])
25316 && !reg_overlap_mentioned_p (operands[3], operands[1])
25317 && !reg_overlap_mentioned_p (operands[3], operands[2])
25318 && (<MODE>mode != QImode
25319 || immediate_operand (operands[2], QImode)
25320 || any_QIreg_operand (operands[2], QImode))"
25321 [(parallel [(set (match_dup 7) (match_dup 9))
25322 (set (match_dup 1) (match_dup 8))])]
25324 operands[7] = SET_DEST (PATTERN (peep2_next_insn (4)));
25325 operands[8] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
25328 = gen_rtx_COMPARE (GET_MODE (operands[7]),
25329 copy_rtx (operands[8]),
25334 [(set (match_operand:SWI12 0 "register_operand")
25335 (match_operand:SWI12 1 "memory_operand"))
25336 (set (match_operand:SWI12 3 "register_operand") (match_dup 0))
25337 (parallel [(set (match_operand:SI 4 "register_operand")
25338 (xor:SI (match_dup 4)
25339 (match_operand:SI 2 "<nonmemory_operand>")))
25340 (clobber (reg:CC FLAGS_REG))])
25341 (set (match_dup 1) (match_operand:SWI12 5 "register_operand"))
25342 (set (reg:CCZ FLAGS_REG)
25343 (compare:CCZ (match_operand:SWI12 6 "register_operand")
25344 (match_operand:SWI12 7 "<nonmemory_operand>")))]
25345 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25346 && (REGNO (operands[5]) == REGNO (operands[0])
25347 || REGNO (operands[5]) == REGNO (operands[3]))
25348 && REGNO (operands[5]) == REGNO (operands[4])
25349 && (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
25350 ? 3 : 0], operands[6])
25351 ? (REG_P (operands[2])
25352 ? REG_P (operands[7]) && REGNO (operands[2]) == REGNO (operands[7])
25353 : rtx_equal_p (operands[2], operands[7]))
25354 : (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
25355 ? 3 : 0], operands[7])
25356 && REG_P (operands[2])
25357 && REGNO (operands[2]) == REGNO (operands[6])))
25358 && peep2_reg_dead_p (4, operands[5])
25359 && peep2_reg_dead_p (5, operands[REGNO (operands[5]) == REGNO (operands[0])
25361 && !reg_overlap_mentioned_p (operands[0], operands[1])
25362 && !reg_overlap_mentioned_p (operands[0], operands[2])
25363 && !reg_overlap_mentioned_p (operands[3], operands[0])
25364 && !reg_overlap_mentioned_p (operands[3], operands[1])
25365 && !reg_overlap_mentioned_p (operands[3], operands[2])
25366 && (<MODE>mode != QImode
25367 || immediate_operand (operands[2], SImode)
25368 || any_QIreg_operand (operands[2], SImode))"
25369 [(parallel [(set (match_dup 8) (match_dup 10))
25370 (set (match_dup 1) (match_dup 9))])]
25372 operands[8] = SET_DEST (PATTERN (peep2_next_insn (4)));
25373 operands[9] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
25374 gen_lowpart (<MODE>mode, operands[2]));
25376 = gen_rtx_COMPARE (GET_MODE (operands[8]),
25377 copy_rtx (operands[9]),
25381 ;; Attempt to optimize away memory stores of values the memory already
25382 ;; has. See PR79593.
25384 [(set (match_operand 0 "register_operand")
25385 (match_operand 1 "memory_operand"))
25386 (set (match_operand 2 "memory_operand") (match_dup 0))]
25387 "!MEM_VOLATILE_P (operands[1])
25388 && !MEM_VOLATILE_P (operands[2])
25389 && rtx_equal_p (operands[1], operands[2])
25390 && !reg_overlap_mentioned_p (operands[0], operands[2])"
25391 [(set (match_dup 0) (match_dup 1))])
25393 ;; Attempt to always use XOR for zeroing registers (including FP modes).
25395 [(set (match_operand 0 "general_reg_operand")
25396 (match_operand 1 "const0_operand"))]
25397 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
25398 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
25399 && peep2_regno_dead_p (0, FLAGS_REG)"
25400 [(parallel [(set (match_dup 0) (const_int 0))
25401 (clobber (reg:CC FLAGS_REG))])]
25402 "operands[0] = gen_lowpart (word_mode, operands[0]);")
25405 [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
25407 "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
25408 && peep2_regno_dead_p (0, FLAGS_REG)"
25409 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
25410 (clobber (reg:CC FLAGS_REG))])])
25412 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
25414 [(set (match_operand:SWI248 0 "general_reg_operand")
25416 "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
25417 && peep2_regno_dead_p (0, FLAGS_REG)"
25418 [(parallel [(set (match_dup 0) (const_int -1))
25419 (clobber (reg:CC FLAGS_REG))])]
25421 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
25422 operands[0] = gen_lowpart (SImode, operands[0]);
25425 ;; Attempt to convert simple lea to add/shift.
25426 ;; These can be created by move expanders.
25427 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
25428 ;; relevant lea instructions were already split.
25431 [(set (match_operand:SWI48 0 "register_operand")
25432 (plus:SWI48 (match_dup 0)
25433 (match_operand:SWI48 1 "<nonmemory_operand>")))]
25435 && peep2_regno_dead_p (0, FLAGS_REG)"
25436 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
25437 (clobber (reg:CC FLAGS_REG))])])
25440 [(set (match_operand:SWI48 0 "register_operand")
25441 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
25444 && peep2_regno_dead_p (0, FLAGS_REG)"
25445 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
25446 (clobber (reg:CC FLAGS_REG))])])
25449 [(set (match_operand:DI 0 "register_operand")
25451 (plus:SI (match_operand:SI 1 "register_operand")
25452 (match_operand:SI 2 "nonmemory_operand"))))]
25453 "TARGET_64BIT && !TARGET_OPT_AGU
25454 && REGNO (operands[0]) == REGNO (operands[1])
25455 && peep2_regno_dead_p (0, FLAGS_REG)"
25456 [(parallel [(set (match_dup 0)
25457 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
25458 (clobber (reg:CC FLAGS_REG))])])
25461 [(set (match_operand:DI 0 "register_operand")
25463 (plus:SI (match_operand:SI 1 "nonmemory_operand")
25464 (match_operand:SI 2 "register_operand"))))]
25465 "TARGET_64BIT && !TARGET_OPT_AGU
25466 && REGNO (operands[0]) == REGNO (operands[2])
25467 && peep2_regno_dead_p (0, FLAGS_REG)"
25468 [(parallel [(set (match_dup 0)
25469 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
25470 (clobber (reg:CC FLAGS_REG))])])
25473 [(set (match_operand:SWI48 0 "register_operand")
25474 (mult:SWI48 (match_dup 0)
25475 (match_operand:SWI48 1 "const_int_operand")))]
25476 "pow2p_hwi (INTVAL (operands[1]))
25477 && peep2_regno_dead_p (0, FLAGS_REG)"
25478 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
25479 (clobber (reg:CC FLAGS_REG))])]
25480 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
25483 [(set (match_operand:DI 0 "register_operand")
25485 (mult:SI (match_operand:SI 1 "register_operand")
25486 (match_operand:SI 2 "const_int_operand"))))]
25488 && pow2p_hwi (INTVAL (operands[2]))
25489 && REGNO (operands[0]) == REGNO (operands[1])
25490 && peep2_regno_dead_p (0, FLAGS_REG)"
25491 [(parallel [(set (match_dup 0)
25492 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
25493 (clobber (reg:CC FLAGS_REG))])]
25494 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
25496 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
25497 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
25498 ;; On many CPUs it is also faster, since special hardware to avoid esp
25499 ;; dependencies is present.
25501 ;; While some of these conversions may be done using splitters, we use
25502 ;; peepholes in order to allow combine_stack_adjustments pass to see
25503 ;; nonobfuscated RTL.
25505 ;; Convert prologue esp subtractions to push.
25506 ;; We need register to push. In order to keep verify_flow_info happy we have
25508 ;; - use scratch and clobber it in order to avoid dependencies
25509 ;; - use already live register
25510 ;; We can't use the second way right now, since there is no reliable way how to
25511 ;; verify that given register is live. First choice will also most likely in
25512 ;; fewer dependencies. On the place of esp adjustments it is very likely that
25513 ;; call clobbered registers are dead. We may want to use base pointer as an
25514 ;; alternative when no register is available later.
25517 [(match_scratch:W 1 "r")
25518 (parallel [(set (reg:P SP_REG)
25519 (plus:P (reg:P SP_REG)
25520 (match_operand:P 0 "const_int_operand")))
25521 (clobber (reg:CC FLAGS_REG))
25522 (clobber (mem:BLK (scratch)))])]
25523 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
25524 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
25525 && !ix86_red_zone_used"
25526 [(clobber (match_dup 1))
25527 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
25528 (clobber (mem:BLK (scratch)))])])
25531 [(match_scratch:W 1 "r")
25532 (parallel [(set (reg:P SP_REG)
25533 (plus:P (reg:P SP_REG)
25534 (match_operand:P 0 "const_int_operand")))
25535 (clobber (reg:CC FLAGS_REG))
25536 (clobber (mem:BLK (scratch)))])]
25537 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
25538 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
25539 && !ix86_red_zone_used"
25540 [(clobber (match_dup 1))
25541 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
25542 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
25543 (clobber (mem:BLK (scratch)))])])
25545 ;; Convert esp subtractions to push.
25547 [(match_scratch:W 1 "r")
25548 (parallel [(set (reg:P SP_REG)
25549 (plus:P (reg:P SP_REG)
25550 (match_operand:P 0 "const_int_operand")))
25551 (clobber (reg:CC FLAGS_REG))])]
25552 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
25553 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
25554 && !ix86_red_zone_used"
25555 [(clobber (match_dup 1))
25556 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
25559 [(match_scratch:W 1 "r")
25560 (parallel [(set (reg:P SP_REG)
25561 (plus:P (reg:P SP_REG)
25562 (match_operand:P 0 "const_int_operand")))
25563 (clobber (reg:CC FLAGS_REG))])]
25564 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
25565 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
25566 && !ix86_red_zone_used"
25567 [(clobber (match_dup 1))
25568 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
25569 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
25571 ;; Convert epilogue deallocator to pop.
25573 [(match_scratch:W 1 "r")
25574 (parallel [(set (reg:P SP_REG)
25575 (plus:P (reg:P SP_REG)
25576 (match_operand:P 0 "const_int_operand")))
25577 (clobber (reg:CC FLAGS_REG))
25578 (clobber (mem:BLK (scratch)))])]
25579 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
25580 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
25581 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25582 (clobber (mem:BLK (scratch)))])])
25584 ;; Two pops case is tricky, since pop causes dependency
25585 ;; on destination register. We use two registers if available.
25587 [(match_scratch:W 1 "r")
25588 (match_scratch:W 2 "r")
25589 (parallel [(set (reg:P SP_REG)
25590 (plus:P (reg:P SP_REG)
25591 (match_operand:P 0 "const_int_operand")))
25592 (clobber (reg:CC FLAGS_REG))
25593 (clobber (mem:BLK (scratch)))])]
25594 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
25595 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
25596 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25597 (clobber (mem:BLK (scratch)))])
25598 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
25601 [(match_scratch:W 1 "r")
25602 (parallel [(set (reg:P SP_REG)
25603 (plus:P (reg:P SP_REG)
25604 (match_operand:P 0 "const_int_operand")))
25605 (clobber (reg:CC FLAGS_REG))
25606 (clobber (mem:BLK (scratch)))])]
25607 "optimize_insn_for_size_p ()
25608 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
25609 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25610 (clobber (mem:BLK (scratch)))])
25611 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
25613 ;; Convert esp additions to pop.
25615 [(match_scratch:W 1 "r")
25616 (parallel [(set (reg:P SP_REG)
25617 (plus:P (reg:P SP_REG)
25618 (match_operand:P 0 "const_int_operand")))
25619 (clobber (reg:CC FLAGS_REG))])]
25620 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
25621 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
25623 ;; Two pops case is tricky, since pop causes dependency
25624 ;; on destination register. We use two registers if available.
25626 [(match_scratch:W 1 "r")
25627 (match_scratch:W 2 "r")
25628 (parallel [(set (reg:P SP_REG)
25629 (plus:P (reg:P SP_REG)
25630 (match_operand:P 0 "const_int_operand")))
25631 (clobber (reg:CC FLAGS_REG))])]
25632 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
25633 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25634 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
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 "optimize_insn_for_size_p ()
25643 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
25644 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25645 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
25647 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
25648 ;; required and register dies. Similarly for 128 to -128.
25650 [(set (match_operand 0 "flags_reg_operand")
25651 (match_operator 1 "compare_operator"
25652 [(match_operand 2 "register_operand")
25653 (match_operand 3 "const_int_operand")]))]
25654 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
25655 && incdec_operand (operands[3], GET_MODE (operands[3])))
25656 || (!TARGET_FUSE_CMP_AND_BRANCH
25657 && INTVAL (operands[3]) == 128))
25658 && ix86_match_ccmode (insn, CCGCmode)
25659 && peep2_reg_dead_p (1, operands[2])"
25660 [(parallel [(set (match_dup 0)
25661 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
25662 (clobber (match_dup 2))])])
25664 ;; Convert imul by three, five and nine into lea
25667 [(set (match_operand:SWI48 0 "register_operand")
25668 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
25669 (match_operand:SWI48 2 "const359_operand")))
25670 (clobber (reg:CC FLAGS_REG))])]
25671 "!TARGET_PARTIAL_REG_STALL
25672 || <MODE>mode == SImode
25673 || optimize_function_for_size_p (cfun)"
25674 [(set (match_dup 0)
25675 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
25677 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
25681 [(set (match_operand:SWI48 0 "register_operand")
25682 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
25683 (match_operand:SWI48 2 "const359_operand")))
25684 (clobber (reg:CC FLAGS_REG))])]
25685 "optimize_insn_for_speed_p ()
25686 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
25687 [(set (match_dup 0) (match_dup 1))
25689 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
25691 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
25693 ;; imul $32bit_imm, mem, reg is vector decoded, while
25694 ;; imul $32bit_imm, reg, reg is direct decoded.
25696 [(match_scratch:SWI48 3 "r")
25697 (parallel [(set (match_operand:SWI48 0 "register_operand")
25698 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
25699 (match_operand:SWI48 2 "immediate_operand")))
25700 (clobber (reg:CC FLAGS_REG))])]
25701 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
25702 && !satisfies_constraint_K (operands[2])"
25703 [(set (match_dup 3) (match_dup 1))
25704 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
25705 (clobber (reg:CC FLAGS_REG))])])
25708 [(match_scratch:SI 3 "r")
25709 (parallel [(set (match_operand:DI 0 "register_operand")
25711 (mult:SI (match_operand:SI 1 "memory_operand")
25712 (match_operand:SI 2 "immediate_operand"))))
25713 (clobber (reg:CC FLAGS_REG))])]
25715 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
25716 && !satisfies_constraint_K (operands[2])"
25717 [(set (match_dup 3) (match_dup 1))
25718 (parallel [(set (match_dup 0)
25719 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
25720 (clobber (reg:CC FLAGS_REG))])])
25722 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
25723 ;; Convert it into imul reg, reg
25724 ;; It would be better to force assembler to encode instruction using long
25725 ;; immediate, but there is apparently no way to do so.
25727 [(parallel [(set (match_operand:SWI248 0 "register_operand")
25729 (match_operand:SWI248 1 "nonimmediate_operand")
25730 (match_operand:SWI248 2 "const_int_operand")))
25731 (clobber (reg:CC FLAGS_REG))])
25732 (match_scratch:SWI248 3 "r")]
25733 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
25734 && satisfies_constraint_K (operands[2])"
25735 [(set (match_dup 3) (match_dup 2))
25736 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
25737 (clobber (reg:CC FLAGS_REG))])]
25739 if (!rtx_equal_p (operands[0], operands[1]))
25740 emit_move_insn (operands[0], operands[1]);
25743 ;; After splitting up read-modify operations, array accesses with memory
25744 ;; operands might end up in form:
25746 ;; movl 4(%esp), %edx
25748 ;; instead of pre-splitting:
25750 ;; addl 4(%esp), %eax
25752 ;; movl 4(%esp), %edx
25753 ;; leal (%edx,%eax,4), %eax
25756 [(match_scratch:W 5 "r")
25757 (parallel [(set (match_operand 0 "register_operand")
25758 (ashift (match_operand 1 "register_operand")
25759 (match_operand 2 "const_int_operand")))
25760 (clobber (reg:CC FLAGS_REG))])
25761 (parallel [(set (match_operand 3 "register_operand")
25762 (plus (match_dup 0)
25763 (match_operand 4 "x86_64_general_operand")))
25764 (clobber (reg:CC FLAGS_REG))])]
25765 "IN_RANGE (INTVAL (operands[2]), 1, 3)
25766 /* Validate MODE for lea. */
25767 && ((!TARGET_PARTIAL_REG_STALL
25768 && (GET_MODE (operands[0]) == QImode
25769 || GET_MODE (operands[0]) == HImode))
25770 || GET_MODE (operands[0]) == SImode
25771 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
25772 && (rtx_equal_p (operands[0], operands[3])
25773 || peep2_reg_dead_p (2, operands[0]))
25774 /* We reorder load and the shift. */
25775 && !reg_overlap_mentioned_p (operands[0], operands[4])"
25776 [(set (match_dup 5) (match_dup 4))
25777 (set (match_dup 0) (match_dup 1))]
25779 machine_mode op1mode = GET_MODE (operands[1]);
25780 machine_mode mode = op1mode == DImode ? DImode : SImode;
25781 int scale = 1 << INTVAL (operands[2]);
25782 rtx index = gen_lowpart (word_mode, operands[1]);
25783 rtx base = gen_lowpart (word_mode, operands[5]);
25784 rtx dest = gen_lowpart (mode, operands[3]);
25786 operands[1] = gen_rtx_PLUS (word_mode, base,
25787 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
25788 if (mode != word_mode)
25789 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
25791 operands[5] = base;
25792 if (op1mode != word_mode)
25793 operands[5] = gen_lowpart (op1mode, operands[5]);
25795 operands[0] = dest;
25798 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
25799 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
25800 ;; caught for use by garbage collectors and the like. Using an insn that
25801 ;; maps to SIGILL makes it more likely the program will rightfully die.
25802 ;; Keeping with tradition, "6" is in honor of #UD.
25803 (define_insn "trap"
25804 [(trap_if (const_int 1) (const_int 6))]
25807 #ifdef HAVE_AS_IX86_UD2
25810 return ASM_SHORT "0x0b0f";
25813 [(set_attr "length" "2")])
25816 [(unspec_volatile [(const_int 0)] UNSPECV_UD2)]
25819 #ifdef HAVE_AS_IX86_UD2
25822 return ASM_SHORT "0x0b0f";
25825 [(set_attr "length" "2")])
25827 (define_expand "prefetch"
25828 [(prefetch (match_operand 0 "address_operand")
25829 (match_operand:SI 1 "const_int_operand")
25830 (match_operand:SI 2 "const_int_operand"))]
25831 "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
25833 bool write = operands[1] != const0_rtx;
25834 int locality = INTVAL (operands[2]);
25836 gcc_assert (IN_RANGE (locality, 0, 3));
25838 /* Use 3dNOW prefetch in case we are asking for write prefetch not
25839 supported by SSE counterpart (non-SSE2 athlon machines) or the
25840 SSE prefetch is not available (K6 machines). Otherwise use SSE
25841 prefetch as it allows specifying of locality. */
25845 if (TARGET_PREFETCHWT1)
25846 operands[2] = GEN_INT (MAX (locality, 2));
25847 else if (TARGET_PRFCHW)
25848 operands[2] = GEN_INT (3);
25849 else if (TARGET_3DNOW && !TARGET_SSE2)
25850 operands[2] = GEN_INT (3);
25851 else if (TARGET_PREFETCH_SSE)
25852 operands[1] = const0_rtx;
25855 gcc_assert (TARGET_3DNOW);
25856 operands[2] = GEN_INT (3);
25861 if (TARGET_PREFETCH_SSE)
25865 gcc_assert (TARGET_3DNOW);
25866 operands[2] = GEN_INT (3);
25871 (define_insn "*prefetch_sse"
25872 [(prefetch (match_operand 0 "address_operand" "p")
25874 (match_operand:SI 1 "const_int_operand"))]
25875 "TARGET_PREFETCH_SSE"
25877 static const char * const patterns[4] = {
25878 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
25881 int locality = INTVAL (operands[1]);
25882 gcc_assert (IN_RANGE (locality, 0, 3));
25884 return patterns[locality];
25886 [(set_attr "type" "sse")
25887 (set_attr "atom_sse_attr" "prefetch")
25888 (set (attr "length_address")
25889 (symbol_ref "memory_address_length (operands[0], false)"))
25890 (set_attr "memory" "none")])
25892 (define_insn "*prefetch_3dnow"
25893 [(prefetch (match_operand 0 "address_operand" "p")
25894 (match_operand:SI 1 "const_int_operand")
25896 "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1"
25898 if (operands[1] == const0_rtx)
25899 return "prefetch\t%a0";
25901 return "prefetchw\t%a0";
25903 [(set_attr "type" "mmx")
25904 (set (attr "length_address")
25905 (symbol_ref "memory_address_length (operands[0], false)"))
25906 (set_attr "memory" "none")])
25908 (define_insn "*prefetch_prefetchwt1"
25909 [(prefetch (match_operand 0 "address_operand" "p")
25912 "TARGET_PREFETCHWT1"
25913 "prefetchwt1\t%a0";
25914 [(set_attr "type" "sse")
25915 (set (attr "length_address")
25916 (symbol_ref "memory_address_length (operands[0], false)"))
25917 (set_attr "memory" "none")])
25919 (define_insn "prefetchi"
25920 [(unspec_volatile [(match_operand 0 "local_func_symbolic_operand" "p")
25921 (match_operand:SI 1 "const_int_operand")]
25922 UNSPECV_PREFETCHI)]
25923 "TARGET_PREFETCHI && TARGET_64BIT"
25925 static const char * const patterns[2] = {
25926 "prefetchit1\t%0", "prefetchit0\t%0"
25929 int locality = INTVAL (operands[1]);
25930 gcc_assert (IN_RANGE (locality, 2, 3));
25932 return patterns[locality - 2];
25934 [(set_attr "type" "sse")
25935 (set (attr "length_address")
25936 (symbol_ref "memory_address_length (operands[0], false)"))
25937 (set_attr "memory" "none")])
25939 (define_insn "sse4_2_crc32<mode>"
25940 [(set (match_operand:SI 0 "register_operand" "=r")
25942 [(match_operand:SI 1 "register_operand" "0")
25943 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
25946 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
25947 [(set_attr "type" "sselog1")
25948 (set_attr "prefix_rep" "1")
25949 (set_attr "prefix_extra" "1")
25950 (set (attr "prefix_data16")
25951 (if_then_else (match_operand:HI 2)
25953 (const_string "*")))
25954 (set (attr "prefix_rex")
25955 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
25957 (const_string "*")))
25958 (set_attr "mode" "SI")])
25960 (define_insn "sse4_2_crc32di"
25961 [(set (match_operand:DI 0 "register_operand" "=r")
25964 [(match_operand:SI 1 "register_operand" "0")
25965 (match_operand:DI 2 "nonimmediate_operand" "rm")]
25967 "TARGET_64BIT && TARGET_CRC32"
25968 "crc32{q}\t{%2, %0|%0, %2}"
25969 [(set_attr "type" "sselog1")
25970 (set_attr "prefix_rep" "1")
25971 (set_attr "prefix_extra" "1")
25972 (set_attr "mode" "DI")])
25974 (define_insn "rdpmc"
25975 [(set (match_operand:DI 0 "register_operand" "=A")
25976 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
25980 [(set_attr "type" "other")
25981 (set_attr "length" "2")])
25983 (define_insn "rdpmc_rex64"
25984 [(set (match_operand:DI 0 "register_operand" "=a")
25985 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
25987 (set (match_operand:DI 1 "register_operand" "=d")
25988 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
25991 [(set_attr "type" "other")
25992 (set_attr "length" "2")])
25994 (define_insn "rdtsc"
25995 [(set (match_operand:DI 0 "register_operand" "=A")
25996 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
25999 [(set_attr "type" "other")
26000 (set_attr "length" "2")])
26002 (define_insn "rdtsc_rex64"
26003 [(set (match_operand:DI 0 "register_operand" "=a")
26004 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
26005 (set (match_operand:DI 1 "register_operand" "=d")
26006 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
26009 [(set_attr "type" "other")
26010 (set_attr "length" "2")])
26012 (define_insn "rdtscp"
26013 [(set (match_operand:DI 0 "register_operand" "=A")
26014 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
26015 (set (match_operand:SI 1 "register_operand" "=c")
26016 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
26019 [(set_attr "type" "other")
26020 (set_attr "length" "3")])
26022 (define_insn "rdtscp_rex64"
26023 [(set (match_operand:DI 0 "register_operand" "=a")
26024 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
26025 (set (match_operand:DI 1 "register_operand" "=d")
26026 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
26027 (set (match_operand:SI 2 "register_operand" "=c")
26028 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
26031 [(set_attr "type" "other")
26032 (set_attr "length" "3")])
26034 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26036 ;; FXSR, XSAVE and XSAVEOPT instructions
26038 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26040 (define_insn "fxsave"
26041 [(set (match_operand:BLK 0 "memory_operand" "=m")
26042 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
26045 [(set_attr "type" "other")
26046 (set_attr "memory" "store")
26047 (set (attr "length")
26048 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
26050 (define_insn "fxsave64"
26051 [(set (match_operand:BLK 0 "memory_operand" "=jm")
26052 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
26053 "TARGET_64BIT && TARGET_FXSR"
26055 [(set_attr "type" "other")
26056 (set_attr "addr" "gpr16")
26057 (set_attr "memory" "store")
26058 (set (attr "length")
26059 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
26061 (define_insn "fxrstor"
26062 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
26066 [(set_attr "type" "other")
26067 (set_attr "memory" "load")
26068 (set (attr "length")
26069 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
26071 (define_insn "fxrstor64"
26072 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "jm")]
26073 UNSPECV_FXRSTOR64)]
26074 "TARGET_64BIT && TARGET_FXSR"
26076 [(set_attr "type" "other")
26077 (set_attr "addr" "gpr16")
26078 (set_attr "memory" "load")
26079 (set (attr "length")
26080 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
26082 (define_int_iterator ANY_XSAVE
26084 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
26085 (UNSPECV_XSAVEC "TARGET_XSAVEC")
26086 (UNSPECV_XSAVES "TARGET_XSAVES")])
26088 (define_int_iterator ANY_XSAVE64
26090 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
26091 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
26092 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
26094 (define_int_attr xsave
26095 [(UNSPECV_XSAVE "xsave")
26096 (UNSPECV_XSAVE64 "xsave64")
26097 (UNSPECV_XSAVEOPT "xsaveopt")
26098 (UNSPECV_XSAVEOPT64 "xsaveopt64")
26099 (UNSPECV_XSAVEC "xsavec")
26100 (UNSPECV_XSAVEC64 "xsavec64")
26101 (UNSPECV_XSAVES "xsaves")
26102 (UNSPECV_XSAVES64 "xsaves64")])
26104 (define_int_iterator ANY_XRSTOR
26106 (UNSPECV_XRSTORS "TARGET_XSAVES")])
26108 (define_int_iterator ANY_XRSTOR64
26110 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
26112 (define_int_attr xrstor
26113 [(UNSPECV_XRSTOR "xrstor")
26114 (UNSPECV_XRSTOR64 "xrstor")
26115 (UNSPECV_XRSTORS "xrstors")
26116 (UNSPECV_XRSTORS64 "xrstors")])
26118 (define_insn "<xsave>"
26119 [(set (match_operand:BLK 0 "memory_operand" "=m")
26120 (unspec_volatile:BLK
26121 [(match_operand:DI 1 "register_operand" "A")]
26123 "!TARGET_64BIT && TARGET_XSAVE"
26125 [(set_attr "type" "other")
26126 (set_attr "memory" "store")
26127 (set (attr "length")
26128 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
26130 (define_insn "<xsave>_rex64"
26131 [(set (match_operand:BLK 0 "memory_operand" "=jm")
26132 (unspec_volatile:BLK
26133 [(match_operand:SI 1 "register_operand" "a")
26134 (match_operand:SI 2 "register_operand" "d")]
26136 "TARGET_64BIT && TARGET_XSAVE"
26138 [(set_attr "type" "other")
26139 (set_attr "memory" "store")
26140 (set_attr "addr" "gpr16")
26141 (set (attr "length")
26142 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
26144 (define_insn "<xsave>"
26145 [(set (match_operand:BLK 0 "memory_operand" "=jm")
26146 (unspec_volatile:BLK
26147 [(match_operand:SI 1 "register_operand" "a")
26148 (match_operand:SI 2 "register_operand" "d")]
26150 "TARGET_64BIT && TARGET_XSAVE"
26152 [(set_attr "type" "other")
26153 (set_attr "memory" "store")
26154 (set_attr "addr" "gpr16")
26155 (set (attr "length")
26156 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
26158 (define_insn "<xrstor>"
26159 [(unspec_volatile:BLK
26160 [(match_operand:BLK 0 "memory_operand" "m")
26161 (match_operand:DI 1 "register_operand" "A")]
26163 "!TARGET_64BIT && TARGET_XSAVE"
26165 [(set_attr "type" "other")
26166 (set_attr "memory" "load")
26167 (set (attr "length")
26168 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
26170 (define_insn "<xrstor>_rex64"
26171 [(unspec_volatile:BLK
26172 [(match_operand:BLK 0 "memory_operand" "jm")
26173 (match_operand:SI 1 "register_operand" "a")
26174 (match_operand:SI 2 "register_operand" "d")]
26176 "TARGET_64BIT && TARGET_XSAVE"
26178 [(set_attr "type" "other")
26179 (set_attr "memory" "load")
26180 (set_attr "addr" "gpr16")
26181 (set (attr "length")
26182 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
26184 (define_insn "<xrstor>64"
26185 [(unspec_volatile:BLK
26186 [(match_operand:BLK 0 "memory_operand" "jm")
26187 (match_operand:SI 1 "register_operand" "a")
26188 (match_operand:SI 2 "register_operand" "d")]
26190 "TARGET_64BIT && TARGET_XSAVE"
26192 [(set_attr "type" "other")
26193 (set_attr "memory" "load")
26194 (set_attr "addr" "gpr16")
26195 (set (attr "length")
26196 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
26198 (define_insn "xsetbv"
26199 [(unspec_volatile:SI
26200 [(match_operand:SI 0 "register_operand" "c")
26201 (match_operand:DI 1 "register_operand" "A")]
26203 "!TARGET_64BIT && TARGET_XSAVE"
26205 [(set_attr "type" "other")])
26207 (define_insn "xsetbv_rex64"
26208 [(unspec_volatile:SI
26209 [(match_operand:SI 0 "register_operand" "c")
26210 (match_operand:SI 1 "register_operand" "a")
26211 (match_operand:SI 2 "register_operand" "d")]
26213 "TARGET_64BIT && TARGET_XSAVE"
26215 [(set_attr "type" "other")])
26217 (define_insn "xgetbv"
26218 [(set (match_operand:DI 0 "register_operand" "=A")
26219 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
26221 "!TARGET_64BIT && TARGET_XSAVE"
26223 [(set_attr "type" "other")])
26225 (define_insn "xgetbv_rex64"
26226 [(set (match_operand:DI 0 "register_operand" "=a")
26227 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
26229 (set (match_operand:DI 1 "register_operand" "=d")
26230 (unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))]
26231 "TARGET_64BIT && TARGET_XSAVE"
26233 [(set_attr "type" "other")])
26235 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26237 ;; Floating-point instructions for atomic compound assignments
26239 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26241 ; Clobber all floating-point registers on environment save and restore
26242 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
26243 (define_insn "fnstenv"
26244 [(set (match_operand:BLK 0 "memory_operand" "=m")
26245 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
26246 (clobber (reg:XF ST0_REG))
26247 (clobber (reg:XF ST1_REG))
26248 (clobber (reg:XF ST2_REG))
26249 (clobber (reg:XF ST3_REG))
26250 (clobber (reg:XF ST4_REG))
26251 (clobber (reg:XF ST5_REG))
26252 (clobber (reg:XF ST6_REG))
26253 (clobber (reg:XF ST7_REG))]
26256 [(set_attr "type" "other")
26257 (set_attr "memory" "store")
26258 (set (attr "length")
26259 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
26261 (define_insn "fldenv"
26262 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
26264 (clobber (reg:XF ST0_REG))
26265 (clobber (reg:XF ST1_REG))
26266 (clobber (reg:XF ST2_REG))
26267 (clobber (reg:XF ST3_REG))
26268 (clobber (reg:XF ST4_REG))
26269 (clobber (reg:XF ST5_REG))
26270 (clobber (reg:XF ST6_REG))
26271 (clobber (reg:XF ST7_REG))]
26274 [(set_attr "type" "other")
26275 (set_attr "memory" "load")
26276 (set (attr "length")
26277 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
26279 (define_insn "fnstsw"
26280 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
26281 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
26284 [(set_attr "type" "other,other")
26285 (set_attr "memory" "none,store")
26286 (set (attr "length")
26287 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
26289 (define_insn "fnclex"
26290 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
26293 [(set_attr "type" "other")
26294 (set_attr "memory" "none")
26295 (set_attr "length" "2")])
26297 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26299 ;; LWP instructions
26301 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26303 (define_insn "@lwp_llwpcb<mode>"
26304 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
26305 UNSPECV_LLWP_INTRINSIC)]
26308 [(set_attr "type" "lwp")
26309 (set_attr "mode" "<MODE>")
26310 (set_attr "length" "5")])
26312 (define_insn "@lwp_slwpcb<mode>"
26313 [(set (match_operand:P 0 "register_operand" "=r")
26314 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
26317 [(set_attr "type" "lwp")
26318 (set_attr "mode" "<MODE>")
26319 (set_attr "length" "5")])
26321 (define_insn "@lwp_lwpval<mode>"
26322 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
26323 (match_operand:SI 1 "nonimmediate_operand" "rm")
26324 (match_operand:SI 2 "const_int_operand")]
26325 UNSPECV_LWPVAL_INTRINSIC)]
26327 "lwpval\t{%2, %1, %0|%0, %1, %2}"
26328 [(set_attr "type" "lwp")
26329 (set_attr "mode" "<MODE>")
26330 (set (attr "length")
26331 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
26333 (define_insn "@lwp_lwpins<mode>"
26334 [(set (reg:CCC FLAGS_REG)
26335 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
26336 (match_operand:SI 1 "nonimmediate_operand" "rm")
26337 (match_operand:SI 2 "const_int_operand")]
26338 UNSPECV_LWPINS_INTRINSIC))]
26340 "lwpins\t{%2, %1, %0|%0, %1, %2}"
26341 [(set_attr "type" "lwp")
26342 (set_attr "mode" "<MODE>")
26343 (set (attr "length")
26344 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
26346 (define_int_iterator RDFSGSBASE
26350 (define_int_iterator WRFSGSBASE
26354 (define_int_attr fsgs
26355 [(UNSPECV_RDFSBASE "fs")
26356 (UNSPECV_RDGSBASE "gs")
26357 (UNSPECV_WRFSBASE "fs")
26358 (UNSPECV_WRGSBASE "gs")])
26360 (define_insn "rd<fsgs>base<mode>"
26361 [(set (match_operand:SWI48 0 "register_operand" "=r")
26362 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
26363 "TARGET_64BIT && TARGET_FSGSBASE"
26365 [(set_attr "type" "other")
26366 (set_attr "prefix_0f" "1")
26367 (set_attr "prefix_rep" "1")])
26369 (define_insn "wr<fsgs>base<mode>"
26370 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
26372 "TARGET_64BIT && TARGET_FSGSBASE"
26374 [(set_attr "type" "other")
26375 (set_attr "prefix_0f" "1")
26376 (set_attr "prefix_rep" "1")])
26378 (define_insn "ptwrite<mode>"
26379 [(unspec_volatile [(match_operand:SWI48 0 "nonimmediate_operand" "rm")]
26383 [(set_attr "type" "other")
26384 (set_attr "prefix_0f" "1")
26385 (set_attr "prefix_rep" "1")])
26387 (define_insn "@rdrand<mode>"
26388 [(set (match_operand:SWI248 0 "register_operand" "=r")
26389 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
26390 (set (reg:CCC FLAGS_REG)
26391 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
26394 [(set_attr "type" "other")
26395 (set_attr "prefix_0f" "1")])
26397 (define_insn "@rdseed<mode>"
26398 [(set (match_operand:SWI248 0 "register_operand" "=r")
26399 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
26400 (set (reg:CCC FLAGS_REG)
26401 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
26404 [(set_attr "type" "other")
26405 (set_attr "prefix_0f" "1")])
26407 (define_expand "pause"
26408 [(set (match_dup 0)
26409 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
26412 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
26413 MEM_VOLATILE_P (operands[0]) = 1;
26416 ;; Use "rep; nop", instead of "pause", to support older assemblers.
26417 ;; They have the same encoding.
26418 (define_insn "*pause"
26419 [(set (match_operand:BLK 0)
26420 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
26423 [(set_attr "length" "2")
26424 (set_attr "memory" "unknown")])
26426 ;; CET instructions
26427 (define_insn "@rdssp<mode>"
26428 [(set (match_operand:SWI48 0 "register_operand" "=r")
26429 (unspec_volatile:SWI48 [(match_operand:SWI48 1 "register_operand" "0")]
26430 UNSPECV_NOP_RDSSP))]
26431 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
26432 "rdssp<mskmodesuffix>\t%0"
26433 [(set_attr "length" "6")
26434 (set_attr "type" "other")])
26436 (define_insn "@incssp<mode>"
26437 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
26439 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
26440 "incssp<mskmodesuffix>\t%0"
26441 [(set_attr "length" "4")
26442 (set_attr "type" "other")])
26444 (define_insn "saveprevssp"
26445 [(unspec_volatile [(const_int 0)] UNSPECV_SAVEPREVSSP)]
26448 [(set_attr "length" "5")
26449 (set_attr "type" "other")])
26451 (define_insn "rstorssp"
26452 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")]
26456 [(set_attr "length" "5")
26457 (set_attr "type" "other")])
26459 (define_insn "@wrss<mode>"
26460 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
26461 (match_operand:SWI48 1 "memory_operand" "m")]
26464 "wrss<mskmodesuffix>\t%0, %1"
26465 [(set_attr "length" "3")
26466 (set_attr "type" "other")])
26468 (define_insn "@wruss<mode>"
26469 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
26470 (match_operand:SWI48 1 "memory_operand" "m")]
26473 "wruss<mskmodesuffix>\t%0, %1"
26474 [(set_attr "length" "4")
26475 (set_attr "type" "other")])
26477 (define_insn "setssbsy"
26478 [(unspec_volatile [(const_int 0)] UNSPECV_SETSSBSY)]
26481 [(set_attr "length" "4")
26482 (set_attr "type" "other")])
26484 (define_insn "clrssbsy"
26485 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")]
26489 [(set_attr "length" "4")
26490 (set_attr "type" "other")])
26492 (define_insn "nop_endbr"
26493 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]
26494 "(flag_cf_protection & CF_BRANCH)"
26496 return TARGET_64BIT ? "endbr64" : "endbr32";
26498 [(set_attr "length" "4")
26499 (set_attr "length_immediate" "0")
26500 (set_attr "modrm" "0")])
26503 (define_expand "xbegin"
26504 [(set (match_operand:SI 0 "register_operand")
26505 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
26508 rtx_code_label *label = gen_label_rtx ();
26510 /* xbegin is emitted as jump_insn, so reload won't be able
26511 to reload its operand. Force the value into AX hard register. */
26512 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
26513 emit_move_insn (ax_reg, constm1_rtx);
26515 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
26517 emit_label (label);
26518 LABEL_NUSES (label) = 1;
26520 emit_move_insn (operands[0], ax_reg);
26525 (define_insn "xbegin_1"
26527 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
26529 (label_ref (match_operand 1))
26531 (set (match_operand:SI 0 "register_operand" "+a")
26532 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
26535 [(set_attr "type" "other")
26536 (set_attr "length" "6")])
26538 (define_insn "xend"
26539 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
26542 [(set_attr "type" "other")
26543 (set_attr "length" "3")])
26545 (define_insn "xabort"
26546 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand")]
26550 [(set_attr "type" "other")
26551 (set_attr "length" "3")])
26553 (define_expand "xtest"
26554 [(set (match_operand:QI 0 "register_operand")
26555 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
26558 emit_insn (gen_xtest_1 ());
26560 ix86_expand_setcc (operands[0], NE,
26561 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
26565 (define_insn "xtest_1"
26566 [(set (reg:CCZ FLAGS_REG)
26567 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
26570 [(set_attr "type" "other")
26571 (set_attr "length" "3")])
26573 (define_insn "clwb"
26574 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
26578 [(set_attr "type" "sse")
26579 (set_attr "atom_sse_attr" "fence")
26580 (set_attr "memory" "unknown")])
26582 (define_insn "clflushopt"
26583 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
26584 UNSPECV_CLFLUSHOPT)]
26585 "TARGET_CLFLUSHOPT"
26587 [(set_attr "type" "sse")
26588 (set_attr "atom_sse_attr" "fence")
26589 (set_attr "memory" "unknown")])
26591 ;; MONITORX and MWAITX
26592 (define_insn "mwaitx"
26593 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
26594 (match_operand:SI 1 "register_operand" "a")
26595 (match_operand:SI 2 "register_operand" "b")]
26598 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
26599 ;; Since 32bit register operands are implicitly zero extended to 64bit,
26600 ;; we only need to set up 32bit registers.
26602 [(set_attr "length" "3")])
26604 (define_insn "@monitorx_<mode>"
26605 [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
26606 (match_operand:SI 1 "register_operand" "c")
26607 (match_operand:SI 2 "register_operand" "d")]
26610 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
26611 ;; RCX and RDX are used. Since 32bit register operands are implicitly
26612 ;; zero extended to 64bit, we only need to set up 32bit registers.
26614 [(set (attr "length")
26615 (symbol_ref ("(Pmode != word_mode) + 3")))])
26618 (define_insn "@clzero_<mode>"
26619 [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
26623 [(set_attr "length" "3")
26624 (set_attr "memory" "unknown")])
26626 ;; RDPKRU and WRPKRU
26628 (define_expand "rdpkru"
26630 [(set (match_operand:SI 0 "register_operand")
26631 (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
26632 (set (match_dup 2) (const_int 0))])]
26635 operands[1] = force_reg (SImode, const0_rtx);
26636 operands[2] = gen_reg_rtx (SImode);
26639 (define_insn "*rdpkru"
26640 [(set (match_operand:SI 0 "register_operand" "=a")
26641 (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
26643 (set (match_operand:SI 1 "register_operand" "=d")
26647 [(set_attr "type" "other")])
26649 (define_expand "wrpkru"
26650 [(unspec_volatile:SI
26651 [(match_operand:SI 0 "register_operand")
26652 (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
26655 operands[1] = force_reg (SImode, const0_rtx);
26656 operands[2] = force_reg (SImode, const0_rtx);
26659 (define_insn "*wrpkru"
26660 [(unspec_volatile:SI
26661 [(match_operand:SI 0 "register_operand" "a")
26662 (match_operand:SI 1 "register_operand" "d")
26663 (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
26666 [(set_attr "type" "other")])
26668 (define_insn "rdpid"
26669 [(set (match_operand:SI 0 "register_operand" "=r")
26670 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDPID))]
26671 "!TARGET_64BIT && TARGET_RDPID"
26673 [(set_attr "type" "other")])
26675 (define_insn "rdpid_rex64"
26676 [(set (match_operand:DI 0 "register_operand" "=r")
26677 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPID))]
26678 "TARGET_64BIT && TARGET_RDPID"
26680 [(set_attr "type" "other")])
26682 ;; Intirinsics for > i486
26684 (define_insn "wbinvd"
26685 [(unspec_volatile [(const_int 0)] UNSPECV_WBINVD)]
26688 [(set_attr "type" "other")])
26690 (define_insn "wbnoinvd"
26691 [(unspec_volatile [(const_int 0)] UNSPECV_WBNOINVD)]
26694 [(set_attr "type" "other")])
26696 ;; MOVDIRI and MOVDIR64B
26698 (define_insn "movdiri<mode>"
26699 [(set (match_operand:SWI48 0 "memory_operand" "=m")
26700 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")]
26703 "movdiri\t{%1, %0|%0, %1}"
26704 [(set_attr "type" "other")])
26706 (define_insn "@movdir64b_<mode>"
26707 [(set (mem:XI (match_operand:P 0 "register_operand" "r"))
26708 (unspec:XI [(match_operand:XI 1 "memory_operand" "m")]
26709 UNSPEC_MOVDIR64B))]
26711 "movdir64b\t{%1, %0|%0, %1}"
26712 [(set_attr "type" "other")])
26715 (define_int_iterator TSXLDTRK [UNSPECV_XSUSLDTRK UNSPECV_XRESLDTRK])
26716 (define_int_attr tsxldtrk [(UNSPECV_XSUSLDTRK "xsusldtrk")
26717 (UNSPECV_XRESLDTRK "xresldtrk")])
26718 (define_insn "<tsxldtrk>"
26719 [(unspec_volatile [(const_int 0)] TSXLDTRK)]
26722 [(set_attr "type" "other")
26723 (set_attr "length" "4")])
26725 ;; ENQCMD and ENQCMDS
26727 (define_int_iterator ENQCMD [UNSPECV_ENQCMD UNSPECV_ENQCMDS])
26728 (define_int_attr enqcmd_sfx [(UNSPECV_ENQCMD "") (UNSPECV_ENQCMDS "s")])
26730 (define_insn "@enqcmd<enqcmd_sfx>_<mode>"
26731 [(set (reg:CCZ FLAGS_REG)
26732 (unspec_volatile:CCZ [(match_operand:P 0 "register_operand" "r")
26733 (match_operand:XI 1 "memory_operand" "m")]
26736 "enqcmd<enqcmd_sfx>\t{%1, %0|%0, %1}"
26737 [(set_attr "type" "other")])
26740 (define_int_iterator UINTR [UNSPECV_CLUI UNSPECV_STUI])
26741 (define_int_attr uintr [(UNSPECV_CLUI "clui") (UNSPECV_STUI "stui")])
26743 (define_insn "<uintr>"
26744 [(unspec_volatile [(const_int 0)] UINTR)]
26745 "TARGET_UINTR && TARGET_64BIT"
26747 [(set_attr "type" "other")
26748 (set_attr "length" "4")])
26750 (define_insn "testui"
26751 [(set (reg:CCC FLAGS_REG)
26752 (unspec_volatile:CCC [(const_int 0)] UNSPECV_TESTUI))]
26753 "TARGET_UINTR && TARGET_64BIT"
26755 [(set_attr "type" "other")
26756 (set_attr "length" "4")])
26758 (define_insn "senduipi"
26760 [(match_operand:DI 0 "register_operand" "r")]
26762 "TARGET_UINTR && TARGET_64BIT"
26764 [(set_attr "type" "other")
26765 (set_attr "length" "4")])
26769 (define_insn "umwait"
26770 [(set (reg:CCC FLAGS_REG)
26771 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26772 (match_operand:DI 1 "register_operand" "A")]
26774 "!TARGET_64BIT && TARGET_WAITPKG"
26776 [(set_attr "length" "3")])
26778 (define_insn "umwait_rex64"
26779 [(set (reg:CCC FLAGS_REG)
26780 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26781 (match_operand:SI 1 "register_operand" "a")
26782 (match_operand:SI 2 "register_operand" "d")]
26784 "TARGET_64BIT && TARGET_WAITPKG"
26786 [(set_attr "length" "3")])
26788 (define_insn "@umonitor_<mode>"
26789 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
26793 [(set (attr "length")
26794 (symbol_ref ("(Pmode != word_mode) + 3")))])
26796 (define_insn "tpause"
26797 [(set (reg:CCC FLAGS_REG)
26798 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26799 (match_operand:DI 1 "register_operand" "A")]
26801 "!TARGET_64BIT && TARGET_WAITPKG"
26803 [(set_attr "length" "3")])
26805 (define_insn "tpause_rex64"
26806 [(set (reg:CCC FLAGS_REG)
26807 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26808 (match_operand:SI 1 "register_operand" "a")
26809 (match_operand:SI 2 "register_operand" "d")]
26811 "TARGET_64BIT && TARGET_WAITPKG"
26813 [(set_attr "length" "3")])
26815 (define_insn "cldemote"
26816 [(unspec_volatile[(match_operand 0 "address_operand" "p")]
26820 [(set_attr "type" "other")
26821 (set_attr "memory" "unknown")])
26823 (define_insn "speculation_barrier"
26824 [(unspec_volatile [(const_int 0)] UNSPECV_SPECULATION_BARRIER)]
26827 [(set_attr "type" "other")
26828 (set_attr "length" "3")])
26830 (define_insn "serialize"
26831 [(unspec_volatile [(const_int 0)] UNSPECV_SERIALIZE)]
26834 [(set_attr "type" "other")
26835 (set_attr "length" "3")])
26837 (define_insn "patchable_area"
26838 [(unspec_volatile [(match_operand 0 "const_int_operand")
26839 (match_operand 1 "const_int_operand")]
26840 UNSPECV_PATCHABLE_AREA)]
26843 ix86_output_patchable_area (INTVAL (operands[0]),
26844 INTVAL (operands[1]) != 0);
26847 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
26848 (set_attr "length_immediate" "0")
26849 (set_attr "modrm" "0")])
26851 (define_insn "hreset"
26852 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")]
26856 [(set_attr "type" "other")
26857 (set_attr "length" "4")])
26859 ;; Spaceship optimization
26860 (define_expand "spaceship<mode>3"
26861 [(match_operand:SI 0 "register_operand")
26862 (match_operand:MODEF 1 "cmp_fp_expander_operand")
26863 (match_operand:MODEF 2 "cmp_fp_expander_operand")]
26864 "(TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
26865 && (TARGET_CMOVE || (TARGET_SAHF && TARGET_USE_SAHF))"
26867 ix86_expand_fp_spaceship (operands[0], operands[1], operands[2]);
26871 (define_expand "spaceshipxf3"
26872 [(match_operand:SI 0 "register_operand")
26873 (match_operand:XF 1 "nonmemory_operand")
26874 (match_operand:XF 2 "nonmemory_operand")]
26875 "TARGET_80387 && (TARGET_CMOVE || (TARGET_SAHF && TARGET_USE_SAHF))"
26877 ix86_expand_fp_spaceship (operands[0], operands[1], operands[2]);
26881 ;; Defined because the generic expand_builtin_issignaling for XFmode
26882 ;; only tests for sNaNs, but i387 treats also pseudo numbers as always
26884 (define_expand "issignalingxf2"
26885 [(match_operand:SI 0 "register_operand")
26886 (match_operand:XF 1 "general_operand")]
26889 rtx temp = operands[1];
26892 rtx mem = assign_stack_temp (XFmode, GET_MODE_SIZE (XFmode));
26893 emit_move_insn (mem, temp);
26896 rtx ex = adjust_address (temp, HImode, 8);
26897 rtx hi = adjust_address (temp, SImode, 4);
26898 rtx lo = adjust_address (temp, SImode, 0);
26899 rtx val = GEN_INT (HOST_WIDE_INT_M1U << 30);
26900 rtx mask = GEN_INT (0x7fff);
26901 rtx bit = GEN_INT (HOST_WIDE_INT_1U << 30);
26903 ((ex & mask) && (int) hi >= 0)
26904 || ((ex & mask) == mask && ((hi ^ bit) | ((lo | -lo) >> 31)) > val). */
26905 rtx nlo = expand_unop (SImode, neg_optab, lo, NULL_RTX, 0);
26906 lo = expand_binop (SImode, ior_optab, lo, nlo,
26907 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26908 lo = expand_shift (RSHIFT_EXPR, SImode, lo, 31, NULL_RTX, 1);
26909 temp = expand_binop (SImode, xor_optab, hi, bit,
26910 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26911 temp = expand_binop (SImode, ior_optab, temp, lo,
26912 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26913 temp = emit_store_flag_force (gen_reg_rtx (SImode), GTU, temp, val,
26915 ex = expand_binop (HImode, and_optab, ex, mask,
26916 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26917 rtx temp2 = emit_store_flag_force (gen_reg_rtx (SImode), NE,
26918 ex, const0_rtx, SImode, 1, 1);
26919 ex = emit_store_flag_force (gen_reg_rtx (SImode), EQ,
26920 ex, mask, HImode, 1, 1);
26921 temp = expand_binop (SImode, and_optab, temp, ex,
26922 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26923 rtx temp3 = emit_store_flag_force (gen_reg_rtx (SImode), GE,
26924 hi, const0_rtx, SImode, 0, 1);
26925 temp2 = expand_binop (SImode, and_optab, temp2, temp3,
26926 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26927 temp = expand_binop (SImode, ior_optab, temp, temp2,
26928 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26929 emit_move_insn (operands[0], temp);
26933 (define_insn "urdmsr"
26934 [(set (match_operand:DI 0 "register_operand" "=r")
26935 (unspec_volatile:DI
26936 [(match_operand:DI 1 "x86_64_szext_nonmemory_operand" "reZ")]
26938 "TARGET_USER_MSR && TARGET_64BIT"
26939 "urdmsr\t{%1, %0|%0, %1}"
26940 [(set_attr "prefix" "vex")
26941 (set_attr "type" "other")])
26943 (define_insn "uwrmsr"
26945 [(match_operand:DI 0 "x86_64_szext_nonmemory_operand" "reZ")
26946 (match_operand:DI 1 "register_operand" "r")]
26948 "TARGET_USER_MSR && TARGET_64BIT"
26949 "uwrmsr\t{%1, %0|%0, %1}"
26950 [(set_attr "prefix" "vex")
26951 (set_attr "type" "other")])
26955 (include "sync.md")