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
119 ;; For SSE/MMX support:
132 ;; Different from generic us_truncate RTX
133 ;; as it does unsigned saturation of signed source.
136 ;; For AVX/AVX512F support
141 ;; Generic math support
142 UNSPEC_IEEE_MIN ; not commutative
143 UNSPEC_IEEE_MAX ; not commutative
145 ;; x87 Floating point
158 UNSPEC_FRNDINT_ROUNDEVEN
165 ;; x87 Double output FP
190 ;; For LZCNT suppoprt
202 UNSPEC_INTERRUPT_RETURN
204 ;; For MOVDIRI and MOVDIR64B support
208 ;; For insn_callee_abi:
211 ;; For PUSH2/POP2 support
217 (define_c_enum "unspecv" [
221 UNSPECV_PROBE_STACK_RANGE
224 UNSPECV_SPLIT_STACK_RETURN
230 UNSPECV_LLWP_INTRINSIC
231 UNSPECV_SLWP_INTRINSIC
232 UNSPECV_LWPVAL_INTRINSIC
233 UNSPECV_LWPINS_INTRINSIC
259 ;; For atomic compound assignments.
265 ;; For RDRAND support
268 ;; For RDSEED support
282 ;; For CLFLUSHOPT support
285 ;; For MONITORX and MWAITX support
289 ;; For CLZERO support
292 ;; For RDPKRU and WRPKRU support
309 ;; For TSXLDTRK support
313 ;; For WAITPKG support
324 ;; For CLDEMOTE support
327 ;; For Speculation Barrier support
328 UNSPECV_SPECULATION_BARRIER
332 ;; For ENQCMD and ENQCMDS support
336 ;; For SERIALIZE support
339 ;; For patchable area support
340 UNSPECV_PATCHABLE_AREA
342 ;; For HRESET support
345 ;; For PREFETCHI support
348 ;; For USER_MSR support
353 ;; Constants to represent rounding modes in the ROUND instruction
355 [(ROUND_ROUNDEVEN 0x0)
363 ;; Constants to represent AVX512F embeded rounding
365 [(ROUND_NEAREST_INT 0)
373 ;; Constants to represent pcomtrue/pcomfalse variants
383 ;; Constants used in the XOP pperm instruction
385 [(PPERM_SRC 0x00) /* copy source */
386 (PPERM_INVERT 0x20) /* invert source */
387 (PPERM_REVERSE 0x40) /* bit reverse source */
388 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
389 (PPERM_ZERO 0x80) /* all 0's */
390 (PPERM_ONES 0xa0) /* all 1's */
391 (PPERM_SIGN 0xc0) /* propagate sign bit */
392 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
393 (PPERM_SRC1 0x00) /* use first source byte */
394 (PPERM_SRC2 0x10) /* use second source byte */
397 ;; Registers by name.
491 (FIRST_PSEUDO_REG 92)
494 ;; Insn callee abi index.
500 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
503 ;; In C guard expressions, put expressions which may be compile-time
504 ;; constants first. This allows for better optimization. For
505 ;; example, write "TARGET_64BIT && reload_completed", not
506 ;; "reload_completed && TARGET_64BIT".
510 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
511 atom,slm,glm,haswell,generic,lujiazui,yongfeng,amdfam10,bdver1,
512 bdver2,bdver3,bdver4,btver2,znver1,znver2,znver3,znver4"
513 (const (symbol_ref "ix86_schedule")))
515 ;; A basic instruction type. Refinements due to arguments to be
516 ;; provided in other attributes.
519 alu,alu1,negnot,imov,imovx,lea,
520 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
521 imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
522 push,pop,call,callv,leave,
524 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
525 fxch,fistp,fisttp,frndint,
526 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
527 ssemul,sseimul,ssediv,sselog,sselog1,
528 sseishft,sseishft1,ssecmp,ssecomi,
529 ssecvt,ssecvt1,sseicvt,sseins,
530 sseshuf,sseshuf1,ssemuladd,sse4arg,
532 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
533 (const_string "other"))
535 ;; Main data type used by the insn
537 "unknown,none,QI,HI,SI,DI,TI,OI,XI,HF,BF,SF,DF,XF,TF,V32HF,V16HF,V8HF,
538 V16SF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF,V8DF,V4HF,V4BF,V2HF,V2BF"
539 (const_string "unknown"))
541 ;; The CPU unit operations uses.
542 (define_attr "unit" "integer,i387,sse,mmx,unknown"
543 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
544 fxch,fistp,fisttp,frndint")
545 (const_string "i387")
546 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
547 ssemul,sseimul,ssediv,sselog,sselog1,
548 sseishft,sseishft1,ssecmp,ssecomi,
549 ssecvt,ssecvt1,sseicvt,sseins,
550 sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
552 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
554 (eq_attr "type" "other")
555 (const_string "unknown")]
556 (const_string "integer")))
558 ;; Used to control the "enabled" attribute on a per-instruction basis.
559 (define_attr "isa" "base,x64,nox64,x64_sse2,x64_sse4,x64_sse4_noavx,
560 x64_avx,x64_avx512bw,x64_avx512dq,aes,
561 sse_noavx,sse2,sse2_noavx,sse3,sse3_noavx,sse4,sse4_noavx,
562 avx,noavx,avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,avx512f_512,
563 noavx512f,avx512bw,avx512bw_512,noavx512bw,avx512dq,
564 noavx512dq,fma_or_avx512vl,avx512vl,noavx512vl,avxvnni,
565 avx512vnnivl,avx512fp16,avxifma,avx512ifmavl,avxneconvert,
566 avx512bf16vl,vpclmulqdqvl,avx_noavx512f,avx_noavx512vl"
567 (const_string "base"))
569 ;; The (bounding maximum) length of an instruction immediate.
570 (define_attr "length_immediate" ""
571 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
572 bitmanip,imulx,msklog,mskmov")
574 (ior (eq_attr "type" "sse4arg")
575 (eq_attr "isa" "fma4"))
577 (eq_attr "unit" "i387,sse,mmx")
579 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
580 rotate,rotatex,rotate1,imul,icmp,push,pop")
581 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
582 (eq_attr "type" "imov,test")
583 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
584 (eq_attr "type" "call")
585 (if_then_else (match_operand 0 "constant_call_address_operand")
588 (eq_attr "type" "callv")
589 (if_then_else (match_operand 1 "constant_call_address_operand")
592 ;; We don't know the size before shorten_branches. Expect
593 ;; the instruction to fit for better scheduling.
594 (eq_attr "type" "ibr")
597 (symbol_ref "/* Update immediate_length and other attributes! */
598 gcc_unreachable (),1")))
600 ;; The (bounding maximum) length of an instruction address.
601 (define_attr "length_address" ""
602 (cond [(eq_attr "type" "str,other,multi,fxch")
604 (and (eq_attr "type" "call")
605 (match_operand 0 "constant_call_address_operand"))
607 (and (eq_attr "type" "callv")
608 (match_operand 1 "constant_call_address_operand"))
611 (symbol_ref "ix86_attr_length_address_default (insn)")))
613 ;; Set when length prefix is used.
614 (define_attr "prefix_data16" ""
615 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
617 (eq_attr "mode" "HI")
619 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
624 ;; Set when string REP prefix is used.
625 (define_attr "prefix_rep" ""
626 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
628 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
633 ;; Set when 0f opcode prefix is used.
634 (define_attr "prefix_0f" ""
636 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov")
637 (eq_attr "unit" "sse,mmx"))
641 ;; Set when REX opcode prefix is used.
642 (define_attr "prefix_rex" ""
643 (cond [(not (match_test "TARGET_64BIT"))
645 (and (eq_attr "mode" "DI")
646 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
647 (eq_attr "unit" "!mmx")))
649 (and (eq_attr "mode" "QI")
650 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
652 (match_test "x86_extended_reg_mentioned_p (insn)")
654 (and (eq_attr "type" "imovx")
655 (match_operand:QI 1 "ext_QIreg_operand"))
660 ;; There are also additional prefixes in 3DNOW, SSSE3.
661 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
662 ;; While generally inapplicable to VEX/XOP/EVEX encodings, "length_vex" uses
663 ;; the attribute evaluating to zero to know that VEX2 encoding may be usable.
664 (define_attr "prefix_extra" ""
665 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
670 ;; Prefix used: original, VEX or maybe VEX.
671 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
672 (cond [(eq_attr "mode" "OI,V8SF,V4DF")
674 (eq_attr "mode" "XI,V16SF,V8DF")
675 (const_string "evex")
676 (eq_attr "type" "ssemuladd")
677 (if_then_else (eq_attr "isa" "fma4")
679 (const_string "maybe_evex"))
680 (eq_attr "type" "sse4arg")
683 (const_string "orig")))
685 ;; VEX W bit is used.
686 (define_attr "prefix_vex_w" "" (const_int 0))
688 ;; The length of VEX prefix
689 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
690 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
691 ;; still prefix_0f 1, with prefix_extra 1.
692 (define_attr "length_vex" ""
693 (if_then_else (and (eq_attr "prefix_0f" "1")
694 (eq_attr "prefix_extra" "0"))
695 (if_then_else (eq_attr "prefix_vex_w" "1")
696 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
697 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
698 (if_then_else (eq_attr "prefix_vex_w" "1")
699 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
700 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
702 ;; 4-bytes evex prefix and 1 byte opcode.
703 (define_attr "length_evex" "" (const_int 5))
705 ;; Set when modrm byte is used.
706 (define_attr "modrm" ""
707 (cond [(eq_attr "type" "str,leave")
709 (eq_attr "unit" "i387")
711 (and (eq_attr "type" "incdec")
712 (and (not (match_test "TARGET_64BIT"))
713 (ior (match_operand:SI 1 "register_operand")
714 (match_operand:HI 1 "register_operand"))))
716 (and (eq_attr "type" "push")
717 (not (match_operand 1 "memory_operand")))
719 (and (eq_attr "type" "pop")
720 (not (match_operand 0 "memory_operand")))
722 (and (eq_attr "type" "imov")
723 (and (not (eq_attr "mode" "DI"))
724 (ior (and (match_operand 0 "register_operand")
725 (match_operand 1 "immediate_operand"))
726 (ior (and (match_operand 0 "ax_reg_operand")
727 (match_operand 1 "memory_displacement_only_operand"))
728 (and (match_operand 0 "memory_displacement_only_operand")
729 (match_operand 1 "ax_reg_operand"))))))
731 (and (eq_attr "type" "call")
732 (match_operand 0 "constant_call_address_operand"))
734 (and (eq_attr "type" "callv")
735 (match_operand 1 "constant_call_address_operand"))
737 (and (eq_attr "type" "alu,alu1,icmp,test")
738 (match_operand 0 "ax_reg_operand"))
739 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
743 ;; The (bounding maximum) length of an instruction in bytes.
744 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
745 ;; Later we may want to split them and compute proper length as for
747 (define_attr "length" ""
748 (cond [(eq_attr "type" "other,multi,fistp,frndint")
750 (eq_attr "type" "fcmp")
752 (eq_attr "unit" "i387")
754 (plus (attr "prefix_data16")
755 (attr "length_address")))
756 (ior (eq_attr "prefix" "evex")
757 (and (ior (eq_attr "prefix" "maybe_evex")
758 (eq_attr "prefix" "maybe_vex"))
759 (match_test "TARGET_AVX512F")))
760 (plus (attr "length_evex")
761 (plus (attr "length_immediate")
763 (attr "length_address"))))
764 (ior (eq_attr "prefix" "vex")
765 (and (ior (eq_attr "prefix" "maybe_vex")
766 (eq_attr "prefix" "maybe_evex"))
767 (match_test "TARGET_AVX")))
768 (plus (attr "length_vex")
769 (plus (attr "length_immediate")
771 (attr "length_address"))))]
772 (plus (plus (attr "modrm")
773 (plus (attr "prefix_0f")
774 (plus (attr "prefix_rex")
775 (plus (attr "prefix_extra")
777 (plus (attr "prefix_rep")
778 (plus (attr "prefix_data16")
779 (plus (attr "length_immediate")
780 (attr "length_address")))))))
782 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
783 ;; `store' if there is a simple memory reference therein, or `unknown'
784 ;; if the instruction is complex.
786 (define_attr "memory" "none,load,store,both,unknown"
787 (cond [(eq_attr "type" "other,multi,str,lwp")
788 (const_string "unknown")
789 (eq_attr "type" "lea,fcmov,fpspc")
790 (const_string "none")
791 (eq_attr "type" "fistp,leave")
792 (const_string "both")
793 (eq_attr "type" "frndint")
794 (const_string "load")
795 (eq_attr "type" "push")
796 (if_then_else (match_operand 1 "memory_operand")
797 (const_string "both")
798 (const_string "store"))
799 (eq_attr "type" "pop")
800 (if_then_else (match_operand 0 "memory_operand")
801 (const_string "both")
802 (const_string "load"))
803 (eq_attr "type" "setcc")
804 (if_then_else (match_operand 0 "memory_operand")
805 (const_string "store")
806 (const_string "none"))
807 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
808 (if_then_else (ior (match_operand 0 "memory_operand")
809 (match_operand 1 "memory_operand"))
810 (const_string "load")
811 (const_string "none"))
812 (eq_attr "type" "ibr")
813 (if_then_else (match_operand 0 "memory_operand")
814 (const_string "load")
815 (const_string "none"))
816 (eq_attr "type" "call")
817 (if_then_else (match_operand 0 "constant_call_address_operand")
818 (const_string "none")
819 (const_string "load"))
820 (eq_attr "type" "callv")
821 (if_then_else (match_operand 1 "constant_call_address_operand")
822 (const_string "none")
823 (const_string "load"))
824 (and (eq_attr "type" "alu1,negnot,ishift1,rotate1,sselog1,sseshuf1")
825 (match_operand 1 "memory_operand"))
826 (const_string "both")
827 (and (match_operand 0 "memory_operand")
828 (match_operand 1 "memory_operand"))
829 (const_string "both")
830 (match_operand 0 "memory_operand")
831 (const_string "store")
832 (match_operand 1 "memory_operand")
833 (const_string "load")
835 "!alu1,negnot,ishift1,rotate1,
836 imov,imovx,icmp,test,bitmanip,
838 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
839 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
840 mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog")
841 (match_operand 2 "memory_operand"))
842 (const_string "load")
843 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
844 (match_operand 3 "memory_operand"))
845 (const_string "load")
847 (const_string "none")))
849 ;; Indicates if an instruction has both an immediate and a displacement.
851 (define_attr "imm_disp" "false,true,unknown"
852 (cond [(eq_attr "type" "other,multi")
853 (const_string "unknown")
854 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
855 (and (match_operand 0 "memory_displacement_operand")
856 (match_operand 1 "immediate_operand")))
857 (const_string "true")
858 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
859 (and (match_operand 0 "memory_displacement_operand")
860 (match_operand 2 "immediate_operand")))
861 (const_string "true")
863 (const_string "false")))
865 ;; Indicates if an FP operation has an integer source.
867 (define_attr "fp_int_src" "false,true"
868 (const_string "false"))
870 ;; Defines rounding mode of an FP operation.
872 (define_attr "i387_cw" "roundeven,floor,ceil,trunc,uninitialized,any"
873 (const_string "any"))
875 ;; Define attribute to indicate AVX insns with partial XMM register update.
876 (define_attr "avx_partial_xmm_update" "false,true"
877 (const_string "false"))
879 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
880 (define_attr "use_carry" "0,1" (const_string "0"))
882 ;; Define attribute to indicate unaligned ssemov insns
883 (define_attr "movu" "0,1" (const_string "0"))
885 ;; Define attribute to limit memory address register set.
886 (define_attr "addr" "gpr8,gpr16,gpr32" (const_string "gpr32"))
888 ;; Define instruction set of MMX instructions
889 (define_attr "mmx_isa" "base,native,sse,sse_noavx,avx"
890 (const_string "base"))
892 (define_attr "enabled" ""
893 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
894 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
895 (eq_attr "isa" "x64_sse2")
896 (symbol_ref "TARGET_64BIT && TARGET_SSE2")
897 (eq_attr "isa" "x64_sse4")
898 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
899 (eq_attr "isa" "x64_sse4_noavx")
900 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
901 (eq_attr "isa" "x64_avx")
902 (symbol_ref "TARGET_64BIT && TARGET_AVX")
903 (eq_attr "isa" "x64_avx512bw")
904 (symbol_ref "TARGET_64BIT && TARGET_AVX512BW")
905 (eq_attr "isa" "x64_avx512dq")
906 (symbol_ref "TARGET_64BIT && TARGET_AVX512DQ")
907 (eq_attr "isa" "aes") (symbol_ref "TARGET_AES")
908 (eq_attr "isa" "sse_noavx")
909 (symbol_ref "TARGET_SSE && !TARGET_AVX")
910 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
911 (eq_attr "isa" "sse2_noavx")
912 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
913 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
914 (eq_attr "isa" "sse3_noavx")
915 (symbol_ref "TARGET_SSE3 && !TARGET_AVX")
916 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
917 (eq_attr "isa" "sse4_noavx")
918 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
919 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
920 (eq_attr "isa" "avx_noavx512f")
921 (symbol_ref "TARGET_AVX && !TARGET_AVX512F")
922 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
923 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
924 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
925 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
926 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
927 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
928 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
929 (eq_attr "isa" "fma_or_avx512vl")
930 (symbol_ref "TARGET_FMA || TARGET_AVX512VL")
931 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
932 (eq_attr "isa" "avx512f_512")
933 (symbol_ref "TARGET_AVX512F && TARGET_EVEX512")
934 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
935 (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
936 (eq_attr "isa" "avx512bw_512")
937 (symbol_ref "TARGET_AVX512BW && TARGET_EVEX512")
938 (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
939 (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
940 (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
941 (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
942 (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
943 (eq_attr "isa" "avxvnni") (symbol_ref "TARGET_AVXVNNI")
944 (eq_attr "isa" "avx512vnnivl")
945 (symbol_ref "TARGET_AVX512VNNI && TARGET_AVX512VL")
946 (eq_attr "isa" "avx512fp16")
947 (symbol_ref "TARGET_AVX512FP16")
948 (eq_attr "isa" "avxifma") (symbol_ref "TARGET_AVXIFMA")
949 (eq_attr "isa" "avx512ifmavl")
950 (symbol_ref "TARGET_AVX512IFMA && TARGET_AVX512VL")
951 (eq_attr "isa" "avxneconvert") (symbol_ref "TARGET_AVXNECONVERT")
952 (eq_attr "isa" "avx512bf16vl")
953 (symbol_ref "TARGET_AVX512BF16 && TARGET_AVX512VL")
954 (eq_attr "isa" "vpclmulqdqvl")
955 (symbol_ref "TARGET_VPCLMULQDQ && TARGET_AVX512VL")
957 (eq_attr "mmx_isa" "native")
958 (symbol_ref "!TARGET_MMX_WITH_SSE")
959 (eq_attr "mmx_isa" "sse")
960 (symbol_ref "TARGET_MMX_WITH_SSE")
961 (eq_attr "mmx_isa" "sse_noavx")
962 (symbol_ref "TARGET_MMX_WITH_SSE && !TARGET_AVX")
963 (eq_attr "mmx_isa" "avx")
964 (symbol_ref "TARGET_MMX_WITH_SSE && TARGET_AVX")
968 (define_attr "preferred_for_size" "" (const_int 1))
969 (define_attr "preferred_for_speed" "" (const_int 1))
971 ;; Describe a user's asm statement.
972 (define_asm_attributes
973 [(set_attr "length" "128")
974 (set_attr "type" "multi")])
976 (define_code_iterator plusminus [plus minus])
977 (define_code_iterator plusminusmult [plus minus mult])
978 (define_code_iterator plusminusmultdiv [plus minus mult div])
980 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
982 ;; Base name for insn mnemonic.
983 (define_code_attr plusminus_mnemonic
984 [(plus "add") (ss_plus "adds") (us_plus "addus")
985 (minus "sub") (ss_minus "subs") (us_minus "subus")])
987 (define_code_iterator multdiv [mult div])
989 (define_code_attr multdiv_mnemonic
990 [(mult "mul") (div "div")])
992 ;; Mark commutative operators as such in constraints.
993 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
994 (minus "") (ss_minus "") (us_minus "")
995 (mult "%") (div "")])
997 ;; Mapping of max and min
998 (define_code_iterator maxmin [smax smin umax umin])
1000 ;; Mapping of signed max and min
1001 (define_code_iterator smaxmin [smax smin])
1003 ;; Mapping of unsigned max and min
1004 (define_code_iterator umaxmin [umax umin])
1006 ;; Base name for integer and FP insn mnemonic
1007 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
1008 (umax "maxu") (umin "minu")])
1009 (define_code_attr maxmin_float [(smax "max") (smin "min")])
1011 (define_int_iterator IEEE_MAXMIN
1015 (define_int_attr ieee_maxmin
1016 [(UNSPEC_IEEE_MAX "max")
1017 (UNSPEC_IEEE_MIN "min")])
1019 ;; Mapping of logic operators
1020 (define_code_iterator any_logic [and ior xor])
1021 (define_code_iterator any_or [ior xor])
1022 (define_code_iterator fpint_logic [and xor])
1024 ;; Base name for insn mnemonic.
1025 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
1027 ;; Mapping of logic-shift operators
1028 (define_code_iterator any_lshift [ashift lshiftrt])
1030 ;; Mapping of shift-right operators
1031 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
1033 ;; Mapping of all shift operators
1034 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
1036 ;; Base name for insn mnemonic.
1037 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
1038 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
1040 ;; Mapping of rotate operators
1041 (define_code_iterator any_rotate [rotate rotatert])
1043 ;; Base name for insn mnemonic.
1044 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
1046 ;; Mapping of abs neg operators
1047 (define_code_iterator absneg [abs neg])
1049 ;; Mapping of abs neg operators to logic operation
1050 (define_code_attr absneg_op [(abs "and") (neg "xor")])
1052 ;; Base name for x87 insn mnemonic.
1053 (define_code_attr absneg_mnemonic [(abs "fabs") (neg "fchs")])
1055 ;; Mapping of extend operators
1056 (define_code_iterator any_extend [sign_extend zero_extend])
1058 ;; Mapping of highpart multiply operators
1059 (define_code_iterator any_mul_highpart [smul_highpart umul_highpart])
1061 ;; Prefix for insn menmonic.
1062 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
1063 (smul_highpart "i") (umul_highpart "")
1064 (div "i") (udiv "")])
1065 ;; Prefix for define_insn
1066 (define_code_attr s [(sign_extend "s") (zero_extend "u")
1067 (smul_highpart "s") (umul_highpart "u")])
1068 (define_code_attr u [(sign_extend "") (zero_extend "u")
1069 (div "") (udiv "u")])
1070 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")
1071 (div "false") (udiv "true")])
1073 ;; Used in signed and unsigned truncations.
1074 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
1075 ;; Instruction suffix for truncations.
1076 (define_code_attr trunsuffix
1077 [(ss_truncate "s") (truncate "") (us_truncate "us")])
1079 ;; Instruction suffix for SSE sign and zero extensions.
1080 (define_code_attr extsuffix [(sign_extend "sx") (zero_extend "zx")])
1082 ;; Used in signed and unsigned fix.
1083 (define_code_iterator any_fix [fix unsigned_fix])
1084 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
1085 (define_code_attr fixunssuffix [(fix "") (unsigned_fix "uns")])
1086 (define_code_attr fixprefix [(fix "s") (unsigned_fix "u")])
1088 ;; Used in signed and unsigned float.
1089 (define_code_iterator any_float [float unsigned_float])
1090 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
1091 (define_code_attr floatunssuffix [(float "") (unsigned_float "uns")])
1092 (define_code_attr floatprefix [(float "s") (unsigned_float "u")])
1094 ;; Base name for expression
1095 (define_code_attr insn
1096 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
1097 (minus "sub") (ss_minus "sssub") (us_minus "ussub")
1098 (sign_extend "extend") (zero_extend "zero_extend")
1099 (ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")
1100 (rotate "rotl") (rotatert "rotr")
1101 (mult "mul") (div "div")])
1103 ;; All integer modes.
1104 (define_mode_iterator SWI1248x [QI HI SI DI])
1106 ;; All integer modes without QImode.
1107 (define_mode_iterator SWI248x [HI SI DI])
1109 ;; All integer modes without QImode and HImode.
1110 (define_mode_iterator SWI48x [SI DI])
1112 ;; All integer modes without SImode and DImode.
1113 (define_mode_iterator SWI12 [QI HI])
1115 ;; All integer modes without DImode.
1116 (define_mode_iterator SWI124 [QI HI SI])
1118 ;; All integer modes without QImode and DImode.
1119 (define_mode_iterator SWI24 [HI SI])
1121 ;; Single word integer modes.
1122 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
1124 ;; Single word integer modes without QImode.
1125 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
1127 ;; Single word integer modes without QImode and HImode.
1128 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
1130 ;; All math-dependant single and double word integer modes.
1131 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
1132 (HI "TARGET_HIMODE_MATH")
1133 SI DI (TI "TARGET_64BIT")])
1135 ;; Math-dependant single word integer modes.
1136 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
1137 (HI "TARGET_HIMODE_MATH")
1138 SI (DI "TARGET_64BIT")])
1140 ;; Math-dependant integer modes without DImode.
1141 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
1142 (HI "TARGET_HIMODE_MATH")
1145 ;; Math-dependant integer modes with DImode.
1146 (define_mode_iterator SWIM1248x
1147 [(QI "TARGET_QIMODE_MATH")
1148 (HI "TARGET_HIMODE_MATH")
1151 ;; Math-dependant single word integer modes without QImode.
1152 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
1153 SI (DI "TARGET_64BIT")])
1155 ;; Double word integer modes.
1156 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
1157 (TI "TARGET_64BIT")])
1159 ;; SWI and DWI together.
1160 (define_mode_iterator SWIDWI [QI HI SI DI (TI "TARGET_64BIT")])
1162 ;; SWI48 and DWI together.
1163 (define_mode_iterator SWI48DWI [SI DI (TI "TARGET_64BIT")])
1165 ;; GET_MODE_SIZE for selected modes. As GET_MODE_SIZE is not
1166 ;; compile time constant, it is faster to use <MODE_SIZE> than
1167 ;; GET_MODE_SIZE (<MODE>mode). For XFmode which depends on
1168 ;; command line options just use GET_MODE_SIZE macro.
1169 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8")
1170 (TI "16") (HF "2") (BF "2") (SF "4") (DF "8")
1171 (XF "GET_MODE_SIZE (XFmode)")
1172 (V16QI "16") (V32QI "32") (V64QI "64")
1173 (V8HI "16") (V16HI "32") (V32HI "64")
1174 (V4SI "16") (V8SI "32") (V16SI "64")
1175 (V2DI "16") (V4DI "32") (V8DI "64")
1176 (V1TI "16") (V2TI "32") (V4TI "64")
1177 (V2DF "16") (V4DF "32") (V8DF "64")
1178 (V4SF "16") (V8SF "32") (V16SF "64")
1179 (V8HF "16") (V16HF "32") (V32HF "64")
1180 (V4HF "8") (V2HF "4")
1181 (V8BF "16") (V16BF "32") (V32BF "64")
1182 (V4BF "8") (V2BF "4")])
1184 ;; Double word integer modes as mode attribute.
1185 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI") (TI "OI")])
1186 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti") (TI "oi")])
1188 ;; Half sized integer modes.
1189 (define_mode_attr HALF [(TI "DI") (DI "SI")])
1190 (define_mode_attr half [(TI "di") (DI "si")])
1192 ;; LEA mode corresponding to an integer mode
1193 (define_mode_attr LEAMODE [(QI "SI") (HI "SI") (SI "SI") (DI "DI")])
1195 ;; Half mode for double word integer modes.
1196 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1197 (DI "TARGET_64BIT")])
1199 ;; Instruction suffix for integer modes.
1200 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1202 ;; Instruction suffix for masks.
1203 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1205 ;; Pointer size prefix for integer modes (Intel asm dialect)
1206 (define_mode_attr iptrsize [(QI "BYTE")
1211 ;; Register class for integer modes.
1212 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1214 ;; Immediate operand constraint for integer modes.
1215 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1217 ;; General operand constraint for word modes.
1218 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1220 ;; Memory operand constraint for word modes.
1221 (define_mode_attr m [(QI "m") (HI "m") (SI "BM") (DI "BM")])
1223 ;; Immediate operand constraint for double integer modes.
1224 (define_mode_attr di [(SI "nF") (DI "Wd")])
1226 ;; Immediate operand constraint for shifts.
1227 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1228 (define_mode_attr KS [(QI "Wb") (HI "Ww") (SI "I") (DI "J")])
1230 ;; Print register name in the specified mode.
1231 (define_mode_attr k [(QI "b") (HI "w") (SI "k") (DI "q")])
1233 ;; General operand predicate for integer modes.
1234 (define_mode_attr general_operand
1235 [(QI "general_operand")
1236 (HI "general_operand")
1237 (SI "x86_64_general_operand")
1238 (DI "x86_64_general_operand")
1239 (TI "x86_64_general_operand")])
1241 ;; General operand predicate for integer modes, where for TImode
1242 ;; we need both words of the operand to be general operands.
1243 (define_mode_attr general_hilo_operand
1244 [(QI "general_operand")
1245 (HI "general_operand")
1246 (SI "x86_64_general_operand")
1247 (DI "x86_64_general_operand")
1248 (TI "x86_64_hilo_general_operand")])
1250 ;; General sign extend operand predicate for integer modes,
1251 ;; which disallows VOIDmode operands and thus it is suitable
1252 ;; for use inside sign_extend.
1253 (define_mode_attr general_sext_operand
1254 [(QI "sext_operand")
1256 (SI "x86_64_sext_operand")
1257 (DI "x86_64_sext_operand")])
1259 ;; General sign/zero extend operand predicate for integer modes.
1260 (define_mode_attr general_szext_operand
1261 [(QI "general_operand")
1262 (HI "general_operand")
1263 (SI "x86_64_szext_general_operand")
1264 (DI "x86_64_szext_general_operand")
1265 (TI "x86_64_hilo_general_operand")])
1267 (define_mode_attr nonmemory_szext_operand
1268 [(QI "nonmemory_operand")
1269 (HI "nonmemory_operand")
1270 (SI "x86_64_szext_nonmemory_operand")
1271 (DI "x86_64_szext_nonmemory_operand")])
1273 ;; Immediate operand predicate for integer modes.
1274 (define_mode_attr immediate_operand
1275 [(QI "immediate_operand")
1276 (HI "immediate_operand")
1277 (SI "x86_64_immediate_operand")
1278 (DI "x86_64_immediate_operand")])
1280 ;; Nonmemory operand predicate for integer modes.
1281 (define_mode_attr nonmemory_operand
1282 [(QI "nonmemory_operand")
1283 (HI "nonmemory_operand")
1284 (SI "x86_64_nonmemory_operand")
1285 (DI "x86_64_nonmemory_operand")])
1287 ;; Operand predicate for shifts.
1288 (define_mode_attr shift_operand
1289 [(QI "nonimmediate_operand")
1290 (HI "nonimmediate_operand")
1291 (SI "nonimmediate_operand")
1292 (DI "shiftdi_operand")
1293 (TI "register_operand")])
1295 ;; Operand predicate for shift argument.
1296 (define_mode_attr shift_immediate_operand
1297 [(QI "const_1_to_31_operand")
1298 (HI "const_1_to_31_operand")
1299 (SI "const_1_to_31_operand")
1300 (DI "const_1_to_63_operand")])
1302 ;; Input operand predicate for arithmetic left shifts.
1303 (define_mode_attr ashl_input_operand
1304 [(QI "nonimmediate_operand")
1305 (HI "nonimmediate_operand")
1306 (SI "nonimmediate_operand")
1307 (DI "ashldi_input_operand")
1308 (TI "reg_or_pm1_operand")])
1310 ;; SSE and x87 SFmode and DFmode floating point modes
1311 (define_mode_iterator MODEF [SF DF])
1313 ;; SSE floating point modes
1314 (define_mode_iterator MODEFH [(HF "TARGET_AVX512FP16") SF DF])
1316 ;; All x87 floating point modes
1317 (define_mode_iterator X87MODEF [SF DF XF])
1319 ;; All x87 floating point modes plus HFmode
1320 (define_mode_iterator X87MODEFH [HF SF DF XF BF])
1322 ;; All SSE floating point modes
1323 (define_mode_iterator SSEMODEF [HF SF DF TF])
1324 (define_mode_attr ssevecmodef [(HF "V8HF") (SF "V4SF") (DF "V2DF") (TF "TF")])
1326 ;; SSE instruction suffix for various modes
1327 (define_mode_attr ssemodesuffix
1328 [(HF "sh") (SF "ss") (DF "sd")
1329 (V32HF "ph") (V16SF "ps") (V8DF "pd")
1330 (V16HF "ph") (V16BF "bf") (V8SF "ps") (V4DF "pd")
1331 (V8HF "ph") (V8BF "bf") (V4SF "ps") (V2DF "pd")
1332 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1333 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1334 (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1336 ;; SSE vector suffix for floating point modes
1337 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1339 ;; SSE vector mode corresponding to a scalar mode
1340 (define_mode_attr ssevecmode
1341 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (HF "V8HF") (BF "V8BF") (SF "V4SF") (DF "V2DF")])
1342 (define_mode_attr ssevecmodelower
1343 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1345 ;; AVX512F vector mode corresponding to a scalar mode
1346 (define_mode_attr avx512fvecmode
1347 [(QI "V64QI") (HI "V32HI") (SI "V16SI") (DI "V8DI") (SF "V16SF") (DF "V8DF")])
1349 ;; Instruction suffix for REX 64bit operators.
1350 (define_mode_attr rex64suffix [(SI "{l}") (DI "{q}")])
1351 (define_mode_attr rex64namesuffix [(SI "") (DI "q")])
1353 ;; This mode iterator allows :P to be used for patterns that operate on
1354 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1355 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1357 ;; This mode iterator allows :W to be used for patterns that operate on
1358 ;; word_mode sized quantities.
1359 (define_mode_iterator W
1360 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1362 ;; This mode iterator allows :PTR to be used for patterns that operate on
1363 ;; ptr_mode sized quantities.
1364 (define_mode_iterator PTR
1365 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1367 ;; Scheduling descriptions
1369 (include "pentium.md")
1372 (include "athlon.md")
1373 (include "bdver1.md")
1374 (include "bdver3.md")
1375 (include "btver2.md")
1376 (include "znver.md")
1377 (include "znver4.md")
1378 (include "geode.md")
1382 (include "core2.md")
1383 (include "haswell.md")
1384 (include "lujiazui.md")
1385 (include "yongfeng.md")
1388 ;; Operand and operator predicates and constraints
1390 (include "predicates.md")
1391 (include "constraints.md")
1394 ;; Compare and branch/compare and store instructions.
1396 (define_expand "cbranch<mode>4"
1397 [(set (reg:CC FLAGS_REG)
1398 (compare:CC (match_operand:SWIM1248x 1 "nonimmediate_operand")
1399 (match_operand:SWIM1248x 2 "<general_operand>")))
1400 (set (pc) (if_then_else
1401 (match_operator 0 "ordered_comparison_operator"
1402 [(reg:CC FLAGS_REG) (const_int 0)])
1403 (label_ref (match_operand 3))
1407 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1408 operands[1] = force_reg (<MODE>mode, operands[1]);
1409 ix86_expand_branch (GET_CODE (operands[0]),
1410 operands[1], operands[2], operands[3]);
1414 (define_expand "cbranchti4"
1415 [(set (reg:CC FLAGS_REG)
1416 (compare:CC (match_operand:TI 1 "nonimmediate_operand")
1417 (match_operand:TI 2 "ix86_timode_comparison_operand")))
1418 (set (pc) (if_then_else
1419 (match_operator 0 "ix86_timode_comparison_operator"
1420 [(reg:CC FLAGS_REG) (const_int 0)])
1421 (label_ref (match_operand 3))
1423 "TARGET_64BIT || TARGET_SSE4_1"
1425 ix86_expand_branch (GET_CODE (operands[0]),
1426 operands[1], operands[2], operands[3]);
1430 (define_expand "cbranchoi4"
1431 [(set (reg:CC FLAGS_REG)
1432 (compare:CC (match_operand:OI 1 "nonimmediate_operand")
1433 (match_operand:OI 2 "nonimmediate_operand")))
1434 (set (pc) (if_then_else
1435 (match_operator 0 "bt_comparison_operator"
1436 [(reg:CC FLAGS_REG) (const_int 0)])
1437 (label_ref (match_operand 3))
1441 ix86_expand_branch (GET_CODE (operands[0]),
1442 operands[1], operands[2], operands[3]);
1446 (define_expand "cbranchxi4"
1447 [(set (reg:CC FLAGS_REG)
1448 (compare:CC (match_operand:XI 1 "nonimmediate_operand")
1449 (match_operand:XI 2 "nonimmediate_operand")))
1450 (set (pc) (if_then_else
1451 (match_operator 0 "bt_comparison_operator"
1452 [(reg:CC FLAGS_REG) (const_int 0)])
1453 (label_ref (match_operand 3))
1455 "TARGET_AVX512F && TARGET_EVEX512 && !TARGET_PREFER_AVX256"
1457 ix86_expand_branch (GET_CODE (operands[0]),
1458 operands[1], operands[2], operands[3]);
1462 (define_expand "cstore<mode>4"
1463 [(set (reg:CC FLAGS_REG)
1464 (compare:CC (match_operand:SDWIM 2 "nonimmediate_operand")
1465 (match_operand:SDWIM 3 "<general_operand>")))
1466 (set (match_operand:QI 0 "register_operand")
1467 (match_operator 1 "ordered_comparison_operator"
1468 [(reg:CC FLAGS_REG) (const_int 0)]))]
1471 if (<MODE>mode == (TARGET_64BIT ? TImode : DImode))
1473 if (GET_CODE (operands[1]) != EQ
1474 && GET_CODE (operands[1]) != NE)
1477 else if (MEM_P (operands[2]) && MEM_P (operands[3]))
1478 operands[2] = force_reg (<MODE>mode, operands[2]);
1479 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1480 operands[2], operands[3]);
1484 (define_expand "@cmp<mode>_1"
1485 [(set (reg:CC FLAGS_REG)
1486 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1487 (match_operand:SWI48 1 "<general_operand>")))])
1489 (define_mode_iterator SWI1248_AVX512BWDQ_64
1490 [(QI "TARGET_AVX512DQ") HI
1491 (SI "TARGET_AVX512BW")
1492 (DI "TARGET_AVX512BW && TARGET_EVEX512 && TARGET_64BIT")])
1494 (define_insn "*cmp<mode>_ccz_1"
1495 [(set (reg FLAGS_REG)
1496 (compare (match_operand:SWI1248_AVX512BWDQ_64 0
1497 "nonimmediate_operand" "<r>,?m<r>,$k")
1498 (match_operand:SWI1248_AVX512BWDQ_64 1 "const0_operand")))]
1499 "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
1501 test{<imodesuffix>}\t%0, %0
1502 cmp{<imodesuffix>}\t{%1, %0|%0, %1}
1503 kortest<mskmodesuffix>\t%0, %0"
1504 [(set_attr "type" "test,icmp,msklog")
1505 (set_attr "length_immediate" "0,1,*")
1506 (set_attr "prefix" "*,*,vex")
1507 (set_attr "mode" "<MODE>")])
1509 (define_insn "*cmp<mode>_ccno_1"
1510 [(set (reg FLAGS_REG)
1511 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1512 (match_operand:SWI 1 "const0_operand")))]
1513 "ix86_match_ccmode (insn, CCNOmode)"
1515 test{<imodesuffix>}\t%0, %0
1516 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1517 [(set_attr "type" "test,icmp")
1518 (set_attr "length_immediate" "0,1")
1519 (set_attr "mode" "<MODE>")])
1521 (define_insn "*cmp<mode>_1"
1522 [(set (reg FLAGS_REG)
1523 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1524 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r><m>")))]
1525 "ix86_match_ccmode (insn, CCmode)"
1526 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1527 [(set_attr "type" "icmp")
1528 (set_attr "mode" "<MODE>")])
1530 (define_insn "*cmp<mode>_minus_1"
1531 [(set (reg FLAGS_REG)
1533 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1534 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r><m>"))
1536 "ix86_match_ccmode (insn, CCGOCmode)"
1537 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1538 [(set_attr "type" "icmp")
1539 (set_attr "mode" "<MODE>")])
1541 (define_insn "*cmpqi_ext<mode>_1"
1542 [(set (reg FLAGS_REG)
1544 (match_operand:QI 0 "nonimmediate_operand" "QBn")
1546 (match_operator:SWI248 2 "extract_operator"
1547 [(match_operand 1 "int248_register_operand" "Q")
1549 (const_int 8)]) 0)))]
1550 "ix86_match_ccmode (insn, CCmode)"
1551 "cmp{b}\t{%h1, %0|%0, %h1}"
1552 [(set_attr "addr" "gpr8")
1553 (set_attr "type" "icmp")
1554 (set_attr "mode" "QI")])
1556 (define_insn "*cmpqi_ext<mode>_2"
1557 [(set (reg FLAGS_REG)
1560 (match_operator:SWI248 2 "extract_operator"
1561 [(match_operand 0 "int248_register_operand" "Q")
1564 (match_operand:QI 1 "const0_operand")))]
1565 "ix86_match_ccmode (insn, CCNOmode)"
1567 [(set_attr "type" "test")
1568 (set_attr "length_immediate" "0")
1569 (set_attr "mode" "QI")])
1571 (define_expand "cmpqi_ext_3"
1572 [(set (reg:CC FLAGS_REG)
1576 (match_operand:HI 0 "register_operand")
1579 (match_operand:QI 1 "const_int_operand")))])
1581 (define_insn "*cmpqi_ext<mode>_3"
1582 [(set (reg FLAGS_REG)
1585 (match_operator:SWI248 2 "extract_operator"
1586 [(match_operand 0 "int248_register_operand" "Q")
1589 (match_operand:QI 1 "general_operand" "QnBn")))]
1590 "ix86_match_ccmode (insn, CCmode)"
1591 "cmp{b}\t{%1, %h0|%h0, %1}"
1592 [(set_attr "addr" "gpr8")
1593 (set_attr "type" "icmp")
1594 (set_attr "mode" "QI")])
1596 (define_insn "*cmpqi_ext<mode>_4"
1597 [(set (reg FLAGS_REG)
1600 (match_operator:SWI248 2 "extract_operator"
1601 [(match_operand 0 "int248_register_operand" "Q")
1605 (match_operator:SWI248 3 "extract_operator"
1606 [(match_operand 1 "int248_register_operand" "Q")
1608 (const_int 8)]) 0)))]
1609 "ix86_match_ccmode (insn, CCmode)"
1610 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1611 [(set_attr "type" "icmp")
1612 (set_attr "mode" "QI")])
1614 (define_insn_and_split "*cmp<dwi>_doubleword"
1615 [(set (reg:CCZ FLAGS_REG)
1616 (compare:CCZ (match_operand:<DWI> 0 "nonimmediate_operand")
1617 (match_operand:<DWI> 1 "general_operand")))]
1618 "ix86_pre_reload_split ()"
1621 [(parallel [(set (reg:CCZ FLAGS_REG)
1622 (compare:CCZ (ior:DWIH (match_dup 4) (match_dup 5))
1624 (set (match_dup 4) (ior:DWIH (match_dup 4) (match_dup 5)))])]
1626 split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);
1627 /* Placing the SUBREG pieces in pseudos helps reload. */
1628 for (int i = 0; i < 4; i++)
1629 if (SUBREG_P (operands[i]))
1630 operands[i] = force_reg (<MODE>mode, operands[i]);
1632 operands[4] = gen_reg_rtx (<MODE>mode);
1634 /* Special case comparisons against -1. */
1635 if (operands[1] == constm1_rtx && operands[3] == constm1_rtx)
1637 emit_insn (gen_and<mode>3 (operands[4], operands[0], operands[2]));
1638 emit_insn (gen_cmp_1 (<MODE>mode, operands[4], constm1_rtx));
1642 if (operands[1] == const0_rtx)
1643 emit_move_insn (operands[4], operands[0]);
1644 else if (operands[0] == const0_rtx)
1645 emit_move_insn (operands[4], operands[1]);
1646 else if (operands[1] == constm1_rtx)
1647 emit_insn (gen_one_cmpl<mode>2 (operands[4], operands[0]));
1648 else if (operands[0] == constm1_rtx)
1649 emit_insn (gen_one_cmpl<mode>2 (operands[4], operands[1]));
1652 if (CONST_SCALAR_INT_P (operands[1])
1653 && !x86_64_immediate_operand (operands[1], <MODE>mode))
1654 operands[1] = force_reg (<MODE>mode, operands[1]);
1655 emit_insn (gen_xor<mode>3 (operands[4], operands[0], operands[1]));
1658 if (operands[3] == const0_rtx)
1659 operands[5] = operands[2];
1660 else if (operands[2] == const0_rtx)
1661 operands[5] = operands[3];
1664 operands[5] = gen_reg_rtx (<MODE>mode);
1665 if (operands[3] == constm1_rtx)
1666 emit_insn (gen_one_cmpl<mode>2 (operands[5], operands[2]));
1667 else if (operands[2] == constm1_rtx)
1668 emit_insn (gen_one_cmpl<mode>2 (operands[5], operands[3]));
1671 if (CONST_SCALAR_INT_P (operands[3])
1672 && !x86_64_immediate_operand (operands[3], <MODE>mode))
1673 operands[3] = force_reg (<MODE>mode, operands[3]);
1674 emit_insn (gen_xor<mode>3 (operands[5], operands[2], operands[3]));
1679 ;; These implement float point compares.
1680 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1681 ;; which would allow mix and match FP modes on the compares. Which is what
1682 ;; the old patterns did, but with many more of them.
1684 (define_expand "cbranchxf4"
1685 [(set (reg:CC FLAGS_REG)
1686 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1687 (match_operand:XF 2 "nonmemory_operand")))
1688 (set (pc) (if_then_else
1689 (match_operator 0 "ix86_fp_comparison_operator"
1692 (label_ref (match_operand 3))
1696 ix86_expand_branch (GET_CODE (operands[0]),
1697 operands[1], operands[2], operands[3]);
1701 (define_expand "cstorexf4"
1702 [(set (reg:CC FLAGS_REG)
1703 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1704 (match_operand:XF 3 "nonmemory_operand")))
1705 (set (match_operand:QI 0 "register_operand")
1706 (match_operator 1 "ix86_fp_comparison_operator"
1711 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1712 operands[2], operands[3]);
1716 (define_expand "cbranchhf4"
1717 [(set (reg:CC FLAGS_REG)
1718 (compare:CC (match_operand:HF 1 "cmp_fp_expander_operand")
1719 (match_operand:HF 2 "cmp_fp_expander_operand")))
1720 (set (pc) (if_then_else
1721 (match_operator 0 "ix86_fp_comparison_operator"
1724 (label_ref (match_operand 3))
1728 ix86_expand_branch (GET_CODE (operands[0]),
1729 operands[1], operands[2], operands[3]);
1733 (define_expand "cbranch<mode>4"
1734 [(set (reg:CC FLAGS_REG)
1735 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1736 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1737 (set (pc) (if_then_else
1738 (match_operator 0 "ix86_fp_comparison_operator"
1741 (label_ref (match_operand 3))
1743 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1745 ix86_expand_branch (GET_CODE (operands[0]),
1746 operands[1], operands[2], operands[3]);
1750 (define_expand "cbranchbf4"
1751 [(set (reg:CC FLAGS_REG)
1752 (compare:CC (match_operand:BF 1 "cmp_fp_expander_operand")
1753 (match_operand:BF 2 "cmp_fp_expander_operand")))
1754 (set (pc) (if_then_else
1755 (match_operator 0 "comparison_operator"
1758 (label_ref (match_operand 3))
1760 "TARGET_80387 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
1762 rtx op1 = ix86_expand_fast_convert_bf_to_sf (operands[1]);
1763 rtx op2 = ix86_expand_fast_convert_bf_to_sf (operands[2]);
1764 do_compare_rtx_and_jump (op1, op2, GET_CODE (operands[0]), 0,
1765 SFmode, NULL_RTX, NULL,
1766 as_a <rtx_code_label *> (operands[3]),
1767 /* Unfortunately this isn't propagated. */
1768 profile_probability::even ());
1772 (define_expand "cstorehf4"
1773 [(set (reg:CC FLAGS_REG)
1774 (compare:CC (match_operand:HF 2 "cmp_fp_expander_operand")
1775 (match_operand:HF 3 "cmp_fp_expander_operand")))
1776 (set (match_operand:QI 0 "register_operand")
1777 (match_operator 1 "ix86_fp_comparison_operator"
1782 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1783 operands[2], operands[3]);
1787 (define_expand "cstorebf4"
1788 [(set (reg:CC FLAGS_REG)
1789 (compare:CC (match_operand:BF 2 "cmp_fp_expander_operand")
1790 (match_operand:BF 3 "cmp_fp_expander_operand")))
1791 (set (match_operand:QI 0 "register_operand")
1792 (match_operator 1 "comparison_operator"
1795 "TARGET_80387 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
1797 rtx op1 = ix86_expand_fast_convert_bf_to_sf (operands[2]);
1798 rtx op2 = ix86_expand_fast_convert_bf_to_sf (operands[3]);
1799 rtx res = emit_store_flag_force (operands[0], GET_CODE (operands[1]),
1800 op1, op2, SFmode, 0, 1);
1801 if (!rtx_equal_p (res, operands[0]))
1802 emit_move_insn (operands[0], res);
1806 (define_expand "cstore<mode>4"
1807 [(set (reg:CC FLAGS_REG)
1808 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1809 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1810 (set (match_operand:QI 0 "register_operand")
1811 (match_operator 1 "ix86_fp_comparison_operator"
1814 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1816 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1817 operands[2], operands[3]);
1821 (define_expand "cbranchcc4"
1822 [(set (pc) (if_then_else
1823 (match_operator 0 "comparison_operator"
1824 [(match_operand 1 "flags_reg_operand")
1825 (match_operand 2 "const0_operand")])
1826 (label_ref (match_operand 3))
1830 ix86_expand_branch (GET_CODE (operands[0]),
1831 operands[1], operands[2], operands[3]);
1835 (define_expand "cstorecc4"
1836 [(set (match_operand:QI 0 "register_operand")
1837 (match_operator 1 "comparison_operator"
1838 [(match_operand 2 "flags_reg_operand")
1839 (match_operand 3 "const0_operand")]))]
1842 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1843 operands[2], operands[3]);
1847 ;; FP compares, step 1:
1848 ;; Set the FP condition codes and move fpsr to ax.
1850 ;; We may not use "#" to split and emit these
1851 ;; due to reg-stack pops killing fpsr.
1853 (define_insn "*cmpxf_i387"
1854 [(set (match_operand:HI 0 "register_operand" "=a")
1857 (match_operand:XF 1 "register_operand" "f")
1858 (match_operand:XF 2 "reg_or_0_operand" "fC"))]
1861 "* return output_fp_compare (insn, operands, false, false);"
1862 [(set_attr "type" "multi")
1863 (set_attr "unit" "i387")
1864 (set_attr "mode" "XF")])
1866 (define_insn "*cmp<mode>_i387"
1867 [(set (match_operand:HI 0 "register_operand" "=a")
1870 (match_operand:MODEF 1 "register_operand" "f")
1871 (match_operand:MODEF 2 "nonimm_or_0_operand" "fmC"))]
1874 "* return output_fp_compare (insn, operands, false, false);"
1875 [(set_attr "type" "multi")
1876 (set_attr "unit" "i387")
1877 (set_attr "mode" "<MODE>")])
1879 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1880 [(set (match_operand:HI 0 "register_operand" "=a")
1883 (match_operand:X87MODEF 1 "register_operand" "f")
1885 (match_operand:SWI24 2 "nonimmediate_operand" "m")))]
1888 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1889 || optimize_function_for_size_p (cfun))"
1890 "* return output_fp_compare (insn, operands, false, false);"
1891 [(set_attr "type" "multi")
1892 (set_attr "unit" "i387")
1893 (set_attr "fp_int_src" "true")
1894 (set_attr "mode" "<SWI24:MODE>")])
1896 (define_insn "*cmpu<mode>_i387"
1897 [(set (match_operand:HI 0 "register_operand" "=a")
1901 (match_operand:X87MODEF 1 "register_operand" "f")
1902 (match_operand:X87MODEF 2 "register_operand" "f"))]
1906 "* return output_fp_compare (insn, operands, false, true);"
1907 [(set_attr "type" "multi")
1908 (set_attr "unit" "i387")
1909 (set_attr "mode" "<MODE>")])
1911 ;; FP compares, step 2:
1912 ;; Get ax into flags, general case.
1914 (define_insn "x86_sahf_1"
1915 [(set (reg:CC FLAGS_REG)
1916 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1920 #ifndef HAVE_AS_IX86_SAHF
1922 return ASM_BYTE "0x9e";
1927 [(set_attr "length" "1")
1928 (set_attr "athlon_decode" "vector")
1929 (set_attr "amdfam10_decode" "direct")
1930 (set_attr "bdver1_decode" "direct")
1931 (set_attr "mode" "SI")])
1933 ;; Pentium Pro can do both steps in one go.
1934 ;; (these instructions set flags directly)
1936 (define_subst_attr "unord" "unord_subst" "" "u")
1937 (define_subst_attr "unordered" "unord_subst" "false" "true")
1939 (define_subst "unord_subst"
1940 [(set (match_operand:CCFP 0)
1941 (match_operand:CCFP 1))]
1948 (define_insn "*cmpi<unord>xf_i387"
1949 [(set (reg:CCFP FLAGS_REG)
1951 (match_operand:XF 0 "register_operand" "f")
1952 (match_operand:XF 1 "register_operand" "f")))]
1953 "TARGET_80387 && TARGET_CMOVE"
1954 "* return output_fp_compare (insn, operands, true, <unordered>);"
1955 [(set_attr "type" "fcmp")
1956 (set_attr "mode" "XF")
1957 (set_attr "athlon_decode" "vector")
1958 (set_attr "amdfam10_decode" "direct")
1959 (set_attr "bdver1_decode" "double")
1960 (set_attr "znver1_decode" "double")])
1962 (define_insn "*cmpi<unord><MODEF:mode>"
1963 [(set (reg:CCFP FLAGS_REG)
1965 (match_operand:MODEF 0 "register_operand" "f,v")
1966 (match_operand:MODEF 1 "register_ssemem_operand" "f,vm")))]
1967 "(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
1968 || (TARGET_80387 && TARGET_CMOVE)"
1970 * return output_fp_compare (insn, operands, true, <unordered>);
1971 %v<unord>comi<MODEF:ssemodesuffix>\t{%1, %0|%0, %1}"
1972 [(set_attr "type" "fcmp,ssecomi")
1973 (set_attr "prefix" "orig,maybe_vex")
1974 (set_attr "mode" "<MODEF:MODE>")
1975 (set_attr "prefix_rep" "*,0")
1976 (set (attr "prefix_data16")
1977 (cond [(eq_attr "alternative" "0")
1979 (eq_attr "mode" "DF")
1982 (const_string "0")))
1983 (set_attr "athlon_decode" "vector")
1984 (set_attr "amdfam10_decode" "direct")
1985 (set_attr "bdver1_decode" "double")
1986 (set_attr "znver1_decode" "double")
1987 (set (attr "enabled")
1989 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
1991 (eq_attr "alternative" "0")
1992 (symbol_ref "TARGET_MIX_SSE_I387")
1993 (symbol_ref "true"))
1995 (eq_attr "alternative" "0")
1997 (symbol_ref "false"))))])
1999 (define_insn "*cmpi<unord>hf"
2000 [(set (reg:CCFP FLAGS_REG)
2002 (match_operand:HF 0 "register_operand" "v")
2003 (match_operand:HF 1 "nonimmediate_operand" "vm")))]
2005 "v<unord>comish\t{%1, %0|%0, %1}"
2006 [(set_attr "type" "ssecomi")
2007 (set_attr "prefix" "evex")
2008 (set_attr "mode" "HF")])
2011 (define_insn "x86_stc"
2012 [(set (reg:CCC FLAGS_REG) (unspec:CCC [(const_int 0)] UNSPEC_STC))]
2015 [(set_attr "length" "1")
2016 (set_attr "length_immediate" "0")
2017 (set_attr "modrm" "0")])
2019 ;; On Pentium 4, set the carry flag using mov $1,%al;addb $-1,%al.
2021 [(match_scratch:QI 0 "r")
2022 (set (reg:CCC FLAGS_REG) (unspec:CCC [(const_int 0)] UNSPEC_STC))]
2023 "TARGET_SLOW_STC && !optimize_insn_for_size_p ()"
2024 [(set (match_dup 0) (const_int 1))
2026 [(set (reg:CCC FLAGS_REG)
2027 (compare:CCC (plus:QI (match_dup 0) (const_int -1))
2029 (set (match_dup 0) (plus:QI (match_dup 0) (const_int -1)))])])
2031 ;; Complement carry flag.
2032 (define_insn "*x86_cmc"
2033 [(set (reg:CCC FLAGS_REG)
2034 (compare:CCC (neg:QI (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
2035 (geu:QI (reg:CCC FLAGS_REG) (const_int 0))))]
2038 [(set_attr "length" "1")
2039 (set_attr "length_immediate" "0")
2040 (set_attr "use_carry" "1")
2041 (set_attr "modrm" "0")])
2043 ;; On Pentium 4, cmc is replaced with setnc %al;addb $-1,%al.
2045 [(match_scratch:QI 0 "r")
2046 (set (reg:CCC FLAGS_REG)
2047 (compare:CCC (neg:QI (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
2048 (geu:QI (reg:CCC FLAGS_REG) (const_int 0))))]
2049 "TARGET_SLOW_STC && !optimize_insn_for_size_p ()"
2050 [(set (match_dup 0) (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))
2052 [(set (reg:CCC FLAGS_REG)
2053 (compare:CCC (plus:QI (match_dup 0) (const_int -1))
2055 (set (match_dup 0) (plus:QI (match_dup 0) (const_int -1)))])])
2057 ;; Push/pop instructions.
2059 (define_insn_and_split "*pushv1ti2"
2060 [(set (match_operand:V1TI 0 "push_operand" "=<")
2061 (match_operand:V1TI 1 "register_operand" "v"))]
2062 "TARGET_64BIT && TARGET_STV"
2064 "&& reload_completed"
2065 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2066 (set (match_dup 0) (match_dup 1))]
2068 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (V1TImode)));
2069 /* Preserve memory attributes. */
2070 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2072 [(set_attr "type" "multi")
2073 (set_attr "mode" "TI")])
2075 (define_insn "*push<mode>2"
2076 [(set (match_operand:DWI 0 "push_operand" "=<,<")
2077 (match_operand:DWI 1 "general_no_elim_operand" "riF*o,*v"))]
2080 [(set_attr "type" "multi")
2081 (set_attr "mode" "<MODE>")])
2084 [(set (match_operand:DWI 0 "push_operand")
2085 (match_operand:DWI 1 "general_gr_operand"))]
2088 "ix86_split_long_move (operands); DONE;")
2090 (define_insn "*pushdi2_rex64"
2091 [(set (match_operand:DI 0 "push_operand" "=<,<,!<")
2092 (match_operand:DI 1 "general_no_elim_operand" "re*m,*v,n"))]
2098 [(set_attr "type" "push,multi,multi")
2099 (set_attr "mode" "DI")])
2101 ;; Convert impossible pushes of immediate to existing instructions.
2102 ;; First try to get scratch register and go through it. In case this
2103 ;; fails, push sign extended lower part first and then overwrite
2104 ;; upper part by 32bit move.
2107 [(match_scratch:DI 2 "r")
2108 (set (match_operand:DI 0 "push_operand")
2109 (match_operand:DI 1 "immediate_operand"))]
2111 && !symbolic_operand (operands[1], DImode)
2112 && !x86_64_immediate_operand (operands[1], DImode)"
2113 [(set (match_dup 2) (match_dup 1))
2114 (set (match_dup 0) (match_dup 2))])
2117 [(set (match_operand:DI 0 "push_operand")
2118 (match_operand:DI 1 "immediate_operand"))]
2119 "TARGET_64BIT && epilogue_completed
2120 && !symbolic_operand (operands[1], DImode)
2121 && !x86_64_immediate_operand (operands[1], DImode)"
2122 [(set (match_dup 0) (match_dup 1))
2123 (set (match_dup 2) (match_dup 3))]
2125 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
2127 operands[1] = gen_lowpart (DImode, operands[2]);
2128 operands[2] = gen_rtx_MEM (SImode,
2129 plus_constant (Pmode, stack_pointer_rtx, 4));
2132 ;; For TARGET_64BIT we always round up to 8 bytes.
2133 (define_insn "*pushsi2_rex64"
2134 [(set (match_operand:SI 0 "push_operand" "=X,X")
2135 (match_operand:SI 1 "nonmemory_no_elim_operand" "re,*v"))]
2140 [(set_attr "type" "push,multi")
2141 (set_attr "mode" "DI")])
2143 (define_insn "*pushsi2"
2144 [(set (match_operand:SI 0 "push_operand" "=<,<")
2145 (match_operand:SI 1 "general_no_elim_operand" "ri*m,*v"))]
2150 [(set_attr "type" "push,multi")
2151 (set_attr "mode" "SI")])
2154 [(set (match_operand:SWI48DWI 0 "push_operand")
2155 (match_operand:SWI48DWI 1 "sse_reg_operand"))]
2156 "TARGET_SSE && reload_completed"
2157 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2158 (set (match_dup 0) (match_dup 1))]
2160 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (<SWI48DWI:MODE>mode)));
2161 /* Preserve memory attributes. */
2162 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2165 ;; emit_push_insn when it calls move_by_pieces requires an insn to
2166 ;; "push a byte/word". But actually we use push{l,q}, which has
2167 ;; the effect of rounding the amount pushed up to a word.
2169 (define_insn "*push<mode>2"
2170 [(set (match_operand:SWI12 0 "push_operand" "=X")
2171 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
2173 "* return TARGET_64BIT ? \"push{q}\t%q1\" : \"push{l}\t%k1\";"
2174 [(set_attr "type" "push")
2176 (if_then_else (match_test "TARGET_64BIT")
2178 (const_string "SI")))])
2180 (define_insn "*push<mode>2_prologue"
2181 [(set (match_operand:W 0 "push_operand" "=<")
2182 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
2183 (clobber (mem:BLK (scratch)))]
2185 "push{<imodesuffix>}\t%1"
2186 [(set_attr "type" "push")
2187 (set_attr "mode" "<MODE>")])
2189 (define_insn "*pop<mode>1"
2190 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
2191 (match_operand:W 1 "pop_operand" ">"))]
2193 "pop{<imodesuffix>}\t%0"
2194 [(set_attr "type" "pop")
2195 (set_attr "mode" "<MODE>")])
2197 (define_insn "*pop<mode>1_epilogue"
2198 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
2199 (match_operand:W 1 "pop_operand" ">"))
2200 (clobber (mem:BLK (scratch)))]
2202 "pop{<imodesuffix>}\t%0"
2203 [(set_attr "type" "pop")
2204 (set_attr "mode" "<MODE>")])
2206 (define_insn "*pushfl<mode>2"
2207 [(set (match_operand:W 0 "push_operand" "=<")
2208 (match_operand:W 1 "flags_reg_operand"))]
2210 "pushf{<imodesuffix>}"
2211 [(set_attr "type" "push")
2212 (set_attr "mode" "<MODE>")])
2214 (define_insn "*popfl<mode>1"
2215 [(set (match_operand:W 0 "flags_reg_operand")
2216 (match_operand:W 1 "pop_operand" ">"))]
2218 "popf{<imodesuffix>}"
2219 [(set_attr "type" "pop")
2220 (set_attr "mode" "<MODE>")])
2223 ;; Reload patterns to support multi-word load/store
2224 ;; with non-offsetable address.
2225 (define_expand "reload_noff_store"
2226 [(parallel [(match_operand 0 "memory_operand" "=m")
2227 (match_operand 1 "register_operand" "r")
2228 (match_operand:DI 2 "register_operand" "=&r")])]
2231 rtx mem = operands[0];
2232 rtx addr = XEXP (mem, 0);
2234 emit_move_insn (operands[2], addr);
2235 mem = replace_equiv_address_nv (mem, operands[2]);
2237 emit_insn (gen_rtx_SET (mem, operands[1]));
2241 (define_expand "reload_noff_load"
2242 [(parallel [(match_operand 0 "register_operand" "=r")
2243 (match_operand 1 "memory_operand" "m")
2244 (match_operand:DI 2 "register_operand" "=r")])]
2247 rtx mem = operands[1];
2248 rtx addr = XEXP (mem, 0);
2250 emit_move_insn (operands[2], addr);
2251 mem = replace_equiv_address_nv (mem, operands[2]);
2253 emit_insn (gen_rtx_SET (operands[0], mem));
2257 ;; Move instructions.
2259 (define_expand "movxi"
2260 [(set (match_operand:XI 0 "nonimmediate_operand")
2261 (match_operand:XI 1 "general_operand"))]
2262 "TARGET_AVX512F && TARGET_EVEX512"
2263 "ix86_expand_vector_move (XImode, operands); DONE;")
2265 (define_expand "movoi"
2266 [(set (match_operand:OI 0 "nonimmediate_operand")
2267 (match_operand:OI 1 "general_operand"))]
2269 "ix86_expand_vector_move (OImode, operands); DONE;")
2271 (define_expand "movti"
2272 [(set (match_operand:TI 0 "nonimmediate_operand")
2273 (match_operand:TI 1 "general_operand"))]
2274 "TARGET_64BIT || TARGET_SSE"
2277 ix86_expand_move (TImode, operands);
2279 ix86_expand_vector_move (TImode, operands);
2283 ;; This expands to what emit_move_complex would generate if we didn't
2284 ;; have a movti pattern. Having this avoids problems with reload on
2285 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2286 ;; to have around all the time.
2287 (define_expand "movcdi"
2288 [(set (match_operand:CDI 0 "nonimmediate_operand")
2289 (match_operand:CDI 1 "general_operand"))]
2292 if (push_operand (operands[0], CDImode))
2293 emit_move_complex_push (CDImode, operands[0], operands[1]);
2295 emit_move_complex_parts (operands[0], operands[1]);
2299 (define_expand "mov<mode>"
2300 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
2301 (match_operand:SWI1248x 1 "general_operand"))]
2303 "ix86_expand_move (<MODE>mode, operands); DONE;")
2305 (define_insn "*mov<mode>_xor"
2306 [(set (match_operand:SWI48 0 "register_operand" "=r")
2307 (match_operand:SWI48 1 "const0_operand"))
2308 (clobber (reg:CC FLAGS_REG))]
2311 [(set_attr "type" "alu1")
2312 (set_attr "mode" "SI")
2313 (set_attr "length_immediate" "0")])
2315 (define_insn "*mov<mode>_and"
2316 [(set (match_operand:SWI248 0 "memory_operand" "=m")
2317 (match_operand:SWI248 1 "const0_operand"))
2318 (clobber (reg:CC FLAGS_REG))]
2320 "and{<imodesuffix>}\t{%1, %0|%0, %1}"
2321 [(set_attr "type" "alu1")
2322 (set_attr "mode" "<MODE>")
2323 (set_attr "length_immediate" "1")])
2325 (define_insn "*mov<mode>_or"
2326 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
2327 (match_operand:SWI248 1 "constm1_operand"))
2328 (clobber (reg:CC FLAGS_REG))]
2330 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
2331 [(set_attr "type" "alu1")
2332 (set_attr "mode" "<MODE>")
2333 (set_attr "length_immediate" "1")])
2335 (define_insn "*movxi_internal_avx512f"
2336 [(set (match_operand:XI 0 "nonimmediate_operand" "=v,v ,v ,m")
2337 (match_operand:XI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2338 "TARGET_AVX512F && TARGET_EVEX512
2339 && (register_operand (operands[0], XImode)
2340 || register_operand (operands[1], XImode))"
2342 switch (get_attr_type (insn))
2345 return standard_sse_constant_opcode (insn, operands);
2348 return ix86_output_ssemov (insn, operands);
2354 [(set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2355 (set_attr "prefix" "evex")
2356 (set_attr "mode" "XI")])
2358 (define_insn "*movoi_internal_avx"
2359 [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,v ,m")
2360 (match_operand:OI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2362 && (register_operand (operands[0], OImode)
2363 || register_operand (operands[1], OImode))"
2365 switch (get_attr_type (insn))
2368 return standard_sse_constant_opcode (insn, operands);
2371 return ix86_output_ssemov (insn, operands);
2377 [(set_attr "isa" "*,avx2,*,*")
2378 (set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2379 (set_attr "prefix" "vex")
2380 (set_attr "mode" "OI")])
2382 (define_insn "*movti_internal"
2383 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,v ,m,?r,?Yd")
2384 (match_operand:TI 1 "general_operand" "riFo,re,C,BC,vm,v,Yd,r"))]
2386 && !(MEM_P (operands[0]) && MEM_P (operands[1])))
2388 && nonimmediate_or_sse_const_operand (operands[1], TImode)
2389 && (register_operand (operands[0], TImode)
2390 || register_operand (operands[1], TImode)))"
2392 switch (get_attr_type (insn))
2398 return standard_sse_constant_opcode (insn, operands);
2401 return ix86_output_ssemov (insn, operands);
2408 (cond [(eq_attr "alternative" "0,1,6,7")
2409 (const_string "x64")
2410 (eq_attr "alternative" "3")
2411 (const_string "sse2")
2413 (const_string "*")))
2415 (cond [(eq_attr "alternative" "0,1,6,7")
2416 (const_string "multi")
2417 (eq_attr "alternative" "2,3")
2418 (const_string "sselog1")
2420 (const_string "ssemov")))
2421 (set (attr "prefix")
2422 (if_then_else (eq_attr "type" "sselog1,ssemov")
2423 (const_string "maybe_vex")
2424 (const_string "orig")))
2426 (cond [(eq_attr "alternative" "0,1")
2428 (match_test "TARGET_AVX")
2430 (ior (not (match_test "TARGET_SSE2"))
2431 (match_test "optimize_function_for_size_p (cfun)"))
2432 (const_string "V4SF")
2433 (and (eq_attr "alternative" "5")
2434 (match_test "TARGET_SSE_TYPELESS_STORES"))
2435 (const_string "V4SF")
2437 (const_string "TI")))
2438 (set (attr "preferred_for_speed")
2439 (cond [(eq_attr "alternative" "6")
2440 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2441 (eq_attr "alternative" "7")
2442 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2444 (symbol_ref "true")))])
2447 [(set (match_operand:TI 0 "sse_reg_operand")
2448 (match_operand:TI 1 "general_reg_operand"))]
2449 "TARGET_64BIT && TARGET_SSE4_1
2450 && reload_completed"
2453 (vec_duplicate:V2DI (match_dup 3))
2457 operands[2] = lowpart_subreg (V2DImode, operands[0], TImode);
2458 operands[3] = gen_highpart (DImode, operands[1]);
2460 emit_move_insn (gen_lowpart (DImode, operands[0]),
2461 gen_lowpart (DImode, operands[1]));
2464 (define_insn "*movdi_internal"
2465 [(set (match_operand:DI 0 "nonimmediate_operand"
2466 "=r ,o ,r,r ,r,m ,*y,*y,?*y,?m,?r,?*y,?Yv,?v,?v,m ,m,?r ,?*Yd,?r,?v,?*y,?*x,*k,*k ,*r,*m,*k")
2467 (match_operand:DI 1 "general_operand"
2468 "riFo,riF,Z,rem,i,re,C ,*y,Bk ,*y,*y,r ,C ,?v,Bk,?v,v,*Yd,r ,?v,r ,*x ,*y ,*r,*kBk,*k,*k,CBC"))]
2469 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2470 && ix86_hardreg_mov_ok (operands[0], operands[1])"
2472 switch (get_attr_type (insn))
2475 return "kmovq\t{%1, %0|%0, %1}";
2478 if (operands[1] == const0_rtx)
2479 return "kxorq\t%0, %0, %0";
2480 else if (operands[1] == constm1_rtx)
2481 return "kxnorq\t%0, %0, %0";
2488 return "pxor\t%0, %0";
2491 /* Handle broken assemblers that require movd instead of movq. */
2492 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2493 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2494 return "movd\t{%1, %0|%0, %1}";
2495 return "movq\t{%1, %0|%0, %1}";
2498 return standard_sse_constant_opcode (insn, operands);
2501 return ix86_output_ssemov (insn, operands);
2504 if (SSE_REG_P (operands[0]))
2505 return "movq2dq\t{%1, %0|%0, %1}";
2507 return "movdq2q\t{%1, %0|%0, %1}";
2510 return "lea{q}\t{%E1, %0|%0, %E1}";
2513 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2514 if (get_attr_mode (insn) == MODE_SI)
2515 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2516 else if (which_alternative == 4)
2517 return "movabs{q}\t{%1, %0|%0, %1}";
2518 else if (ix86_use_lea_for_mov (insn, operands))
2519 return "lea{q}\t{%E1, %0|%0, %E1}";
2521 return "mov{q}\t{%1, %0|%0, %1}";
2528 (cond [(eq_attr "alternative" "0,1,17,18")
2529 (const_string "nox64")
2530 (eq_attr "alternative" "2,3,4,5,10,11,23,25")
2531 (const_string "x64")
2532 (eq_attr "alternative" "19,20")
2533 (const_string "x64_sse2")
2534 (eq_attr "alternative" "21,22")
2535 (const_string "sse2")
2537 (const_string "*")))
2539 (cond [(eq_attr "alternative" "0,1,17,18")
2540 (const_string "multi")
2541 (eq_attr "alternative" "6")
2542 (const_string "mmx")
2543 (eq_attr "alternative" "7,8,9,10,11")
2544 (const_string "mmxmov")
2545 (eq_attr "alternative" "12")
2546 (const_string "sselog1")
2547 (eq_attr "alternative" "13,14,15,16,19,20")
2548 (const_string "ssemov")
2549 (eq_attr "alternative" "21,22")
2550 (const_string "ssecvt")
2551 (eq_attr "alternative" "23,24,25,26")
2552 (const_string "mskmov")
2553 (eq_attr "alternative" "27")
2554 (const_string "msklog")
2555 (and (match_operand 0 "register_operand")
2556 (match_operand 1 "pic_32bit_operand"))
2557 (const_string "lea")
2559 (const_string "imov")))
2562 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2564 (const_string "*")))
2565 (set (attr "length_immediate")
2567 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2569 (const_string "*")))
2570 (set (attr "prefix_rex")
2572 (eq_attr "alternative" "10,11,19,20")
2574 (const_string "*")))
2575 (set (attr "prefix")
2576 (if_then_else (eq_attr "type" "sselog1,ssemov")
2577 (const_string "maybe_vex")
2578 (const_string "orig")))
2579 (set (attr "prefix_data16")
2580 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2582 (const_string "*")))
2584 (cond [(eq_attr "alternative" "2")
2586 (eq_attr "alternative" "12")
2587 (cond [(match_test "TARGET_AVX")
2589 (ior (not (match_test "TARGET_SSE2"))
2590 (match_test "optimize_function_for_size_p (cfun)"))
2591 (const_string "V4SF")
2593 (const_string "TI"))
2594 (eq_attr "alternative" "13")
2595 (cond [(match_test "TARGET_AVX512VL")
2597 (match_test "TARGET_AVX512F")
2599 (match_test "TARGET_AVX")
2601 (ior (not (match_test "TARGET_SSE2"))
2602 (match_test "optimize_function_for_size_p (cfun)"))
2603 (const_string "V4SF")
2605 (const_string "TI"))
2607 (and (eq_attr "alternative" "14,15,16")
2608 (not (match_test "TARGET_SSE2")))
2609 (const_string "V2SF")
2611 (const_string "DI")))
2612 (set (attr "preferred_for_speed")
2613 (cond [(eq_attr "alternative" "10,17,19")
2614 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2615 (eq_attr "alternative" "11,18,20")
2616 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2618 (symbol_ref "true")))
2619 (set (attr "enabled")
2620 (cond [(eq_attr "alternative" "15")
2622 (match_test "TARGET_STV && TARGET_SSE2")
2623 (symbol_ref "false")
2625 (eq_attr "alternative" "16")
2627 (match_test "TARGET_STV && TARGET_SSE2")
2629 (symbol_ref "false"))
2631 (const_string "*")))])
2634 [(set (match_operand:<DWI> 0 "general_reg_operand")
2635 (match_operand:<DWI> 1 "sse_reg_operand"))]
2637 && reload_completed"
2641 (parallel [(const_int 1)])))]
2643 operands[2] = gen_highpart (<MODE>mode, operands[0]);
2644 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[1], <DWI>mode);
2646 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]),
2647 gen_lowpart (<MODE>mode, operands[1]));
2651 [(set (match_operand:DWI 0 "nonimmediate_gr_operand")
2652 (match_operand:DWI 1 "general_gr_operand"))]
2655 "ix86_split_long_move (operands); DONE;")
2658 [(set (match_operand:DI 0 "sse_reg_operand")
2659 (match_operand:DI 1 "general_reg_operand"))]
2660 "!TARGET_64BIT && TARGET_SSE4_1
2661 && reload_completed"
2664 (vec_duplicate:V4SI (match_dup 3))
2668 operands[2] = lowpart_subreg (V4SImode, operands[0], DImode);
2669 operands[3] = gen_highpart (SImode, operands[1]);
2671 emit_move_insn (gen_lowpart (SImode, operands[0]),
2672 gen_lowpart (SImode, operands[1]));
2675 ;; movabsq $0x0012345678000000, %rax is longer
2676 ;; than movl $0x12345678, %eax; shlq $24, %rax.
2678 [(set (match_operand:DI 0 "register_operand")
2679 (match_operand:DI 1 "const_int_operand"))]
2681 && optimize_insn_for_size_p ()
2682 && LEGACY_INT_REG_P (operands[0])
2683 && !x86_64_immediate_operand (operands[1], DImode)
2684 && !x86_64_zext_immediate_operand (operands[1], DImode)
2685 && !((UINTVAL (operands[1]) >> ctz_hwi (UINTVAL (operands[1])))
2686 & ~(HOST_WIDE_INT) 0xffffffff)
2687 && peep2_regno_dead_p (0, FLAGS_REG)"
2688 [(set (match_dup 0) (match_dup 1))
2689 (parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
2690 (clobber (reg:CC FLAGS_REG))])]
2692 int shift = ctz_hwi (UINTVAL (operands[1]));
2693 operands[1] = gen_int_mode (UINTVAL (operands[1]) >> shift, DImode);
2694 operands[2] = gen_int_mode (shift, QImode);
2697 (define_insn "*movsi_internal"
2698 [(set (match_operand:SI 0 "nonimmediate_operand"
2699 "=r,m ,*y,*y,?*y,?m,?r,?*y,?Yv,?v,?v,m ,?r,?v,*k,*k ,*rm,*k")
2700 (match_operand:SI 1 "general_operand"
2701 "g ,re,C ,*y,Bk ,*y,*y,r ,C ,?v,Bk,?v,?v,r ,*r,*kBk,*k ,CBC"))]
2702 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2703 && ix86_hardreg_mov_ok (operands[0], operands[1])"
2705 switch (get_attr_type (insn))
2708 return standard_sse_constant_opcode (insn, operands);
2711 return "kmovd\t{%1, %0|%0, %1}";
2714 if (operands[1] == const0_rtx)
2715 return "kxord\t%0, %0, %0";
2716 else if (operands[1] == constm1_rtx)
2717 return "kxnord\t%0, %0, %0";
2721 return ix86_output_ssemov (insn, operands);
2724 return "pxor\t%0, %0";
2727 switch (get_attr_mode (insn))
2730 return "movq\t{%1, %0|%0, %1}";
2732 return "movd\t{%1, %0|%0, %1}";
2739 return "lea{l}\t{%E1, %0|%0, %E1}";
2742 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2743 if (ix86_use_lea_for_mov (insn, operands))
2744 return "lea{l}\t{%E1, %0|%0, %E1}";
2746 return "mov{l}\t{%1, %0|%0, %1}";
2753 (cond [(eq_attr "alternative" "12,13")
2754 (const_string "sse2")
2756 (const_string "*")))
2758 (cond [(eq_attr "alternative" "2")
2759 (const_string "mmx")
2760 (eq_attr "alternative" "3,4,5,6,7")
2761 (const_string "mmxmov")
2762 (eq_attr "alternative" "8")
2763 (const_string "sselog1")
2764 (eq_attr "alternative" "9,10,11,12,13")
2765 (const_string "ssemov")
2766 (eq_attr "alternative" "14,15,16")
2767 (const_string "mskmov")
2768 (eq_attr "alternative" "17")
2769 (const_string "msklog")
2770 (and (match_operand 0 "register_operand")
2771 (match_operand 1 "pic_32bit_operand"))
2772 (const_string "lea")
2774 (const_string "imov")))
2775 (set (attr "prefix")
2776 (if_then_else (eq_attr "type" "sselog1,ssemov")
2777 (const_string "maybe_vex")
2778 (const_string "orig")))
2779 (set (attr "prefix_data16")
2780 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2782 (const_string "*")))
2784 (cond [(eq_attr "alternative" "2,3")
2786 (eq_attr "alternative" "8")
2787 (cond [(match_test "TARGET_AVX")
2789 (ior (not (match_test "TARGET_SSE2"))
2790 (match_test "optimize_function_for_size_p (cfun)"))
2791 (const_string "V4SF")
2793 (const_string "TI"))
2794 (eq_attr "alternative" "9")
2795 (cond [(match_test "TARGET_AVX512VL")
2797 (match_test "TARGET_AVX512F")
2799 (match_test "TARGET_AVX")
2801 (ior (not (match_test "TARGET_SSE2"))
2802 (match_test "optimize_function_for_size_p (cfun)"))
2803 (const_string "V4SF")
2805 (const_string "TI"))
2807 (and (eq_attr "alternative" "10,11")
2808 (not (match_test "TARGET_SSE2")))
2811 (const_string "SI")))
2812 (set (attr "preferred_for_speed")
2813 (cond [(eq_attr "alternative" "6,12")
2814 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2815 (eq_attr "alternative" "7,13")
2816 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2818 (symbol_ref "true")))])
2820 ;; With -Oz, transform mov $imm,reg to the shorter push $imm; pop reg.
2822 [(set (match_operand:SWI248 0 "general_reg_operand")
2823 (match_operand:SWI248 1 "const_int_operand"))]
2824 "optimize_insn_for_size_p () && optimize_size > 1
2825 && operands[1] != const0_rtx
2826 && IN_RANGE (INTVAL (operands[1]), -128, 127)
2827 && !ix86_red_zone_used
2828 && REGNO (operands[0]) != SP_REG"
2829 [(set (match_dup 2) (match_dup 1))
2830 (set (match_dup 0) (match_dup 3))]
2832 if (GET_MODE (operands[0]) != word_mode)
2833 operands[0] = gen_rtx_REG (word_mode, REGNO (operands[0]));
2835 operands[2] = gen_rtx_MEM (word_mode,
2836 gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
2837 operands[3] = gen_rtx_MEM (word_mode,
2838 gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
2841 ;; With -Oz, transform mov $0,mem to the shorter and $0,mem.
2842 ;; Likewise, transform mov $-1,mem to the shorter or $-1,mem.
2844 [(set (match_operand:SWI248 0 "memory_operand")
2845 (match_operand:SWI248 1 "const_int_operand"))]
2846 "(operands[1] == const0_rtx || operands[1] == constm1_rtx)
2847 && optimize_insn_for_size_p () && optimize_size > 1
2848 && peep2_regno_dead_p (0, FLAGS_REG)"
2849 [(parallel [(set (match_dup 0) (match_dup 1))
2850 (clobber (reg:CC FLAGS_REG))])])
2852 (define_insn "*movhi_internal"
2853 [(set (match_operand:HI 0 "nonimmediate_operand"
2854 "=r,r,r,m ,*k,*k ,r ,m ,*k ,?r,?*v,*Yv,*v,*v,jm,m")
2855 (match_operand:HI 1 "general_operand"
2856 "r ,n,m,rn,r ,*km,*k,*k,CBC,*v,r ,C ,*v,m ,*x,*v"))]
2857 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2858 && ix86_hardreg_mov_ok (operands[0], operands[1])"
2860 switch (get_attr_type (insn))
2863 /* movzwl is faster than movw on p2 due to partial word stalls,
2864 though not as fast as an aligned movl. */
2865 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2868 switch (which_alternative)
2871 return "kmovw\t{%k1, %0|%0, %k1}";
2873 return "kmovw\t{%1, %k0|%k0, %1}";
2876 return "kmovw\t{%1, %0|%0, %1}";
2882 return ix86_output_ssemov (insn, operands);
2885 if (satisfies_constraint_C (operands[1]))
2886 return standard_sse_constant_opcode (insn, operands);
2888 if (SSE_REG_P (operands[0]))
2889 return "%vpinsrw\t{$0, %1, %d0|%d0, %1, 0}";
2891 return "%vpextrw\t{$0, %1, %0|%0, %1, 0}";
2894 if (operands[1] == const0_rtx)
2895 return "kxorw\t%0, %0, %0";
2896 else if (operands[1] == constm1_rtx)
2897 return "kxnorw\t%0, %0, %0";
2901 if (get_attr_mode (insn) == MODE_SI)
2902 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2904 return "mov{w}\t{%1, %0|%0, %1}";
2908 (cond [(eq_attr "alternative" "9,10,11,12,13")
2909 (const_string "sse2")
2910 (eq_attr "alternative" "14")
2911 (const_string "sse4_noavx")
2912 (eq_attr "alternative" "15")
2913 (const_string "avx")
2915 (const_string "*")))
2917 (if_then_else (eq_attr "alternative" "14")
2918 (const_string "gpr16")
2919 (const_string "*")))
2921 (cond [(eq_attr "alternative" "4,5,6,7")
2922 (const_string "mskmov")
2923 (eq_attr "alternative" "8")
2924 (const_string "msklog")
2925 (eq_attr "alternative" "13,14,15")
2926 (if_then_else (match_test "TARGET_AVX512FP16")
2927 (const_string "ssemov")
2928 (const_string "sselog1"))
2929 (eq_attr "alternative" "11")
2930 (const_string "sselog1")
2931 (eq_attr "alternative" "9,10,12")
2932 (const_string "ssemov")
2933 (match_test "optimize_function_for_size_p (cfun)")
2934 (const_string "imov")
2935 (and (eq_attr "alternative" "0")
2936 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2937 (not (match_test "TARGET_HIMODE_MATH"))))
2938 (const_string "imov")
2939 (and (eq_attr "alternative" "1,2")
2940 (match_operand:HI 1 "aligned_operand"))
2941 (const_string "imov")
2942 (and (match_test "TARGET_MOVX")
2943 (eq_attr "alternative" "0,2"))
2944 (const_string "imovx")
2946 (const_string "imov")))
2947 (set (attr "prefix")
2948 (cond [(eq_attr "alternative" "4,5,6,7,8")
2949 (const_string "vex")
2950 (eq_attr "alternative" "9,10,11,12,13,14,15")
2951 (const_string "maybe_evex")
2953 (const_string "orig")))
2955 (cond [(eq_attr "alternative" "9,10")
2956 (if_then_else (match_test "TARGET_AVX512FP16")
2958 (const_string "SI"))
2959 (eq_attr "alternative" "13,14,15")
2960 (if_then_else (match_test "TARGET_AVX512FP16")
2962 (const_string "TI"))
2963 (eq_attr "alternative" "11")
2964 (cond [(match_test "TARGET_AVX")
2966 (ior (not (match_test "TARGET_SSE2"))
2967 (match_test "optimize_function_for_size_p (cfun)"))
2968 (const_string "V4SF")
2970 (const_string "TI"))
2971 (eq_attr "alternative" "12")
2972 (cond [(match_test "TARGET_AVX512VL")
2974 (match_test "TARGET_AVX512FP16")
2976 (match_test "TARGET_AVX512F")
2978 (match_test "TARGET_AVX")
2980 (ior (not (match_test "TARGET_SSE2"))
2981 (match_test "optimize_function_for_size_p (cfun)"))
2982 (const_string "V4SF")
2984 (const_string "TI"))
2985 (eq_attr "type" "imovx")
2987 (and (eq_attr "alternative" "1,2")
2988 (match_operand:HI 1 "aligned_operand"))
2990 (and (eq_attr "alternative" "0")
2991 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2992 (not (match_test "TARGET_HIMODE_MATH"))))
2995 (const_string "HI")))
2996 (set (attr "preferred_for_speed")
2997 (cond [(eq_attr "alternative" "9")
2998 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2999 (eq_attr "alternative" "10")
3000 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3002 (symbol_ref "true")))])
3004 ;; Situation is quite tricky about when to choose full sized (SImode) move
3005 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
3006 ;; partial register dependency machines (such as AMD Athlon), where QImode
3007 ;; moves issue extra dependency and for partial register stalls machines
3008 ;; that don't use QImode patterns (and QImode move cause stall on the next
3011 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
3012 ;; register stall machines with, where we use QImode instructions, since
3013 ;; partial register stall can be caused there. Then we use movzx.
3015 (define_insn "*movqi_internal"
3016 [(set (match_operand:QI 0 "nonimmediate_operand"
3017 "=Q,R,r,q,q,r,r ,?r,m ,*k,*k,*r,*m,*k,*k,*k")
3018 (match_operand:QI 1 "general_operand"
3019 "Q ,R,r,n,m,q,rn, m,qn,*r,*k,*k,*k,*m,C,BC"))]
3020 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3021 && ix86_hardreg_mov_ok (operands[0], operands[1])"
3028 switch (get_attr_type (insn))
3031 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
3032 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
3035 switch (which_alternative)
3038 ops = "kmov%s\t{%%k1, %%0|%%0, %%k1}";
3041 ops = "kmov%s\t{%%1, %%k0|%%k0, %%1}";
3045 gcc_assert (TARGET_AVX512DQ);
3048 ops = "kmov%s\t{%%1, %%0|%%0, %%1}";
3054 suffix = (get_attr_mode (insn) == MODE_HI) ? "w" : "b";
3056 snprintf (buf, sizeof (buf), ops, suffix);
3057 output_asm_insn (buf, operands);
3061 if (operands[1] == const0_rtx)
3063 if (get_attr_mode (insn) == MODE_HI)
3064 return "kxorw\t%0, %0, %0";
3066 return "kxorb\t%0, %0, %0";
3068 else if (operands[1] == constm1_rtx)
3070 gcc_assert (TARGET_AVX512DQ);
3071 return "kxnorb\t%0, %0, %0";
3076 if (get_attr_mode (insn) == MODE_SI)
3077 return "mov{l}\t{%k1, %k0|%k0, %k1}";
3079 return "mov{b}\t{%1, %0|%0, %1}";
3083 (cond [(eq_attr "alternative" "1,2")
3084 (const_string "x64")
3085 (eq_attr "alternative" "12,13,15")
3086 (const_string "avx512dq")
3088 (const_string "*")))
3090 (cond [(eq_attr "alternative" "9,10,11,12,13")
3091 (const_string "mskmov")
3092 (eq_attr "alternative" "14,15")
3093 (const_string "msklog")
3094 (and (eq_attr "alternative" "7")
3095 (not (match_operand:QI 1 "aligned_operand")))
3096 (const_string "imovx")
3097 (match_test "optimize_function_for_size_p (cfun)")
3098 (const_string "imov")
3099 (and (eq_attr "alternative" "5")
3100 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
3101 (not (match_test "TARGET_QIMODE_MATH"))))
3102 (const_string "imov")
3103 (eq_attr "alternative" "5,7")
3104 (const_string "imovx")
3105 (and (match_test "TARGET_MOVX")
3106 (eq_attr "alternative" "4"))
3107 (const_string "imovx")
3109 (const_string "imov")))
3110 (set (attr "prefix")
3111 (if_then_else (eq_attr "alternative" "9,10,11,12,13,14,15")
3112 (const_string "vex")
3113 (const_string "orig")))
3115 (cond [(eq_attr "alternative" "5,6,7")
3117 (eq_attr "alternative" "8")
3119 (and (eq_attr "alternative" "9,10,11,14")
3120 (not (match_test "TARGET_AVX512DQ")))
3122 (eq_attr "type" "imovx")
3124 ;; For -Os, 8-bit immediates are always shorter than 32-bit
3126 (and (eq_attr "type" "imov")
3127 (and (eq_attr "alternative" "3")
3128 (match_test "optimize_function_for_size_p (cfun)")))
3130 ;; For -Os, movl where one or both operands are NON_Q_REGS
3131 ;; and both are LEGACY_REGS is shorter than movb.
3132 ;; Otherwise movb and movl sizes are the same, so decide purely
3133 ;; based on speed factors.
3134 (and (eq_attr "type" "imov")
3135 (and (eq_attr "alternative" "1")
3136 (match_test "optimize_function_for_size_p (cfun)")))
3138 (and (eq_attr "type" "imov")
3139 (and (eq_attr "alternative" "0,1,2,3")
3140 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
3141 (not (match_test "TARGET_PARTIAL_REG_STALL")))))
3143 ;; Avoid partial register stalls when not using QImode arithmetic
3144 (and (eq_attr "type" "imov")
3145 (and (eq_attr "alternative" "0,1,2,3")
3146 (and (match_test "TARGET_PARTIAL_REG_STALL")
3147 (not (match_test "TARGET_QIMODE_MATH")))))
3150 (const_string "QI")))])
3152 /* Reload dislikes loading 0/-1 directly into mask registers.
3153 Try to tidy things up here. */
3155 [(set (match_operand:SWI 0 "general_reg_operand")
3156 (match_operand:SWI 1 "immediate_operand"))
3157 (set (match_operand:SWI 2 "mask_reg_operand")
3159 "peep2_reg_dead_p (2, operands[0])
3160 && (const0_operand (operands[1], <MODE>mode)
3161 || (constm1_operand (operands[1], <MODE>mode)
3162 && (<MODE_SIZE> > 1 || TARGET_AVX512DQ)))"
3163 [(set (match_dup 2) (match_dup 1))])
3165 ;; Stores and loads of ax to arbitrary constant address.
3166 ;; We fake an second form of instruction to force reload to load address
3167 ;; into register when rax is not available
3168 (define_insn "*movabs<mode>_1"
3169 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
3170 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
3171 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
3173 /* Recover the full memory rtx. */
3174 operands[0] = SET_DEST (PATTERN (insn));
3175 switch (which_alternative)
3178 return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}";
3180 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
3185 [(set_attr "type" "imov")
3186 (set_attr "modrm" "0,*")
3187 (set_attr "length_address" "8,0")
3188 (set_attr "length_immediate" "0,*")
3189 (set_attr "memory" "store")
3190 (set_attr "mode" "<MODE>")])
3192 (define_insn "*movabs<mode>_2"
3193 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
3194 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
3195 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
3197 /* Recover the full memory rtx. */
3198 operands[1] = SET_SRC (PATTERN (insn));
3199 switch (which_alternative)
3202 return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}";
3204 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
3209 [(set_attr "type" "imov")
3210 (set_attr "modrm" "0,*")
3211 (set_attr "length_address" "8,0")
3212 (set_attr "length_immediate" "0")
3213 (set_attr "memory" "load")
3214 (set_attr "mode" "<MODE>")])
3216 (define_insn "swap<mode>"
3217 [(set (match_operand:SWI48 0 "register_operand" "+r")
3218 (match_operand:SWI48 1 "register_operand" "+r"))
3222 "xchg{<imodesuffix>}\t%1, %0"
3223 [(set_attr "type" "imov")
3224 (set_attr "mode" "<MODE>")
3225 (set_attr "pent_pair" "np")
3226 (set_attr "athlon_decode" "vector")
3227 (set_attr "amdfam10_decode" "double")
3228 (set_attr "bdver1_decode" "double")])
3230 (define_insn "*swap<mode>"
3231 [(set (match_operand:SWI12 0 "register_operand" "+<r>,r")
3232 (match_operand:SWI12 1 "register_operand" "+<r>,r"))
3237 xchg{<imodesuffix>}\t%1, %0
3239 [(set_attr "type" "imov")
3240 (set_attr "mode" "<MODE>,SI")
3241 (set (attr "preferred_for_size")
3242 (cond [(eq_attr "alternative" "0")
3243 (symbol_ref "false")]
3244 (symbol_ref "true")))
3245 ;; Potential partial reg stall on alternative 1.
3246 (set (attr "preferred_for_speed")
3247 (cond [(eq_attr "alternative" "1")
3248 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
3249 (symbol_ref "true")))
3250 (set_attr "pent_pair" "np")
3251 (set_attr "athlon_decode" "vector")
3252 (set_attr "amdfam10_decode" "double")
3253 (set_attr "bdver1_decode" "double")])
3256 [(set (match_operand:SWI 0 "general_reg_operand")
3257 (match_operand:SWI 1 "general_reg_operand"))
3259 (match_operand:SWI 2 "general_reg_operand"))
3260 (set (match_dup 2) (match_dup 0))]
3261 "peep2_reg_dead_p (3, operands[0])
3262 && optimize_insn_for_size_p ()"
3263 [(parallel [(set (match_dup 1) (match_dup 2))
3264 (set (match_dup 2) (match_dup 1))])])
3266 ;; Convert xchg with a REG_UNUSED note to a mov (variant #1).
3268 [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
3269 (match_operand:SWI 1 "general_reg_operand"))
3270 (set (match_dup 1) (match_dup 0))])]
3271 "((REGNO (operands[0]) != AX_REG
3272 && REGNO (operands[1]) != AX_REG)
3273 || optimize_size < 2
3274 || !optimize_insn_for_size_p ())
3275 && peep2_reg_dead_p (1, operands[0])"
3276 [(set (match_dup 1) (match_dup 0))])
3278 ;; Convert xchg with a REG_UNUSED note to a mov (variant #2).
3280 [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
3281 (match_operand:SWI 1 "general_reg_operand"))
3282 (set (match_dup 1) (match_dup 0))])]
3283 "((REGNO (operands[0]) != AX_REG
3284 && REGNO (operands[1]) != AX_REG)
3285 || optimize_size < 2
3286 || !optimize_insn_for_size_p ())
3287 && peep2_reg_dead_p (1, operands[1])"
3288 [(set (match_dup 0) (match_dup 1))])
3290 ;; Convert moves to/from AX_REG into xchg with -Oz.
3292 [(set (match_operand:SWI48 0 "general_reg_operand")
3293 (match_operand:SWI48 1 "general_reg_operand"))]
3295 && ((REGNO (operands[0]) == AX_REG)
3296 != (REGNO (operands[1]) == AX_REG))
3297 && optimize_insn_for_size_p ()
3298 && peep2_reg_dead_p (1, operands[1])"
3299 [(parallel [(set (match_dup 0) (match_dup 1))
3300 (set (match_dup 1) (match_dup 0))])])
3302 (define_expand "movstrict<mode>"
3303 [(set (strict_low_part (match_operand:SWI12 0 "register_operand"))
3304 (match_operand:SWI12 1 "general_operand"))]
3307 gcc_assert (SUBREG_P (operands[0]));
3308 if ((TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
3309 || !VALID_INT_MODE_P (GET_MODE (SUBREG_REG (operands[0]))))
3313 (define_insn "*movstrict<mode>_1"
3314 [(set (strict_low_part
3315 (match_operand:SWI12 0 "register_operand" "+<r>"))
3316 (match_operand:SWI12 1 "general_operand" "<r>mn"))]
3317 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
3318 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
3319 [(set_attr "type" "imov")
3320 (set_attr "mode" "<MODE>")])
3322 (define_insn "*movstrict<mode>_xor"
3323 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
3324 (match_operand:SWI12 1 "const0_operand"))
3325 (clobber (reg:CC FLAGS_REG))]
3327 "xor{<imodesuffix>}\t%0, %0"
3328 [(set_attr "type" "alu1")
3329 (set_attr "mode" "<MODE>")
3330 (set_attr "length_immediate" "0")])
3332 (define_expand "extv<mode>"
3333 [(set (match_operand:SWI24 0 "register_operand")
3334 (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
3335 (match_operand:QI 2 "const_int_operand")
3336 (match_operand:QI 3 "const_int_operand")))]
3339 /* Handle extractions from %ah et al. */
3340 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
3343 unsigned int regno = reg_or_subregno (operands[1]);
3345 /* Be careful to expand only with registers having upper parts. */
3346 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3347 operands[1] = copy_to_reg (operands[1]);
3350 (define_insn "*extv<mode>"
3351 [(set (match_operand:SWI24 0 "register_operand" "=R")
3352 (sign_extract:SWI24 (match_operand 1 "int248_register_operand" "Q")
3356 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
3357 [(set_attr "type" "imovx")
3358 (set_attr "mode" "SI")])
3360 ;; Split sign-extension of single least significant bit as and x,$1;neg x
3361 (define_insn_and_split "*extv<mode>_1_0"
3362 [(set (match_operand:SWI48 0 "register_operand" "=r")
3363 (sign_extract:SWI48 (match_operand:SWI48 1 "register_operand" "0")
3366 (clobber (reg:CC FLAGS_REG))]
3370 [(parallel [(set (match_dup 0) (and:SWI48 (match_dup 1) (const_int 1)))
3371 (clobber (reg:CC FLAGS_REG))])
3372 (parallel [(set (match_dup 0) (neg:SWI48 (match_dup 0)))
3373 (clobber (reg:CC FLAGS_REG))])])
3375 (define_expand "extzv<mode>"
3376 [(set (match_operand:SWI248 0 "register_operand")
3377 (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
3378 (match_operand:QI 2 "const_int_operand")
3379 (match_operand:QI 3 "const_int_operand")))]
3382 if (ix86_expand_pextr (operands))
3385 /* Handle extractions from %ah et al. */
3386 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
3389 unsigned int regno = reg_or_subregno (operands[1]);
3391 /* Be careful to expand only with registers having upper parts. */
3392 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3393 operands[1] = copy_to_reg (operands[1]);
3396 (define_insn "*extzv<mode>"
3397 [(set (match_operand:SWI248 0 "register_operand" "=R")
3398 (zero_extract:SWI248 (match_operand 1 "int248_register_operand" "Q")
3402 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
3403 [(set_attr "type" "imovx")
3404 (set_attr "mode" "SI")])
3406 (define_insn "*extzvqi"
3407 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn,?R")
3409 (match_operator:SWI248 2 "extract_operator"
3410 [(match_operand 1 "int248_register_operand" "Q,Q")
3412 (const_int 8)]) 0))]
3415 switch (get_attr_type (insn))
3418 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
3420 return "mov{b}\t{%h1, %0|%0, %h1}";
3423 [(set_attr "addr" "gpr8,*")
3425 (if_then_else (and (match_operand:QI 0 "register_operand")
3426 (ior (not (match_operand:QI 0 "QIreg_operand"))
3427 (match_test "TARGET_MOVX")))
3428 (const_string "imovx")
3429 (const_string "imov")))
3431 (if_then_else (eq_attr "type" "imovx")
3433 (const_string "QI")))])
3435 (define_expand "insv<mode>"
3436 [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
3437 (match_operand:QI 1 "const_int_operand")
3438 (match_operand:QI 2 "const_int_operand"))
3439 (match_operand:SWI248 3 "register_operand"))]
3444 if (ix86_expand_pinsr (operands))
3447 /* Handle insertions to %ah et al. */
3448 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
3451 unsigned int regno = reg_or_subregno (operands[0]);
3453 /* Be careful to expand only with registers having upper parts. */
3454 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3455 dst = copy_to_reg (operands[0]);
3459 emit_insn (gen_insv_1 (<MODE>mode, dst, operands[3]));
3461 /* Fix up the destination if needed. */
3462 if (dst != operands[0])
3463 emit_move_insn (operands[0], dst);
3468 (define_insn "@insv<mode>_1"
3469 [(set (zero_extract:SWI248
3470 (match_operand 0 "int248_register_operand" "+Q")
3473 (match_operand:SWI248 1 "general_operand" "QnBn"))]
3476 if (CONST_INT_P (operands[1]))
3477 operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
3478 return "mov{b}\t{%b1, %h0|%h0, %b1}";
3480 [(set_attr "addr" "gpr8")
3481 (set_attr "type" "imov")
3482 (set_attr "mode" "QI")])
3484 (define_insn "*insvqi_1"
3485 [(set (zero_extract:SWI248
3486 (match_operand 0 "int248_register_operand" "+Q")
3490 (match_operand:QI 1 "general_operand" "QnBn") 0))]
3492 "mov{b}\t{%1, %h0|%h0, %1}"
3493 [(set_attr "addr" "gpr8")
3494 (set_attr "type" "imov")
3495 (set_attr "mode" "QI")])
3497 ;; Eliminate redundant insv, e.g. xorl %eax,%eax; movb $0, %ah
3499 [(parallel [(set (match_operand:SWI48 0 "general_reg_operand")
3501 (clobber (reg:CC FLAGS_REG))])
3502 (set (zero_extract:SWI248 (match_operand 1 "int248_register_operand")
3506 "REGNO (operands[0]) == REGNO (operands[1])"
3507 [(parallel [(set (match_operand:SWI48 0 "general_reg_operand")
3509 (clobber (reg:CC FLAGS_REG))])])
3511 ;; Combine movl followed by movb.
3513 [(set (match_operand:SWI48 0 "general_reg_operand")
3514 (match_operand:SWI48 1 "const_int_operand"))
3515 (set (zero_extract:SWI248 (match_operand 2 "int248_register_operand")
3518 (match_operand:SWI248 3 "const_int_operand"))]
3519 "REGNO (operands[0]) == REGNO (operands[2])"
3520 [(set (match_operand:SWI48 0 "general_reg_operand")
3523 HOST_WIDE_INT tmp = INTVAL (operands[1]) & ~(HOST_WIDE_INT)0xff00;
3524 tmp |= (INTVAL (operands[3]) & 0xff) << 8;
3525 operands[4] = gen_int_mode (tmp, <SWI48:MODE>mode);
3528 (define_insn "*insvqi_2"
3529 [(set (zero_extract:SWI248
3530 (match_operand 0 "int248_register_operand" "+Q")
3533 (match_operator:SWI248 2 "extract_operator"
3534 [(match_operand 1 "int248_register_operand" "Q")
3538 "mov{b}\t{%h1, %h0|%h0, %h1}"
3539 [(set_attr "type" "imov")
3540 (set_attr "mode" "QI")])
3542 (define_insn "*insvqi_3"
3543 [(set (zero_extract:SWI248
3544 (match_operand 0 "int248_register_operand" "+Q")
3548 (match_operand:SWI248 1 "register_operand" "Q")
3551 "mov{b}\t{%h1, %h0|%h0, %h1}"
3552 [(set_attr "type" "imov")
3553 (set_attr "mode" "QI")])
3555 (define_code_iterator any_or_plus [plus ior xor])
3557 (define_insn_and_split "*insvti_highpart_1"
3558 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro,r,r,&r")
3561 (match_operand:TI 1 "nonimmediate_operand" "r,m,r,m")
3562 (match_operand:TI 3 "const_scalar_int_operand" "n,n,n,n"))
3565 (match_operand:DI 2 "nonimmediate_operand" "r,r,m,m"))
3568 && CONST_WIDE_INT_P (operands[3])
3569 && CONST_WIDE_INT_NUNITS (operands[3]) == 2
3570 && CONST_WIDE_INT_ELT (operands[3], 0) == -1
3571 && CONST_WIDE_INT_ELT (operands[3], 1) == 0"
3573 "&& reload_completed"
3576 operands[4] = gen_lowpart (DImode, operands[1]);
3577 split_double_concat (TImode, operands[0], operands[4], operands[2]);
3581 (define_insn_and_split "*insvti_lowpart_1"
3582 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro,r,r,&r")
3585 (match_operand:TI 1 "nonimmediate_operand" "r,m,r,m")
3586 (match_operand:TI 3 "const_scalar_int_operand" "n,n,n,n"))
3588 (match_operand:DI 2 "nonimmediate_operand" "r,r,m,m"))))]
3590 && CONST_WIDE_INT_P (operands[3])
3591 && CONST_WIDE_INT_NUNITS (operands[3]) == 2
3592 && CONST_WIDE_INT_ELT (operands[3], 0) == 0
3593 && CONST_WIDE_INT_ELT (operands[3], 1) == -1"
3595 "&& reload_completed"
3598 operands[4] = gen_highpart (DImode, operands[1]);
3599 split_double_concat (TImode, operands[0], operands[2], operands[4]);
3603 (define_insn_and_split "*insvdi_lowpart_1"
3604 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro,r,r,&r")
3607 (match_operand:DI 1 "nonimmediate_operand" "r,m,r,m")
3608 (match_operand:DI 3 "const_int_operand" "n,n,n,n"))
3610 (match_operand:SI 2 "nonimmediate_operand" "r,r,m,m"))))]
3612 && CONST_INT_P (operands[3])
3613 && UINTVAL (operands[3]) == 0xffffffff00000000ll"
3615 "&& reload_completed"
3618 operands[4] = gen_highpart (SImode, operands[1]);
3619 split_double_concat (DImode, operands[0], operands[2], operands[4]);
3623 ;; Floating point push instructions.
3625 (define_insn "*pushtf"
3626 [(set (match_operand:TF 0 "push_operand" "=<,<")
3627 (match_operand:TF 1 "general_no_elim_operand" "v,*roC"))]
3628 "TARGET_64BIT || TARGET_SSE"
3630 /* This insn should be already split before reg-stack. */
3633 [(set_attr "isa" "*,x64")
3634 (set_attr "type" "multi")
3635 (set_attr "unit" "sse,*")
3636 (set_attr "mode" "TF,DI")])
3638 ;; %%% Kill this when call knows how to work this out.
3640 [(set (match_operand:TF 0 "push_operand")
3641 (match_operand:TF 1 "sse_reg_operand"))]
3642 "TARGET_SSE && reload_completed"
3643 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3644 (set (match_dup 0) (match_dup 1))]
3646 /* Preserve memory attributes. */
3647 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3650 (define_insn "*pushxf"
3651 [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<")
3652 (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF,oC"))]
3655 /* This insn should be already split before reg-stack. */
3658 [(set_attr "isa" "*,*,*,nox64,x64")
3659 (set_attr "type" "multi")
3660 (set_attr "unit" "i387,*,*,*,*")
3662 (cond [(eq_attr "alternative" "1,2,3,4")
3663 (if_then_else (match_test "TARGET_64BIT")
3665 (const_string "SI"))
3667 (const_string "XF")))
3668 (set (attr "preferred_for_size")
3669 (cond [(eq_attr "alternative" "1")
3670 (symbol_ref "false")]
3671 (symbol_ref "true")))])
3673 ;; %%% Kill this when call knows how to work this out.
3675 [(set (match_operand:XF 0 "push_operand")
3676 (match_operand:XF 1 "fp_register_operand"))]
3678 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3679 (set (match_dup 0) (match_dup 1))]
3681 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (XFmode)));
3682 /* Preserve memory attributes. */
3683 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3686 (define_insn "*pushdf"
3687 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
3688 (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmC,v"))]
3691 /* This insn should be already split before reg-stack. */
3694 [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
3695 (set_attr "type" "multi")
3696 (set_attr "unit" "i387,*,*,*,*,sse")
3697 (set_attr "mode" "DF,SI,SI,SI,DI,DF")
3698 (set (attr "preferred_for_size")
3699 (cond [(eq_attr "alternative" "1")
3700 (symbol_ref "false")]
3701 (symbol_ref "true")))
3702 (set (attr "preferred_for_speed")
3703 (cond [(eq_attr "alternative" "1")
3704 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3705 (symbol_ref "true")))])
3707 ;; %%% Kill this when call knows how to work this out.
3709 [(set (match_operand:DF 0 "push_operand")
3710 (match_operand:DF 1 "any_fp_register_operand"))]
3712 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3713 (set (match_dup 0) (match_dup 1))]
3715 /* Preserve memory attributes. */
3716 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3719 (define_mode_iterator HFBF [HF BF])
3721 (define_insn "*push<mode>_rex64"
3722 [(set (match_operand:HFBF 0 "push_operand" "=X,X")
3723 (match_operand:HFBF 1 "nonmemory_no_elim_operand" "r,x"))]
3726 /* Anything else should be already split before reg-stack. */
3727 gcc_assert (which_alternative == 0);
3728 return "push{q}\t%q1";
3730 [(set_attr "isa" "*,sse4")
3731 (set_attr "type" "push,multi")
3732 (set_attr "mode" "DI,TI")])
3734 (define_insn "*push<mode>"
3735 [(set (match_operand:HFBF 0 "push_operand" "=X,X")
3736 (match_operand:HFBF 1 "general_no_elim_operand" "rmF,x"))]
3739 /* Anything else should be already split before reg-stack. */
3740 gcc_assert (which_alternative == 0);
3741 return "push{l}\t%k1";
3743 [(set_attr "isa" "*,sse4")
3744 (set_attr "type" "push,multi")
3745 (set_attr "mode" "SI,TI")])
3747 (define_insn "push2_di"
3748 [(set (match_operand:TI 0 "push_operand" "=<")
3749 (unspec:TI [(match_operand:DI 1 "register_operand" "r")
3750 (match_operand:DI 2 "register_operand" "r")]
3752 "TARGET_APX_PUSH2POP2"
3754 [(set_attr "mode" "TI")
3755 (set_attr "type" "multi")
3756 (set_attr "prefix" "evex")])
3758 (define_insn "pop2_di"
3759 [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
3760 (unspec:DI [(match_operand:TI 1 "pop_operand" ">")]
3761 UNSPEC_APXPOP2_LOW))
3762 (set (match_operand:DI 2 "register_operand" "=r")
3763 (unspec:DI [(const_int 0)] UNSPEC_APXPOP2_HIGH))])]
3764 "TARGET_APX_PUSH2POP2"
3766 [(set_attr "mode" "TI")
3767 (set_attr "prefix" "evex")])
3769 (define_insn "*pushsf_rex64"
3770 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3771 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,v"))]
3774 /* Anything else should be already split before reg-stack. */
3775 if (which_alternative != 1)
3777 return "push{q}\t%q1";
3779 [(set_attr "type" "multi,push,multi")
3780 (set_attr "unit" "i387,*,*")
3781 (set_attr "mode" "SF,DI,SF")])
3783 (define_insn "*pushsf"
3784 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3785 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,v"))]
3788 /* Anything else should be already split before reg-stack. */
3789 if (which_alternative != 1)
3791 return "push{l}\t%1";
3793 [(set_attr "type" "multi,push,multi")
3794 (set_attr "unit" "i387,*,*")
3795 (set_attr "mode" "SF,SI,SF")])
3797 (define_mode_iterator MODESH [SF HF BF])
3798 ;; %%% Kill this when call knows how to work this out.
3800 [(set (match_operand:MODESH 0 "push_operand")
3801 (match_operand:MODESH 1 "any_fp_register_operand"))]
3803 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3804 (set (match_dup 0) (match_dup 1))]
3806 rtx op = XEXP (operands[0], 0);
3807 if (GET_CODE (op) == PRE_DEC)
3809 gcc_assert (!TARGET_64BIT);
3814 op = XEXP (XEXP (op, 1), 1);
3815 gcc_assert (CONST_INT_P (op));
3818 /* Preserve memory attributes. */
3819 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3823 [(set (match_operand:SF 0 "push_operand")
3824 (match_operand:SF 1 "memory_operand"))]
3826 && find_constant_src (insn)"
3827 [(set (match_dup 0) (match_dup 2))]
3828 "operands[2] = find_constant_src (curr_insn);")
3831 [(set (match_operand 0 "push_operand")
3832 (match_operand 1 "general_gr_operand"))]
3834 && (GET_MODE (operands[0]) == TFmode
3835 || GET_MODE (operands[0]) == XFmode
3836 || GET_MODE (operands[0]) == DFmode)"
3838 "ix86_split_long_move (operands); DONE;")
3840 ;; Floating point move instructions.
3842 (define_expand "movtf"
3843 [(set (match_operand:TF 0 "nonimmediate_operand")
3844 (match_operand:TF 1 "nonimmediate_operand"))]
3845 "TARGET_64BIT || TARGET_SSE"
3846 "ix86_expand_move (TFmode, operands); DONE;")
3848 (define_expand "mov<mode>"
3849 [(set (match_operand:X87MODEFH 0 "nonimmediate_operand")
3850 (match_operand:X87MODEFH 1 "general_operand"))]
3852 "ix86_expand_move (<MODE>mode, operands); DONE;")
3854 (define_insn "*movtf_internal"
3855 [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o")
3856 (match_operand:TF 1 "general_operand" "C ,vm,v,*roF,*rC"))]
3857 "(TARGET_64BIT || TARGET_SSE)
3858 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3859 && (lra_in_progress || reload_completed
3860 || !CONST_DOUBLE_P (operands[1])
3861 || (standard_sse_constant_p (operands[1], TFmode) == 1
3862 && !memory_operand (operands[0], TFmode))
3863 || (!TARGET_MEMORY_MISMATCH_STALL
3864 && memory_operand (operands[0], TFmode)))"
3866 switch (get_attr_type (insn))
3869 return standard_sse_constant_opcode (insn, operands);
3872 return ix86_output_ssemov (insn, operands);
3881 [(set_attr "isa" "*,*,*,x64,x64")
3882 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3883 (set (attr "prefix")
3884 (if_then_else (eq_attr "type" "sselog1,ssemov")
3885 (const_string "maybe_vex")
3886 (const_string "orig")))
3888 (cond [(eq_attr "alternative" "3,4")
3890 (match_test "TARGET_AVX")
3892 (ior (not (match_test "TARGET_SSE2"))
3893 (match_test "optimize_function_for_size_p (cfun)"))
3894 (const_string "V4SF")
3895 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3896 (const_string "V4SF")
3897 (and (eq_attr "alternative" "2")
3898 (match_test "TARGET_SSE_TYPELESS_STORES"))
3899 (const_string "V4SF")
3901 (const_string "TI")))])
3904 [(set (match_operand:TF 0 "nonimmediate_gr_operand")
3905 (match_operand:TF 1 "general_gr_operand"))]
3908 "ix86_split_long_move (operands); DONE;")
3910 ;; Possible store forwarding (partial memory) stall
3911 ;; in alternatives 4, 6, 7 and 8.
3912 (define_insn "*movxf_internal"
3913 [(set (match_operand:XF 0 "nonimmediate_operand"
3914 "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r ,o ,o")
3915 (match_operand:XF 1 "general_operand"
3916 "fm,f,G,roF,r ,*roF,*r,F ,C ,roF,rF,rC"))]
3917 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3918 && (lra_in_progress || reload_completed
3919 || !CONST_DOUBLE_P (operands[1])
3920 || ((optimize_function_for_size_p (cfun)
3921 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3922 && standard_80387_constant_p (operands[1]) > 0
3923 && !memory_operand (operands[0], XFmode))
3924 || (!TARGET_MEMORY_MISMATCH_STALL
3925 && memory_operand (operands[0], XFmode))
3926 || !TARGET_HARD_XF_REGS)"
3928 switch (get_attr_type (insn))
3931 if (which_alternative == 2)
3932 return standard_80387_constant_opcode (operands[1]);
3933 return output_387_reg_move (insn, operands);
3943 (cond [(eq_attr "alternative" "7,10")
3944 (const_string "nox64")
3945 (eq_attr "alternative" "8,11")
3946 (const_string "x64")
3948 (const_string "*")))
3950 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3951 (const_string "multi")
3953 (const_string "fmov")))
3955 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3956 (if_then_else (match_test "TARGET_64BIT")
3958 (const_string "SI"))
3960 (const_string "XF")))
3961 (set (attr "preferred_for_size")
3962 (cond [(eq_attr "alternative" "3,4")
3963 (symbol_ref "false")]
3964 (symbol_ref "true")))
3965 (set (attr "enabled")
3966 (cond [(eq_attr "alternative" "9,10,11")
3968 (match_test "TARGET_HARD_XF_REGS")
3969 (symbol_ref "false")
3971 (not (match_test "TARGET_HARD_XF_REGS"))
3972 (symbol_ref "false")
3974 (const_string "*")))])
3977 [(set (match_operand:XF 0 "nonimmediate_gr_operand")
3978 (match_operand:XF 1 "general_gr_operand"))]
3981 "ix86_split_long_move (operands); DONE;")
3983 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3984 (define_insn "*movdf_internal"
3985 [(set (match_operand:DF 0 "nonimmediate_operand"
3986 "=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")
3987 (match_operand:DF 1 "general_operand"
3988 "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"))]
3989 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3990 && (lra_in_progress || reload_completed
3991 || !CONST_DOUBLE_P (operands[1])
3992 || ((optimize_function_for_size_p (cfun)
3993 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3994 && IS_STACK_MODE (DFmode)
3995 && standard_80387_constant_p (operands[1]) > 0
3996 && !memory_operand (operands[0], DFmode))
3997 || (TARGET_SSE2 && TARGET_SSE_MATH
3998 && standard_sse_constant_p (operands[1], DFmode) == 1
3999 && !memory_operand (operands[0], DFmode))
4000 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
4001 && memory_operand (operands[0], DFmode))
4002 || !TARGET_HARD_DF_REGS)"
4004 switch (get_attr_type (insn))
4007 if (which_alternative == 2)
4008 return standard_80387_constant_opcode (operands[1]);
4009 return output_387_reg_move (insn, operands);
4015 if (get_attr_mode (insn) == MODE_SI)
4016 return "mov{l}\t{%1, %k0|%k0, %1}";
4017 else if (which_alternative == 11)
4018 return "movabs{q}\t{%1, %0|%0, %1}";
4020 return "mov{q}\t{%1, %0|%0, %1}";
4023 return standard_sse_constant_opcode (insn, operands);
4026 return ix86_output_ssemov (insn, operands);
4033 (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
4034 (const_string "nox64")
4035 (eq_attr "alternative" "8,9,10,11,24,25")
4036 (const_string "x64")
4037 (eq_attr "alternative" "12,13,14,15")
4038 (const_string "sse2")
4039 (eq_attr "alternative" "20,21")
4040 (const_string "x64_sse2")
4042 (const_string "*")))
4044 (cond [(eq_attr "alternative" "0,1,2")
4045 (const_string "fmov")
4046 (eq_attr "alternative" "3,4,5,6,7,22,23")
4047 (const_string "multi")
4048 (eq_attr "alternative" "8,9,10,11,24,25")
4049 (const_string "imov")
4050 (eq_attr "alternative" "12,16")
4051 (const_string "sselog1")
4053 (const_string "ssemov")))
4055 (if_then_else (eq_attr "alternative" "11")
4057 (const_string "*")))
4058 (set (attr "length_immediate")
4059 (if_then_else (eq_attr "alternative" "11")
4061 (const_string "*")))
4062 (set (attr "prefix")
4063 (if_then_else (eq_attr "type" "sselog1,ssemov")
4064 (const_string "maybe_vex")
4065 (const_string "orig")))
4066 (set (attr "prefix_data16")
4068 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
4069 (eq_attr "mode" "V1DF"))
4071 (const_string "*")))
4073 (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
4075 (eq_attr "alternative" "8,9,11,20,21,24,25")
4078 /* xorps is one byte shorter for non-AVX targets. */
4079 (eq_attr "alternative" "12,16")
4080 (cond [(match_test "TARGET_AVX")
4081 (const_string "V2DF")
4082 (ior (not (match_test "TARGET_SSE2"))
4083 (match_test "optimize_function_for_size_p (cfun)"))
4084 (const_string "V4SF")
4085 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
4088 (const_string "V2DF"))
4090 /* For architectures resolving dependencies on
4091 whole SSE registers use movapd to break dependency
4092 chains, otherwise use short move to avoid extra work. */
4094 /* movaps is one byte shorter for non-AVX targets. */
4095 (eq_attr "alternative" "13,17")
4096 (cond [(match_test "TARGET_AVX512VL")
4097 (const_string "V2DF")
4098 (match_test "TARGET_AVX512F")
4100 (match_test "TARGET_AVX")
4101 (const_string "V2DF")
4102 (ior (not (match_test "TARGET_SSE2"))
4103 (match_test "optimize_function_for_size_p (cfun)"))
4104 (const_string "V4SF")
4105 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
4106 (const_string "V4SF")
4107 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
4108 (const_string "V2DF")
4110 (const_string "DF"))
4112 /* For architectures resolving dependencies on register
4113 parts we may avoid extra work to zero out upper part
4115 (eq_attr "alternative" "14,18")
4116 (cond [(not (match_test "TARGET_SSE2"))
4117 (const_string "V2SF")
4118 (match_test "TARGET_AVX")
4120 (match_test "TARGET_SSE_SPLIT_REGS")
4121 (const_string "V1DF")
4123 (const_string "DF"))
4125 (and (eq_attr "alternative" "15,19")
4126 (not (match_test "TARGET_SSE2")))
4127 (const_string "V2SF")
4129 (const_string "DF")))
4130 (set (attr "preferred_for_size")
4131 (cond [(eq_attr "alternative" "3,4")
4132 (symbol_ref "false")]
4133 (symbol_ref "true")))
4134 (set (attr "preferred_for_speed")
4135 (cond [(eq_attr "alternative" "3,4")
4136 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")
4137 (eq_attr "alternative" "20")
4138 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4139 (eq_attr "alternative" "21")
4140 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4142 (symbol_ref "true")))
4143 (set (attr "enabled")
4144 (cond [(eq_attr "alternative" "22,23,24,25")
4146 (match_test "TARGET_HARD_DF_REGS")
4147 (symbol_ref "false")
4149 (not (match_test "TARGET_HARD_DF_REGS"))
4150 (symbol_ref "false")
4152 (const_string "*")))])
4155 [(set (match_operand:DF 0 "nonimmediate_gr_operand")
4156 (match_operand:DF 1 "general_gr_operand"))]
4157 "!TARGET_64BIT && reload_completed"
4159 "ix86_split_long_move (operands); DONE;")
4161 (define_insn "*movsf_internal"
4162 [(set (match_operand:SF 0 "nonimmediate_operand"
4163 "=Yf*f,m ,Yf*f,?r ,?m,Yv,v,v,m,?r,?v,!*y,!*y,!m,!r,!*y,r ,m")
4164 (match_operand:SF 1 "general_operand"
4165 "Yf*fm,Yf*f,G ,rmF,rF,C ,v,m,v,v ,r ,*y ,m ,*y,*y,r ,rmF,rF"))]
4166 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
4167 && (lra_in_progress || reload_completed
4168 || !CONST_DOUBLE_P (operands[1])
4169 || ((optimize_function_for_size_p (cfun)
4170 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
4171 && IS_STACK_MODE (SFmode)
4172 && standard_80387_constant_p (operands[1]) > 0)
4173 || (TARGET_SSE && TARGET_SSE_MATH
4174 && standard_sse_constant_p (operands[1], SFmode) == 1)
4175 || memory_operand (operands[0], SFmode)
4176 || !TARGET_HARD_SF_REGS)"
4178 switch (get_attr_type (insn))
4181 if (which_alternative == 2)
4182 return standard_80387_constant_opcode (operands[1]);
4183 return output_387_reg_move (insn, operands);
4186 return "mov{l}\t{%1, %0|%0, %1}";
4189 return standard_sse_constant_opcode (insn, operands);
4192 return ix86_output_ssemov (insn, operands);
4195 switch (get_attr_mode (insn))
4198 return "movq\t{%1, %0|%0, %1}";
4200 return "movd\t{%1, %0|%0, %1}";
4211 (cond [(eq_attr "alternative" "9,10")
4212 (const_string "sse2")
4214 (const_string "*")))
4216 (cond [(eq_attr "alternative" "0,1,2")
4217 (const_string "fmov")
4218 (eq_attr "alternative" "3,4,16,17")
4219 (const_string "imov")
4220 (eq_attr "alternative" "5")
4221 (const_string "sselog1")
4222 (eq_attr "alternative" "11,12,13,14,15")
4223 (const_string "mmxmov")
4225 (const_string "ssemov")))
4226 (set (attr "prefix")
4227 (if_then_else (eq_attr "type" "sselog1,ssemov")
4228 (const_string "maybe_vex")
4229 (const_string "orig")))
4230 (set (attr "prefix_data16")
4231 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
4233 (const_string "*")))
4235 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
4237 (eq_attr "alternative" "11")
4239 (eq_attr "alternative" "5")
4240 (cond [(and (match_test "TARGET_AVX512F && TARGET_EVEX512")
4241 (not (match_test "TARGET_PREFER_AVX256")))
4242 (const_string "V16SF")
4243 (match_test "TARGET_AVX")
4244 (const_string "V4SF")
4245 (ior (not (match_test "TARGET_SSE2"))
4246 (match_test "optimize_function_for_size_p (cfun)"))
4247 (const_string "V4SF")
4248 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
4251 (const_string "V4SF"))
4253 /* For architectures resolving dependencies on
4254 whole SSE registers use APS move to break dependency
4255 chains, otherwise use short move to avoid extra work.
4257 Do the same for architectures resolving dependencies on
4258 the parts. While in DF mode it is better to always handle
4259 just register parts, the SF mode is different due to lack
4260 of instructions to load just part of the register. It is
4261 better to maintain the whole registers in single format
4262 to avoid problems on using packed logical operations. */
4263 (eq_attr "alternative" "6")
4264 (cond [(match_test "TARGET_AVX512VL")
4265 (const_string "V4SF")
4266 (match_test "TARGET_AVX512F")
4268 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
4269 (match_test "TARGET_SSE_SPLIT_REGS"))
4270 (const_string "V4SF")
4272 (const_string "SF"))
4274 (const_string "SF")))
4275 (set (attr "preferred_for_speed")
4276 (cond [(eq_attr "alternative" "9,14")
4277 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4278 (eq_attr "alternative" "10,15")
4279 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4281 (symbol_ref "true")))
4282 (set (attr "enabled")
4283 (cond [(eq_attr "alternative" "16,17")
4285 (match_test "TARGET_HARD_SF_REGS")
4286 (symbol_ref "false")
4288 (not (match_test "TARGET_HARD_SF_REGS"))
4289 (symbol_ref "false")
4291 (const_string "*")))])
4293 (define_mode_attr hfbfconstf
4296 (define_insn "*mov<mode>_internal"
4297 [(set (match_operand:HFBF 0 "nonimmediate_operand"
4298 "=?r,?r,?r,?m ,Yv,v,?r,jm,m,?v,v")
4299 (match_operand:HFBF 1 "general_operand"
4300 "r ,F ,m ,r<hfbfconstf>,C ,v, v,v ,v,r ,m"))]
4301 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
4304 || !CONST_DOUBLE_P (operands[1])
4306 && standard_sse_constant_p (operands[1], <MODE>mode) == 1)
4307 || memory_operand (operands[0], <MODE>mode))"
4309 switch (get_attr_type (insn))
4312 /* movzwl is faster than movw on p2 due to partial word stalls,
4313 though not as fast as an aligned movl. */
4314 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
4317 return ix86_output_ssemov (insn, operands);
4320 if (satisfies_constraint_C (operands[1]))
4321 return standard_sse_constant_opcode (insn, operands);
4323 if (SSE_REG_P (operands[0]))
4324 return "%vpinsrw\t{$0, %1, %d0|%d0, %1, 0}";
4326 return "%vpextrw\t{$0, %1, %0|%0, %1, 0}";
4329 if (get_attr_mode (insn) == MODE_SI)
4330 return "mov{l}\t{%k1, %k0|%k0, %k1}";
4332 return "mov{w}\t{%1, %0|%0, %1}";
4336 (cond [(eq_attr "alternative" "4,5,6,9,10")
4337 (const_string "sse2")
4338 (eq_attr "alternative" "7")
4339 (const_string "sse4_noavx")
4340 (eq_attr "alternative" "8")
4341 (const_string "avx")
4343 (const_string "*")))
4345 (if_then_else (eq_attr "alternative" "7")
4346 (const_string "gpr16")
4347 (const_string "*")))
4349 (cond [(eq_attr "alternative" "4")
4350 (const_string "sselog1")
4351 (eq_attr "alternative" "5,6,9")
4352 (const_string "ssemov")
4353 (eq_attr "alternative" "7,8,10")
4355 (match_test ("TARGET_AVX512FP16"))
4356 (const_string "ssemov")
4357 (const_string "sselog1"))
4358 (match_test "optimize_function_for_size_p (cfun)")
4359 (const_string "imov")
4360 (and (eq_attr "alternative" "0")
4361 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
4362 (not (match_test "TARGET_HIMODE_MATH"))))
4363 (const_string "imov")
4364 (and (eq_attr "alternative" "1,2")
4365 (match_operand:HI 1 "aligned_operand"))
4366 (const_string "imov")
4367 (and (match_test "TARGET_MOVX")
4368 (eq_attr "alternative" "0,2"))
4369 (const_string "imovx")
4371 (const_string "imov")))
4372 (set (attr "prefix")
4373 (cond [(eq_attr "alternative" "4,5,6,7,8,9,10")
4374 (const_string "maybe_vex")
4376 (const_string "orig")))
4378 (cond [(eq_attr "alternative" "4")
4379 (const_string "V4SF")
4380 (eq_attr "alternative" "6,9")
4382 (match_test "TARGET_AVX512FP16")
4384 (const_string "SI"))
4385 (eq_attr "alternative" "7,8,10")
4387 (match_test "TARGET_AVX512FP16")
4389 (const_string "TI"))
4390 (eq_attr "alternative" "5")
4391 (cond [(match_test "TARGET_AVX512VL")
4392 (const_string "V4SF")
4393 (match_test "TARGET_AVX512FP16")
4395 (match_test "TARGET_AVX512F")
4397 (match_test "TARGET_AVX")
4398 (const_string "V4SF")
4399 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
4400 (match_test "TARGET_SSE_SPLIT_REGS"))
4401 (const_string "V4SF")
4403 (const_string "SF"))
4404 (eq_attr "type" "imovx")
4406 (and (eq_attr "alternative" "1,2")
4407 (match_operand:HI 1 "aligned_operand"))
4409 (and (eq_attr "alternative" "0")
4410 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
4411 (not (match_test "TARGET_HIMODE_MATH"))))
4414 (const_string "HI")))
4415 (set (attr "enabled")
4416 (cond [(and (match_test "<MODE>mode == BFmode")
4417 (eq_attr "alternative" "1"))
4418 (symbol_ref "false")
4420 (const_string "*")))])
4423 [(set (match_operand 0 "any_fp_register_operand")
4424 (match_operand 1 "memory_operand"))]
4426 && (GET_MODE (operands[0]) == TFmode
4427 || GET_MODE (operands[0]) == XFmode
4428 || GET_MODE (operands[0]) == DFmode
4429 || GET_MODE (operands[0]) == SFmode)
4430 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
4431 [(set (match_dup 0) (match_dup 2))]
4432 "operands[2] = find_constant_src (curr_insn);")
4435 [(set (match_operand 0 "any_fp_register_operand")
4436 (float_extend (match_operand 1 "memory_operand")))]
4438 && (GET_MODE (operands[0]) == TFmode
4439 || GET_MODE (operands[0]) == XFmode
4440 || GET_MODE (operands[0]) == DFmode)
4441 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
4442 [(set (match_dup 0) (match_dup 2))]
4443 "operands[2] = find_constant_src (curr_insn);")
4445 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
4447 [(set (match_operand:X87MODEF 0 "fp_register_operand")
4448 (match_operand:X87MODEF 1 "immediate_operand"))]
4450 && (standard_80387_constant_p (operands[1]) == 8
4451 || standard_80387_constant_p (operands[1]) == 9)"
4452 [(set (match_dup 0)(match_dup 1))
4454 (neg:X87MODEF (match_dup 0)))]
4456 if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
4457 operands[1] = CONST0_RTX (<MODE>mode);
4459 operands[1] = CONST1_RTX (<MODE>mode);
4462 (define_insn "*swapxf"
4463 [(set (match_operand:XF 0 "register_operand" "+f")
4464 (match_operand:XF 1 "register_operand" "+f"))
4469 if (STACK_TOP_P (operands[0]))
4474 [(set_attr "type" "fxch")
4475 (set_attr "mode" "XF")])
4478 ;; Zero extension instructions
4480 (define_insn_and_split "zero_extendditi2"
4481 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4482 (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "rm,r")))]
4485 "&& reload_completed"
4486 [(set (match_dup 3) (match_dup 1))
4487 (set (match_dup 4) (const_int 0))]
4488 "split_double_mode (TImode, &operands[0], 1, &operands[3], &operands[4]);")
4490 (define_expand "zero_extendsidi2"
4491 [(set (match_operand:DI 0 "nonimmediate_operand")
4492 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
4494 (define_insn "*zero_extendsidi2"
4495 [(set (match_operand:DI 0 "nonimmediate_operand"
4496 "=r,?r,?o,r ,o,?*y,?!*y,$r,$v,$x,*x,*v,*r,*k")
4498 (match_operand:SI 1 "x86_64_zext_operand"
4499 "0 ,rm,r ,rmWz,0,r ,m ,v ,r ,m ,*x,*v,*k,*km")))]
4502 switch (get_attr_type (insn))
4505 if (ix86_use_lea_for_mov (insn, operands))
4506 return "lea{l}\t{%E1, %k0|%k0, %E1}";
4508 return "mov{l}\t{%1, %k0|%k0, %1}";
4514 return "movd\t{%1, %0|%0, %1}";
4517 if (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1]))
4519 if (EXT_REX_SSE_REG_P (operands[0])
4520 || EXT_REX_SSE_REG_P (operands[1]))
4521 return "vpmovzxdq\t{%t1, %g0|%g0, %t1}";
4523 return "%vpmovzxdq\t{%1, %0|%0, %1}";
4526 if (GENERAL_REG_P (operands[0]))
4527 return "%vmovd\t{%1, %k0|%k0, %1}";
4529 return "%vmovd\t{%1, %0|%0, %1}";
4532 return "kmovd\t{%1, %k0|%k0, %1}";
4539 (cond [(eq_attr "alternative" "0,1,2")
4540 (const_string "nox64")
4541 (eq_attr "alternative" "3")
4542 (const_string "x64")
4543 (eq_attr "alternative" "7,8,9")
4544 (const_string "sse2")
4545 (eq_attr "alternative" "10")
4546 (const_string "sse4")
4547 (eq_attr "alternative" "11")
4548 (const_string "avx512f")
4549 (eq_attr "alternative" "12")
4550 (const_string "x64_avx512bw")
4551 (eq_attr "alternative" "13")
4552 (const_string "avx512bw_512")
4554 (const_string "*")))
4555 (set (attr "mmx_isa")
4556 (if_then_else (eq_attr "alternative" "5,6")
4557 (const_string "native")
4558 (const_string "*")))
4560 (cond [(eq_attr "alternative" "0,1,2,4")
4561 (const_string "multi")
4562 (eq_attr "alternative" "5,6")
4563 (const_string "mmxmov")
4564 (eq_attr "alternative" "7")
4565 (if_then_else (match_test "TARGET_64BIT")
4566 (const_string "ssemov")
4567 (const_string "multi"))
4568 (eq_attr "alternative" "8,9,10,11")
4569 (const_string "ssemov")
4570 (eq_attr "alternative" "12,13")
4571 (const_string "mskmov")
4573 (const_string "imovx")))
4574 (set (attr "prefix_extra")
4575 (if_then_else (eq_attr "alternative" "10,11")
4577 (const_string "*")))
4578 (set (attr "prefix")
4579 (if_then_else (eq_attr "type" "ssemov")
4580 (const_string "maybe_vex")
4581 (const_string "orig")))
4582 (set (attr "prefix_0f")
4583 (if_then_else (eq_attr "type" "imovx")
4585 (const_string "*")))
4587 (cond [(eq_attr "alternative" "5,6")
4589 (and (eq_attr "alternative" "7")
4590 (match_test "TARGET_64BIT"))
4592 (eq_attr "alternative" "8,10,11")
4595 (const_string "SI")))
4596 (set (attr "preferred_for_speed")
4597 (cond [(eq_attr "alternative" "7")
4598 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4599 (eq_attr "alternative" "5,8")
4600 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4602 (symbol_ref "true")))])
4605 [(set (match_operand:DI 0 "memory_operand")
4606 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
4608 [(set (match_dup 4) (const_int 0))]
4609 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4612 [(set (match_operand:DI 0 "general_reg_operand")
4613 (zero_extend:DI (match_operand:SI 1 "general_reg_operand")))]
4614 "!TARGET_64BIT && reload_completed
4615 && REGNO (operands[0]) == REGNO (operands[1])"
4616 [(set (match_dup 4) (const_int 0))]
4617 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4620 [(set (match_operand:DI 0 "nonimmediate_gr_operand")
4621 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
4622 "!TARGET_64BIT && reload_completed
4623 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
4624 [(set (match_dup 3) (match_dup 1))
4625 (set (match_dup 4) (const_int 0))]
4626 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4628 (define_mode_attr kmov_isa
4629 [(QI "avx512dq") (HI "avx512f") (SI "avx512bw") (DI "avx512bw_512")])
4631 (define_insn "zero_extend<mode>di2"
4632 [(set (match_operand:DI 0 "register_operand" "=r,*r,*k")
4634 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k,*km")))]
4637 movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}
4638 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}
4639 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}"
4640 [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
4641 (set_attr "type" "imovx,mskmov,mskmov")
4642 (set_attr "mode" "SI,<MODE>,<MODE>")])
4644 (define_expand "zero_extend<mode>si2"
4645 [(set (match_operand:SI 0 "register_operand")
4646 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
4649 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4651 operands[1] = force_reg (<MODE>mode, operands[1]);
4652 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
4657 (define_insn_and_split "zero_extend<mode>si2_and"
4658 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
4660 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
4661 (clobber (reg:CC FLAGS_REG))]
4662 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4664 "&& reload_completed"
4665 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
4666 (clobber (reg:CC FLAGS_REG))])]
4668 if (!REG_P (operands[1])
4669 || REGNO (operands[0]) != REGNO (operands[1]))
4671 ix86_expand_clear (operands[0]);
4673 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4674 emit_insn (gen_rtx_SET
4675 (gen_rtx_STRICT_LOW_PART
4676 (VOIDmode, gen_lowpart (<MODE>mode, operands[0])),
4681 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
4683 [(set_attr "type" "alu1")
4684 (set_attr "mode" "SI")])
4686 (define_insn "*zero_extend<mode>si2"
4687 [(set (match_operand:SI 0 "register_operand" "=r,*r,*k")
4689 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k,*km")))]
4690 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4692 movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}
4693 kmov<mskmodesuffix>\t{%1, %0|%0, %1}
4694 kmov<mskmodesuffix>\t{%1, %0|%0, %1}"
4695 [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
4696 (set_attr "type" "imovx,mskmov,mskmov")
4697 (set_attr "mode" "SI,<MODE>,<MODE>")])
4699 (define_expand "zero_extendqihi2"
4700 [(set (match_operand:HI 0 "register_operand")
4701 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
4704 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4706 operands[1] = force_reg (QImode, operands[1]);
4707 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
4712 (define_insn_and_split "zero_extendqihi2_and"
4713 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
4714 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4715 (clobber (reg:CC FLAGS_REG))]
4716 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4718 "&& reload_completed"
4719 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4720 (clobber (reg:CC FLAGS_REG))])]
4722 if (!REG_P (operands[1])
4723 || REGNO (operands[0]) != REGNO (operands[1]))
4725 ix86_expand_clear (operands[0]);
4727 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4728 emit_insn (gen_rtx_SET
4729 (gen_rtx_STRICT_LOW_PART
4730 (VOIDmode, gen_lowpart (QImode, operands[0])),
4735 operands[0] = gen_lowpart (SImode, operands[0]);
4737 [(set_attr "type" "alu1")
4738 (set_attr "mode" "SI")])
4740 ; zero extend to SImode to avoid partial register stalls
4741 (define_insn "*zero_extendqihi2"
4742 [(set (match_operand:HI 0 "register_operand" "=r,*r,*k")
4743 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,*k,*km")))]
4744 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4746 movz{bl|x}\t{%1, %k0|%k0, %1}
4747 kmovb\t{%1, %k0|%k0, %1}
4748 kmovb\t{%1, %0|%0, %1}"
4749 [(set_attr "isa" "*,avx512dq,avx512dq")
4750 (set_attr "type" "imovx,mskmov,mskmov")
4751 (set_attr "mode" "SI,QI,QI")])
4753 ;; Transform xorl; mov[bw] (set strict_low_part) into movz[bw]l.
4755 [(parallel [(set (match_operand:SWI48 0 "general_reg_operand")
4757 (clobber (reg:CC FLAGS_REG))])
4758 (set (strict_low_part (match_operand:SWI12 1 "general_reg_operand"))
4759 (match_operand:SWI12 2 "nonimmediate_operand"))]
4760 "REGNO (operands[0]) == REGNO (operands[1])
4761 && (<SWI48:MODE>mode != SImode
4762 || !TARGET_ZERO_EXTEND_WITH_AND
4763 || !optimize_function_for_speed_p (cfun))"
4764 [(set (match_dup 0) (zero_extend:SWI48 (match_dup 2)))])
4766 ;; Likewise, but preserving FLAGS_REG.
4768 [(set (match_operand:SWI48 0 "general_reg_operand") (const_int 0))
4769 (set (strict_low_part (match_operand:SWI12 1 "general_reg_operand"))
4770 (match_operand:SWI12 2 "nonimmediate_operand"))]
4771 "REGNO (operands[0]) == REGNO (operands[1])
4772 && (<SWI48:MODE>mode != SImode
4773 || !TARGET_ZERO_EXTEND_WITH_AND
4774 || !optimize_function_for_speed_p (cfun))"
4775 [(set (match_dup 0) (zero_extend:SWI48 (match_dup 2)))])
4777 ;; Sign extension instructions
4779 (define_expand "extendsidi2"
4780 [(set (match_operand:DI 0 "register_operand")
4781 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
4786 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
4791 (define_insn "*extendsidi2_rex64"
4792 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4793 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4797 movs{lq|x}\t{%1, %0|%0, %1}"
4798 [(set_attr "type" "imovx")
4799 (set_attr "mode" "DI")
4800 (set_attr "prefix_0f" "0")
4801 (set_attr "modrm" "0,1")])
4803 (define_insn "extendsidi2_1"
4804 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4805 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4806 (clobber (reg:CC FLAGS_REG))
4807 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4811 (define_insn "extendditi2"
4812 [(set (match_operand:TI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4813 (sign_extend:TI (match_operand:DI 1 "register_operand" "0,0,r,r")))
4814 (clobber (reg:CC FLAGS_REG))
4815 (clobber (match_scratch:DI 2 "=X,X,X,&r"))]
4819 ;; Split the memory case. If the source register doesn't die, it will stay
4820 ;; this way, if it does die, following peephole2s take care of it.
4822 [(set (match_operand:<DWI> 0 "memory_operand")
4823 (sign_extend:<DWI> (match_operand:DWIH 1 "register_operand")))
4824 (clobber (reg:CC FLAGS_REG))
4825 (clobber (match_operand:DWIH 2 "register_operand"))]
4829 rtx bits = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
4831 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
4833 emit_move_insn (operands[3], operands[1]);
4835 /* Generate a cltd if possible and doing so it profitable. */
4836 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4837 && REGNO (operands[1]) == AX_REG
4838 && REGNO (operands[2]) == DX_REG)
4840 emit_insn (gen_ashr<mode>3_cvt (operands[2], operands[1], bits));
4844 emit_move_insn (operands[2], operands[1]);
4845 emit_insn (gen_ashr<mode>3_cvt (operands[2], operands[2], bits));
4847 emit_move_insn (operands[4], operands[2]);
4851 ;; Peepholes for the case where the source register does die, after
4852 ;; being split with the above splitter.
4854 [(set (match_operand:DWIH 0 "memory_operand")
4855 (match_operand:DWIH 1 "general_reg_operand"))
4856 (set (match_operand:DWIH 2 "general_reg_operand") (match_dup 1))
4857 (parallel [(set (match_dup 2)
4858 (ashiftrt:DWIH (match_dup 2)
4859 (match_operand 4 "const_int_operand")))
4860 (clobber (reg:CC FLAGS_REG))])
4861 (set (match_operand:DWIH 3 "memory_operand") (match_dup 2))]
4862 "REGNO (operands[1]) != REGNO (operands[2])
4863 && INTVAL (operands[4]) == (<MODE_SIZE> * BITS_PER_UNIT - 1)
4864 && peep2_reg_dead_p (2, operands[1])
4865 && peep2_reg_dead_p (4, operands[2])
4866 && !reg_mentioned_p (operands[2], operands[3])"
4867 [(set (match_dup 0) (match_dup 1))
4868 (parallel [(set (match_dup 1) (ashiftrt:DWIH (match_dup 1) (match_dup 4)))
4869 (clobber (reg:CC FLAGS_REG))])
4870 (set (match_dup 3) (match_dup 1))])
4873 [(set (match_operand:DWIH 0 "memory_operand")
4874 (match_operand:DWIH 1 "general_reg_operand"))
4875 (parallel [(set (match_operand:DWIH 2 "general_reg_operand")
4876 (ashiftrt:DWIH (match_dup 1)
4877 (match_operand 4 "const_int_operand")))
4878 (clobber (reg:CC FLAGS_REG))])
4879 (set (match_operand:DWIH 3 "memory_operand") (match_dup 2))]
4880 "/* cltd is shorter than sarl $31, %eax */
4881 !optimize_function_for_size_p (cfun)
4882 && REGNO (operands[1]) == AX_REG
4883 && REGNO (operands[2]) == DX_REG
4884 && INTVAL (operands[4]) == (<MODE_SIZE> * BITS_PER_UNIT - 1)
4885 && peep2_reg_dead_p (2, operands[1])
4886 && peep2_reg_dead_p (3, operands[2])
4887 && !reg_mentioned_p (operands[2], operands[3])"
4888 [(set (match_dup 0) (match_dup 1))
4889 (parallel [(set (match_dup 1) (ashiftrt:DWIH (match_dup 1) (match_dup 4)))
4890 (clobber (reg:CC FLAGS_REG))])
4891 (set (match_dup 3) (match_dup 1))])
4893 ;; Extend to register case. Optimize case where source and destination
4894 ;; registers match and cases where we can use cltd.
4896 [(set (match_operand:<DWI> 0 "register_operand")
4897 (sign_extend:<DWI> (match_operand:DWIH 1 "register_operand")))
4898 (clobber (reg:CC FLAGS_REG))
4899 (clobber (match_scratch:DWIH 2))]
4903 rtx bits = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
4905 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
4907 if (REGNO (operands[3]) != REGNO (operands[1]))
4908 emit_move_insn (operands[3], operands[1]);
4910 rtx src = operands[1];
4911 if (REGNO (operands[3]) == AX_REG)
4914 /* Generate a cltd if possible and doing so it profitable. */
4915 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4916 && REGNO (src) == AX_REG
4917 && REGNO (operands[4]) == DX_REG)
4919 emit_insn (gen_ashr<mode>3_cvt (operands[4], src, bits));
4923 if (REGNO (operands[4]) != REGNO (operands[1]))
4924 emit_move_insn (operands[4], operands[1]);
4926 emit_insn (gen_ashr<mode>3_cvt (operands[4], operands[4], bits));
4930 (define_insn "extend<mode>di2"
4931 [(set (match_operand:DI 0 "register_operand" "=r")
4933 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4935 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
4936 [(set_attr "type" "imovx")
4937 (set_attr "mode" "DI")])
4939 (define_insn "extendhisi2"
4940 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4941 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4944 switch (get_attr_prefix_0f (insn))
4947 return "{cwtl|cwde}";
4949 return "movs{wl|x}\t{%1, %0|%0, %1}";
4952 [(set_attr "type" "imovx")
4953 (set_attr "mode" "SI")
4954 (set (attr "prefix_0f")
4955 ;; movsx is short decodable while cwtl is vector decoded.
4956 (if_then_else (and (eq_attr "cpu" "!k6")
4957 (eq_attr "alternative" "0"))
4959 (const_string "1")))
4960 (set (attr "znver1_decode")
4961 (if_then_else (eq_attr "prefix_0f" "0")
4962 (const_string "double")
4963 (const_string "direct")))
4965 (if_then_else (eq_attr "prefix_0f" "0")
4967 (const_string "1")))])
4969 (define_insn "*extendhisi2_zext"
4970 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4973 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4976 switch (get_attr_prefix_0f (insn))
4979 return "{cwtl|cwde}";
4981 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4984 [(set_attr "type" "imovx")
4985 (set_attr "mode" "SI")
4986 (set (attr "prefix_0f")
4987 ;; movsx is short decodable while cwtl is vector decoded.
4988 (if_then_else (and (eq_attr "cpu" "!k6")
4989 (eq_attr "alternative" "0"))
4991 (const_string "1")))
4993 (if_then_else (eq_attr "prefix_0f" "0")
4995 (const_string "1")))])
4997 (define_insn "extendqisi2"
4998 [(set (match_operand:SI 0 "register_operand" "=r")
4999 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
5001 "movs{bl|x}\t{%1, %0|%0, %1}"
5002 [(set_attr "type" "imovx")
5003 (set_attr "mode" "SI")])
5005 (define_insn "*extendqisi2_zext"
5006 [(set (match_operand:DI 0 "register_operand" "=r")
5008 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
5010 "movs{bl|x}\t{%1, %k0|%k0, %1}"
5011 [(set_attr "type" "imovx")
5012 (set_attr "mode" "SI")])
5014 (define_insn "extendqihi2"
5015 [(set (match_operand:HI 0 "register_operand" "=*a,r")
5016 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
5019 switch (get_attr_prefix_0f (insn))
5022 return "{cbtw|cbw}";
5024 return "movs{bw|x}\t{%1, %0|%0, %1}";
5027 [(set_attr "type" "imovx")
5028 (set_attr "mode" "HI")
5029 (set (attr "prefix_0f")
5030 ;; movsx is short decodable while cwtl is vector decoded.
5031 (if_then_else (and (eq_attr "cpu" "!k6")
5032 (eq_attr "alternative" "0"))
5034 (const_string "1")))
5036 (if_then_else (eq_attr "prefix_0f" "0")
5038 (const_string "1")))])
5040 (define_insn "*extendqi<SWI24:mode>_ext_1"
5041 [(set (match_operand:SWI24 0 "register_operand" "=R")
5044 (match_operator:SWI248 2 "extract_operator"
5045 [(match_operand 1 "int248_register_operand" "Q")
5047 (const_int 8)]) 0)))]
5049 "movs{b<SWI24:imodesuffix>|x}\t{%h1, %0|%0, %h1}"
5050 [(set_attr "type" "imovx")
5051 (set_attr "mode" "<SWI24:MODE>")])
5053 ;; Conversions between float and double.
5055 ;; These are all no-ops in the model used for the 80387.
5056 ;; So just emit moves.
5058 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
5060 [(set (match_operand:DF 0 "push_operand")
5061 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
5063 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
5064 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
5067 [(set (match_operand:XF 0 "push_operand")
5068 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
5070 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
5071 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
5072 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
5074 (define_expand "extendsfdf2"
5075 [(set (match_operand:DF 0 "nonimm_ssenomem_operand")
5076 (float_extend:DF (match_operand:SF 1 "general_operand")))]
5077 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5079 /* ??? Needed for compress_float_constant since all fp constants
5080 are TARGET_LEGITIMATE_CONSTANT_P. */
5081 if (CONST_DOUBLE_P (operands[1]))
5083 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
5084 && standard_80387_constant_p (operands[1]) > 0)
5086 operands[1] = simplify_const_unary_operation
5087 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
5088 emit_move_insn_1 (operands[0], operands[1]);
5091 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
5095 (define_insn "*extendsfdf2"
5096 [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v,v")
5098 (match_operand:SF 1 "nonimmediate_operand" "fm,f,v,m")))]
5099 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5101 switch (which_alternative)
5105 return output_387_reg_move (insn, operands);
5108 return "%vcvtss2sd\t{%d1, %0|%0, %d1}";
5110 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
5116 [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
5117 (set_attr "avx_partial_xmm_update" "false,false,false,true")
5118 (set_attr "prefix" "orig,orig,maybe_vex,maybe_vex")
5119 (set_attr "mode" "SF,XF,DF,DF")
5120 (set (attr "enabled")
5122 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
5124 (eq_attr "alternative" "0,1")
5125 (symbol_ref "TARGET_MIX_SSE_I387")
5126 (symbol_ref "true"))
5128 (eq_attr "alternative" "0,1")
5130 (symbol_ref "false"))))])
5132 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
5134 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
5136 We do the conversion post reload to avoid producing of 128bit spills
5137 that might lead to ICE on 32bit target. The sequence unlikely combine
5140 [(set (match_operand:DF 0 "sse_reg_operand")
5142 (match_operand:SF 1 "nonimmediate_operand")))]
5143 "TARGET_USE_VECTOR_FP_CONVERTS
5144 && optimize_insn_for_speed_p ()
5146 && (!EXT_REX_SSE_REG_P (operands[0])
5147 || TARGET_AVX512VL || TARGET_EVEX512)"
5152 (parallel [(const_int 0) (const_int 1)]))))]
5154 operands[2] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5155 operands[3] = lowpart_subreg (V4SFmode, operands[0], DFmode);
5156 /* Use movss for loading from memory, unpcklps reg, reg for registers.
5157 Try to avoid move when unpacking can be done in source. */
5158 if (REG_P (operands[1]))
5160 /* If it is unsafe to overwrite upper half of source, we need
5161 to move to destination and unpack there. */
5162 if (REGNO (operands[0]) != REGNO (operands[1])
5163 || (EXT_REX_SSE_REG_P (operands[1])
5164 && !TARGET_AVX512VL))
5166 rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode);
5167 emit_move_insn (tmp, operands[1]);
5170 operands[3] = lowpart_subreg (V4SFmode, operands[1], SFmode);
5171 /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
5172 =v, v, then vbroadcastss will be only needed for AVX512F without
5174 if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3])))
5175 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
5179 rtx tmp = lowpart_subreg (V16SFmode, operands[3], V4SFmode);
5180 emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
5184 emit_insn (gen_vec_setv4sf_0 (operands[3],
5185 CONST0_RTX (V4SFmode), operands[1]));
5188 ;; It's more profitable to split and then extend in the same register.
5190 [(set (match_operand:DF 0 "sse_reg_operand")
5192 (match_operand:SF 1 "memory_operand")))]
5193 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
5194 && optimize_insn_for_speed_p ()"
5195 [(set (match_dup 2) (match_dup 1))
5196 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
5197 "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);")
5199 ;; Break partial SSE register dependency stall. This splitter should split
5200 ;; late in the pass sequence (after register rename pass), so allocated
5201 ;; registers won't change anymore
5204 [(set (match_operand:DF 0 "sse_reg_operand")
5206 (match_operand:SF 1 "nonimmediate_operand")))]
5208 && TARGET_SSE_PARTIAL_REG_FP_CONVERTS_DEPENDENCY
5209 && epilogue_completed
5210 && optimize_function_for_speed_p (cfun)
5211 && (!REG_P (operands[1])
5212 || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
5213 && (!EXT_REX_SSE_REG_P (operands[0])
5214 || TARGET_AVX512VL)"
5223 operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5224 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5227 (define_expand "extendhfsf2"
5228 [(set (match_operand:SF 0 "register_operand")
5230 (match_operand:HF 1 "nonimmediate_operand")))]
5231 "TARGET_AVX512FP16 || TARGET_F16C || TARGET_AVX512VL"
5233 if (!TARGET_AVX512FP16)
5235 rtx res = gen_reg_rtx (V4SFmode);
5236 rtx tmp = gen_reg_rtx (V8HFmode);
5237 rtx zero = force_reg (V8HFmode, CONST0_RTX (V8HFmode));
5239 emit_insn (gen_vec_setv8hf_0 (tmp, zero, operands[1]));
5240 emit_insn (gen_vcvtph2ps (res, gen_lowpart (V8HImode, tmp)));
5241 emit_move_insn (operands[0], gen_lowpart (SFmode, res));
5246 (define_expand "extendhfdf2"
5247 [(set (match_operand:DF 0 "register_operand")
5249 (match_operand:HF 1 "nonimmediate_operand")))]
5250 "TARGET_AVX512FP16")
5252 (define_insn "*extendhf<mode>2"
5253 [(set (match_operand:MODEF 0 "register_operand" "=v")
5255 (match_operand:HF 1 "nonimmediate_operand" "vm")))]
5257 "vcvtsh2<ssemodesuffix>\t{%1, %0, %0|%0, %0, %1}"
5258 [(set_attr "type" "ssecvt")
5259 (set_attr "prefix" "evex")
5260 (set_attr "mode" "<MODE>")])
5262 (define_expand "extendbfsf2"
5263 [(set (match_operand:SF 0 "register_operand")
5265 [(match_operand:BF 1 "register_operand")]
5267 "TARGET_SSE2 && !HONOR_NANS (BFmode)")
5269 ;; Don't use float_extend since psrlld doesn't raise
5270 ;; exceptions and turn a sNaN into a qNaN.
5271 (define_insn "extendbfsf2_1"
5272 [(set (match_operand:SF 0 "register_operand" "=x,Yv,v")
5274 [(match_operand:BF 1 "register_operand" " 0,Yv,v")]
5278 pslld\t{$16, %0|%0, 16}
5279 vpslld\t{$16, %1, %0|%0, %1, 16}
5280 vpslld\t{$16, %g1, %g0|%g0, %g1, 16}"
5281 [(set_attr "isa" "noavx,avx,*")
5282 (set_attr "type" "sseishft1")
5283 (set_attr "length_immediate" "1")
5284 (set_attr "prefix_data16" "1,*,*")
5285 (set_attr "prefix" "orig,maybe_evex,evex")
5286 (set_attr "mode" "TI,TI,XI")
5287 (set_attr "memory" "none")
5288 (set (attr "enabled")
5289 (if_then_else (eq_attr "alternative" "2")
5290 (symbol_ref "TARGET_AVX512F && TARGET_EVEX512
5291 && !TARGET_AVX512VL && !TARGET_PREFER_AVX256")
5292 (const_string "*")))])
5294 (define_expand "extend<mode>xf2"
5295 [(set (match_operand:XF 0 "nonimmediate_operand")
5296 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
5299 /* ??? Needed for compress_float_constant since all fp constants
5300 are TARGET_LEGITIMATE_CONSTANT_P. */
5301 if (CONST_DOUBLE_P (operands[1]))
5303 if (standard_80387_constant_p (operands[1]) > 0)
5305 operands[1] = simplify_const_unary_operation
5306 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
5307 emit_move_insn_1 (operands[0], operands[1]);
5310 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
5314 (define_insn "*extend<mode>xf2_i387"
5315 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
5317 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
5319 "* return output_387_reg_move (insn, operands);"
5320 [(set_attr "type" "fmov")
5321 (set_attr "mode" "<MODE>,XF")])
5323 ;; %%% This seems like bad news.
5324 ;; This cannot output into an f-reg because there is no way to be sure
5325 ;; of truncating in that case. Otherwise this is just like a simple move
5326 ;; insn. So we pretend we can output to a reg in order to get better
5327 ;; register preferencing, but we really use a stack slot.
5329 ;; Conversion from DFmode to SFmode.
5331 (define_insn "truncdfsf2"
5332 [(set (match_operand:SF 0 "nonimm_ssenomem_operand" "=m,f,v,v")
5334 (match_operand:DF 1 "register_ssemem_operand" "f,f,v,m")))]
5335 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5337 switch (which_alternative)
5341 return output_387_reg_move (insn, operands);
5344 return "%vcvtsd2ss\t{%d1, %0|%0, %d1}";
5346 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
5352 [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
5353 (set_attr "avx_partial_xmm_update" "false,false,false,true")
5354 (set_attr "mode" "SF")
5355 (set (attr "enabled")
5357 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
5358 (cond [(eq_attr "alternative" "0")
5359 (symbol_ref "TARGET_MIX_SSE_I387")
5360 (eq_attr "alternative" "1")
5361 (symbol_ref "TARGET_MIX_SSE_I387
5362 && flag_unsafe_math_optimizations")
5364 (symbol_ref "true"))
5365 (cond [(eq_attr "alternative" "0")
5367 (eq_attr "alternative" "1")
5368 (symbol_ref "flag_unsafe_math_optimizations")
5370 (symbol_ref "false"))))])
5372 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
5374 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
5376 We do the conversion post reload to avoid producing of 128bit spills
5377 that might lead to ICE on 32bit target. The sequence unlikely combine
5380 [(set (match_operand:SF 0 "sse_reg_operand")
5382 (match_operand:DF 1 "nonimmediate_operand")))]
5383 "TARGET_USE_VECTOR_FP_CONVERTS
5384 && optimize_insn_for_speed_p ()
5386 && (!EXT_REX_SSE_REG_P (operands[0])
5387 || TARGET_AVX512VL)"
5390 (float_truncate:V2SF
5394 operands[2] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5395 operands[3] = CONST0_RTX (V2SFmode);
5396 operands[4] = lowpart_subreg (V2DFmode, operands[0], SFmode);
5397 /* Use movsd for loading from memory, unpcklpd for registers.
5398 Try to avoid move when unpacking can be done in source, or SSE3
5399 movddup is available. */
5400 if (REG_P (operands[1]))
5402 if ((!TARGET_SSE3 && REGNO (operands[0]) != REGNO (operands[1]))
5403 || (EXT_REX_SSE_REG_P (operands[1]) && !TARGET_AVX512VL))
5405 rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode);
5406 emit_move_insn (tmp, operands[1]);
5409 else if (!TARGET_SSE3)
5410 operands[4] = lowpart_subreg (V2DFmode, operands[1], DFmode);
5411 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
5414 emit_insn (gen_vec_concatv2df (operands[4], operands[1],
5415 CONST0_RTX (DFmode)));
5418 ;; It's more profitable to split and then truncate in the same register.
5420 [(set (match_operand:SF 0 "sse_reg_operand")
5422 (match_operand:DF 1 "memory_operand")))]
5423 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
5424 && optimize_insn_for_speed_p ()"
5425 [(set (match_dup 2) (match_dup 1))
5426 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
5427 "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
5429 ;; Break partial SSE register dependency stall. This splitter should split
5430 ;; late in the pass sequence (after register rename pass), so allocated
5431 ;; registers won't change anymore
5434 [(set (match_operand:SF 0 "sse_reg_operand")
5436 (match_operand:DF 1 "nonimmediate_operand")))]
5438 && TARGET_SSE_PARTIAL_REG_FP_CONVERTS_DEPENDENCY
5439 && epilogue_completed
5440 && optimize_function_for_speed_p (cfun)
5441 && (!REG_P (operands[1])
5442 || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
5443 && (!EXT_REX_SSE_REG_P (operands[0])
5444 || TARGET_AVX512VL)"
5453 operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5454 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5457 ;; Conversion from XFmode to {SF,DF}mode
5459 (define_insn "truncxf<mode>2"
5460 [(set (match_operand:MODEF 0 "nonimmediate_operand" "=m,f")
5461 (float_truncate:MODEF
5462 (match_operand:XF 1 "register_operand" "f,f")))]
5464 "* return output_387_reg_move (insn, operands);"
5465 [(set_attr "type" "fmov")
5466 (set_attr "mode" "<MODE>")
5467 (set (attr "enabled")
5468 (cond [(eq_attr "alternative" "1")
5469 (symbol_ref "flag_unsafe_math_optimizations")
5471 (symbol_ref "true")))])
5473 ;; Conversion from {SF,DF}mode to HFmode.
5475 (define_expand "truncsfhf2"
5476 [(set (match_operand:HF 0 "register_operand")
5478 (match_operand:SF 1 "nonimmediate_operand")))]
5479 "TARGET_AVX512FP16 || TARGET_F16C || TARGET_AVX512VL"
5481 if (!TARGET_AVX512FP16)
5483 rtx res = gen_reg_rtx (V8HFmode);
5484 rtx tmp = gen_reg_rtx (V4SFmode);
5485 rtx zero = force_reg (V4SFmode, CONST0_RTX (V4SFmode));
5487 emit_insn (gen_vec_setv4sf_0 (tmp, zero, operands[1]));
5488 emit_insn (gen_vcvtps2ph (gen_lowpart (V8HImode, res), tmp, GEN_INT (4)));
5489 emit_move_insn (operands[0], gen_lowpart (HFmode, res));
5494 (define_expand "truncdfhf2"
5495 [(set (match_operand:HF 0 "register_operand")
5497 (match_operand:DF 1 "nonimmediate_operand")))]
5498 "TARGET_AVX512FP16")
5500 (define_insn "*trunc<mode>hf2"
5501 [(set (match_operand:HF 0 "register_operand" "=v")
5503 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5505 "vcvt<ssemodesuffix>2sh\t{%1, %d0|%d0, %1}"
5506 [(set_attr "type" "ssecvt")
5507 (set_attr "prefix" "evex")
5508 (set_attr "mode" "HF")])
5510 (define_insn "truncsfbf2"
5511 [(set (match_operand:BF 0 "register_operand" "=x, v")
5513 (match_operand:SF 1 "register_operand" "x,v")))]
5514 "((TARGET_AVX512BF16 && TARGET_AVX512VL) || TARGET_AVXNECONVERT)
5515 && !HONOR_NANS (BFmode) && flag_unsafe_math_optimizations"
5517 %{vex%} vcvtneps2bf16\t{%1, %0|%0, %1}
5518 vcvtneps2bf16\t{%1, %0|%0, %1}"
5519 [(set_attr "isa" "avxneconvert,avx512bf16vl")
5520 (set_attr "prefix" "vex,evex")])
5522 ;; Signed conversion to DImode.
5524 (define_expand "fix_truncxfdi2"
5525 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
5526 (fix:DI (match_operand:XF 1 "register_operand")))
5527 (clobber (reg:CC FLAGS_REG))])]
5532 emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
5537 (define_expand "fix_trunc<mode>di2"
5538 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
5539 (fix:DI (match_operand:MODEF 1 "register_operand")))
5540 (clobber (reg:CC FLAGS_REG))])]
5541 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
5544 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
5546 emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
5549 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
5551 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
5552 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
5553 if (out != operands[0])
5554 emit_move_insn (operands[0], out);
5559 (define_insn "fix<fixunssuffix>_trunchf<mode>2"
5560 [(set (match_operand:SWI48 0 "register_operand" "=r")
5562 (match_operand:HF 1 "nonimmediate_operand" "vm")))]
5564 "vcvttsh2<fixsuffix>si\t{%1, %0|%0, %1}"
5565 [(set_attr "type" "sseicvt")
5566 (set_attr "prefix" "evex")
5567 (set_attr "mode" "<MODE>")])
5569 ;; Signed conversion to SImode.
5571 (define_expand "fix_truncxfsi2"
5572 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
5573 (fix:SI (match_operand:XF 1 "register_operand")))
5574 (clobber (reg:CC FLAGS_REG))])]
5579 emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
5584 (define_expand "fix_trunc<mode>si2"
5585 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
5586 (fix:SI (match_operand:MODEF 1 "register_operand")))
5587 (clobber (reg:CC FLAGS_REG))])]
5588 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
5591 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
5593 emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
5596 if (SSE_FLOAT_MODE_P (<MODE>mode))
5598 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
5599 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
5600 if (out != operands[0])
5601 emit_move_insn (operands[0], out);
5606 ;; Signed conversion to HImode.
5608 (define_expand "fix_trunc<mode>hi2"
5609 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
5610 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
5611 (clobber (reg:CC FLAGS_REG))])]
5613 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
5617 emit_insn (gen_fix_trunchi_i387_fisttp (operands[0], operands[1]));
5622 ;; Unsigned conversion to DImode
5624 (define_insn "fixuns_trunc<mode>di2"
5625 [(set (match_operand:DI 0 "register_operand" "=r")
5627 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5628 "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
5629 "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
5630 [(set_attr "type" "sseicvt")
5631 (set_attr "prefix" "evex")
5632 (set_attr "mode" "DI")])
5634 ;; Unsigned conversion to SImode.
5636 (define_expand "fixuns_trunc<mode>si2"
5638 [(set (match_operand:SI 0 "register_operand")
5640 (match_operand:MODEF 1 "nonimmediate_operand")))
5642 (clobber (scratch:<ssevecmode>))
5643 (clobber (scratch:<ssevecmode>))])]
5644 "(!TARGET_64BIT || TARGET_AVX512F) && TARGET_SSE2 && TARGET_SSE_MATH"
5646 machine_mode mode = <MODE>mode;
5647 machine_mode vecmode = <ssevecmode>mode;
5648 REAL_VALUE_TYPE TWO31r;
5653 emit_insn (gen_fixuns_trunc<mode>si2_avx512f (operands[0], operands[1]));
5657 if (optimize_insn_for_size_p ())
5660 real_ldexp (&TWO31r, &dconst1, 31);
5661 two31 = const_double_from_real_value (TWO31r, mode);
5662 two31 = ix86_build_const_vector (vecmode, true, two31);
5663 operands[2] = force_reg (vecmode, two31);
5666 (define_insn "fixuns_trunc<mode>si2_avx512f"
5667 [(set (match_operand:SI 0 "register_operand" "=r")
5669 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5670 "TARGET_AVX512F && TARGET_SSE_MATH"
5671 "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
5672 [(set_attr "type" "sseicvt")
5673 (set_attr "prefix" "evex")
5674 (set_attr "mode" "SI")])
5676 (define_insn "*fixuns_trunchfsi2zext"
5677 [(set (match_operand:DI 0 "register_operand" "=r")
5680 (match_operand:HF 1 "nonimmediate_operand" "vm"))))]
5681 "TARGET_64BIT && TARGET_AVX512FP16"
5682 "vcvttsh2usi\t{%1, %k0|%k0, %1}"
5683 [(set_attr "type" "sseicvt")
5684 (set_attr "prefix" "evex")
5685 (set_attr "mode" "SI")])
5687 (define_insn "*fixuns_trunc<mode>si2_avx512f_zext"
5688 [(set (match_operand:DI 0 "register_operand" "=r")
5691 (match_operand:MODEF 1 "nonimmediate_operand" "vm"))))]
5692 "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
5693 "vcvtt<ssemodesuffix>2usi\t{%1, %k0|%k0, %1}"
5694 [(set_attr "type" "sseicvt")
5695 (set_attr "prefix" "evex")
5696 (set_attr "mode" "SI")])
5698 (define_insn_and_split "*fixuns_trunc<mode>_1"
5699 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
5701 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
5702 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
5703 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
5704 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
5705 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5706 && optimize_function_for_speed_p (cfun)"
5708 "&& reload_completed"
5711 ix86_split_convert_uns_si_sse (operands);
5715 ;; Unsigned conversion to HImode.
5716 ;; Without these patterns, we'll try the unsigned SI conversion which
5717 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
5719 (define_expand "fixuns_trunchfhi2"
5721 (fix:SI (match_operand:HF 1 "nonimmediate_operand")))
5722 (set (match_operand:HI 0 "nonimmediate_operand")
5723 (subreg:HI (match_dup 2) 0))]
5725 "operands[2] = gen_reg_rtx (SImode);")
5727 (define_expand "fixuns_trunc<mode>hi2"
5729 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
5730 (set (match_operand:HI 0 "nonimmediate_operand")
5731 (subreg:HI (match_dup 2) 0))]
5732 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
5733 "operands[2] = gen_reg_rtx (SImode);")
5735 ;; When SSE is available, it is always faster to use it!
5736 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
5737 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
5738 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
5739 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5740 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
5741 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
5742 [(set_attr "type" "sseicvt")
5743 (set_attr "prefix" "maybe_vex")
5744 (set (attr "prefix_rex")
5746 (match_test "<SWI48:MODE>mode == DImode")
5748 (const_string "*")))
5749 (set_attr "mode" "<MODEF:MODE>")
5750 (set_attr "athlon_decode" "double,vector")
5751 (set_attr "amdfam10_decode" "double,double")
5752 (set_attr "bdver1_decode" "double,double")])
5754 ;; Avoid vector decoded forms of the instruction.
5756 [(match_scratch:MODEF 2 "x")
5757 (set (match_operand:SWI48 0 "register_operand")
5758 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
5759 "TARGET_AVOID_VECTOR_DECODE
5760 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5761 && optimize_insn_for_speed_p ()"
5762 [(set (match_dup 2) (match_dup 1))
5763 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
5765 (define_insn "fix_trunc<mode>_i387_fisttp"
5766 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m")
5767 (fix:SWI248x (match_operand 1 "register_operand" "f")))
5768 (clobber (match_scratch:XF 2 "=&f"))]
5769 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5771 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5772 && (TARGET_64BIT || <MODE>mode != DImode))
5773 && TARGET_SSE_MATH)"
5774 "* return output_fix_trunc (insn, operands, true);"
5775 [(set_attr "type" "fisttp")
5776 (set_attr "mode" "<MODE>")])
5778 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5779 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5780 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5781 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5782 ;; function in i386.cc.
5783 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5784 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
5785 (fix:SWI248x (match_operand 1 "register_operand")))
5786 (clobber (reg:CC FLAGS_REG))]
5787 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5789 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5790 && (TARGET_64BIT || <MODE>mode != DImode))
5791 && ix86_pre_reload_split ()"
5796 ix86_optimize_mode_switching[I387_TRUNC] = 1;
5798 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5799 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5801 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5802 operands[2], operands[3]));
5805 [(set_attr "type" "fistp")
5806 (set_attr "i387_cw" "trunc")
5807 (set_attr "mode" "<MODE>")])
5809 (define_insn "fix_truncdi_i387"
5810 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
5811 (fix:DI (match_operand 1 "register_operand" "f")))
5812 (use (match_operand:HI 2 "memory_operand" "m"))
5813 (use (match_operand:HI 3 "memory_operand" "m"))
5814 (clobber (match_scratch:XF 4 "=&f"))]
5815 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5817 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5818 "* return output_fix_trunc (insn, operands, false);"
5819 [(set_attr "type" "fistp")
5820 (set_attr "i387_cw" "trunc")
5821 (set_attr "mode" "DI")])
5823 (define_insn "fix_trunc<mode>_i387"
5824 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
5825 (fix:SWI24 (match_operand 1 "register_operand" "f")))
5826 (use (match_operand:HI 2 "memory_operand" "m"))
5827 (use (match_operand:HI 3 "memory_operand" "m"))]
5828 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5830 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5831 "* return output_fix_trunc (insn, operands, false);"
5832 [(set_attr "type" "fistp")
5833 (set_attr "i387_cw" "trunc")
5834 (set_attr "mode" "<MODE>")])
5836 (define_insn "x86_fnstcw_1"
5837 [(set (match_operand:HI 0 "memory_operand" "=m")
5838 (unspec:HI [(const_int 0)] UNSPEC_FSTCW))]
5841 [(set (attr "length")
5842 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5843 (set_attr "mode" "HI")
5844 (set_attr "unit" "i387")
5845 (set_attr "bdver1_decode" "vector")])
5847 ;; Conversion between fixed point and floating point.
5849 ;; Even though we only accept memory inputs, the backend _really_
5850 ;; wants to be able to do this between registers. Thankfully, LRA
5851 ;; will fix this up for us during register allocation.
5853 (define_insn "floathi<mode>2"
5854 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5855 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
5857 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5858 || TARGET_MIX_SSE_I387)"
5860 [(set_attr "type" "fmov")
5861 (set_attr "mode" "<MODE>")
5862 (set_attr "znver1_decode" "double")
5863 (set_attr "fp_int_src" "true")])
5865 (define_insn "float<SWI48x:mode>xf2"
5866 [(set (match_operand:XF 0 "register_operand" "=f")
5867 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5870 [(set_attr "type" "fmov")
5871 (set_attr "mode" "XF")
5872 (set_attr "znver1_decode" "double")
5873 (set_attr "fp_int_src" "true")])
5875 (define_expand "float<SWI48x:mode><MODEF:mode>2"
5876 [(set (match_operand:MODEF 0 "register_operand")
5877 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand")))]
5878 "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode))
5879 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5880 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT))")
5882 (define_insn "*float<SWI48:mode><MODEF:mode>2"
5883 [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
5885 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
5886 "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
5887 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
5890 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
5891 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5892 [(set_attr "type" "fmov,sseicvt,sseicvt")
5893 (set_attr "avx_partial_xmm_update" "false,true,true")
5894 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5895 (set_attr "mode" "<MODEF:MODE>")
5896 (set (attr "prefix_rex")
5898 (and (eq_attr "prefix" "maybe_vex")
5899 (match_test "<SWI48:MODE>mode == DImode"))
5901 (const_string "*")))
5902 (set_attr "unit" "i387,*,*")
5903 (set_attr "athlon_decode" "*,double,direct")
5904 (set_attr "amdfam10_decode" "*,vector,double")
5905 (set_attr "bdver1_decode" "*,double,direct")
5906 (set_attr "znver1_decode" "double,*,*")
5907 (set_attr "fp_int_src" "true")
5908 (set (attr "enabled")
5910 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
5912 (eq_attr "alternative" "0")
5913 (symbol_ref "TARGET_MIX_SSE_I387
5914 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
5916 (symbol_ref "true"))
5918 (eq_attr "alternative" "0")
5920 (symbol_ref "false"))))
5921 (set (attr "preferred_for_speed")
5922 (cond [(eq_attr "alternative" "1")
5923 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
5924 (symbol_ref "true")))])
5926 (define_insn "float<floatunssuffix><mode>hf2"
5927 [(set (match_operand:HF 0 "register_operand" "=v")
5929 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
5931 "vcvt<floatsuffix>si2sh<rex64suffix>\t{%1, %d0|%d0, %1}"
5932 [(set_attr "type" "sseicvt")
5933 (set_attr "prefix" "evex")
5934 (set_attr "mode" "HF")])
5936 (define_insn "*floatdi<MODEF:mode>2_i387"
5937 [(set (match_operand:MODEF 0 "register_operand" "=f")
5938 (float:MODEF (match_operand:DI 1 "nonimmediate_operand" "m")))]
5940 && TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, DImode)"
5942 [(set_attr "type" "fmov")
5943 (set_attr "mode" "<MODEF:MODE>")
5944 (set_attr "znver1_decode" "double")
5945 (set_attr "fp_int_src" "true")])
5947 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
5948 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
5949 ;; alternative in sse2_loadld.
5951 [(set (match_operand:MODEF 0 "sse_reg_operand")
5952 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5954 && TARGET_USE_VECTOR_CONVERTS
5955 && optimize_function_for_speed_p (cfun)
5957 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
5958 && (!EXT_REX_SSE_REG_P (operands[0])
5959 || TARGET_AVX512VL)"
5962 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode);
5963 operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode);
5965 emit_insn (gen_sse2_loadld (operands[4],
5966 CONST0_RTX (V4SImode), operands[1]));
5968 if (<ssevecmode>mode == V4SFmode)
5969 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5971 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5975 ;; Avoid store forwarding (partial memory) stall penalty
5976 ;; by passing DImode value through XMM registers. */
5979 [(set (match_operand:X87MODEF 0 "register_operand")
5981 (match_operand:DI 1 "register_operand")))]
5982 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
5983 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5984 && TARGET_SSE2 && optimize_function_for_speed_p (cfun)
5985 && can_create_pseudo_p ()"
5988 rtx s = assign_386_stack_local (DImode, SLOT_FLOATxFDI_387);
5989 emit_insn (gen_floatdi<mode>2_i387_with_xmm (operands[0], operands[1], s));
5993 (define_insn_and_split "floatdi<X87MODEF:mode>2_i387_with_xmm"
5994 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5996 (match_operand:DI 1 "register_operand" "r,r")))
5997 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5998 (clobber (match_scratch:V4SI 3 "=x,x"))
5999 (clobber (match_scratch:V4SI 4 "=X,x"))]
6000 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
6001 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6002 && TARGET_SSE2 && optimize_function_for_speed_p (cfun)"
6004 "&& reload_completed"
6005 [(set (match_dup 2) (match_dup 3))
6006 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
6008 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
6009 Assemble the 64-bit DImode value in an xmm register. */
6010 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
6011 gen_lowpart (SImode, operands[1])));
6013 emit_insn (gen_sse4_1_pinsrd (operands[3], operands[3],
6014 gen_highpart (SImode, operands[1]),
6018 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
6019 gen_highpart (SImode, operands[1])));
6020 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
6023 operands[3] = gen_lowpart (DImode, operands[3]);
6025 [(set_attr "isa" "sse4,*")
6026 (set_attr "type" "multi")
6027 (set_attr "mode" "<X87MODEF:MODE>")
6028 (set_attr "unit" "i387")
6029 (set_attr "fp_int_src" "true")])
6031 ;; Break partial SSE register dependency stall. This splitter should split
6032 ;; late in the pass sequence (after register rename pass), so allocated
6033 ;; registers won't change anymore
6036 [(set (match_operand:MODEF 0 "sse_reg_operand")
6037 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
6039 && TARGET_SSE_PARTIAL_REG_CONVERTS_DEPENDENCY
6040 && epilogue_completed
6041 && optimize_function_for_speed_p (cfun)
6042 && (!EXT_REX_SSE_REG_P (operands[0])
6043 || TARGET_AVX512VL)"
6045 (vec_merge:<MODEF:ssevecmode>
6046 (vec_duplicate:<MODEF:ssevecmode>
6052 const machine_mode vmode = <MODEF:ssevecmode>mode;
6054 operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode);
6055 emit_move_insn (operands[0], CONST0_RTX (vmode));
6058 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
6059 [(set (match_operand:MODEF 0 "register_operand")
6060 (unsigned_float:MODEF
6061 (match_operand:SWI12 1 "nonimmediate_operand")))]
6063 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
6065 operands[1] = convert_to_mode (SImode, operands[1], 1);
6066 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
6070 (define_insn "*floatuns<SWI48:mode><MODEF:mode>2_avx512"
6071 [(set (match_operand:MODEF 0 "register_operand" "=v")
6072 (unsigned_float:MODEF
6073 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
6074 "TARGET_AVX512F && TARGET_SSE_MATH"
6075 "vcvtusi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %0, %0|%0, %0, %1}"
6076 [(set_attr "type" "sseicvt")
6077 (set_attr "avx_partial_xmm_update" "true")
6078 (set_attr "prefix" "evex")
6079 (set_attr "mode" "<MODEF:MODE>")])
6081 ;; Avoid store forwarding (partial memory) stall penalty by extending
6082 ;; SImode value to DImode through XMM register instead of pushing two
6083 ;; SImode values to stack. Also note that fild loads from memory only.
6085 (define_insn_and_split "floatunssi<mode>2_i387_with_xmm"
6086 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
6087 (unsigned_float:X87MODEF
6088 (match_operand:SI 1 "nonimmediate_operand" "rm")))
6089 (clobber (match_operand:DI 2 "memory_operand" "=m"))
6090 (clobber (match_scratch:DI 3 "=x"))]
6092 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6093 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
6095 "&& reload_completed"
6096 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
6097 (set (match_dup 2) (match_dup 3))
6099 (float:X87MODEF (match_dup 2)))]
6101 [(set_attr "type" "multi")
6102 (set_attr "mode" "<MODE>")])
6104 (define_expand "floatunssi<mode>2"
6105 [(set (match_operand:X87MODEF 0 "register_operand")
6106 (unsigned_float:X87MODEF
6107 (match_operand:SI 1 "nonimmediate_operand")))]
6109 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6110 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
6111 || ((!TARGET_64BIT || TARGET_AVX512F)
6112 && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
6114 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
6116 emit_insn (gen_floatunssi<mode>2_i387_with_xmm
6117 (operands[0], operands[1],
6118 assign_386_stack_local (DImode, SLOT_TEMP)));
6121 if (!TARGET_AVX512F)
6123 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
6128 (define_expand "floatunsdisf2"
6129 [(set (match_operand:SF 0 "register_operand")
6131 (match_operand:DI 1 "nonimmediate_operand")))]
6132 "TARGET_64BIT && TARGET_SSE && TARGET_SSE_MATH"
6134 if (!TARGET_AVX512F)
6136 x86_emit_floatuns (operands);
6141 (define_expand "floatunsdidf2"
6142 [(set (match_operand:DF 0 "register_operand")
6144 (match_operand:DI 1 "nonimmediate_operand")))]
6145 "((TARGET_64BIT && TARGET_AVX512F)
6146 || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
6147 && TARGET_SSE2 && TARGET_SSE_MATH"
6151 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
6154 if (!TARGET_AVX512F)
6156 x86_emit_floatuns (operands);
6161 ;; Load effective address instructions
6163 (define_insn "*lea<mode>"
6164 [(set (match_operand:SWI48 0 "register_operand" "=r")
6165 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
6166 "ix86_hardreg_mov_ok (operands[0], operands[1])"
6168 if (SImode_address_operand (operands[1], VOIDmode))
6170 gcc_assert (TARGET_64BIT);
6171 return "lea{l}\t{%E1, %k0|%k0, %E1}";
6174 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
6176 [(set_attr "type" "lea")
6179 (match_operand 1 "SImode_address_operand")
6181 (const_string "<MODE>")))])
6184 [(set (match_operand:SWI48 0 "register_operand")
6185 (match_operand:SWI48 1 "address_no_seg_operand"))]
6186 "ix86_hardreg_mov_ok (operands[0], operands[1])
6187 && peep2_regno_dead_p (0, FLAGS_REG)
6188 && ix86_avoid_lea_for_addr (peep2_next_insn (0), operands)"
6191 machine_mode mode = <MODE>mode;
6193 /* Emit all operations in SImode for zero-extended addresses. */
6194 if (SImode_address_operand (operands[1], VOIDmode))
6197 ix86_split_lea_for_addr (peep2_next_insn (0), operands, mode);
6199 /* Zero-extend return register to DImode for zero-extended addresses. */
6200 if (mode != <MODE>mode)
6201 emit_insn (gen_zero_extendsidi2 (operands[0],
6202 gen_lowpart (mode, operands[0])));
6207 ;; ix86_split_lea_for_addr emits the shifts as MULT to avoid it from being
6208 ;; peephole2 optimized back into a lea. Split that into the shift during
6209 ;; the following split pass.
6211 [(set (match_operand:SWI48 0 "general_reg_operand")
6212 (mult:SWI48 (match_dup 0) (match_operand:SWI48 1 "const1248_operand")))
6213 (clobber (reg:CC FLAGS_REG))]
6215 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
6216 (clobber (reg:CC FLAGS_REG))])]
6217 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
6221 (define_expand "add<mode>3"
6222 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6223 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6224 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
6226 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
6228 (define_insn_and_split "*add<dwi>3_doubleword"
6229 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
6231 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
6232 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
6233 (clobber (reg:CC FLAGS_REG))]
6234 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
6236 "&& reload_completed"
6237 [(parallel [(set (reg:CCC FLAGS_REG)
6239 (plus:DWIH (match_dup 1) (match_dup 2))
6242 (plus:DWIH (match_dup 1) (match_dup 2)))])
6243 (parallel [(set (match_dup 3)
6246 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6249 (clobber (reg:CC FLAGS_REG))])]
6251 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6252 if (operands[2] == const0_rtx)
6254 if (operands[5] != const0_rtx)
6255 ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]);
6256 else if (!rtx_equal_p (operands[3], operands[4]))
6257 emit_move_insn (operands[3], operands[4]);
6259 emit_note (NOTE_INSN_DELETED);
6264 (define_insn_and_split "*add<dwi>3_doubleword_zext"
6265 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6268 (match_operand:DWIH 2 "nonimmediate_operand" "rm,r"))
6269 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")))
6270 (clobber (reg:CC FLAGS_REG))]
6271 "ix86_binary_operator_ok (UNKNOWN, <DWI>mode, operands)"
6273 "&& reload_completed"
6274 [(parallel [(set (reg:CCC FLAGS_REG)
6276 (plus:DWIH (match_dup 1) (match_dup 2))
6279 (plus:DWIH (match_dup 1) (match_dup 2)))])
6280 (parallel [(set (match_dup 3)
6283 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6286 (clobber (reg:CC FLAGS_REG))])]
6287 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[3]);")
6289 (define_insn_and_split "*add<dwi>3_doubleword_concat"
6290 [(set (match_operand:<DWI> 0 "register_operand" "=&r")
6295 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))
6296 (match_operand:QI 3 "const_int_operand"))
6298 (match_operand:DWIH 4 "nonimmediate_operand" "rm")))
6299 (match_operand:<DWI> 1 "register_operand" "0")))
6300 (clobber (reg:CC FLAGS_REG))]
6301 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
6303 "&& reload_completed"
6304 [(parallel [(set (reg:CCC FLAGS_REG)
6306 (plus:DWIH (match_dup 1) (match_dup 4))
6309 (plus:DWIH (match_dup 1) (match_dup 4)))])
6310 (parallel [(set (match_dup 5)
6313 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6316 (clobber (reg:CC FLAGS_REG))])]
6317 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[5]);")
6319 (define_insn_and_split "*add<dwi>3_doubleword_concat_zext"
6320 [(set (match_operand:<DWI> 0 "register_operand" "=&r")
6325 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))
6326 (match_operand:QI 3 "const_int_operand"))
6328 (match_operand:DWIH 4 "nonimmediate_operand" "rm")))
6330 (match_operand:DWIH 1 "nonimmediate_operand" "rm"))))
6331 (clobber (reg:CC FLAGS_REG))]
6332 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
6334 "&& reload_completed"
6335 [(set (match_dup 0) (match_dup 4))
6336 (set (match_dup 5) (match_dup 2))
6337 (parallel [(set (reg:CCC FLAGS_REG)
6339 (plus:DWIH (match_dup 0) (match_dup 1))
6342 (plus:DWIH (match_dup 0) (match_dup 1)))])
6343 (parallel [(set (match_dup 5)
6346 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6349 (clobber (reg:CC FLAGS_REG))])]
6350 "split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[5]);")
6352 (define_insn "*add<mode>_1"
6353 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,r")
6355 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
6356 (match_operand:SWI48 2 "x86_64_general_operand" "re,BM,0,le")))
6357 (clobber (reg:CC FLAGS_REG))]
6358 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6360 switch (get_attr_type (insn))
6366 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6367 if (operands[2] == const1_rtx)
6368 return "inc{<imodesuffix>}\t%0";
6371 gcc_assert (operands[2] == constm1_rtx);
6372 return "dec{<imodesuffix>}\t%0";
6376 /* For most processors, ADD is faster than LEA. This alternative
6377 was added to use ADD as much as possible. */
6378 if (which_alternative == 2)
6379 std::swap (operands[1], operands[2]);
6381 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6382 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6383 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6385 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6389 (cond [(eq_attr "alternative" "3")
6390 (const_string "lea")
6391 (match_operand:SWI48 2 "incdec_operand")
6392 (const_string "incdec")
6394 (const_string "alu")))
6395 (set (attr "length_immediate")
6397 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6399 (const_string "*")))
6400 (set_attr "mode" "<MODE>")])
6402 ;; It may seem that nonimmediate operand is proper one for operand 1.
6403 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6404 ;; we take care in ix86_binary_operator_ok to not allow two memory
6405 ;; operands so proper swapping will be done in reload. This allow
6406 ;; patterns constructed from addsi_1 to match.
6408 (define_insn "addsi_1_zext"
6409 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6411 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
6412 (match_operand:SI 2 "x86_64_general_operand" "rBMe,0,le"))))
6413 (clobber (reg:CC FLAGS_REG))]
6414 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6416 switch (get_attr_type (insn))
6422 if (operands[2] == const1_rtx)
6423 return "inc{l}\t%k0";
6426 gcc_assert (operands[2] == constm1_rtx);
6427 return "dec{l}\t%k0";
6431 /* For most processors, ADD is faster than LEA. This alternative
6432 was added to use ADD as much as possible. */
6433 if (which_alternative == 1)
6434 std::swap (operands[1], operands[2]);
6436 if (x86_maybe_negate_const_int (&operands[2], SImode))
6437 return "sub{l}\t{%2, %k0|%k0, %2}";
6439 return "add{l}\t{%2, %k0|%k0, %2}";
6443 (cond [(eq_attr "alternative" "2")
6444 (const_string "lea")
6445 (match_operand:SI 2 "incdec_operand")
6446 (const_string "incdec")
6448 (const_string "alu")))
6449 (set (attr "length_immediate")
6451 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6453 (const_string "*")))
6454 (set_attr "mode" "SI")])
6456 (define_insn "*addhi_1"
6457 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
6458 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
6459 (match_operand:HI 2 "general_operand" "rn,m,0,ln")))
6460 (clobber (reg:CC FLAGS_REG))]
6461 "ix86_binary_operator_ok (PLUS, HImode, operands)"
6463 switch (get_attr_type (insn))
6469 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6470 if (operands[2] == const1_rtx)
6471 return "inc{w}\t%0";
6474 gcc_assert (operands[2] == constm1_rtx);
6475 return "dec{w}\t%0";
6479 /* For most processors, ADD is faster than LEA. This alternative
6480 was added to use ADD as much as possible. */
6481 if (which_alternative == 2)
6482 std::swap (operands[1], operands[2]);
6484 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6485 if (x86_maybe_negate_const_int (&operands[2], HImode))
6486 return "sub{w}\t{%2, %0|%0, %2}";
6488 return "add{w}\t{%2, %0|%0, %2}";
6492 (cond [(eq_attr "alternative" "3")
6493 (const_string "lea")
6494 (match_operand:HI 2 "incdec_operand")
6495 (const_string "incdec")
6497 (const_string "alu")))
6498 (set (attr "length_immediate")
6500 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6502 (const_string "*")))
6503 (set_attr "mode" "HI,HI,HI,SI")])
6505 (define_insn "*addqi_1"
6506 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
6507 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
6508 (match_operand:QI 2 "general_operand" "qn,m,0,rn,0,ln")))
6509 (clobber (reg:CC FLAGS_REG))]
6510 "ix86_binary_operator_ok (PLUS, QImode, operands)"
6512 bool widen = (get_attr_mode (insn) != MODE_QI);
6514 switch (get_attr_type (insn))
6520 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6521 if (operands[2] == const1_rtx)
6522 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6525 gcc_assert (operands[2] == constm1_rtx);
6526 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6530 /* For most processors, ADD is faster than LEA. These alternatives
6531 were added to use ADD as much as possible. */
6532 if (which_alternative == 2 || which_alternative == 4)
6533 std::swap (operands[1], operands[2]);
6535 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6536 if (x86_maybe_negate_const_int (&operands[2], QImode))
6539 return "sub{l}\t{%2, %k0|%k0, %2}";
6541 return "sub{b}\t{%2, %0|%0, %2}";
6544 return "add{l}\t{%k2, %k0|%k0, %k2}";
6546 return "add{b}\t{%2, %0|%0, %2}";
6550 (cond [(eq_attr "alternative" "5")
6551 (const_string "lea")
6552 (match_operand:QI 2 "incdec_operand")
6553 (const_string "incdec")
6555 (const_string "alu")))
6556 (set (attr "length_immediate")
6558 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6560 (const_string "*")))
6561 (set_attr "mode" "QI,QI,QI,SI,SI,SI")
6562 ;; Potential partial reg stall on alternatives 3 and 4.
6563 (set (attr "preferred_for_speed")
6564 (cond [(eq_attr "alternative" "3,4")
6565 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
6566 (symbol_ref "true")))])
6568 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
6569 (define_insn_and_split "*add<mode>_1_slp"
6570 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
6571 (plus:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0,!<r>")
6572 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
6573 (clobber (reg:CC FLAGS_REG))]
6574 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6576 if (which_alternative)
6579 switch (get_attr_type (insn))
6582 if (operands[2] == const1_rtx)
6583 return "inc{<imodesuffix>}\t%0";
6586 gcc_assert (operands[2] == constm1_rtx);
6587 return "dec{<imodesuffix>}\t%0";
6591 if (x86_maybe_negate_const_int (&operands[2], QImode))
6592 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6594 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6597 "&& reload_completed"
6598 [(set (strict_low_part (match_dup 0)) (match_dup 1))
6600 [(set (strict_low_part (match_dup 0))
6601 (plus:SWI12 (match_dup 0) (match_dup 2)))
6602 (clobber (reg:CC FLAGS_REG))])]
6605 (if_then_else (match_operand:QI 2 "incdec_operand")
6606 (const_string "incdec")
6607 (const_string "alu")))
6608 (set_attr "mode" "<MODE>")])
6610 ;; Split non destructive adds if we cannot use lea.
6612 [(set (match_operand:SWI48 0 "register_operand")
6613 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
6614 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
6615 (clobber (reg:CC FLAGS_REG))]
6616 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
6617 [(set (match_dup 0) (match_dup 1))
6618 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
6619 (clobber (reg:CC FLAGS_REG))])])
6621 ;; Split non destructive adds if we cannot use lea.
6623 [(set (match_operand:DI 0 "register_operand")
6625 (plus:SI (match_operand:SI 1 "register_operand")
6626 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
6627 (clobber (reg:CC FLAGS_REG))]
6629 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
6630 [(set (match_dup 3) (match_dup 1))
6631 (parallel [(set (match_dup 0)
6632 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
6633 (clobber (reg:CC FLAGS_REG))])]
6634 "operands[3] = gen_lowpart (SImode, operands[0]);")
6636 ;; Convert add to the lea pattern to avoid flags dependency.
6638 [(set (match_operand:SWI 0 "register_operand")
6639 (plus:SWI (match_operand:SWI 1 "register_operand")
6640 (match_operand:SWI 2 "<nonmemory_operand>")))
6641 (clobber (reg:CC FLAGS_REG))]
6642 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
6644 (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
6646 if (<MODE>mode != <LEAMODE>mode)
6648 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
6649 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
6650 operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
6654 ;; Convert add to the lea pattern to avoid flags dependency.
6656 [(set (match_operand:DI 0 "register_operand")
6658 (plus:SI (match_operand:SI 1 "register_operand")
6659 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
6660 (clobber (reg:CC FLAGS_REG))]
6661 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
6663 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
6665 (define_insn "*add<mode>_2"
6666 [(set (reg FLAGS_REG)
6669 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
6670 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,0"))
6672 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,<r>")
6673 (plus:SWI (match_dup 1) (match_dup 2)))]
6674 "ix86_match_ccmode (insn, CCGOCmode)
6675 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6677 switch (get_attr_type (insn))
6680 if (operands[2] == const1_rtx)
6681 return "inc{<imodesuffix>}\t%0";
6684 gcc_assert (operands[2] == constm1_rtx);
6685 return "dec{<imodesuffix>}\t%0";
6689 if (which_alternative == 2)
6690 std::swap (operands[1], operands[2]);
6692 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6693 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6694 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6696 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6700 (if_then_else (match_operand:SWI 2 "incdec_operand")
6701 (const_string "incdec")
6702 (const_string "alu")))
6703 (set (attr "length_immediate")
6705 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6707 (const_string "*")))
6708 (set_attr "mode" "<MODE>")])
6710 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6711 (define_insn "*addsi_2_zext"
6712 [(set (reg FLAGS_REG)
6714 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6715 (match_operand:SI 2 "x86_64_general_operand" "rBMe,0"))
6717 (set (match_operand:DI 0 "register_operand" "=r,r")
6718 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6719 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6720 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6722 switch (get_attr_type (insn))
6725 if (operands[2] == const1_rtx)
6726 return "inc{l}\t%k0";
6729 gcc_assert (operands[2] == constm1_rtx);
6730 return "dec{l}\t%k0";
6734 if (which_alternative == 1)
6735 std::swap (operands[1], operands[2]);
6737 if (x86_maybe_negate_const_int (&operands[2], SImode))
6738 return "sub{l}\t{%2, %k0|%k0, %2}";
6740 return "add{l}\t{%2, %k0|%k0, %2}";
6744 (if_then_else (match_operand:SI 2 "incdec_operand")
6745 (const_string "incdec")
6746 (const_string "alu")))
6747 (set (attr "length_immediate")
6749 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6751 (const_string "*")))
6752 (set_attr "mode" "SI")])
6754 (define_insn "*add<mode>_3"
6755 [(set (reg FLAGS_REG)
6757 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6758 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
6759 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6760 "ix86_match_ccmode (insn, CCZmode)
6761 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6763 switch (get_attr_type (insn))
6766 if (operands[2] == const1_rtx)
6767 return "inc{<imodesuffix>}\t%0";
6770 gcc_assert (operands[2] == constm1_rtx);
6771 return "dec{<imodesuffix>}\t%0";
6775 if (which_alternative == 1)
6776 std::swap (operands[1], operands[2]);
6778 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6779 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6780 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6782 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6786 (if_then_else (match_operand:SWI 2 "incdec_operand")
6787 (const_string "incdec")
6788 (const_string "alu")))
6789 (set (attr "length_immediate")
6791 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6793 (const_string "*")))
6794 (set_attr "mode" "<MODE>")])
6796 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6797 (define_insn "*addsi_3_zext"
6798 [(set (reg FLAGS_REG)
6800 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rBMe,0"))
6801 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
6802 (set (match_operand:DI 0 "register_operand" "=r,r")
6803 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6804 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6805 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6807 switch (get_attr_type (insn))
6810 if (operands[2] == const1_rtx)
6811 return "inc{l}\t%k0";
6814 gcc_assert (operands[2] == constm1_rtx);
6815 return "dec{l}\t%k0";
6819 if (which_alternative == 1)
6820 std::swap (operands[1], operands[2]);
6822 if (x86_maybe_negate_const_int (&operands[2], SImode))
6823 return "sub{l}\t{%2, %k0|%k0, %2}";
6825 return "add{l}\t{%2, %k0|%k0, %2}";
6829 (if_then_else (match_operand:SI 2 "incdec_operand")
6830 (const_string "incdec")
6831 (const_string "alu")))
6832 (set (attr "length_immediate")
6834 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6836 (const_string "*")))
6837 (set_attr "mode" "SI")])
6839 ; For comparisons against 1, -1 and 128, we may generate better code
6840 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6841 ; is matched then. We can't accept general immediate, because for
6842 ; case of overflows, the result is messed up.
6843 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6844 ; only for comparisons not depending on it.
6846 (define_insn "*adddi_4"
6847 [(set (reg FLAGS_REG)
6849 (match_operand:DI 1 "nonimmediate_operand" "0")
6850 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6851 (clobber (match_scratch:DI 0 "=r"))]
6853 && ix86_match_ccmode (insn, CCGCmode)"
6855 switch (get_attr_type (insn))
6858 if (operands[2] == constm1_rtx)
6859 return "inc{q}\t%0";
6862 gcc_assert (operands[2] == const1_rtx);
6863 return "dec{q}\t%0";
6867 if (x86_maybe_negate_const_int (&operands[2], DImode))
6868 return "add{q}\t{%2, %0|%0, %2}";
6870 return "sub{q}\t{%2, %0|%0, %2}";
6874 (if_then_else (match_operand:DI 2 "incdec_operand")
6875 (const_string "incdec")
6876 (const_string "alu")))
6877 (set (attr "length_immediate")
6879 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6881 (const_string "*")))
6882 (set_attr "mode" "DI")])
6884 ; For comparisons against 1, -1 and 128, we may generate better code
6885 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6886 ; is matched then. We can't accept general immediate, because for
6887 ; case of overflows, the result is messed up.
6888 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6889 ; only for comparisons not depending on it.
6891 (define_insn "*add<mode>_4"
6892 [(set (reg FLAGS_REG)
6894 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6895 (match_operand:SWI124 2 "const_int_operand")))
6896 (clobber (match_scratch:SWI124 0 "=<r>"))]
6897 "ix86_match_ccmode (insn, CCGCmode)"
6899 switch (get_attr_type (insn))
6902 if (operands[2] == constm1_rtx)
6903 return "inc{<imodesuffix>}\t%0";
6906 gcc_assert (operands[2] == const1_rtx);
6907 return "dec{<imodesuffix>}\t%0";
6911 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6912 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6914 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6918 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6919 (const_string "incdec")
6920 (const_string "alu")))
6921 (set (attr "length_immediate")
6923 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6925 (const_string "*")))
6926 (set_attr "mode" "<MODE>")])
6928 (define_insn "*add<mode>_5"
6929 [(set (reg FLAGS_REG)
6932 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6933 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6935 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6936 "ix86_match_ccmode (insn, CCGOCmode)
6937 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6939 switch (get_attr_type (insn))
6942 if (operands[2] == const1_rtx)
6943 return "inc{<imodesuffix>}\t%0";
6946 gcc_assert (operands[2] == constm1_rtx);
6947 return "dec{<imodesuffix>}\t%0";
6951 if (which_alternative == 1)
6952 std::swap (operands[1], operands[2]);
6954 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6955 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6956 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6958 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6962 (if_then_else (match_operand:SWI 2 "incdec_operand")
6963 (const_string "incdec")
6964 (const_string "alu")))
6965 (set (attr "length_immediate")
6967 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6969 (const_string "*")))
6970 (set_attr "mode" "<MODE>")])
6972 (define_insn "*addqi_ext<mode>_0"
6973 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn")
6976 (match_operator:SWI248 3 "extract_operator"
6977 [(match_operand 2 "int248_register_operand" "Q")
6980 (match_operand:QI 1 "nonimmediate_operand" "0")))
6981 (clobber (reg:CC FLAGS_REG))]
6983 "add{b}\t{%h2, %0|%0, %h2}"
6984 [(set_attr "addr" "gpr8")
6985 (set_attr "type" "alu")
6986 (set_attr "mode" "QI")])
6988 (define_expand "addqi_ext_1"
6990 [(set (zero_extract:HI (match_operand:HI 0 "register_operand")
6996 (zero_extract:HI (match_operand:HI 1 "register_operand")
6999 (match_operand:QI 2 "const_int_operand")) 0))
7000 (clobber (reg:CC FLAGS_REG))])])
7002 (define_insn "*addqi_ext<mode>_1"
7003 [(set (zero_extract:SWI248
7004 (match_operand 0 "int248_register_operand" "+Q")
7010 (match_operator:SWI248 3 "extract_operator"
7011 [(match_operand 1 "int248_register_operand" "0")
7014 (match_operand:QI 2 "general_operand" "QnBn")) 0))
7015 (clobber (reg:CC FLAGS_REG))]
7016 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
7017 rtx_equal_p (operands[0], operands[1])"
7019 switch (get_attr_type (insn))
7022 if (operands[2] == const1_rtx)
7023 return "inc{b}\t%h0";
7026 gcc_assert (operands[2] == constm1_rtx);
7027 return "dec{b}\t%h0";
7031 return "add{b}\t{%2, %h0|%h0, %2}";
7034 [(set_attr "addr" "gpr8")
7036 (if_then_else (match_operand:QI 2 "incdec_operand")
7037 (const_string "incdec")
7038 (const_string "alu")))
7039 (set_attr "mode" "QI")])
7041 (define_insn "*addqi_ext<mode>_2"
7042 [(set (zero_extract:SWI248
7043 (match_operand 0 "int248_register_operand" "+Q")
7049 (match_operator:SWI248 3 "extract_operator"
7050 [(match_operand 1 "int248_register_operand" "%0")
7054 (match_operator:SWI248 4 "extract_operator"
7055 [(match_operand 2 "int248_register_operand" "Q")
7057 (const_int 8)]) 0)) 0))
7058 (clobber (reg:CC FLAGS_REG))]
7059 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
7060 rtx_equal_p (operands[0], operands[1])
7061 || rtx_equal_p (operands[0], operands[2])"
7062 "add{b}\t{%h2, %h0|%h0, %h2}"
7063 [(set_attr "type" "alu")
7064 (set_attr "mode" "QI")])
7066 ;; Like DWI, but use POImode instead of OImode.
7067 (define_mode_attr DPWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI") (TI "POI")])
7069 ;; Add with jump on overflow.
7070 (define_expand "addv<mode>4"
7071 [(parallel [(set (reg:CCO FLAGS_REG)
7075 (match_operand:SWIDWI 1 "nonimmediate_operand"))
7078 (plus:SWIDWI (match_dup 1)
7079 (match_operand:SWIDWI 2
7080 "<general_hilo_operand>")))))
7081 (set (match_operand:SWIDWI 0 "register_operand")
7082 (plus:SWIDWI (match_dup 1) (match_dup 2)))])
7083 (set (pc) (if_then_else
7084 (eq (reg:CCO FLAGS_REG) (const_int 0))
7085 (label_ref (match_operand 3))
7089 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
7090 if (CONST_SCALAR_INT_P (operands[2]))
7091 operands[4] = operands[2];
7093 operands[4] = gen_rtx_SIGN_EXTEND (<DPWI>mode, operands[2]);
7096 (define_insn "*addv<mode>4"
7097 [(set (reg:CCO FLAGS_REG)
7100 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
7102 (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m")))
7104 (plus:SWI (match_dup 1) (match_dup 2)))))
7105 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7106 (plus:SWI (match_dup 1) (match_dup 2)))]
7107 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7108 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7109 [(set_attr "type" "alu")
7110 (set_attr "mode" "<MODE>")])
7112 (define_insn "addv<mode>4_1"
7113 [(set (reg:CCO FLAGS_REG)
7116 (match_operand:SWI 1 "nonimmediate_operand" "0"))
7117 (match_operand:<DWI> 3 "const_int_operand"))
7121 (match_operand:SWI 2 "x86_64_immediate_operand" "<i>")))))
7122 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
7123 (plus:SWI (match_dup 1) (match_dup 2)))]
7124 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
7125 && CONST_INT_P (operands[2])
7126 && INTVAL (operands[2]) == INTVAL (operands[3])"
7127 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7128 [(set_attr "type" "alu")
7129 (set_attr "mode" "<MODE>")
7130 (set (attr "length_immediate")
7131 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7133 (match_test "<MODE_SIZE> == 8")
7135 (const_string "<MODE_SIZE>")))])
7137 ;; Quad word integer modes as mode attribute.
7138 (define_mode_attr QPWI [(SI "TI") (DI "POI")])
7140 (define_insn_and_split "*addv<dwi>4_doubleword"
7141 [(set (reg:CCO FLAGS_REG)
7145 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0"))
7147 (match_operand:<DWI> 2 "nonimmediate_operand" "r,o")))
7149 (plus:<DWI> (match_dup 1) (match_dup 2)))))
7150 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
7151 (plus:<DWI> (match_dup 1) (match_dup 2)))]
7152 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
7154 "&& reload_completed"
7155 [(parallel [(set (reg:CCC FLAGS_REG)
7157 (plus:DWIH (match_dup 1) (match_dup 2))
7160 (plus:DWIH (match_dup 1) (match_dup 2)))])
7161 (parallel [(set (reg:CCO FLAGS_REG)
7165 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7166 (sign_extend:<DWI> (match_dup 4)))
7167 (sign_extend:<DWI> (match_dup 5)))
7171 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7177 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7181 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7184 (define_insn_and_split "*addv<dwi>4_doubleword_1"
7185 [(set (reg:CCO FLAGS_REG)
7189 (match_operand:<DWI> 1 "nonimmediate_operand" "%0"))
7190 (match_operand:<QPWI> 3 "const_scalar_int_operand" "n"))
7194 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>")))))
7195 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
7196 (plus:<DWI> (match_dup 1) (match_dup 2)))]
7197 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)
7198 && CONST_SCALAR_INT_P (operands[2])
7199 && rtx_equal_p (operands[2], operands[3])"
7201 "&& reload_completed"
7202 [(parallel [(set (reg:CCC FLAGS_REG)
7204 (plus:DWIH (match_dup 1) (match_dup 2))
7207 (plus:DWIH (match_dup 1) (match_dup 2)))])
7208 (parallel [(set (reg:CCO FLAGS_REG)
7212 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7213 (sign_extend:<DWI> (match_dup 4)))
7218 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7224 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7228 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7229 if (operands[2] == const0_rtx)
7231 emit_insn (gen_addv<mode>4_1 (operands[3], operands[4], operands[5],
7237 (define_insn "*addv<mode>4_overflow_1"
7238 [(set (reg:CCO FLAGS_REG)
7242 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7243 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7245 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")))
7247 (match_operand:SWI 2 "<general_sext_operand>" "rWe,m")))
7251 (match_operator:SWI 5 "ix86_carry_flag_operator"
7252 [(match_dup 3) (const_int 0)])
7255 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r")
7258 (match_op_dup 5 [(match_dup 3) (const_int 0)])
7261 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7262 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
7263 [(set_attr "type" "alu")
7264 (set_attr "mode" "<MODE>")])
7266 (define_insn "*addv<mode>4_overflow_2"
7267 [(set (reg:CCO FLAGS_REG)
7271 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7272 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7274 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
7275 (match_operand:<DWI> 6 "const_int_operand" "n"))
7279 (match_operator:SWI 5 "ix86_carry_flag_operator"
7280 [(match_dup 3) (const_int 0)])
7282 (match_operand:SWI 2 "x86_64_immediate_operand" "e")))))
7283 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm")
7286 (match_op_dup 5 [(match_dup 3) (const_int 0)])
7289 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
7290 && CONST_INT_P (operands[2])
7291 && INTVAL (operands[2]) == INTVAL (operands[6])"
7292 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
7293 [(set_attr "type" "alu")
7294 (set_attr "mode" "<MODE>")
7295 (set (attr "length_immediate")
7296 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7298 (const_string "4")))])
7300 (define_expand "uaddv<mode>4"
7301 [(parallel [(set (reg:CCC FLAGS_REG)
7304 (match_operand:SWIDWI 1 "nonimmediate_operand")
7305 (match_operand:SWIDWI 2 "<general_hilo_operand>"))
7307 (set (match_operand:SWIDWI 0 "register_operand")
7308 (plus:SWIDWI (match_dup 1) (match_dup 2)))])
7309 (set (pc) (if_then_else
7310 (ltu (reg:CCC FLAGS_REG) (const_int 0))
7311 (label_ref (match_operand 3))
7314 "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
7316 ;; The lea patterns for modes less than 32 bits need to be matched by
7317 ;; several insns converted to real lea by splitters.
7319 (define_insn_and_split "*lea<mode>_general_1"
7320 [(set (match_operand:SWI12 0 "register_operand" "=r")
7322 (plus:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7323 (match_operand:SWI12 2 "register_operand" "r"))
7324 (match_operand:SWI12 3 "immediate_operand" "i")))]
7325 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7327 "&& reload_completed"
7330 (plus:SI (match_dup 1) (match_dup 2))
7333 operands[0] = gen_lowpart (SImode, operands[0]);
7334 operands[1] = gen_lowpart (SImode, operands[1]);
7335 operands[2] = gen_lowpart (SImode, operands[2]);
7336 operands[3] = gen_lowpart (SImode, operands[3]);
7338 [(set_attr "type" "lea")
7339 (set_attr "mode" "SI")])
7341 (define_insn_and_split "*lea<mode>_general_2"
7342 [(set (match_operand:SWI12 0 "register_operand" "=r")
7344 (mult:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7345 (match_operand 2 "const248_operand" "n"))
7346 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
7347 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7349 "&& reload_completed"
7352 (mult:SI (match_dup 1) (match_dup 2))
7355 operands[0] = gen_lowpart (SImode, operands[0]);
7356 operands[1] = gen_lowpart (SImode, operands[1]);
7357 operands[3] = gen_lowpart (SImode, operands[3]);
7359 [(set_attr "type" "lea")
7360 (set_attr "mode" "SI")])
7362 (define_insn_and_split "*lea<mode>_general_2b"
7363 [(set (match_operand:SWI12 0 "register_operand" "=r")
7365 (ashift:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7366 (match_operand 2 "const123_operand" "n"))
7367 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
7368 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7370 "&& reload_completed"
7373 (ashift:SI (match_dup 1) (match_dup 2))
7376 operands[0] = gen_lowpart (SImode, operands[0]);
7377 operands[1] = gen_lowpart (SImode, operands[1]);
7378 operands[3] = gen_lowpart (SImode, operands[3]);
7380 [(set_attr "type" "lea")
7381 (set_attr "mode" "SI")])
7383 (define_insn_and_split "*lea<mode>_general_3"
7384 [(set (match_operand:SWI12 0 "register_operand" "=r")
7387 (mult:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7388 (match_operand 2 "const248_operand" "n"))
7389 (match_operand:SWI12 3 "register_operand" "r"))
7390 (match_operand:SWI12 4 "immediate_operand" "i")))]
7391 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7393 "&& reload_completed"
7397 (mult:SI (match_dup 1) (match_dup 2))
7401 operands[0] = gen_lowpart (SImode, operands[0]);
7402 operands[1] = gen_lowpart (SImode, operands[1]);
7403 operands[3] = gen_lowpart (SImode, operands[3]);
7404 operands[4] = gen_lowpart (SImode, operands[4]);
7406 [(set_attr "type" "lea")
7407 (set_attr "mode" "SI")])
7409 (define_insn_and_split "*lea<mode>_general_3b"
7410 [(set (match_operand:SWI12 0 "register_operand" "=r")
7413 (ashift:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7414 (match_operand 2 "const123_operand" "n"))
7415 (match_operand:SWI12 3 "register_operand" "r"))
7416 (match_operand:SWI12 4 "immediate_operand" "i")))]
7417 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7419 "&& reload_completed"
7423 (ashift:SI (match_dup 1) (match_dup 2))
7427 operands[0] = gen_lowpart (SImode, operands[0]);
7428 operands[1] = gen_lowpart (SImode, operands[1]);
7429 operands[3] = gen_lowpart (SImode, operands[3]);
7430 operands[4] = gen_lowpart (SImode, operands[4]);
7432 [(set_attr "type" "lea")
7433 (set_attr "mode" "SI")])
7435 (define_insn_and_split "*lea<mode>_general_4"
7436 [(set (match_operand:SWI12 0 "register_operand" "=r")
7439 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7440 (match_operand 2 "const_0_to_3_operand"))
7441 (match_operand 3 "const_int_operand")))]
7442 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7443 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
7444 < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
7446 "&& reload_completed"
7449 (mult:SI (match_dup 1) (match_dup 2))
7452 operands[0] = gen_lowpart (SImode, operands[0]);
7453 operands[1] = gen_lowpart (SImode, operands[1]);
7454 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
7456 [(set_attr "type" "lea")
7457 (set_attr "mode" "SI")])
7459 (define_insn_and_split "*lea<mode>_general_4"
7460 [(set (match_operand:SWI48 0 "register_operand" "=r")
7463 (match_operand:SWI48 1 "register_no_SP_operand" "l")
7464 (match_operand 2 "const_0_to_3_operand"))
7465 (match_operand 3 "const_int_operand")))]
7466 "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
7467 < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
7469 "&& reload_completed"
7472 (mult:SWI48 (match_dup 1) (match_dup 2))
7474 "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
7475 [(set_attr "type" "lea")
7476 (set_attr "mode" "<MODE>")])
7478 ;; Subtract instructions
7480 (define_expand "sub<mode>3"
7481 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
7482 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
7483 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
7485 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
7487 (define_insn_and_split "*sub<dwi>3_doubleword"
7488 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
7490 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7491 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
7492 (clobber (reg:CC FLAGS_REG))]
7493 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7495 "&& reload_completed"
7496 [(parallel [(set (reg:CC FLAGS_REG)
7497 (compare:CC (match_dup 1) (match_dup 2)))
7499 (minus:DWIH (match_dup 1) (match_dup 2)))])
7500 (parallel [(set (match_dup 3)
7504 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7506 (clobber (reg:CC FLAGS_REG))])]
7508 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7509 if (operands[2] == const0_rtx)
7511 ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
7516 (define_insn_and_split "*sub<dwi>3_doubleword_zext"
7517 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
7519 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7521 (match_operand:DWIH 2 "nonimmediate_operand" "rm,r"))))
7522 (clobber (reg:CC FLAGS_REG))]
7523 "ix86_binary_operator_ok (UNKNOWN, <DWI>mode, operands)"
7525 "&& reload_completed"
7526 [(parallel [(set (reg:CC FLAGS_REG)
7527 (compare:CC (match_dup 1) (match_dup 2)))
7529 (minus:DWIH (match_dup 1) (match_dup 2)))])
7530 (parallel [(set (match_dup 3)
7534 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7536 (clobber (reg:CC FLAGS_REG))])]
7537 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[3]);")
7539 (define_insn "*sub<mode>_1"
7540 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7542 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7543 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
7544 (clobber (reg:CC FLAGS_REG))]
7545 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7546 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7547 [(set_attr "type" "alu")
7548 (set_attr "mode" "<MODE>")])
7550 (define_insn "*subsi_1_zext"
7551 [(set (match_operand:DI 0 "register_operand" "=r")
7553 (minus:SI (match_operand:SI 1 "register_operand" "0")
7554 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
7555 (clobber (reg:CC FLAGS_REG))]
7556 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7557 "sub{l}\t{%2, %k0|%k0, %2}"
7558 [(set_attr "type" "alu")
7559 (set_attr "mode" "SI")])
7561 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
7562 (define_insn_and_split "*sub<mode>_1_slp"
7563 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
7564 (minus:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
7565 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
7566 (clobber (reg:CC FLAGS_REG))]
7567 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7569 sub{<imodesuffix>}\t{%2, %0|%0, %2}
7571 "&& reload_completed"
7572 [(set (strict_low_part (match_dup 0)) (match_dup 1))
7574 [(set (strict_low_part (match_dup 0))
7575 (minus:SWI12 (match_dup 0) (match_dup 2)))
7576 (clobber (reg:CC FLAGS_REG))])]
7578 [(set_attr "type" "alu")
7579 (set_attr "mode" "<MODE>")])
7581 (define_insn "*sub<mode>_2"
7582 [(set (reg FLAGS_REG)
7585 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7586 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
7588 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7589 (minus:SWI (match_dup 1) (match_dup 2)))]
7590 "ix86_match_ccmode (insn, CCGOCmode)
7591 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7592 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7593 [(set_attr "type" "alu")
7594 (set_attr "mode" "<MODE>")])
7596 (define_insn "*subsi_2_zext"
7597 [(set (reg FLAGS_REG)
7599 (minus:SI (match_operand:SI 1 "register_operand" "0")
7600 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
7602 (set (match_operand:DI 0 "register_operand" "=r")
7604 (minus:SI (match_dup 1)
7606 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7607 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7608 "sub{l}\t{%2, %k0|%k0, %2}"
7609 [(set_attr "type" "alu")
7610 (set_attr "mode" "SI")])
7612 (define_insn "*subqi_ext<mode>_0"
7613 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn")
7615 (match_operand:QI 1 "nonimmediate_operand" "0")
7617 (match_operator:SWI248 3 "extract_operator"
7618 [(match_operand 2 "int248_register_operand" "Q")
7620 (const_int 8)]) 0)))
7621 (clobber (reg:CC FLAGS_REG))]
7623 "sub{b}\t{%h2, %0|%0, %h2}"
7624 [(set_attr "addr" "gpr8")
7625 (set_attr "type" "alu")
7626 (set_attr "mode" "QI")])
7628 (define_insn "*subqi_ext<mode>_2"
7629 [(set (zero_extract:SWI248
7630 (match_operand 0 "int248_register_operand" "+Q")
7636 (match_operator:SWI248 3 "extract_operator"
7637 [(match_operand 1 "int248_register_operand" "0")
7641 (match_operator:SWI248 4 "extract_operator"
7642 [(match_operand 2 "int248_register_operand" "Q")
7644 (const_int 8)]) 0)) 0))
7645 (clobber (reg:CC FLAGS_REG))]
7646 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
7647 rtx_equal_p (operands[0], operands[1])"
7648 "sub{b}\t{%h2, %h0|%h0, %h2}"
7649 [(set_attr "type" "alu")
7650 (set_attr "mode" "QI")])
7652 ;; Subtract with jump on overflow.
7653 (define_expand "subv<mode>4"
7654 [(parallel [(set (reg:CCO FLAGS_REG)
7658 (match_operand:SWIDWI 1 "nonimmediate_operand"))
7661 (minus:SWIDWI (match_dup 1)
7662 (match_operand:SWIDWI 2
7663 "<general_hilo_operand>")))))
7664 (set (match_operand:SWIDWI 0 "register_operand")
7665 (minus:SWIDWI (match_dup 1) (match_dup 2)))])
7666 (set (pc) (if_then_else
7667 (eq (reg:CCO FLAGS_REG) (const_int 0))
7668 (label_ref (match_operand 3))
7672 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
7673 if (CONST_SCALAR_INT_P (operands[2]))
7674 operands[4] = operands[2];
7676 operands[4] = gen_rtx_SIGN_EXTEND (<DPWI>mode, operands[2]);
7679 (define_insn "*subv<mode>4"
7680 [(set (reg:CCO FLAGS_REG)
7681 (eq:CCO (minus:<DWI>
7683 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
7685 (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m")))
7687 (minus:SWI (match_dup 1) (match_dup 2)))))
7688 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7689 (minus:SWI (match_dup 1) (match_dup 2)))]
7690 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7691 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7692 [(set_attr "type" "alu")
7693 (set_attr "mode" "<MODE>")])
7695 (define_insn "subv<mode>4_1"
7696 [(set (reg:CCO FLAGS_REG)
7697 (eq:CCO (minus:<DWI>
7699 (match_operand:SWI 1 "nonimmediate_operand" "0"))
7700 (match_operand:<DWI> 3 "const_int_operand"))
7704 (match_operand:SWI 2 "x86_64_immediate_operand" "<i>")))))
7705 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
7706 (minus:SWI (match_dup 1) (match_dup 2)))]
7707 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7708 && CONST_INT_P (operands[2])
7709 && INTVAL (operands[2]) == INTVAL (operands[3])"
7710 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7711 [(set_attr "type" "alu")
7712 (set_attr "mode" "<MODE>")
7713 (set (attr "length_immediate")
7714 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7716 (match_test "<MODE_SIZE> == 8")
7718 (const_string "<MODE_SIZE>")))])
7720 (define_insn_and_split "*subv<dwi>4_doubleword"
7721 [(set (reg:CCO FLAGS_REG)
7725 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0"))
7727 (match_operand:<DWI> 2 "nonimmediate_operand" "r,o")))
7729 (minus:<DWI> (match_dup 1) (match_dup 2)))))
7730 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
7731 (minus:<DWI> (match_dup 1) (match_dup 2)))]
7732 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7734 "&& reload_completed"
7735 [(parallel [(set (reg:CC FLAGS_REG)
7736 (compare:CC (match_dup 1) (match_dup 2)))
7738 (minus:DWIH (match_dup 1) (match_dup 2)))])
7739 (parallel [(set (reg:CCO FLAGS_REG)
7743 (sign_extend:<DWI> (match_dup 4))
7744 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))
7745 (sign_extend:<DWI> (match_dup 5)))
7750 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7756 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7759 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7762 (define_insn_and_split "*subv<dwi>4_doubleword_1"
7763 [(set (reg:CCO FLAGS_REG)
7767 (match_operand:<DWI> 1 "nonimmediate_operand" "0"))
7768 (match_operand:<QPWI> 3 "const_scalar_int_operand"))
7772 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>")))))
7773 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
7774 (minus:<DWI> (match_dup 1) (match_dup 2)))]
7775 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7776 && CONST_SCALAR_INT_P (operands[2])
7777 && rtx_equal_p (operands[2], operands[3])"
7779 "&& reload_completed"
7780 [(parallel [(set (reg:CC FLAGS_REG)
7781 (compare:CC (match_dup 1) (match_dup 2)))
7783 (minus:DWIH (match_dup 1) (match_dup 2)))])
7784 (parallel [(set (reg:CCO FLAGS_REG)
7788 (sign_extend:<DWI> (match_dup 4))
7789 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))
7795 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7801 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7804 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7805 if (operands[2] == const0_rtx)
7807 emit_insn (gen_subv<mode>4_1 (operands[3], operands[4], operands[5],
7813 (define_insn "*subv<mode>4_overflow_1"
7814 [(set (reg:CCO FLAGS_REG)
7819 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
7820 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7821 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
7823 (match_operand:SWI 2 "<general_sext_operand>" "rWe,m")))
7828 (match_operator:SWI 5 "ix86_carry_flag_operator"
7829 [(match_dup 3) (const_int 0)]))
7831 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r")
7835 (match_op_dup 5 [(match_dup 3) (const_int 0)]))
7837 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7838 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7839 [(set_attr "type" "alu")
7840 (set_attr "mode" "<MODE>")])
7842 (define_insn "*subv<mode>4_overflow_2"
7843 [(set (reg:CCO FLAGS_REG)
7848 (match_operand:SWI 1 "nonimmediate_operand" "%0"))
7849 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7850 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
7851 (match_operand:<DWI> 6 "const_int_operand" "n"))
7856 (match_operator:SWI 5 "ix86_carry_flag_operator"
7857 [(match_dup 3) (const_int 0)]))
7858 (match_operand:SWI 2 "x86_64_immediate_operand" "e")))))
7859 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm")
7863 (match_op_dup 5 [(match_dup 3) (const_int 0)]))
7865 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7866 && CONST_INT_P (operands[2])
7867 && INTVAL (operands[2]) == INTVAL (operands[6])"
7868 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7869 [(set_attr "type" "alu")
7870 (set_attr "mode" "<MODE>")
7871 (set (attr "length_immediate")
7872 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7874 (const_string "4")))])
7876 (define_expand "usubv<mode>4"
7877 [(parallel [(set (reg:CC FLAGS_REG)
7879 (match_operand:SWI 1 "nonimmediate_operand")
7880 (match_operand:SWI 2 "<general_operand>")))
7881 (set (match_operand:SWI 0 "register_operand")
7882 (minus:SWI (match_dup 1) (match_dup 2)))])
7883 (set (pc) (if_then_else
7884 (ltu (reg:CC FLAGS_REG) (const_int 0))
7885 (label_ref (match_operand 3))
7888 "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
7890 (define_insn "*sub<mode>_3"
7891 [(set (reg FLAGS_REG)
7892 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7893 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
7894 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7895 (minus:SWI (match_dup 1) (match_dup 2)))]
7896 "ix86_match_ccmode (insn, CCmode)
7897 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7898 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7899 [(set_attr "type" "alu")
7900 (set_attr "mode" "<MODE>")])
7904 [(set (reg:CC FLAGS_REG)
7905 (compare:CC (match_operand:SWI 0 "general_reg_operand")
7906 (match_operand:SWI 1 "general_gr_operand")))
7908 (minus:SWI (match_dup 0) (match_dup 1)))])]
7909 "find_regno_note (peep2_next_insn (0), REG_UNUSED, REGNO (operands[0])) != 0"
7910 [(set (reg:CC FLAGS_REG)
7911 (compare:CC (match_dup 0) (match_dup 1)))])
7914 [(set (match_operand:SWI 0 "general_reg_operand")
7915 (match_operand:SWI 1 "memory_operand"))
7916 (parallel [(set (reg:CC FLAGS_REG)
7917 (compare:CC (match_dup 0)
7918 (match_operand:SWI 2 "memory_operand")))
7920 (minus:SWI (match_dup 0) (match_dup 2)))])
7921 (set (match_dup 1) (match_dup 0))]
7922 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
7923 && peep2_reg_dead_p (3, operands[0])
7924 && !reg_overlap_mentioned_p (operands[0], operands[1])
7925 && !reg_overlap_mentioned_p (operands[0], operands[2])"
7926 [(set (match_dup 0) (match_dup 2))
7927 (parallel [(set (reg:CC FLAGS_REG)
7928 (compare:CC (match_dup 1) (match_dup 0)))
7930 (minus:SWI (match_dup 1) (match_dup 0)))])])
7932 ;; decl %eax; cmpl $-1, %eax; jne .Lxx; can be optimized into
7933 ;; subl $1, %eax; jnc .Lxx;
7936 [(set (match_operand:SWI 0 "general_reg_operand")
7937 (plus:SWI (match_dup 0) (const_int -1)))
7938 (clobber (reg FLAGS_REG))])
7939 (set (reg:CCZ FLAGS_REG)
7940 (compare:CCZ (match_dup 0) (const_int -1)))
7942 (if_then_else (match_operator 1 "bt_comparison_operator"
7943 [(reg:CCZ FLAGS_REG) (const_int 0)])
7946 "peep2_regno_dead_p (3, FLAGS_REG)"
7948 [(set (reg:CC FLAGS_REG)
7949 (compare:CC (match_dup 0) (const_int 1)))
7951 (minus:SWI (match_dup 0) (const_int 1)))])
7953 (if_then_else (match_dup 3)
7957 rtx cc = gen_rtx_REG (CCmode, FLAGS_REG);
7958 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE
7959 ? GEU : LTU, VOIDmode, cc, const0_rtx);
7962 ;; Help combine use borrow flag to test for -1 after dec (add $-1).
7963 (define_insn_and_split "*dec_cmov<mode>"
7964 [(set (match_operand:SWI248 0 "register_operand" "=r")
7965 (if_then_else:SWI248
7966 (match_operator 1 "bt_comparison_operator"
7967 [(match_operand:SWI248 2 "register_operand" "0") (const_int 0)])
7968 (plus:SWI248 (match_dup 2) (const_int -1))
7969 (match_operand:SWI248 3 "nonimmediate_operand" "rm")))
7970 (clobber (reg:CC FLAGS_REG))]
7973 "&& reload_completed"
7974 [(parallel [(set (reg:CC FLAGS_REG)
7975 (compare:CC (match_dup 2) (const_int 1)))
7976 (set (match_dup 0) (minus:SWI248 (match_dup 2) (const_int 1)))])
7978 (if_then_else:SWI248 (match_dup 4) (match_dup 0) (match_dup 3)))]
7980 rtx cc = gen_rtx_REG (CCCmode, FLAGS_REG);
7981 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE
7982 ? GEU : LTU, VOIDmode, cc, const0_rtx);
7985 (define_insn "*subsi_3_zext"
7986 [(set (reg FLAGS_REG)
7987 (compare (match_operand:SI 1 "register_operand" "0")
7988 (match_operand:SI 2 "x86_64_general_operand" "rBMe")))
7989 (set (match_operand:DI 0 "register_operand" "=r")
7991 (minus:SI (match_dup 1)
7993 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7994 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7995 "sub{l}\t{%2, %1|%1, %2}"
7996 [(set_attr "type" "alu")
7997 (set_attr "mode" "SI")])
7999 ;; Add with carry and subtract with borrow
8001 (define_insn "@add<mode>3_carry"
8002 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
8005 (match_operator:SWI 4 "ix86_carry_flag_operator"
8006 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8007 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
8008 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
8009 (clobber (reg:CC FLAGS_REG))]
8010 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
8011 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
8012 [(set_attr "type" "alu")
8013 (set_attr "use_carry" "1")
8014 (set_attr "pent_pair" "pu")
8015 (set_attr "mode" "<MODE>")])
8018 [(set (match_operand:SWI 0 "general_reg_operand")
8019 (match_operand:SWI 1 "memory_operand"))
8020 (parallel [(set (match_dup 0)
8023 (match_operator:SWI 4 "ix86_carry_flag_operator"
8024 [(match_operand 3 "flags_reg_operand")
8027 (match_operand:SWI 2 "memory_operand")))
8028 (clobber (reg:CC FLAGS_REG))])
8029 (set (match_dup 1) (match_dup 0))]
8030 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8031 && peep2_reg_dead_p (3, operands[0])
8032 && !reg_overlap_mentioned_p (operands[0], operands[1])
8033 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8034 [(set (match_dup 0) (match_dup 2))
8035 (parallel [(set (match_dup 1)
8036 (plus:SWI (plus:SWI (match_op_dup 4
8037 [(match_dup 3) (const_int 0)])
8040 (clobber (reg:CC FLAGS_REG))])])
8043 [(set (match_operand:SWI 0 "general_reg_operand")
8044 (match_operand:SWI 1 "memory_operand"))
8045 (parallel [(set (match_dup 0)
8048 (match_operator:SWI 4 "ix86_carry_flag_operator"
8049 [(match_operand 3 "flags_reg_operand")
8052 (match_operand:SWI 2 "memory_operand")))
8053 (clobber (reg:CC FLAGS_REG))])
8054 (set (match_operand:SWI 5 "general_reg_operand") (match_dup 0))
8055 (set (match_dup 1) (match_dup 5))]
8056 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8057 && peep2_reg_dead_p (3, operands[0])
8058 && peep2_reg_dead_p (4, operands[5])
8059 && !reg_overlap_mentioned_p (operands[0], operands[1])
8060 && !reg_overlap_mentioned_p (operands[0], operands[2])
8061 && !reg_overlap_mentioned_p (operands[5], operands[1])"
8062 [(set (match_dup 0) (match_dup 2))
8063 (parallel [(set (match_dup 1)
8064 (plus:SWI (plus:SWI (match_op_dup 4
8065 [(match_dup 3) (const_int 0)])
8068 (clobber (reg:CC FLAGS_REG))])])
8070 (define_insn "*add<mode>3_carry_0"
8071 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8073 (match_operator:SWI 2 "ix86_carry_flag_operator"
8074 [(reg FLAGS_REG) (const_int 0)])
8075 (match_operand:SWI 1 "nonimmediate_operand" "0")))
8076 (clobber (reg:CC FLAGS_REG))]
8077 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8078 "adc{<imodesuffix>}\t{$0, %0|%0, 0}"
8079 [(set_attr "type" "alu")
8080 (set_attr "use_carry" "1")
8081 (set_attr "pent_pair" "pu")
8082 (set_attr "mode" "<MODE>")])
8084 (define_insn "*add<mode>3_carry_0r"
8085 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8087 (match_operator:SWI 2 "ix86_carry_flag_unset_operator"
8088 [(reg FLAGS_REG) (const_int 0)])
8089 (match_operand:SWI 1 "nonimmediate_operand" "0")))
8090 (clobber (reg:CC FLAGS_REG))]
8091 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8092 "sbb{<imodesuffix>}\t{$-1, %0|%0, -1}"
8093 [(set_attr "type" "alu")
8094 (set_attr "use_carry" "1")
8095 (set_attr "pent_pair" "pu")
8096 (set_attr "mode" "<MODE>")])
8098 (define_insn "*addsi3_carry_zext"
8099 [(set (match_operand:DI 0 "register_operand" "=r")
8102 (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
8103 [(reg FLAGS_REG) (const_int 0)])
8104 (match_operand:SI 1 "register_operand" "%0"))
8105 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
8106 (clobber (reg:CC FLAGS_REG))]
8107 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
8108 "adc{l}\t{%2, %k0|%k0, %2}"
8109 [(set_attr "type" "alu")
8110 (set_attr "use_carry" "1")
8111 (set_attr "pent_pair" "pu")
8112 (set_attr "mode" "SI")])
8114 (define_insn "*addsi3_carry_zext_0"
8115 [(set (match_operand:DI 0 "register_operand" "=r")
8117 (plus:SI (match_operator:SI 2 "ix86_carry_flag_operator"
8118 [(reg FLAGS_REG) (const_int 0)])
8119 (match_operand:SI 1 "register_operand" "0"))))
8120 (clobber (reg:CC FLAGS_REG))]
8122 "adc{l}\t{$0, %k0|%k0, 0}"
8123 [(set_attr "type" "alu")
8124 (set_attr "use_carry" "1")
8125 (set_attr "pent_pair" "pu")
8126 (set_attr "mode" "SI")])
8128 (define_insn "*addsi3_carry_zext_0r"
8129 [(set (match_operand:DI 0 "register_operand" "=r")
8131 (plus:SI (match_operator:SI 2 "ix86_carry_flag_unset_operator"
8132 [(reg FLAGS_REG) (const_int 0)])
8133 (match_operand:SI 1 "register_operand" "0"))))
8134 (clobber (reg:CC FLAGS_REG))]
8136 "sbb{l}\t{$-1, %k0|%k0, -1}"
8137 [(set_attr "type" "alu")
8138 (set_attr "use_carry" "1")
8139 (set_attr "pent_pair" "pu")
8140 (set_attr "mode" "SI")])
8142 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
8144 (define_insn "addcarry<mode>"
8145 [(set (reg:CCC FLAGS_REG)
8150 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8151 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8152 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0"))
8153 (match_operand:SWI48 2 "nonimmediate_operand" "r,rm")))
8155 (zero_extend:<DWI> (match_dup 2))
8156 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8157 [(match_dup 3) (const_int 0)]))))
8158 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
8159 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8160 [(match_dup 3) (const_int 0)])
8163 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
8164 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
8165 [(set_attr "type" "alu")
8166 (set_attr "use_carry" "1")
8167 (set_attr "pent_pair" "pu")
8168 (set_attr "mode" "<MODE>")])
8171 [(parallel [(set (reg:CCC FLAGS_REG)
8176 (match_operator:SWI48 4 "ix86_carry_flag_operator"
8177 [(match_operand 2 "flags_reg_operand")
8179 (match_operand:SWI48 0 "general_reg_operand"))
8180 (match_operand:SWI48 1 "memory_operand")))
8182 (zero_extend:<DWI> (match_dup 1))
8183 (match_operator:<DWI> 3 "ix86_carry_flag_operator"
8184 [(match_dup 2) (const_int 0)]))))
8186 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8187 [(match_dup 2) (const_int 0)])
8190 (set (match_dup 1) (match_dup 0))]
8191 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8192 && peep2_reg_dead_p (2, operands[0])
8193 && !reg_overlap_mentioned_p (operands[0], operands[1])"
8194 [(parallel [(set (reg:CCC FLAGS_REG)
8200 [(match_dup 2) (const_int 0)])
8204 (zero_extend:<DWI> (match_dup 0))
8206 [(match_dup 2) (const_int 0)]))))
8208 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8209 [(match_dup 2) (const_int 0)])
8214 [(set (match_operand:SWI48 0 "general_reg_operand")
8215 (match_operand:SWI48 1 "memory_operand"))
8216 (parallel [(set (reg:CCC FLAGS_REG)
8221 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8222 [(match_operand 3 "flags_reg_operand")
8225 (match_operand:SWI48 2 "memory_operand")))
8227 (zero_extend:<DWI> (match_dup 2))
8228 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8229 [(match_dup 3) (const_int 0)]))))
8231 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8232 [(match_dup 3) (const_int 0)])
8235 (set (match_dup 1) (match_dup 0))]
8236 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8237 && peep2_reg_dead_p (3, operands[0])
8238 && !reg_overlap_mentioned_p (operands[0], operands[1])
8239 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8240 [(set (match_dup 0) (match_dup 2))
8241 (parallel [(set (reg:CCC FLAGS_REG)
8247 [(match_dup 3) (const_int 0)])
8251 (zero_extend:<DWI> (match_dup 0))
8253 [(match_dup 3) (const_int 0)]))))
8255 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8256 [(match_dup 3) (const_int 0)])
8261 [(parallel [(set (reg:CCC FLAGS_REG)
8266 (match_operator:SWI48 4 "ix86_carry_flag_operator"
8267 [(match_operand 2 "flags_reg_operand")
8269 (match_operand:SWI48 0 "general_reg_operand"))
8270 (match_operand:SWI48 1 "memory_operand")))
8272 (zero_extend:<DWI> (match_dup 1))
8273 (match_operator:<DWI> 3 "ix86_carry_flag_operator"
8274 [(match_dup 2) (const_int 0)]))))
8276 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8277 [(match_dup 2) (const_int 0)])
8280 (set (match_operand:QI 5 "general_reg_operand")
8281 (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8282 (set (match_operand:SWI48 6 "general_reg_operand")
8283 (zero_extend:SWI48 (match_dup 5)))
8284 (set (match_dup 1) (match_dup 0))]
8285 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8286 && peep2_reg_dead_p (4, operands[0])
8287 && !reg_overlap_mentioned_p (operands[0], operands[1])
8288 && !reg_overlap_mentioned_p (operands[0], operands[5])
8289 && !reg_overlap_mentioned_p (operands[5], operands[1])
8290 && !reg_overlap_mentioned_p (operands[0], operands[6])
8291 && !reg_overlap_mentioned_p (operands[6], operands[1])"
8292 [(parallel [(set (reg:CCC FLAGS_REG)
8298 [(match_dup 2) (const_int 0)])
8302 (zero_extend:<DWI> (match_dup 0))
8304 [(match_dup 2) (const_int 0)]))))
8306 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8307 [(match_dup 2) (const_int 0)])
8310 (set (match_dup 5) (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8311 (set (match_dup 6) (zero_extend:SWI48 (match_dup 5)))])
8313 (define_expand "addcarry<mode>_0"
8315 [(set (reg:CCC FLAGS_REG)
8318 (match_operand:SWI48 1 "nonimmediate_operand")
8319 (match_operand:SWI48 2 "x86_64_general_operand"))
8321 (set (match_operand:SWI48 0 "nonimmediate_operand")
8322 (plus:SWI48 (match_dup 1) (match_dup 2)))])]
8323 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)")
8325 (define_insn "*addcarry<mode>_1"
8326 [(set (reg:CCC FLAGS_REG)
8331 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8332 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8333 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
8334 (match_operand:SWI48 2 "x86_64_immediate_operand" "e")))
8336 (match_operand:<DWI> 6 "const_scalar_int_operand")
8337 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8338 [(match_dup 3) (const_int 0)]))))
8339 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
8340 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8341 [(match_dup 3) (const_int 0)])
8344 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
8345 && CONST_INT_P (operands[2])
8346 /* Check that operands[6] is operands[2] zero extended from
8347 <MODE>mode to <DWI>mode. */
8348 && ((<MODE>mode == SImode || INTVAL (operands[2]) >= 0)
8349 ? (CONST_INT_P (operands[6])
8350 && UINTVAL (operands[6]) == (UINTVAL (operands[2])
8351 & GET_MODE_MASK (<MODE>mode)))
8352 : (CONST_WIDE_INT_P (operands[6])
8353 && CONST_WIDE_INT_NUNITS (operands[6]) == 2
8354 && ((unsigned HOST_WIDE_INT) CONST_WIDE_INT_ELT (operands[6], 0)
8355 == UINTVAL (operands[2]))
8356 && CONST_WIDE_INT_ELT (operands[6], 1) == 0))"
8357 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
8358 [(set_attr "type" "alu")
8359 (set_attr "use_carry" "1")
8360 (set_attr "pent_pair" "pu")
8361 (set_attr "mode" "<MODE>")
8362 (set (attr "length_immediate")
8363 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
8365 (const_string "4")))])
8367 (define_insn "@sub<mode>3_carry"
8368 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
8371 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
8372 (match_operator:SWI 4 "ix86_carry_flag_operator"
8373 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
8374 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
8375 (clobber (reg:CC FLAGS_REG))]
8376 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
8377 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8378 [(set_attr "type" "alu")
8379 (set_attr "use_carry" "1")
8380 (set_attr "pent_pair" "pu")
8381 (set_attr "mode" "<MODE>")])
8384 [(set (match_operand:SWI 0 "general_reg_operand")
8385 (match_operand:SWI 1 "memory_operand"))
8386 (parallel [(set (match_dup 0)
8390 (match_operator:SWI 4 "ix86_carry_flag_operator"
8391 [(match_operand 3 "flags_reg_operand")
8393 (match_operand:SWI 2 "memory_operand")))
8394 (clobber (reg:CC FLAGS_REG))])
8395 (set (match_dup 1) (match_dup 0))]
8396 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8397 && peep2_reg_dead_p (3, operands[0])
8398 && !reg_overlap_mentioned_p (operands[0], operands[1])
8399 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8400 [(set (match_dup 0) (match_dup 2))
8401 (parallel [(set (match_dup 1)
8402 (minus:SWI (minus:SWI (match_dup 1)
8404 [(match_dup 3) (const_int 0)]))
8406 (clobber (reg:CC FLAGS_REG))])])
8409 [(set (match_operand:SWI 0 "general_reg_operand")
8410 (match_operand:SWI 1 "memory_operand"))
8411 (parallel [(set (match_dup 0)
8415 (match_operator:SWI 4 "ix86_carry_flag_operator"
8416 [(match_operand 3 "flags_reg_operand")
8418 (match_operand:SWI 2 "memory_operand")))
8419 (clobber (reg:CC FLAGS_REG))])
8420 (set (match_operand:SWI 5 "general_reg_operand") (match_dup 0))
8421 (set (match_dup 1) (match_dup 5))]
8422 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8423 && peep2_reg_dead_p (3, operands[0])
8424 && peep2_reg_dead_p (4, operands[5])
8425 && !reg_overlap_mentioned_p (operands[0], operands[1])
8426 && !reg_overlap_mentioned_p (operands[0], operands[2])
8427 && !reg_overlap_mentioned_p (operands[5], operands[1])"
8428 [(set (match_dup 0) (match_dup 2))
8429 (parallel [(set (match_dup 1)
8430 (minus:SWI (minus:SWI (match_dup 1)
8432 [(match_dup 3) (const_int 0)]))
8434 (clobber (reg:CC FLAGS_REG))])])
8436 (define_insn "*sub<mode>3_carry_0"
8437 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8439 (match_operand:SWI 1 "nonimmediate_operand" "0")
8440 (match_operator:SWI 2 "ix86_carry_flag_operator"
8441 [(reg FLAGS_REG) (const_int 0)])))
8442 (clobber (reg:CC FLAGS_REG))]
8443 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8444 "sbb{<imodesuffix>}\t{$0, %0|%0, 0}"
8445 [(set_attr "type" "alu")
8446 (set_attr "use_carry" "1")
8447 (set_attr "pent_pair" "pu")
8448 (set_attr "mode" "<MODE>")])
8450 (define_insn "*sub<mode>3_carry_0r"
8451 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8453 (match_operand:SWI 1 "nonimmediate_operand" "0")
8454 (match_operator:SWI 2 "ix86_carry_flag_unset_operator"
8455 [(reg FLAGS_REG) (const_int 0)])))
8456 (clobber (reg:CC FLAGS_REG))]
8457 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8458 "adc{<imodesuffix>}\t{$-1, %0|%0, -1}"
8459 [(set_attr "type" "alu")
8460 (set_attr "use_carry" "1")
8461 (set_attr "pent_pair" "pu")
8462 (set_attr "mode" "<MODE>")])
8464 (define_insn "*subsi3_carry_zext"
8465 [(set (match_operand:DI 0 "register_operand" "=r")
8469 (match_operand:SI 1 "register_operand" "0")
8470 (match_operator:SI 3 "ix86_carry_flag_operator"
8471 [(reg FLAGS_REG) (const_int 0)]))
8472 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
8473 (clobber (reg:CC FLAGS_REG))]
8474 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
8475 "sbb{l}\t{%2, %k0|%k0, %2}"
8476 [(set_attr "type" "alu")
8477 (set_attr "use_carry" "1")
8478 (set_attr "pent_pair" "pu")
8479 (set_attr "mode" "SI")])
8481 (define_insn "*subsi3_carry_zext_0"
8482 [(set (match_operand:DI 0 "register_operand" "=r")
8485 (match_operand:SI 1 "register_operand" "0")
8486 (match_operator:SI 2 "ix86_carry_flag_operator"
8487 [(reg FLAGS_REG) (const_int 0)]))))
8488 (clobber (reg:CC FLAGS_REG))]
8490 "sbb{l}\t{$0, %k0|%k0, 0}"
8491 [(set_attr "type" "alu")
8492 (set_attr "use_carry" "1")
8493 (set_attr "pent_pair" "pu")
8494 (set_attr "mode" "SI")])
8496 (define_insn "*subsi3_carry_zext_0r"
8497 [(set (match_operand:DI 0 "register_operand" "=r")
8500 (match_operand:SI 1 "register_operand" "0")
8501 (match_operator:SI 2 "ix86_carry_flag_unset_operator"
8502 [(reg FLAGS_REG) (const_int 0)]))))
8503 (clobber (reg:CC FLAGS_REG))]
8505 "adc{l}\t{$-1, %k0|%k0, -1}"
8506 [(set_attr "type" "alu")
8507 (set_attr "use_carry" "1")
8508 (set_attr "pent_pair" "pu")
8509 (set_attr "mode" "SI")])
8511 (define_insn "@sub<mode>3_carry_ccc"
8512 [(set (reg:CCC FLAGS_REG)
8514 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
8516 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
8518 (match_operand:DWIH 2 "x86_64_sext_operand" "rmWe")))))
8519 (clobber (match_scratch:DWIH 0 "=r"))]
8521 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8522 [(set_attr "type" "alu")
8523 (set_attr "mode" "<MODE>")])
8525 (define_insn "*sub<mode>3_carry_ccc_1"
8526 [(set (reg:CCC FLAGS_REG)
8528 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
8530 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
8531 (match_operand:<DWI> 2 "x86_64_dwzext_immediate_operand" "Wf"))))
8532 (clobber (match_scratch:DWIH 0 "=r"))]
8535 operands[3] = simplify_subreg (<MODE>mode, operands[2], <DWI>mode, 0);
8536 return "sbb{<imodesuffix>}\t{%3, %0|%0, %3}";
8538 [(set_attr "type" "alu")
8539 (set_attr "mode" "<MODE>")])
8541 ;; The sign flag is set from the
8542 ;; (compare (match_dup 1) (plus:DWIH (ltu:DWIH ...) (match_dup 2)))
8543 ;; result, the overflow flag likewise, but the overflow flag is also
8544 ;; set if the (plus:DWIH (ltu:DWIH ...) (match_dup 2)) overflows.
8545 (define_insn "@sub<mode>3_carry_ccgz"
8546 [(set (reg:CCGZ FLAGS_REG)
8547 (unspec:CCGZ [(match_operand:DWIH 1 "register_operand" "0")
8548 (match_operand:DWIH 2 "x86_64_general_operand" "rBMe")
8549 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))]
8551 (clobber (match_scratch:DWIH 0 "=r"))]
8553 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8554 [(set_attr "type" "alu")
8555 (set_attr "mode" "<MODE>")])
8557 (define_insn "subborrow<mode>"
8558 [(set (reg:CCC FLAGS_REG)
8561 (match_operand:SWI48 1 "nonimmediate_operand" "0,0"))
8563 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8564 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8566 (match_operand:SWI48 2 "nonimmediate_operand" "r,rm")))))
8567 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
8568 (minus:SWI48 (minus:SWI48
8570 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8571 [(match_dup 3) (const_int 0)]))
8573 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
8574 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8575 [(set_attr "type" "alu")
8576 (set_attr "use_carry" "1")
8577 (set_attr "pent_pair" "pu")
8578 (set_attr "mode" "<MODE>")])
8581 [(set (match_operand:SWI48 0 "general_reg_operand")
8582 (match_operand:SWI48 1 "memory_operand"))
8583 (parallel [(set (reg:CCC FLAGS_REG)
8585 (zero_extend:<DWI> (match_dup 0))
8587 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8588 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8590 (match_operand:SWI48 2 "memory_operand")))))
8595 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8596 [(match_dup 3) (const_int 0)]))
8598 (set (match_dup 1) (match_dup 0))]
8599 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8600 && peep2_reg_dead_p (3, operands[0])
8601 && !reg_overlap_mentioned_p (operands[0], operands[1])
8602 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8603 [(set (match_dup 0) (match_dup 2))
8604 (parallel [(set (reg:CCC FLAGS_REG)
8606 (zero_extend:<DWI> (match_dup 1))
8607 (plus:<DWI> (match_op_dup 4
8608 [(match_dup 3) (const_int 0)])
8609 (zero_extend:<DWI> (match_dup 0)))))
8611 (minus:SWI48 (minus:SWI48 (match_dup 1)
8613 [(match_dup 3) (const_int 0)]))
8617 [(set (match_operand:SWI48 6 "general_reg_operand")
8618 (match_operand:SWI48 7 "memory_operand"))
8619 (set (match_operand:SWI48 8 "general_reg_operand")
8620 (match_operand:SWI48 9 "memory_operand"))
8621 (parallel [(set (reg:CCC FLAGS_REG)
8624 (match_operand:SWI48 0 "general_reg_operand"))
8626 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8627 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8629 (match_operand:SWI48 2 "general_reg_operand")))))
8634 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8635 [(match_dup 3) (const_int 0)]))
8637 (set (match_operand:SWI48 1 "memory_operand") (match_dup 0))]
8638 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8639 && peep2_reg_dead_p (4, operands[0])
8640 && peep2_reg_dead_p (3, operands[2])
8641 && !reg_overlap_mentioned_p (operands[0], operands[1])
8642 && !reg_overlap_mentioned_p (operands[2], operands[1])
8643 && !reg_overlap_mentioned_p (operands[6], operands[9])
8644 && (rtx_equal_p (operands[6], operands[0])
8645 ? (rtx_equal_p (operands[7], operands[1])
8646 && rtx_equal_p (operands[8], operands[2]))
8647 : (rtx_equal_p (operands[8], operands[0])
8648 && rtx_equal_p (operands[9], operands[1])
8649 && rtx_equal_p (operands[6], operands[2])))"
8650 [(set (match_dup 0) (match_dup 9))
8651 (parallel [(set (reg:CCC FLAGS_REG)
8653 (zero_extend:<DWI> (match_dup 1))
8654 (plus:<DWI> (match_op_dup 4
8655 [(match_dup 3) (const_int 0)])
8656 (zero_extend:<DWI> (match_dup 0)))))
8658 (minus:SWI48 (minus:SWI48 (match_dup 1)
8660 [(match_dup 3) (const_int 0)]))
8663 if (!rtx_equal_p (operands[6], operands[0]))
8664 operands[9] = operands[7];
8668 [(set (match_operand:SWI48 6 "general_reg_operand")
8669 (match_operand:SWI48 7 "memory_operand"))
8670 (set (match_operand:SWI48 8 "general_reg_operand")
8671 (match_operand:SWI48 9 "memory_operand"))
8672 (parallel [(set (reg:CCC FLAGS_REG)
8675 (match_operand:SWI48 0 "general_reg_operand"))
8677 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8678 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8680 (match_operand:SWI48 2 "general_reg_operand")))))
8685 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8686 [(match_dup 3) (const_int 0)]))
8688 (set (match_operand:QI 10 "general_reg_operand")
8689 (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8690 (set (match_operand:SWI48 11 "general_reg_operand")
8691 (zero_extend:SWI48 (match_dup 10)))
8692 (set (match_operand:SWI48 1 "memory_operand") (match_dup 0))]
8693 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8694 && peep2_reg_dead_p (6, operands[0])
8695 && peep2_reg_dead_p (3, operands[2])
8696 && !reg_overlap_mentioned_p (operands[0], operands[1])
8697 && !reg_overlap_mentioned_p (operands[2], operands[1])
8698 && !reg_overlap_mentioned_p (operands[6], operands[9])
8699 && !reg_overlap_mentioned_p (operands[0], operands[10])
8700 && !reg_overlap_mentioned_p (operands[10], operands[1])
8701 && !reg_overlap_mentioned_p (operands[0], operands[11])
8702 && !reg_overlap_mentioned_p (operands[11], operands[1])
8703 && (rtx_equal_p (operands[6], operands[0])
8704 ? (rtx_equal_p (operands[7], operands[1])
8705 && rtx_equal_p (operands[8], operands[2]))
8706 : (rtx_equal_p (operands[8], operands[0])
8707 && rtx_equal_p (operands[9], operands[1])
8708 && rtx_equal_p (operands[6], operands[2])))"
8709 [(set (match_dup 0) (match_dup 9))
8710 (parallel [(set (reg:CCC FLAGS_REG)
8712 (zero_extend:<DWI> (match_dup 1))
8713 (plus:<DWI> (match_op_dup 4
8714 [(match_dup 3) (const_int 0)])
8715 (zero_extend:<DWI> (match_dup 0)))))
8717 (minus:SWI48 (minus:SWI48 (match_dup 1)
8719 [(match_dup 3) (const_int 0)]))
8721 (set (match_dup 10) (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8722 (set (match_dup 11) (zero_extend:SWI48 (match_dup 10)))]
8724 if (!rtx_equal_p (operands[6], operands[0]))
8725 operands[9] = operands[7];
8728 (define_expand "subborrow<mode>_0"
8730 [(set (reg:CC FLAGS_REG)
8732 (match_operand:SWI48 1 "nonimmediate_operand")
8733 (match_operand:SWI48 2 "<general_operand>")))
8734 (set (match_operand:SWI48 0 "register_operand")
8735 (minus:SWI48 (match_dup 1) (match_dup 2)))])]
8736 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)")
8738 (define_expand "uaddc<mode>5"
8739 [(match_operand:SWI48 0 "register_operand")
8740 (match_operand:SWI48 1 "register_operand")
8741 (match_operand:SWI48 2 "register_operand")
8742 (match_operand:SWI48 3 "register_operand")
8743 (match_operand:SWI48 4 "nonmemory_operand")]
8746 rtx cf = gen_rtx_REG (CCCmode, FLAGS_REG), pat, pat2;
8747 if (operands[4] == const0_rtx)
8748 emit_insn (gen_addcarry<mode>_0 (operands[0], operands[2], operands[3]));
8751 ix86_expand_carry (operands[4]);
8752 pat = gen_rtx_LTU (<DWI>mode, cf, const0_rtx);
8753 pat2 = gen_rtx_LTU (<MODE>mode, cf, const0_rtx);
8754 emit_insn (gen_addcarry<mode> (operands[0], operands[2], operands[3],
8757 rtx cc = gen_reg_rtx (QImode);
8758 pat = gen_rtx_LTU (QImode, cf, const0_rtx);
8759 emit_insn (gen_rtx_SET (cc, pat));
8760 emit_insn (gen_zero_extendqi<mode>2 (operands[1], cc));
8764 (define_expand "usubc<mode>5"
8765 [(match_operand:SWI48 0 "register_operand")
8766 (match_operand:SWI48 1 "register_operand")
8767 (match_operand:SWI48 2 "register_operand")
8768 (match_operand:SWI48 3 "register_operand")
8769 (match_operand:SWI48 4 "nonmemory_operand")]
8773 if (operands[4] == const0_rtx)
8775 cf = gen_rtx_REG (CCmode, FLAGS_REG);
8776 emit_insn (gen_subborrow<mode>_0 (operands[0], operands[2],
8781 cf = gen_rtx_REG (CCCmode, FLAGS_REG);
8782 ix86_expand_carry (operands[4]);
8783 pat = gen_rtx_LTU (<DWI>mode, cf, const0_rtx);
8784 pat2 = gen_rtx_LTU (<MODE>mode, cf, const0_rtx);
8785 emit_insn (gen_subborrow<mode> (operands[0], operands[2], operands[3],
8788 rtx cc = gen_reg_rtx (QImode);
8789 pat = gen_rtx_LTU (QImode, cf, const0_rtx);
8790 emit_insn (gen_rtx_SET (cc, pat));
8791 emit_insn (gen_zero_extendqi<mode>2 (operands[1], cc));
8795 (define_mode_iterator CC_CCC [CC CCC])
8797 ;; Pre-reload splitter to optimize
8798 ;; *setcc_qi followed by *addqi3_cconly_overflow_1 with the same QI
8799 ;; operand and no intervening flags modifications into nothing.
8800 (define_insn_and_split "*setcc_qi_addqi3_cconly_overflow_1_<mode>"
8801 [(set (reg:CCC FLAGS_REG)
8802 (compare:CCC (neg:QI (geu:QI (reg:CC_CCC FLAGS_REG) (const_int 0)))
8803 (ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))))]
8804 "ix86_pre_reload_split ()"
8808 "emit_note (NOTE_INSN_DELETED); DONE;")
8810 ;; Set the carry flag from the carry flag.
8811 (define_insn_and_split "*setccc"
8812 [(set (reg:CCC FLAGS_REG)
8813 (reg:CCC FLAGS_REG))]
8814 "ix86_pre_reload_split ()"
8818 "emit_note (NOTE_INSN_DELETED); DONE;")
8820 ;; Set the carry flag from the carry flag.
8821 (define_insn_and_split "*setcc_qi_negqi_ccc_1_<mode>"
8822 [(set (reg:CCC FLAGS_REG)
8823 (ltu:CCC (reg:CC_CCC FLAGS_REG) (const_int 0)))]
8824 "ix86_pre_reload_split ()"
8828 "emit_note (NOTE_INSN_DELETED); DONE;")
8830 ;; Set the carry flag from the carry flag.
8831 (define_insn_and_split "*setcc_qi_negqi_ccc_2_<mode>"
8832 [(set (reg:CCC FLAGS_REG)
8833 (unspec:CCC [(ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))
8834 (const_int 0)] UNSPEC_CC_NE))]
8835 "ix86_pre_reload_split ()"
8839 "emit_note (NOTE_INSN_DELETED); DONE;")
8841 ;; Overflow setting add instructions
8843 (define_expand "addqi3_cconly_overflow"
8845 [(set (reg:CCC FLAGS_REG)
8848 (match_operand:QI 0 "nonimmediate_operand")
8849 (match_operand:QI 1 "general_operand"))
8851 (clobber (scratch:QI))])]
8852 "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
8854 (define_insn "*add<mode>3_cconly_overflow_1"
8855 [(set (reg:CCC FLAGS_REG)
8858 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8859 (match_operand:SWI 2 "<general_operand>" "<g>"))
8861 (clobber (match_scratch:SWI 0 "=<r>"))]
8862 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8863 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
8864 [(set_attr "type" "alu")
8865 (set_attr "mode" "<MODE>")])
8867 (define_insn "@add<mode>3_cc_overflow_1"
8868 [(set (reg:CCC FLAGS_REG)
8871 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8872 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
8874 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
8875 (plus:SWI (match_dup 1) (match_dup 2)))]
8876 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
8877 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
8878 [(set_attr "type" "alu")
8879 (set_attr "mode" "<MODE>")])
8882 [(parallel [(set (reg:CCC FLAGS_REG)
8884 (plus:SWI (match_operand:SWI 0 "general_reg_operand")
8885 (match_operand:SWI 1 "memory_operand"))
8887 (set (match_dup 0) (plus:SWI (match_dup 0) (match_dup 1)))])
8888 (set (match_dup 1) (match_dup 0))]
8889 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8890 && peep2_reg_dead_p (2, operands[0])
8891 && !reg_overlap_mentioned_p (operands[0], operands[1])"
8892 [(parallel [(set (reg:CCC FLAGS_REG)
8894 (plus:SWI (match_dup 1) (match_dup 0))
8896 (set (match_dup 1) (plus:SWI (match_dup 1) (match_dup 0)))])])
8899 [(set (match_operand:SWI 0 "general_reg_operand")
8900 (match_operand:SWI 1 "memory_operand"))
8901 (parallel [(set (reg:CCC FLAGS_REG)
8903 (plus:SWI (match_dup 0)
8904 (match_operand:SWI 2 "memory_operand"))
8906 (set (match_dup 0) (plus:SWI (match_dup 0) (match_dup 2)))])
8907 (set (match_dup 1) (match_dup 0))]
8908 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8909 && peep2_reg_dead_p (3, operands[0])
8910 && !reg_overlap_mentioned_p (operands[0], operands[1])
8911 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8912 [(set (match_dup 0) (match_dup 2))
8913 (parallel [(set (reg:CCC FLAGS_REG)
8915 (plus:SWI (match_dup 1) (match_dup 0))
8917 (set (match_dup 1) (plus:SWI (match_dup 1) (match_dup 0)))])])
8919 (define_insn "*addsi3_zext_cc_overflow_1"
8920 [(set (reg:CCC FLAGS_REG)
8923 (match_operand:SI 1 "nonimmediate_operand" "%0")
8924 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
8926 (set (match_operand:DI 0 "register_operand" "=r")
8927 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8928 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
8929 "add{l}\t{%2, %k0|%k0, %2}"
8930 [(set_attr "type" "alu")
8931 (set_attr "mode" "SI")])
8933 (define_insn "*add<mode>3_cconly_overflow_2"
8934 [(set (reg:CCC FLAGS_REG)
8937 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8938 (match_operand:SWI 2 "<general_operand>" "<g>"))
8940 (clobber (match_scratch:SWI 0 "=<r>"))]
8941 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8942 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
8943 [(set_attr "type" "alu")
8944 (set_attr "mode" "<MODE>")])
8946 (define_insn "*add<mode>3_cc_overflow_2"
8947 [(set (reg:CCC FLAGS_REG)
8950 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8951 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
8953 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
8954 (plus:SWI (match_dup 1) (match_dup 2)))]
8955 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
8956 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
8957 [(set_attr "type" "alu")
8958 (set_attr "mode" "<MODE>")])
8960 (define_insn "*addsi3_zext_cc_overflow_2"
8961 [(set (reg:CCC FLAGS_REG)
8964 (match_operand:SI 1 "nonimmediate_operand" "%0")
8965 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
8967 (set (match_operand:DI 0 "register_operand" "=r")
8968 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8969 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
8970 "add{l}\t{%2, %k0|%k0, %2}"
8971 [(set_attr "type" "alu")
8972 (set_attr "mode" "SI")])
8974 (define_insn_and_split "*add<dwi>3_doubleword_cc_overflow_1"
8975 [(set (reg:CCC FLAGS_REG)
8978 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
8979 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o"))
8981 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
8982 (plus:<DWI> (match_dup 1) (match_dup 2)))]
8983 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
8985 "&& reload_completed"
8986 [(parallel [(set (reg:CCC FLAGS_REG)
8988 (plus:DWIH (match_dup 1) (match_dup 2))
8991 (plus:DWIH (match_dup 1) (match_dup 2)))])
8992 (parallel [(set (reg:CCC FLAGS_REG)
8997 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9002 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))))
9005 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9009 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
9010 if (operands[2] == const0_rtx)
9012 emit_insn (gen_addcarry<mode>_0 (operands[3], operands[4], operands[5]));
9015 if (CONST_INT_P (operands[5]))
9016 operands[6] = simplify_unary_operation (ZERO_EXTEND, <DWI>mode,
9017 operands[5], <MODE>mode);
9019 operands[6] = gen_rtx_ZERO_EXTEND (<DWI>mode, operands[5]);
9022 ;; x == 0 with zero flag test can be done also as x < 1U with carry flag
9023 ;; test, where the latter is preferrable if we have some carry consuming
9025 ;; For x != 0, we need to use x < 1U with negation of carry, i.e.
9027 (define_insn_and_split "*add<mode>3_eq"
9028 [(set (match_operand:SWI 0 "nonimmediate_operand")
9031 (eq:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0))
9032 (match_operand:SWI 1 "nonimmediate_operand"))
9033 (match_operand:SWI 2 "<general_operand>")))
9034 (clobber (reg:CC FLAGS_REG))]
9035 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
9036 && ix86_pre_reload_split ()"
9039 [(set (reg:CC FLAGS_REG)
9040 (compare:CC (match_dup 3) (const_int 1)))
9041 (parallel [(set (match_dup 0)
9043 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9046 (clobber (reg:CC FLAGS_REG))])])
9048 (define_insn_and_split "*add<mode>3_ne"
9049 [(set (match_operand:SWI 0 "nonimmediate_operand")
9052 (ne:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0))
9053 (match_operand:SWI 1 "nonimmediate_operand"))
9054 (match_operand:SWI 2 "<immediate_operand>")))
9055 (clobber (reg:CC FLAGS_REG))]
9056 "CONST_INT_P (operands[2])
9057 && (<MODE>mode != DImode
9058 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
9059 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
9060 && ix86_pre_reload_split ()"
9063 [(set (reg:CC FLAGS_REG)
9064 (compare:CC (match_dup 3) (const_int 1)))
9065 (parallel [(set (match_dup 0)
9067 (minus:SWI (match_dup 1)
9068 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9070 (clobber (reg:CC FLAGS_REG))])]
9072 operands[2] = gen_int_mode (~INTVAL (operands[2]),
9073 <MODE>mode == DImode ? SImode : <MODE>mode);
9076 (define_insn_and_split "*add<mode>3_eq_0"
9077 [(set (match_operand:SWI 0 "nonimmediate_operand")
9079 (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))
9080 (match_operand:SWI 1 "<general_operand>")))
9081 (clobber (reg:CC FLAGS_REG))]
9082 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)
9083 && ix86_pre_reload_split ()"
9086 [(set (reg:CC FLAGS_REG)
9087 (compare:CC (match_dup 2) (const_int 1)))
9088 (parallel [(set (match_dup 0)
9089 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9091 (clobber (reg:CC FLAGS_REG))])]
9093 if (!nonimmediate_operand (operands[1], <MODE>mode))
9094 operands[1] = force_reg (<MODE>mode, operands[1]);
9097 (define_insn_and_split "*add<mode>3_ne_0"
9098 [(set (match_operand:SWI 0 "nonimmediate_operand")
9100 (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))
9101 (match_operand:SWI 1 "<general_operand>")))
9102 (clobber (reg:CC FLAGS_REG))]
9103 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)
9104 && ix86_pre_reload_split ()"
9107 [(set (reg:CC FLAGS_REG)
9108 (compare:CC (match_dup 2) (const_int 1)))
9109 (parallel [(set (match_dup 0)
9110 (minus:SWI (minus:SWI
9112 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9114 (clobber (reg:CC FLAGS_REG))])]
9116 if (!nonimmediate_operand (operands[1], <MODE>mode))
9117 operands[1] = force_reg (<MODE>mode, operands[1]);
9120 (define_insn_and_split "*sub<mode>3_eq"
9121 [(set (match_operand:SWI 0 "nonimmediate_operand")
9124 (match_operand:SWI 1 "nonimmediate_operand")
9125 (eq:SWI (match_operand 3 "int_nonimmediate_operand")
9127 (match_operand:SWI 2 "<general_operand>")))
9128 (clobber (reg:CC FLAGS_REG))]
9129 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
9130 && ix86_pre_reload_split ()"
9133 [(set (reg:CC FLAGS_REG)
9134 (compare:CC (match_dup 3) (const_int 1)))
9135 (parallel [(set (match_dup 0)
9137 (minus:SWI (match_dup 1)
9138 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9140 (clobber (reg:CC FLAGS_REG))])])
9142 (define_insn_and_split "*sub<mode>3_ne"
9143 [(set (match_operand:SWI 0 "nonimmediate_operand")
9146 (match_operand:SWI 1 "nonimmediate_operand")
9147 (ne:SWI (match_operand 3 "int_nonimmediate_operand")
9149 (match_operand:SWI 2 "<immediate_operand>")))
9150 (clobber (reg:CC FLAGS_REG))]
9151 "CONST_INT_P (operands[2])
9152 && (<MODE>mode != DImode
9153 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
9154 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
9155 && ix86_pre_reload_split ()"
9158 [(set (reg:CC FLAGS_REG)
9159 (compare:CC (match_dup 3) (const_int 1)))
9160 (parallel [(set (match_dup 0)
9162 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9165 (clobber (reg:CC FLAGS_REG))])]
9167 operands[2] = gen_int_mode (INTVAL (operands[2]) - 1,
9168 <MODE>mode == DImode ? SImode : <MODE>mode);
9171 (define_insn_and_split "*sub<mode>3_eq_1"
9172 [(set (match_operand:SWI 0 "nonimmediate_operand")
9175 (match_operand:SWI 1 "nonimmediate_operand")
9176 (eq:SWI (match_operand 3 "int_nonimmediate_operand")
9178 (match_operand:SWI 2 "<immediate_operand>")))
9179 (clobber (reg:CC FLAGS_REG))]
9180 "CONST_INT_P (operands[2])
9181 && (<MODE>mode != DImode
9182 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
9183 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
9184 && ix86_pre_reload_split ()"
9187 [(set (reg:CC FLAGS_REG)
9188 (compare:CC (match_dup 3) (const_int 1)))
9189 (parallel [(set (match_dup 0)
9191 (minus:SWI (match_dup 1)
9192 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9194 (clobber (reg:CC FLAGS_REG))])]
9196 operands[2] = gen_int_mode (-INTVAL (operands[2]),
9197 <MODE>mode == DImode ? SImode : <MODE>mode);
9200 (define_insn_and_split "*sub<mode>3_eq_0"
9201 [(set (match_operand:SWI 0 "nonimmediate_operand")
9203 (match_operand:SWI 1 "<general_operand>")
9204 (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))))
9205 (clobber (reg:CC FLAGS_REG))]
9206 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)
9207 && ix86_pre_reload_split ()"
9210 [(set (reg:CC FLAGS_REG)
9211 (compare:CC (match_dup 2) (const_int 1)))
9212 (parallel [(set (match_dup 0)
9213 (minus:SWI (match_dup 1)
9214 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))))
9215 (clobber (reg:CC FLAGS_REG))])]
9217 if (!nonimmediate_operand (operands[1], <MODE>mode))
9218 operands[1] = force_reg (<MODE>mode, operands[1]);
9221 (define_insn_and_split "*sub<mode>3_ne_0"
9222 [(set (match_operand:SWI 0 "nonimmediate_operand")
9224 (match_operand:SWI 1 "<general_operand>")
9225 (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))))
9226 (clobber (reg:CC FLAGS_REG))]
9227 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)
9228 && ix86_pre_reload_split ()"
9231 [(set (reg:CC FLAGS_REG)
9232 (compare:CC (match_dup 2) (const_int 1)))
9233 (parallel [(set (match_dup 0)
9235 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9238 (clobber (reg:CC FLAGS_REG))])]
9240 if (!nonimmediate_operand (operands[1], <MODE>mode))
9241 operands[1] = force_reg (<MODE>mode, operands[1]);
9244 ;; The patterns that match these are at the end of this file.
9246 (define_expand "<insn>xf3"
9247 [(set (match_operand:XF 0 "register_operand")
9249 (match_operand:XF 1 "register_operand")
9250 (match_operand:XF 2 "register_operand")))]
9253 (define_expand "<insn>hf3"
9254 [(set (match_operand:HF 0 "register_operand")
9256 (match_operand:HF 1 "register_operand")
9257 (match_operand:HF 2 "nonimmediate_operand")))]
9258 "TARGET_AVX512FP16")
9260 (define_expand "<insn><mode>3"
9261 [(set (match_operand:MODEF 0 "register_operand")
9263 (match_operand:MODEF 1 "register_operand")
9264 (match_operand:MODEF 2 "nonimmediate_operand")))]
9265 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
9266 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
9268 ;; Multiply instructions
9270 (define_expand "mul<mode>3"
9271 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
9273 (match_operand:SWIM248 1 "register_operand")
9274 (match_operand:SWIM248 2 "<general_operand>")))
9275 (clobber (reg:CC FLAGS_REG))])])
9277 (define_expand "mulqi3"
9278 [(parallel [(set (match_operand:QI 0 "register_operand")
9280 (match_operand:QI 1 "register_operand")
9281 (match_operand:QI 2 "nonimmediate_operand")))
9282 (clobber (reg:CC FLAGS_REG))])]
9283 "TARGET_QIMODE_MATH")
9286 ;; IMUL reg32/64, reg32/64, imm8 Direct
9287 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
9288 ;; IMUL reg32/64, reg32/64, imm32 Direct
9289 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
9290 ;; IMUL reg32/64, reg32/64 Direct
9291 ;; IMUL reg32/64, mem32/64 Direct
9293 ;; On BDVER1, all above IMULs use DirectPath
9296 ;; IMUL reg16, reg16, imm8 VectorPath
9297 ;; IMUL reg16, mem16, imm8 VectorPath
9298 ;; IMUL reg16, reg16, imm16 VectorPath
9299 ;; IMUL reg16, mem16, imm16 VectorPath
9300 ;; IMUL reg16, reg16 Direct
9301 ;; IMUL reg16, mem16 Direct
9303 ;; On BDVER1, all HI MULs use DoublePath
9305 (define_insn "*mul<mode>3_1"
9306 [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
9308 (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
9309 (match_operand:SWIM248 2 "<general_operand>" "K,<i>,<m>r")))
9310 (clobber (reg:CC FLAGS_REG))]
9311 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9313 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9314 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9315 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
9316 [(set_attr "type" "imul")
9317 (set_attr "prefix_0f" "0,0,1")
9318 (set (attr "athlon_decode")
9319 (cond [(eq_attr "cpu" "athlon")
9320 (const_string "vector")
9321 (eq_attr "alternative" "1")
9322 (const_string "vector")
9323 (and (eq_attr "alternative" "2")
9324 (ior (match_test "<MODE>mode == HImode")
9325 (match_operand 1 "memory_operand")))
9326 (const_string "vector")]
9327 (const_string "direct")))
9328 (set (attr "amdfam10_decode")
9329 (cond [(and (eq_attr "alternative" "0,1")
9330 (ior (match_test "<MODE>mode == HImode")
9331 (match_operand 1 "memory_operand")))
9332 (const_string "vector")]
9333 (const_string "direct")))
9334 (set (attr "bdver1_decode")
9336 (match_test "<MODE>mode == HImode")
9337 (const_string "double")
9338 (const_string "direct")))
9339 (set_attr "mode" "<MODE>")])
9341 (define_insn "*mulsi3_1_zext"
9342 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9344 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
9345 (match_operand:SI 2 "x86_64_general_operand" "K,e,BMr"))))
9346 (clobber (reg:CC FLAGS_REG))]
9348 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9350 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
9351 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
9352 imul{l}\t{%2, %k0|%k0, %2}"
9353 [(set_attr "type" "imul")
9354 (set_attr "prefix_0f" "0,0,1")
9355 (set (attr "athlon_decode")
9356 (cond [(eq_attr "cpu" "athlon")
9357 (const_string "vector")
9358 (eq_attr "alternative" "1")
9359 (const_string "vector")
9360 (and (eq_attr "alternative" "2")
9361 (match_operand 1 "memory_operand"))
9362 (const_string "vector")]
9363 (const_string "direct")))
9364 (set (attr "amdfam10_decode")
9365 (cond [(and (eq_attr "alternative" "0,1")
9366 (match_operand 1 "memory_operand"))
9367 (const_string "vector")]
9368 (const_string "direct")))
9369 (set_attr "bdver1_decode" "direct")
9370 (set_attr "mode" "SI")])
9372 ;;On AMDFAM10 and BDVER1
9376 (define_insn "*mulqi3_1"
9377 [(set (match_operand:QI 0 "register_operand" "=a")
9378 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9379 (match_operand:QI 2 "nonimmediate_operand" "qm")))
9380 (clobber (reg:CC FLAGS_REG))]
9382 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9384 [(set_attr "type" "imul")
9385 (set_attr "length_immediate" "0")
9386 (set (attr "athlon_decode")
9387 (if_then_else (eq_attr "cpu" "athlon")
9388 (const_string "vector")
9389 (const_string "direct")))
9390 (set_attr "amdfam10_decode" "direct")
9391 (set_attr "bdver1_decode" "direct")
9392 (set_attr "mode" "QI")])
9394 ;; Multiply with jump on overflow.
9395 (define_expand "mulv<mode>4"
9396 [(parallel [(set (reg:CCO FLAGS_REG)
9399 (match_operand:SWI248 1 "register_operand"))
9402 (mult:SWI248 (match_dup 1)
9403 (match_operand:SWI248 2
9404 "<general_operand>")))))
9405 (set (match_operand:SWI248 0 "register_operand")
9406 (mult:SWI248 (match_dup 1) (match_dup 2)))])
9407 (set (pc) (if_then_else
9408 (eq (reg:CCO FLAGS_REG) (const_int 0))
9409 (label_ref (match_operand 3))
9413 if (CONST_INT_P (operands[2]))
9414 operands[4] = operands[2];
9416 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
9419 (define_insn "*mulv<mode>4"
9420 [(set (reg:CCO FLAGS_REG)
9423 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
9425 (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
9427 (mult:SWI48 (match_dup 1) (match_dup 2)))))
9428 (set (match_operand:SWI48 0 "register_operand" "=r,r")
9429 (mult:SWI48 (match_dup 1) (match_dup 2)))]
9430 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9432 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9433 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
9434 [(set_attr "type" "imul")
9435 (set_attr "prefix_0f" "0,1")
9436 (set (attr "athlon_decode")
9437 (cond [(eq_attr "cpu" "athlon")
9438 (const_string "vector")
9439 (eq_attr "alternative" "0")
9440 (const_string "vector")
9441 (and (eq_attr "alternative" "1")
9442 (match_operand 1 "memory_operand"))
9443 (const_string "vector")]
9444 (const_string "direct")))
9445 (set (attr "amdfam10_decode")
9446 (cond [(and (eq_attr "alternative" "1")
9447 (match_operand 1 "memory_operand"))
9448 (const_string "vector")]
9449 (const_string "direct")))
9450 (set_attr "bdver1_decode" "direct")
9451 (set_attr "mode" "<MODE>")])
9453 (define_insn "*mulvhi4"
9454 [(set (reg:CCO FLAGS_REG)
9457 (match_operand:HI 1 "nonimmediate_operand" "%0"))
9459 (match_operand:HI 2 "nonimmediate_operand" "mr")))
9461 (mult:HI (match_dup 1) (match_dup 2)))))
9462 (set (match_operand:HI 0 "register_operand" "=r")
9463 (mult:HI (match_dup 1) (match_dup 2)))]
9464 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9465 "imul{w}\t{%2, %0|%0, %2}"
9466 [(set_attr "type" "imul")
9467 (set_attr "prefix_0f" "1")
9468 (set_attr "athlon_decode" "vector")
9469 (set_attr "amdfam10_decode" "direct")
9470 (set_attr "bdver1_decode" "double")
9471 (set_attr "mode" "HI")])
9473 (define_insn "*mulv<mode>4_1"
9474 [(set (reg:CCO FLAGS_REG)
9477 (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
9478 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
9480 (mult:SWI248 (match_dup 1)
9481 (match_operand:SWI248 2
9482 "<immediate_operand>" "K,<i>")))))
9483 (set (match_operand:SWI248 0 "register_operand" "=r,r")
9484 (mult:SWI248 (match_dup 1) (match_dup 2)))]
9485 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
9486 && CONST_INT_P (operands[2])
9487 && INTVAL (operands[2]) == INTVAL (operands[3])"
9488 "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
9489 [(set_attr "type" "imul")
9490 (set (attr "prefix_0f")
9492 (match_test "<MODE>mode == HImode")
9494 (const_string "*")))
9495 (set (attr "athlon_decode")
9496 (cond [(eq_attr "cpu" "athlon")
9497 (const_string "vector")
9498 (eq_attr "alternative" "1")
9499 (const_string "vector")]
9500 (const_string "direct")))
9501 (set (attr "amdfam10_decode")
9502 (cond [(ior (match_test "<MODE>mode == HImode")
9503 (match_operand 1 "memory_operand"))
9504 (const_string "vector")]
9505 (const_string "direct")))
9506 (set (attr "bdver1_decode")
9508 (match_test "<MODE>mode == HImode")
9509 (const_string "double")
9510 (const_string "direct")))
9511 (set_attr "mode" "<MODE>")
9512 (set (attr "length_immediate")
9513 (cond [(eq_attr "alternative" "0")
9515 (match_test "<MODE_SIZE> == 8")
9517 (const_string "<MODE_SIZE>")))])
9519 (define_expand "umulv<mode>4"
9520 [(parallel [(set (reg:CCO FLAGS_REG)
9523 (match_operand:SWI248 1
9524 "nonimmediate_operand"))
9526 (match_operand:SWI248 2
9527 "nonimmediate_operand")))
9529 (mult:SWI248 (match_dup 1) (match_dup 2)))))
9530 (set (match_operand:SWI248 0 "register_operand")
9531 (mult:SWI248 (match_dup 1) (match_dup 2)))
9532 (clobber (scratch:SWI248))])
9533 (set (pc) (if_then_else
9534 (eq (reg:CCO FLAGS_REG) (const_int 0))
9535 (label_ref (match_operand 3))
9539 if (MEM_P (operands[1]) && MEM_P (operands[2]))
9540 operands[1] = force_reg (<MODE>mode, operands[1]);
9543 (define_insn "*umulv<mode>4"
9544 [(set (reg:CCO FLAGS_REG)
9547 (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
9549 (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
9551 (mult:SWI248 (match_dup 1) (match_dup 2)))))
9552 (set (match_operand:SWI248 0 "register_operand" "=a")
9553 (mult:SWI248 (match_dup 1) (match_dup 2)))
9554 (clobber (match_scratch:SWI248 3 "=d"))]
9555 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9556 "mul{<imodesuffix>}\t%2"
9557 [(set_attr "type" "imul")
9558 (set_attr "length_immediate" "0")
9559 (set (attr "athlon_decode")
9560 (if_then_else (eq_attr "cpu" "athlon")
9561 (const_string "vector")
9562 (const_string "double")))
9563 (set_attr "amdfam10_decode" "double")
9564 (set_attr "bdver1_decode" "direct")
9565 (set_attr "mode" "<MODE>")])
9567 (define_expand "<u>mulvqi4"
9568 [(parallel [(set (reg:CCO FLAGS_REG)
9571 (match_operand:QI 1 "nonimmediate_operand"))
9573 (match_operand:QI 2 "nonimmediate_operand")))
9575 (mult:QI (match_dup 1) (match_dup 2)))))
9576 (set (match_operand:QI 0 "register_operand")
9577 (mult:QI (match_dup 1) (match_dup 2)))])
9578 (set (pc) (if_then_else
9579 (eq (reg:CCO FLAGS_REG) (const_int 0))
9580 (label_ref (match_operand 3))
9582 "TARGET_QIMODE_MATH"
9584 if (MEM_P (operands[1]) && MEM_P (operands[2]))
9585 operands[1] = force_reg (QImode, operands[1]);
9588 (define_insn "*<u>mulvqi4"
9589 [(set (reg:CCO FLAGS_REG)
9592 (match_operand:QI 1 "nonimmediate_operand" "%0"))
9594 (match_operand:QI 2 "nonimmediate_operand" "qm")))
9596 (mult:QI (match_dup 1) (match_dup 2)))))
9597 (set (match_operand:QI 0 "register_operand" "=a")
9598 (mult:QI (match_dup 1) (match_dup 2)))]
9600 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9601 "<sgnprefix>mul{b}\t%2"
9602 [(set_attr "type" "imul")
9603 (set_attr "length_immediate" "0")
9604 (set (attr "athlon_decode")
9605 (if_then_else (eq_attr "cpu" "athlon")
9606 (const_string "vector")
9607 (const_string "direct")))
9608 (set_attr "amdfam10_decode" "direct")
9609 (set_attr "bdver1_decode" "direct")
9610 (set_attr "mode" "QI")])
9612 (define_expand "<u>mul<mode><dwi>3"
9613 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
9616 (match_operand:DWIH 1 "register_operand"))
9618 (match_operand:DWIH 2 "nonimmediate_operand"))))
9619 (clobber (reg:CC FLAGS_REG))])])
9621 (define_expand "<u>mulqihi3"
9622 [(parallel [(set (match_operand:HI 0 "register_operand")
9625 (match_operand:QI 1 "register_operand"))
9627 (match_operand:QI 2 "nonimmediate_operand"))))
9628 (clobber (reg:CC FLAGS_REG))])]
9629 "TARGET_QIMODE_MATH")
9631 (define_insn "*bmi2_umul<mode><dwi>3_1"
9632 [(set (match_operand:DWIH 0 "register_operand" "=r")
9634 (match_operand:DWIH 2 "register_operand" "%d")
9635 (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
9636 (set (match_operand:DWIH 1 "register_operand" "=r")
9637 (umul_highpart:DWIH (match_dup 2) (match_dup 3)))]
9639 "mulx\t{%3, %0, %1|%1, %0, %3}"
9640 [(set_attr "type" "imulx")
9641 (set_attr "prefix" "vex")
9642 (set_attr "mode" "<MODE>")])
9644 ;; Tweak *bmi2_umul<mode><dwi>3_1 to eliminate following mov.
9646 [(parallel [(set (match_operand:DWIH 0 "general_reg_operand")
9647 (mult:DWIH (match_operand:DWIH 2 "register_operand")
9648 (match_operand:DWIH 3 "nonimmediate_operand")))
9649 (set (match_operand:DWIH 1 "general_reg_operand")
9650 (umul_highpart:DWIH (match_dup 2) (match_dup 3)))])
9651 (set (match_operand:DWIH 4 "general_reg_operand")
9652 (match_operand:DWIH 5 "general_reg_operand"))]
9654 && ((REGNO (operands[5]) == REGNO (operands[0])
9655 && REGNO (operands[1]) != REGNO (operands[4]))
9656 || (REGNO (operands[5]) == REGNO (operands[1])
9657 && REGNO (operands[0]) != REGNO (operands[4])))
9658 && peep2_reg_dead_p (2, operands[5])"
9659 [(parallel [(set (match_dup 0) (mult:DWIH (match_dup 2) (match_dup 3)))
9661 (umul_highpart:DWIH (match_dup 2) (match_dup 3)))])]
9663 if (REGNO (operands[5]) == REGNO (operands[0]))
9664 operands[0] = operands[4];
9666 operands[1] = operands[4];
9669 (define_insn "*umul<mode><dwi>3_1"
9670 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
9673 (match_operand:DWIH 1 "register_operand" "%d,a"))
9675 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
9676 (clobber (reg:CC FLAGS_REG))]
9677 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9680 mul{<imodesuffix>}\t%2"
9681 [(set_attr "isa" "bmi2,*")
9682 (set_attr "type" "imulx,imul")
9683 (set_attr "length_immediate" "*,0")
9684 (set (attr "athlon_decode")
9685 (cond [(eq_attr "alternative" "1")
9686 (if_then_else (eq_attr "cpu" "athlon")
9687 (const_string "vector")
9688 (const_string "double"))]
9689 (const_string "*")))
9690 (set_attr "amdfam10_decode" "*,double")
9691 (set_attr "bdver1_decode" "*,direct")
9692 (set_attr "prefix" "vex,orig")
9693 (set_attr "mode" "<MODE>")])
9695 ;; Convert mul to the mulx pattern to avoid flags dependency.
9697 [(set (match_operand:<DWI> 0 "register_operand")
9700 (match_operand:DWIH 1 "register_operand"))
9702 (match_operand:DWIH 2 "nonimmediate_operand"))))
9703 (clobber (reg:CC FLAGS_REG))]
9704 "TARGET_BMI2 && reload_completed
9705 && REGNO (operands[1]) == DX_REG"
9706 [(parallel [(set (match_dup 3)
9707 (mult:DWIH (match_dup 1) (match_dup 2)))
9709 (umul_highpart:DWIH (match_dup 1) (match_dup 2)))])]
9711 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
9713 operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
9716 (define_insn "*mul<mode><dwi>3_1"
9717 [(set (match_operand:<DWI> 0 "register_operand" "=A")
9720 (match_operand:DWIH 1 "register_operand" "%a"))
9722 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
9723 (clobber (reg:CC FLAGS_REG))]
9724 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9725 "imul{<imodesuffix>}\t%2"
9726 [(set_attr "type" "imul")
9727 (set_attr "length_immediate" "0")
9728 (set (attr "athlon_decode")
9729 (if_then_else (eq_attr "cpu" "athlon")
9730 (const_string "vector")
9731 (const_string "double")))
9732 (set_attr "amdfam10_decode" "double")
9733 (set_attr "bdver1_decode" "direct")
9734 (set_attr "mode" "<MODE>")])
9736 (define_insn "*<u>mulqihi3_1"
9737 [(set (match_operand:HI 0 "register_operand" "=a")
9740 (match_operand:QI 1 "register_operand" "%0"))
9742 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
9743 (clobber (reg:CC FLAGS_REG))]
9745 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9746 "<sgnprefix>mul{b}\t%2"
9747 [(set_attr "type" "imul")
9748 (set_attr "length_immediate" "0")
9749 (set (attr "athlon_decode")
9750 (if_then_else (eq_attr "cpu" "athlon")
9751 (const_string "vector")
9752 (const_string "direct")))
9753 (set_attr "amdfam10_decode" "direct")
9754 (set_attr "bdver1_decode" "direct")
9755 (set_attr "mode" "QI")])
9757 ;; Widening multiplication peephole2s to tweak register allocation.
9758 ;; mov imm,%rdx; mov %rdi,%rax; mulq %rdx -> mov imm,%rax; mulq %rdi
9760 [(set (match_operand:DWIH 0 "general_reg_operand")
9761 (match_operand:DWIH 1 "immediate_operand"))
9762 (set (match_operand:DWIH 2 "general_reg_operand")
9763 (match_operand:DWIH 3 "general_reg_operand"))
9764 (parallel [(set (match_operand:<DWI> 4 "general_reg_operand")
9765 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
9766 (zero_extend:<DWI> (match_dup 0))))
9767 (clobber (reg:CC FLAGS_REG))])]
9768 "REGNO (operands[3]) != AX_REG
9769 && REGNO (operands[0]) != REGNO (operands[2])
9770 && REGNO (operands[0]) != REGNO (operands[3])
9771 && (REGNO (operands[0]) == REGNO (operands[4])
9772 || REGNO (operands[0]) == DX_REG
9773 || peep2_reg_dead_p (3, operands[0]))"
9774 [(set (match_dup 2) (match_dup 1))
9775 (parallel [(set (match_dup 4)
9776 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
9777 (zero_extend:<DWI> (match_dup 3))))
9778 (clobber (reg:CC FLAGS_REG))])])
9780 ;; mov imm,%rax; mov %rdi,%rdx; mulx %rax -> mov imm,%rdx; mulx %rdi
9782 [(set (match_operand:DWIH 0 "general_reg_operand")
9783 (match_operand:DWIH 1 "immediate_operand"))
9784 (set (match_operand:DWIH 2 "general_reg_operand")
9785 (match_operand:DWIH 3 "general_reg_operand"))
9786 (parallel [(set (match_operand:DWIH 4 "general_reg_operand")
9787 (mult:DWIH (match_dup 2) (match_dup 0)))
9788 (set (match_operand:DWIH 5 "general_reg_operand")
9789 (umul_highpart:DWIH (match_dup 2) (match_dup 0)))])]
9790 "REGNO (operands[3]) != DX_REG
9791 && REGNO (operands[0]) != REGNO (operands[2])
9792 && REGNO (operands[0]) != REGNO (operands[3])
9793 && (REGNO (operands[0]) == REGNO (operands[4])
9794 || REGNO (operands[0]) == REGNO (operands[5])
9795 || peep2_reg_dead_p (3, operands[0]))"
9796 [(set (match_dup 2) (match_dup 1))
9797 (parallel [(set (match_dup 4)
9798 (mult:DWIH (match_dup 2) (match_dup 3)))
9800 (umul_highpart:DWIH (match_dup 2) (match_dup 3)))])])
9802 ;; Highpart multiplication patterns
9803 (define_insn "<s>mul<mode>3_highpart"
9804 [(set (match_operand:DWIH 0 "register_operand" "=d")
9805 (any_mul_highpart:DWIH
9806 (match_operand:DWIH 1 "register_operand" "%a")
9807 (match_operand:DWIH 2 "nonimmediate_operand" "rm")))
9808 (clobber (match_scratch:DWIH 3 "=1"))
9809 (clobber (reg:CC FLAGS_REG))]
9811 "<sgnprefix>mul{<imodesuffix>}\t%2"
9812 [(set_attr "type" "imul")
9813 (set_attr "length_immediate" "0")
9814 (set (attr "athlon_decode")
9815 (if_then_else (eq_attr "cpu" "athlon")
9816 (const_string "vector")
9817 (const_string "double")))
9818 (set_attr "amdfam10_decode" "double")
9819 (set_attr "bdver1_decode" "direct")
9820 (set_attr "mode" "<MODE>")])
9822 (define_insn "*<s>mulsi3_highpart_zext"
9823 [(set (match_operand:DI 0 "register_operand" "=d")
9825 (any_mul_highpart:SI
9826 (match_operand:SI 1 "register_operand" "%a")
9827 (match_operand:SI 2 "nonimmediate_operand" "rm"))))
9828 (clobber (match_scratch:SI 3 "=1"))
9829 (clobber (reg:CC FLAGS_REG))]
9831 "<sgnprefix>mul{l}\t%2"
9832 [(set_attr "type" "imul")
9833 (set_attr "length_immediate" "0")
9834 (set (attr "athlon_decode")
9835 (if_then_else (eq_attr "cpu" "athlon")
9836 (const_string "vector")
9837 (const_string "double")))
9838 (set_attr "amdfam10_decode" "double")
9839 (set_attr "bdver1_decode" "direct")
9840 (set_attr "mode" "SI")])
9842 (define_insn "*<s>muldi3_highpart_1"
9843 [(set (match_operand:DI 0 "register_operand" "=d")
9848 (match_operand:DI 1 "nonimmediate_operand" "%a"))
9850 (match_operand:DI 2 "nonimmediate_operand" "rm")))
9852 (clobber (match_scratch:DI 3 "=1"))
9853 (clobber (reg:CC FLAGS_REG))]
9855 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9856 "<sgnprefix>mul{q}\t%2"
9857 [(set_attr "type" "imul")
9858 (set_attr "length_immediate" "0")
9859 (set (attr "athlon_decode")
9860 (if_then_else (eq_attr "cpu" "athlon")
9861 (const_string "vector")
9862 (const_string "double")))
9863 (set_attr "amdfam10_decode" "double")
9864 (set_attr "bdver1_decode" "direct")
9865 (set_attr "mode" "DI")])
9867 (define_insn "*<s>mulsi3_highpart_zext"
9868 [(set (match_operand:DI 0 "register_operand" "=d")
9869 (zero_extend:DI (truncate:SI
9871 (mult:DI (any_extend:DI
9872 (match_operand:SI 1 "nonimmediate_operand" "%a"))
9874 (match_operand:SI 2 "nonimmediate_operand" "rm")))
9876 (clobber (match_scratch:SI 3 "=1"))
9877 (clobber (reg:CC FLAGS_REG))]
9879 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9880 "<sgnprefix>mul{l}\t%2"
9881 [(set_attr "type" "imul")
9882 (set_attr "length_immediate" "0")
9883 (set (attr "athlon_decode")
9884 (if_then_else (eq_attr "cpu" "athlon")
9885 (const_string "vector")
9886 (const_string "double")))
9887 (set_attr "amdfam10_decode" "double")
9888 (set_attr "bdver1_decode" "direct")
9889 (set_attr "mode" "SI")])
9891 (define_insn "*<s>mulsi3_highpart_1"
9892 [(set (match_operand:SI 0 "register_operand" "=d")
9897 (match_operand:SI 1 "nonimmediate_operand" "%a"))
9899 (match_operand:SI 2 "nonimmediate_operand" "rm")))
9901 (clobber (match_scratch:SI 3 "=1"))
9902 (clobber (reg:CC FLAGS_REG))]
9903 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9904 "<sgnprefix>mul{l}\t%2"
9905 [(set_attr "type" "imul")
9906 (set_attr "length_immediate" "0")
9907 (set (attr "athlon_decode")
9908 (if_then_else (eq_attr "cpu" "athlon")
9909 (const_string "vector")
9910 (const_string "double")))
9911 (set_attr "amdfam10_decode" "double")
9912 (set_attr "bdver1_decode" "direct")
9913 (set_attr "mode" "SI")])
9915 ;; Highpart multiplication peephole2s to tweak register allocation.
9916 ;; mov imm,%rdx; mov %rdi,%rax; imulq %rdx -> mov imm,%rax; imulq %rdi
9918 [(set (match_operand:SWI48 0 "general_reg_operand")
9919 (match_operand:SWI48 1 "immediate_operand"))
9920 (set (match_operand:SWI48 2 "general_reg_operand")
9921 (match_operand:SWI48 3 "general_reg_operand"))
9922 (parallel [(set (match_operand:SWI48 4 "general_reg_operand")
9923 (any_mul_highpart:SWI48 (match_dup 2) (match_dup 0)))
9924 (clobber (match_dup 2))
9925 (clobber (reg:CC FLAGS_REG))])]
9926 "REGNO (operands[3]) != AX_REG
9927 && REGNO (operands[0]) != REGNO (operands[2])
9928 && REGNO (operands[0]) != REGNO (operands[3])
9929 && (REGNO (operands[0]) == REGNO (operands[4])
9930 || peep2_reg_dead_p (3, operands[0]))"
9931 [(set (match_dup 2) (match_dup 1))
9932 (parallel [(set (match_dup 4)
9933 (any_mul_highpart:SWI48 (match_dup 2) (match_dup 3)))
9934 (clobber (match_dup 2))
9935 (clobber (reg:CC FLAGS_REG))])])
9938 [(set (match_operand:SI 0 "general_reg_operand")
9939 (match_operand:SI 1 "immediate_operand"))
9940 (set (match_operand:SI 2 "general_reg_operand")
9941 (match_operand:SI 3 "general_reg_operand"))
9942 (parallel [(set (match_operand:DI 4 "general_reg_operand")
9944 (any_mul_highpart:SI (match_dup 2) (match_dup 0))))
9945 (clobber (match_dup 2))
9946 (clobber (reg:CC FLAGS_REG))])]
9948 && REGNO (operands[3]) != AX_REG
9949 && REGNO (operands[0]) != REGNO (operands[2])
9950 && REGNO (operands[2]) != REGNO (operands[3])
9951 && REGNO (operands[0]) != REGNO (operands[3])
9952 && (REGNO (operands[0]) == REGNO (operands[4])
9953 || peep2_reg_dead_p (3, operands[0]))"
9954 [(set (match_dup 2) (match_dup 1))
9955 (parallel [(set (match_dup 4)
9957 (any_mul_highpart:SI (match_dup 2) (match_dup 3))))
9958 (clobber (match_dup 2))
9959 (clobber (reg:CC FLAGS_REG))])])
9961 ;; The patterns that match these are at the end of this file.
9963 (define_expand "mulxf3"
9964 [(set (match_operand:XF 0 "register_operand")
9965 (mult:XF (match_operand:XF 1 "register_operand")
9966 (match_operand:XF 2 "register_operand")))]
9969 (define_expand "mulhf3"
9970 [(set (match_operand:HF 0 "register_operand")
9971 (mult:HF (match_operand:HF 1 "register_operand")
9972 (match_operand:HF 2 "nonimmediate_operand")))]
9973 "TARGET_AVX512FP16")
9975 (define_expand "mul<mode>3"
9976 [(set (match_operand:MODEF 0 "register_operand")
9977 (mult:MODEF (match_operand:MODEF 1 "register_operand")
9978 (match_operand:MODEF 2 "nonimmediate_operand")))]
9979 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
9980 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
9982 ;; Divide instructions
9984 ;; The patterns that match these are at the end of this file.
9986 (define_expand "divxf3"
9987 [(set (match_operand:XF 0 "register_operand")
9988 (div:XF (match_operand:XF 1 "register_operand")
9989 (match_operand:XF 2 "register_operand")))]
9992 /* There is no more precision loss than Newton-Rhapson approximation
9993 when using HFmode rcp/rsqrt, so do the transformation directly under
9994 TARGET_RECIP_DIV and fast-math. */
9995 (define_expand "divhf3"
9996 [(set (match_operand:HF 0 "register_operand")
9997 (div:HF (match_operand:HF 1 "register_operand")
9998 (match_operand:HF 2 "nonimmediate_operand")))]
10001 if (TARGET_RECIP_DIV
10002 && optimize_insn_for_speed_p ()
10003 && flag_finite_math_only && !flag_trapping_math
10004 && flag_unsafe_math_optimizations)
10006 rtx op = gen_reg_rtx (HFmode);
10007 operands[2] = force_reg (HFmode, operands[2]);
10008 emit_insn (gen_rcphf2 (op, operands[2]));
10009 emit_insn (gen_mulhf3 (operands[0], operands[1], op));
10014 (define_expand "div<mode>3"
10015 [(set (match_operand:MODEF 0 "register_operand")
10016 (div:MODEF (match_operand:MODEF 1 "register_operand")
10017 (match_operand:MODEF 2 "nonimmediate_operand")))]
10018 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
10019 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10021 if (<MODE>mode == SFmode
10022 && TARGET_SSE && TARGET_SSE_MATH
10023 && TARGET_RECIP_DIV
10024 && optimize_insn_for_speed_p ()
10025 && flag_finite_math_only && !flag_trapping_math
10026 && flag_unsafe_math_optimizations)
10028 ix86_emit_swdivsf (operands[0], operands[1],
10029 operands[2], SFmode);
10034 ;; Divmod instructions.
10036 (define_code_iterator any_div [div udiv])
10037 (define_code_attr paired_mod [(div "mod") (udiv "umod")])
10039 (define_expand "<u>divmod<mode>4"
10040 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
10042 (match_operand:SWIM248 1 "register_operand")
10043 (match_operand:SWIM248 2 "nonimmediate_operand")))
10044 (set (match_operand:SWIM248 3 "register_operand")
10045 (<paired_mod>:SWIM248 (match_dup 1) (match_dup 2)))
10046 (clobber (reg:CC FLAGS_REG))])])
10048 ;; Split with 8bit unsigned divide:
10049 ;; if (dividend an divisor are in [0-255])
10050 ;; use 8bit unsigned integer divide
10052 ;; use original integer divide
10054 [(set (match_operand:SWI48 0 "register_operand")
10055 (any_div:SWI48 (match_operand:SWI48 2 "register_operand")
10056 (match_operand:SWI48 3 "nonimmediate_operand")))
10057 (set (match_operand:SWI48 1 "register_operand")
10058 (<paired_mod>:SWI48 (match_dup 2) (match_dup 3)))
10059 (clobber (reg:CC FLAGS_REG))]
10060 "TARGET_USE_8BIT_IDIV
10061 && TARGET_QIMODE_MATH
10062 && can_create_pseudo_p ()
10063 && !optimize_insn_for_size_p ()"
10065 "ix86_split_idivmod (<MODE>mode, operands, <u_bool>); DONE;")
10068 [(set (match_operand:DI 0 "register_operand")
10070 (any_div:SI (match_operand:SI 2 "register_operand")
10071 (match_operand:SI 3 "nonimmediate_operand"))))
10072 (set (match_operand:SI 1 "register_operand")
10073 (<paired_mod>:SI (match_dup 2) (match_dup 3)))
10074 (clobber (reg:CC FLAGS_REG))]
10076 && TARGET_USE_8BIT_IDIV
10077 && TARGET_QIMODE_MATH
10078 && can_create_pseudo_p ()
10079 && !optimize_insn_for_size_p ()"
10081 "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
10084 [(set (match_operand:DI 1 "register_operand")
10086 (<paired_mod>:SI (match_operand:SI 2 "register_operand")
10087 (match_operand:SI 3 "nonimmediate_operand"))))
10088 (set (match_operand:SI 0 "register_operand")
10089 (any_div:SI (match_dup 2) (match_dup 3)))
10090 (clobber (reg:CC FLAGS_REG))]
10092 && TARGET_USE_8BIT_IDIV
10093 && TARGET_QIMODE_MATH
10094 && can_create_pseudo_p ()
10095 && !optimize_insn_for_size_p ()"
10097 "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
10099 (define_insn_and_split "divmod<mode>4_1"
10100 [(set (match_operand:SWI48 0 "register_operand" "=a")
10101 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
10102 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
10103 (set (match_operand:SWI48 1 "register_operand" "=&d")
10104 (mod:SWI48 (match_dup 2) (match_dup 3)))
10105 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10106 (clobber (reg:CC FLAGS_REG))]
10110 [(parallel [(set (match_dup 1)
10111 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
10112 (clobber (reg:CC FLAGS_REG))])
10113 (parallel [(set (match_dup 0)
10114 (div:SWI48 (match_dup 2) (match_dup 3)))
10116 (mod:SWI48 (match_dup 2) (match_dup 3)))
10117 (use (match_dup 1))
10118 (clobber (reg:CC FLAGS_REG))])]
10120 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
10122 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10123 operands[4] = operands[2];
10126 /* Avoid use of cltd in favor of a mov+shift. */
10127 emit_move_insn (operands[1], operands[2]);
10128 operands[4] = operands[1];
10131 [(set_attr "type" "multi")
10132 (set_attr "mode" "<MODE>")])
10134 (define_insn_and_split "udivmod<mode>4_1"
10135 [(set (match_operand:SWI48 0 "register_operand" "=a")
10136 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
10137 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
10138 (set (match_operand:SWI48 1 "register_operand" "=&d")
10139 (umod:SWI48 (match_dup 2) (match_dup 3)))
10140 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10141 (clobber (reg:CC FLAGS_REG))]
10145 [(set (match_dup 1) (const_int 0))
10146 (parallel [(set (match_dup 0)
10147 (udiv:SWI48 (match_dup 2) (match_dup 3)))
10149 (umod:SWI48 (match_dup 2) (match_dup 3)))
10150 (use (match_dup 1))
10151 (clobber (reg:CC FLAGS_REG))])]
10153 [(set_attr "type" "multi")
10154 (set_attr "mode" "<MODE>")])
10156 (define_insn_and_split "divmodsi4_zext_1"
10157 [(set (match_operand:DI 0 "register_operand" "=a")
10159 (div:SI (match_operand:SI 2 "register_operand" "0")
10160 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10161 (set (match_operand:SI 1 "register_operand" "=&d")
10162 (mod:SI (match_dup 2) (match_dup 3)))
10163 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10164 (clobber (reg:CC FLAGS_REG))]
10167 "&& reload_completed"
10168 [(parallel [(set (match_dup 1)
10169 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10170 (clobber (reg:CC FLAGS_REG))])
10171 (parallel [(set (match_dup 0)
10172 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
10174 (mod:SI (match_dup 2) (match_dup 3)))
10175 (use (match_dup 1))
10176 (clobber (reg:CC FLAGS_REG))])]
10178 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10180 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10181 operands[4] = operands[2];
10184 /* Avoid use of cltd in favor of a mov+shift. */
10185 emit_move_insn (operands[1], operands[2]);
10186 operands[4] = operands[1];
10189 [(set_attr "type" "multi")
10190 (set_attr "mode" "SI")])
10192 (define_insn_and_split "udivmodsi4_zext_1"
10193 [(set (match_operand:DI 0 "register_operand" "=a")
10195 (udiv:SI (match_operand:SI 2 "register_operand" "0")
10196 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10197 (set (match_operand:SI 1 "register_operand" "=&d")
10198 (umod:SI (match_dup 2) (match_dup 3)))
10199 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10200 (clobber (reg:CC FLAGS_REG))]
10203 "&& reload_completed"
10204 [(set (match_dup 1) (const_int 0))
10205 (parallel [(set (match_dup 0)
10206 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
10208 (umod:SI (match_dup 2) (match_dup 3)))
10209 (use (match_dup 1))
10210 (clobber (reg:CC FLAGS_REG))])]
10212 [(set_attr "type" "multi")
10213 (set_attr "mode" "SI")])
10215 (define_insn_and_split "divmodsi4_zext_2"
10216 [(set (match_operand:DI 1 "register_operand" "=&d")
10218 (mod:SI (match_operand:SI 2 "register_operand" "0")
10219 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10220 (set (match_operand:SI 0 "register_operand" "=a")
10221 (div:SI (match_dup 2) (match_dup 3)))
10222 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10223 (clobber (reg:CC FLAGS_REG))]
10226 "&& reload_completed"
10227 [(parallel [(set (match_dup 6)
10228 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10229 (clobber (reg:CC FLAGS_REG))])
10230 (parallel [(set (match_dup 1)
10231 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
10233 (div:SI (match_dup 2) (match_dup 3)))
10234 (use (match_dup 6))
10235 (clobber (reg:CC FLAGS_REG))])]
10237 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10238 operands[6] = gen_lowpart (SImode, operands[1]);
10240 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10241 operands[4] = operands[2];
10244 /* Avoid use of cltd in favor of a mov+shift. */
10245 emit_move_insn (operands[6], operands[2]);
10246 operands[4] = operands[6];
10249 [(set_attr "type" "multi")
10250 (set_attr "mode" "SI")])
10252 (define_insn_and_split "udivmodsi4_zext_2"
10253 [(set (match_operand:DI 1 "register_operand" "=&d")
10255 (umod:SI (match_operand:SI 2 "register_operand" "0")
10256 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10257 (set (match_operand:SI 0 "register_operand" "=a")
10258 (udiv:SI (match_dup 2) (match_dup 3)))
10259 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10260 (clobber (reg:CC FLAGS_REG))]
10263 "&& reload_completed"
10264 [(set (match_dup 4) (const_int 0))
10265 (parallel [(set (match_dup 1)
10266 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
10268 (udiv:SI (match_dup 2) (match_dup 3)))
10269 (use (match_dup 4))
10270 (clobber (reg:CC FLAGS_REG))])]
10271 "operands[4] = gen_lowpart (SImode, operands[1]);"
10272 [(set_attr "type" "multi")
10273 (set_attr "mode" "SI")])
10275 (define_insn_and_split "*divmod<mode>4"
10276 [(set (match_operand:SWIM248 0 "register_operand" "=a")
10277 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
10278 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
10279 (set (match_operand:SWIM248 1 "register_operand" "=&d")
10280 (mod:SWIM248 (match_dup 2) (match_dup 3)))
10281 (clobber (reg:CC FLAGS_REG))]
10285 [(parallel [(set (match_dup 1)
10286 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
10287 (clobber (reg:CC FLAGS_REG))])
10288 (parallel [(set (match_dup 0)
10289 (div:SWIM248 (match_dup 2) (match_dup 3)))
10291 (mod:SWIM248 (match_dup 2) (match_dup 3)))
10292 (use (match_dup 1))
10293 (clobber (reg:CC FLAGS_REG))])]
10295 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
10297 if (<MODE>mode != HImode
10298 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
10299 operands[4] = operands[2];
10302 /* Avoid use of cltd in favor of a mov+shift. */
10303 emit_move_insn (operands[1], operands[2]);
10304 operands[4] = operands[1];
10307 [(set_attr "type" "multi")
10308 (set_attr "mode" "<MODE>")])
10310 (define_insn_and_split "*udivmod<mode>4"
10311 [(set (match_operand:SWIM248 0 "register_operand" "=a")
10312 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
10313 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
10314 (set (match_operand:SWIM248 1 "register_operand" "=&d")
10315 (umod:SWIM248 (match_dup 2) (match_dup 3)))
10316 (clobber (reg:CC FLAGS_REG))]
10320 [(set (match_dup 1) (const_int 0))
10321 (parallel [(set (match_dup 0)
10322 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
10324 (umod:SWIM248 (match_dup 2) (match_dup 3)))
10325 (use (match_dup 1))
10326 (clobber (reg:CC FLAGS_REG))])]
10328 [(set_attr "type" "multi")
10329 (set_attr "mode" "<MODE>")])
10331 ;; Optimize division or modulo by constant power of 2, if the constant
10332 ;; materializes only after expansion.
10333 (define_insn_and_split "*udivmod<mode>4_pow2"
10334 [(set (match_operand:SWI48 0 "register_operand" "=r")
10335 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
10336 (match_operand:SWI48 3 "const_int_operand")))
10337 (set (match_operand:SWI48 1 "register_operand" "=r")
10338 (umod:SWI48 (match_dup 2) (match_dup 3)))
10339 (clobber (reg:CC FLAGS_REG))]
10340 "IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
10342 "&& reload_completed"
10343 [(set (match_dup 1) (match_dup 2))
10344 (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
10345 (clobber (reg:CC FLAGS_REG))])
10346 (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
10347 (clobber (reg:CC FLAGS_REG))])]
10349 int v = exact_log2 (UINTVAL (operands[3]));
10350 operands[4] = GEN_INT (v);
10351 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
10353 [(set_attr "type" "multi")
10354 (set_attr "mode" "<MODE>")])
10356 (define_insn_and_split "*divmodsi4_zext_1"
10357 [(set (match_operand:DI 0 "register_operand" "=a")
10359 (div:SI (match_operand:SI 2 "register_operand" "0")
10360 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10361 (set (match_operand:SI 1 "register_operand" "=&d")
10362 (mod:SI (match_dup 2) (match_dup 3)))
10363 (clobber (reg:CC FLAGS_REG))]
10366 "&& reload_completed"
10367 [(parallel [(set (match_dup 1)
10368 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10369 (clobber (reg:CC FLAGS_REG))])
10370 (parallel [(set (match_dup 0)
10371 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
10373 (mod:SI (match_dup 2) (match_dup 3)))
10374 (use (match_dup 1))
10375 (clobber (reg:CC FLAGS_REG))])]
10377 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10379 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10380 operands[4] = operands[2];
10383 /* Avoid use of cltd in favor of a mov+shift. */
10384 emit_move_insn (operands[1], operands[2]);
10385 operands[4] = operands[1];
10388 [(set_attr "type" "multi")
10389 (set_attr "mode" "SI")])
10391 (define_insn_and_split "*udivmodsi4_zext_1"
10392 [(set (match_operand:DI 0 "register_operand" "=a")
10394 (udiv:SI (match_operand:SI 2 "register_operand" "0")
10395 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10396 (set (match_operand:SI 1 "register_operand" "=&d")
10397 (umod:SI (match_dup 2) (match_dup 3)))
10398 (clobber (reg:CC FLAGS_REG))]
10401 "&& reload_completed"
10402 [(set (match_dup 1) (const_int 0))
10403 (parallel [(set (match_dup 0)
10404 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
10406 (umod:SI (match_dup 2) (match_dup 3)))
10407 (use (match_dup 1))
10408 (clobber (reg:CC FLAGS_REG))])]
10410 [(set_attr "type" "multi")
10411 (set_attr "mode" "SI")])
10413 (define_insn_and_split "*udivmodsi4_pow2_zext_1"
10414 [(set (match_operand:DI 0 "register_operand" "=r")
10416 (udiv:SI (match_operand:SI 2 "register_operand" "0")
10417 (match_operand:SI 3 "const_int_operand"))))
10418 (set (match_operand:SI 1 "register_operand" "=r")
10419 (umod:SI (match_dup 2) (match_dup 3)))
10420 (clobber (reg:CC FLAGS_REG))]
10422 && IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
10424 "&& reload_completed"
10425 [(set (match_dup 1) (match_dup 2))
10426 (parallel [(set (match_dup 0)
10427 (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4))))
10428 (clobber (reg:CC FLAGS_REG))])
10429 (parallel [(set (match_dup 1) (and:SI (match_dup 1) (match_dup 5)))
10430 (clobber (reg:CC FLAGS_REG))])]
10432 int v = exact_log2 (UINTVAL (operands[3]));
10433 operands[4] = GEN_INT (v);
10434 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
10436 [(set_attr "type" "multi")
10437 (set_attr "mode" "SI")])
10439 (define_insn_and_split "*divmodsi4_zext_2"
10440 [(set (match_operand:DI 1 "register_operand" "=&d")
10442 (mod:SI (match_operand:SI 2 "register_operand" "0")
10443 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10444 (set (match_operand:SI 0 "register_operand" "=a")
10445 (div:SI (match_dup 2) (match_dup 3)))
10446 (clobber (reg:CC FLAGS_REG))]
10449 "&& reload_completed"
10450 [(parallel [(set (match_dup 6)
10451 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10452 (clobber (reg:CC FLAGS_REG))])
10453 (parallel [(set (match_dup 1)
10454 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
10456 (div:SI (match_dup 2) (match_dup 3)))
10457 (use (match_dup 6))
10458 (clobber (reg:CC FLAGS_REG))])]
10460 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10461 operands[6] = gen_lowpart (SImode, operands[1]);
10463 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10464 operands[4] = operands[2];
10467 /* Avoid use of cltd in favor of a mov+shift. */
10468 emit_move_insn (operands[6], operands[2]);
10469 operands[4] = operands[6];
10472 [(set_attr "type" "multi")
10473 (set_attr "mode" "SI")])
10475 (define_insn_and_split "*udivmodsi4_zext_2"
10476 [(set (match_operand:DI 1 "register_operand" "=&d")
10478 (umod:SI (match_operand:SI 2 "register_operand" "0")
10479 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10480 (set (match_operand:SI 0 "register_operand" "=a")
10481 (udiv:SI (match_dup 2) (match_dup 3)))
10482 (clobber (reg:CC FLAGS_REG))]
10485 "&& reload_completed"
10486 [(set (match_dup 4) (const_int 0))
10487 (parallel [(set (match_dup 1)
10488 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
10490 (udiv:SI (match_dup 2) (match_dup 3)))
10491 (use (match_dup 4))
10492 (clobber (reg:CC FLAGS_REG))])]
10493 "operands[4] = gen_lowpart (SImode, operands[1]);"
10494 [(set_attr "type" "multi")
10495 (set_attr "mode" "SI")])
10497 (define_insn_and_split "*udivmodsi4_pow2_zext_2"
10498 [(set (match_operand:DI 1 "register_operand" "=r")
10500 (umod:SI (match_operand:SI 2 "register_operand" "0")
10501 (match_operand:SI 3 "const_int_operand"))))
10502 (set (match_operand:SI 0 "register_operand" "=r")
10503 (udiv:SI (match_dup 2) (match_dup 3)))
10504 (clobber (reg:CC FLAGS_REG))]
10506 && IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
10508 "&& reload_completed"
10509 [(set (match_dup 1) (match_dup 2))
10510 (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4)))
10511 (clobber (reg:CC FLAGS_REG))])
10512 (parallel [(set (match_dup 1)
10513 (zero_extend:DI (and:SI (match_dup 1) (match_dup 5))))
10514 (clobber (reg:CC FLAGS_REG))])]
10516 int v = exact_log2 (UINTVAL (operands[3]));
10517 operands[4] = GEN_INT (v);
10518 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
10520 [(set_attr "type" "multi")
10521 (set_attr "mode" "SI")])
10523 (define_insn "*<u>divmod<mode>4_noext"
10524 [(set (match_operand:SWIM248 0 "register_operand" "=a")
10526 (match_operand:SWIM248 2 "register_operand" "0")
10527 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
10528 (set (match_operand:SWIM248 1 "register_operand" "=d")
10529 (<paired_mod>:SWIM248 (match_dup 2) (match_dup 3)))
10530 (use (match_operand:SWIM248 4 "register_operand" "1"))
10531 (clobber (reg:CC FLAGS_REG))]
10533 "<sgnprefix>div{<imodesuffix>}\t%3"
10534 [(set_attr "type" "idiv")
10535 (set_attr "mode" "<MODE>")])
10537 (define_insn "*<u>divmodsi4_noext_zext_1"
10538 [(set (match_operand:DI 0 "register_operand" "=a")
10540 (any_div:SI (match_operand:SI 2 "register_operand" "0")
10541 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10542 (set (match_operand:SI 1 "register_operand" "=d")
10543 (<paired_mod>:SI (match_dup 2) (match_dup 3)))
10544 (use (match_operand:SI 4 "register_operand" "1"))
10545 (clobber (reg:CC FLAGS_REG))]
10547 "<sgnprefix>div{l}\t%3"
10548 [(set_attr "type" "idiv")
10549 (set_attr "mode" "SI")])
10551 (define_insn "*<u>divmodsi4_noext_zext_2"
10552 [(set (match_operand:DI 1 "register_operand" "=d")
10554 (<paired_mod>:SI (match_operand:SI 2 "register_operand" "0")
10555 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10556 (set (match_operand:SI 0 "register_operand" "=a")
10557 (any_div:SI (match_dup 2) (match_dup 3)))
10558 (use (match_operand:SI 4 "register_operand" "1"))
10559 (clobber (reg:CC FLAGS_REG))]
10561 "<sgnprefix>div{l}\t%3"
10562 [(set_attr "type" "idiv")
10563 (set_attr "mode" "SI")])
10565 ;; Avoid sign-extension (using cdq) for constant numerators.
10566 (define_insn_and_split "*divmodsi4_const"
10567 [(set (match_operand:SI 0 "register_operand" "=&a")
10568 (div:SI (match_operand:SI 2 "const_int_operand")
10569 (match_operand:SI 3 "nonimmediate_operand" "rm")))
10570 (set (match_operand:SI 1 "register_operand" "=&d")
10571 (mod:SI (match_dup 2) (match_dup 3)))
10572 (clobber (reg:CC FLAGS_REG))]
10573 "!optimize_function_for_size_p (cfun)"
10575 "&& reload_completed"
10576 [(set (match_dup 0) (match_dup 2))
10577 (set (match_dup 1) (match_dup 4))
10578 (parallel [(set (match_dup 0)
10579 (div:SI (match_dup 0) (match_dup 3)))
10581 (mod:SI (match_dup 0) (match_dup 3)))
10582 (use (match_dup 1))
10583 (clobber (reg:CC FLAGS_REG))])]
10585 operands[4] = INTVAL (operands[2]) < 0 ? constm1_rtx : const0_rtx;
10587 [(set_attr "type" "multi")
10588 (set_attr "mode" "SI")])
10590 (define_expand "divmodqi4"
10591 [(parallel [(set (match_operand:QI 0 "register_operand")
10593 (match_operand:QI 1 "register_operand")
10594 (match_operand:QI 2 "nonimmediate_operand")))
10595 (set (match_operand:QI 3 "register_operand")
10596 (mod:QI (match_dup 1) (match_dup 2)))
10597 (clobber (reg:CC FLAGS_REG))])]
10598 "TARGET_QIMODE_MATH"
10603 tmp0 = gen_reg_rtx (HImode);
10604 tmp1 = gen_reg_rtx (HImode);
10606 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
10607 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
10608 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
10610 /* Extract remainder from AH. */
10611 tmp1 = gen_rtx_ZERO_EXTRACT (HImode, tmp0, GEN_INT (8), GEN_INT (8));
10612 tmp1 = lowpart_subreg (QImode, tmp1, HImode);
10613 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
10615 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
10616 set_unique_reg_note (insn, REG_EQUAL, mod);
10618 /* Extract quotient from AL. */
10619 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
10621 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
10622 set_unique_reg_note (insn, REG_EQUAL, div);
10627 (define_expand "udivmodqi4"
10628 [(parallel [(set (match_operand:QI 0 "register_operand")
10630 (match_operand:QI 1 "register_operand")
10631 (match_operand:QI 2 "nonimmediate_operand")))
10632 (set (match_operand:QI 3 "register_operand")
10633 (umod:QI (match_dup 1) (match_dup 2)))
10634 (clobber (reg:CC FLAGS_REG))])]
10635 "TARGET_QIMODE_MATH"
10640 tmp0 = gen_reg_rtx (HImode);
10641 tmp1 = gen_reg_rtx (HImode);
10643 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
10644 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
10645 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
10647 /* Extract remainder from AH. */
10648 tmp1 = gen_rtx_ZERO_EXTRACT (HImode, tmp0, GEN_INT (8), GEN_INT (8));
10649 tmp1 = lowpart_subreg (QImode, tmp1, HImode);
10650 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
10652 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
10653 set_unique_reg_note (insn, REG_EQUAL, mod);
10655 /* Extract quotient from AL. */
10656 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
10658 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
10659 set_unique_reg_note (insn, REG_EQUAL, div);
10664 ;; Divide AX by r/m8, with result stored in
10667 ;; Change div/mod to HImode and extend the second argument to HImode
10668 ;; so that mode of div/mod matches with mode of arguments. Otherwise
10669 ;; combine may fail.
10670 (define_insn "<u>divmodhiqi3"
10671 [(set (match_operand:HI 0 "register_operand" "=a")
10676 (mod:HI (match_operand:HI 1 "register_operand" "0")
10678 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
10682 (div:HI (match_dup 1) (any_extend:HI (match_dup 2)))))))
10683 (clobber (reg:CC FLAGS_REG))]
10684 "TARGET_QIMODE_MATH"
10685 "<sgnprefix>div{b}\t%2"
10686 [(set_attr "type" "idiv")
10687 (set_attr "mode" "QI")])
10689 ;; We cannot use div/idiv for double division, because it causes
10690 ;; "division by zero" on the overflow and that's not what we expect
10691 ;; from truncate. Because true (non truncating) double division is
10692 ;; never generated, we can't create this insn anyway.
10695 ; [(set (match_operand:SI 0 "register_operand" "=a")
10697 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
10699 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
10700 ; (set (match_operand:SI 3 "register_operand" "=d")
10702 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
10703 ; (clobber (reg:CC FLAGS_REG))]
10705 ; "div{l}\t{%2, %0|%0, %2}"
10706 ; [(set_attr "type" "idiv")])
10708 ;;- Logical AND instructions
10710 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
10711 ;; Note that this excludes ah.
10713 (define_expand "@test<mode>_ccno_1"
10714 [(set (reg:CCNO FLAGS_REG)
10717 (match_operand:SWI48 0 "nonimmediate_operand")
10718 (match_operand:SWI48 1 "<nonmemory_szext_operand>"))
10721 (define_expand "testqi_ccz_1"
10722 [(set (reg:CCZ FLAGS_REG)
10725 (match_operand:QI 0 "nonimmediate_operand")
10726 (match_operand:QI 1 "nonmemory_operand"))
10729 (define_insn "*testdi_1"
10730 [(set (reg FLAGS_REG)
10733 (match_operand:DI 0 "nonimmediate_operand" "%r,rm")
10734 (match_operand:DI 1 "x86_64_szext_nonmemory_operand" "Z,re"))
10737 && ix86_match_ccmode
10739 /* If we are going to emit testl instead of testq, and the operands[1]
10740 constant might have the SImode sign bit set, make sure the sign
10741 flag isn't tested, because the instruction will set the sign flag
10742 based on bit 31 rather than bit 63. If it isn't CONST_INT,
10743 conservatively assume it might have bit 31 set. */
10744 (satisfies_constraint_Z (operands[1])
10745 && (!CONST_INT_P (operands[1])
10746 || val_signbit_known_set_p (SImode, INTVAL (operands[1]))))
10747 ? CCZmode : CCNOmode)"
10749 test{l}\t{%k1, %k0|%k0, %k1}
10750 test{q}\t{%1, %0|%0, %1}"
10751 [(set_attr "type" "test")
10752 (set_attr "mode" "SI,DI")])
10754 (define_insn "*testqi_1_maybe_si"
10755 [(set (reg FLAGS_REG)
10758 (match_operand:QI 0 "nonimmediate_operand" "%qm,qm,r")
10759 (match_operand:QI 1 "nonmemory_operand" "q,n,n"))
10761 "ix86_match_ccmode (insn,
10762 CONST_INT_P (operands[1])
10763 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
10765 if (get_attr_mode (insn) == MODE_SI)
10767 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
10768 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
10769 return "test{l}\t{%1, %k0|%k0, %1}";
10771 return "test{b}\t{%1, %0|%0, %1}";
10773 [(set_attr "type" "test")
10775 (cond [(eq_attr "alternative" "2")
10776 (const_string "SI")
10777 (and (match_test "optimize_insn_for_size_p ()")
10778 (and (match_operand 0 "ext_QIreg_operand")
10779 (match_operand 1 "const_0_to_127_operand")))
10780 (const_string "SI")
10782 (const_string "QI")))
10783 (set_attr "pent_pair" "uv,np,np")])
10785 (define_insn "*test<mode>_1"
10786 [(set (reg FLAGS_REG)
10789 (match_operand:SWI124 0 "nonimmediate_operand" "%<r>m,*a,<r>m")
10790 (match_operand:SWI124 1 "<nonmemory_szext_operand>" "<r>,<i>,<i>"))
10792 "ix86_match_ccmode (insn, CCNOmode)"
10793 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
10794 [(set_attr "type" "test")
10795 (set_attr "mode" "<MODE>")
10796 (set_attr "pent_pair" "uv,uv,np")])
10798 (define_expand "testqi_ext_1_ccno"
10799 [(set (reg:CCNO FLAGS_REG)
10804 (match_operand:HI 0 "register_operand")
10807 (match_operand:QI 1 "const_int_operand"))
10810 (define_insn "*testqi_ext<mode>_1"
10811 [(set (reg FLAGS_REG)
10815 (match_operator:SWI248 2 "extract_operator"
10816 [(match_operand 0 "int248_register_operand" "Q")
10819 (match_operand:QI 1 "general_operand" "QnBn"))
10821 "ix86_match_ccmode (insn, CCNOmode)"
10822 "test{b}\t{%1, %h0|%h0, %1}"
10823 [(set_attr "addr" "gpr8")
10824 (set_attr "type" "test")
10825 (set_attr "mode" "QI")])
10827 (define_insn "*testqi_ext<mode>_2"
10828 [(set (reg FLAGS_REG)
10832 (match_operator:SWI248 2 "extract_operator"
10833 [(match_operand 0 "int248_register_operand" "Q")
10837 (match_operator:SWI248 3 "extract_operator"
10838 [(match_operand 1 "int248_register_operand" "Q")
10840 (const_int 8)]) 0))
10842 "ix86_match_ccmode (insn, CCNOmode)"
10843 "test{b}\t{%h1, %h0|%h0, %h1}"
10844 [(set_attr "type" "test")
10845 (set_attr "mode" "QI")])
10847 ;; Provide a *testti instruction that STV can implement using ptest.
10848 ;; This pattern splits into *andti3_doubleword and *cmpti_doubleword.
10849 (define_insn_and_split "*testti_doubleword"
10850 [(set (reg:CCZ FLAGS_REG)
10852 (and:TI (match_operand:TI 0 "register_operand")
10853 (match_operand:TI 1 "general_operand"))
10856 && ix86_pre_reload_split ()"
10859 [(parallel [(set (match_dup 2) (and:TI (match_dup 0) (match_dup 1)))
10860 (clobber (reg:CC FLAGS_REG))])
10861 (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 2) (const_int 0)))]
10863 operands[2] = gen_reg_rtx (TImode);
10864 if (!x86_64_hilo_general_operand (operands[1], TImode))
10865 operands[1] = force_reg (TImode, operands[1]);
10868 ;; Combine likes to form bit extractions for some tests. Humor it.
10869 (define_insn_and_split "*testqi_ext_3"
10870 [(set (match_operand 0 "flags_reg_operand")
10871 (match_operator 1 "compare_operator"
10872 [(zero_extract:SWI248
10873 (match_operand 2 "int_nonimmediate_operand" "rm")
10874 (match_operand:QI 3 "const_int_operand")
10875 (match_operand:QI 4 "const_int_operand"))
10877 "/* Ensure that resulting mask is zero or sign extended operand. */
10878 INTVAL (operands[4]) >= 0
10879 && ((INTVAL (operands[3]) > 0
10880 && INTVAL (operands[3]) + INTVAL (operands[4]) <= 32)
10881 || (<MODE>mode == DImode
10882 && INTVAL (operands[3]) > 32
10883 && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))
10884 && ix86_match_ccmode (insn,
10885 /* If zero_extract mode precision is the same
10886 as len, the SF of the zero_extract
10887 comparison will be the most significant
10888 extracted bit, but this could be matched
10889 after splitting only for pos 0 len all bits
10890 trivial extractions. Require CCZmode. */
10891 (GET_MODE_PRECISION (<MODE>mode)
10892 == INTVAL (operands[3]))
10893 /* Otherwise, require CCZmode if we'd use a mask
10894 with the most significant bit set and can't
10895 widen it to wider mode. *testdi_1 also
10896 requires CCZmode if the mask has bit
10897 31 set and all bits above it clear. */
10898 || (INTVAL (operands[3]) + INTVAL (operands[4])
10900 /* We can't widen also if val is not a REG. */
10901 || (INTVAL (operands[3]) + INTVAL (operands[4])
10902 == GET_MODE_PRECISION (GET_MODE (operands[2]))
10903 && !register_operand (operands[2],
10904 GET_MODE (operands[2])))
10905 /* And we shouldn't widen if
10906 TARGET_PARTIAL_REG_STALL. */
10907 || (TARGET_PARTIAL_REG_STALL
10908 && (INTVAL (operands[3]) + INTVAL (operands[4])
10909 >= (paradoxical_subreg_p (operands[2])
10911 (GET_MODE (SUBREG_REG (operands[2])))
10913 ? GET_MODE_PRECISION
10914 (GET_MODE (SUBREG_REG (operands[2])))
10915 : GET_MODE_PRECISION
10916 (GET_MODE (operands[2])))))
10917 ? CCZmode : CCNOmode)"
10920 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
10922 rtx val = operands[2];
10923 HOST_WIDE_INT len = INTVAL (operands[3]);
10924 HOST_WIDE_INT pos = INTVAL (operands[4]);
10925 machine_mode mode = GET_MODE (val);
10927 if (SUBREG_P (val))
10929 machine_mode submode = GET_MODE (SUBREG_REG (val));
10931 /* Narrow paradoxical subregs to prevent partial register stalls. */
10932 if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)
10933 && GET_MODE_CLASS (submode) == MODE_INT
10934 && (GET_MODE (operands[0]) == CCZmode
10935 || pos + len < GET_MODE_PRECISION (submode)
10936 || REG_P (SUBREG_REG (val))))
10938 val = SUBREG_REG (val);
10943 /* Small HImode tests can be converted to QImode. */
10945 && register_operand (val, HImode))
10947 rtx nval = gen_lowpart (QImode, val);
10949 || GET_MODE (operands[0]) == CCZmode
10957 gcc_assert (pos + len <= GET_MODE_PRECISION (mode));
10959 /* If the mask is going to have the sign bit set in the mode
10960 we want to do the comparison in and user isn't interested just
10961 in the zero flag, then we must widen the target mode. */
10962 if (pos + len == GET_MODE_PRECISION (mode)
10963 && GET_MODE (operands[0]) != CCZmode)
10965 gcc_assert (pos + len < 32 && !MEM_P (val));
10967 val = gen_lowpart (mode, val);
10971 = wi::shifted_mask (pos, len, false, GET_MODE_PRECISION (mode));
10973 operands[2] = gen_rtx_AND (mode, val, immed_wide_int_const (mask, mode));
10976 ;; Split and;cmp (as optimized by combine) into not;test
10977 ;; Except when TARGET_BMI provides andn (*andn_<mode>_ccno).
10978 (define_insn_and_split "*test<mode>_not"
10979 [(set (reg:CCZ FLAGS_REG)
10982 (not:SWI (match_operand:SWI 0 "register_operand"))
10983 (match_operand:SWI 1 "<nonmemory_szext_operand>"))
10985 "ix86_pre_reload_split ()
10986 && (!TARGET_BMI || !REG_P (operands[1]))"
10989 [(set (match_dup 2) (not:SWI (match_dup 0)))
10990 (set (reg:CCZ FLAGS_REG)
10991 (compare:CCZ (and:SWI (match_dup 2) (match_dup 1))
10993 "operands[2] = gen_reg_rtx (<MODE>mode);")
10995 ;; Split and;cmp (as optimized by combine) into andn;cmp $0
10996 (define_insn_and_split "*test<mode>_not_doubleword"
10997 [(set (reg:CCZ FLAGS_REG)
11000 (not:DWI (match_operand:DWI 0 "nonimmediate_operand"))
11001 (match_operand:DWI 1 "nonimmediate_operand"))
11003 "ix86_pre_reload_split ()"
11007 [(set (match_dup 2) (and:DWI (not:DWI (match_dup 0)) (match_dup 1)))
11008 (clobber (reg:CC FLAGS_REG))])
11009 (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 2) (const_int 0)))]
11011 operands[0] = force_reg (<MODE>mode, operands[0]);
11012 operands[2] = gen_reg_rtx (<MODE>mode);
11015 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
11016 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
11017 ;; this is relatively important trick.
11018 ;; Do the conversion only post-reload to avoid limiting of the register class
11021 [(set (match_operand 0 "flags_reg_operand")
11022 (match_operator 1 "compare_operator"
11023 [(and (match_operand 2 "QIreg_operand")
11024 (match_operand 3 "const_int_operand"))
11027 && GET_MODE (operands[2]) != QImode
11028 && ((ix86_match_ccmode (insn, CCZmode)
11029 && !(INTVAL (operands[3]) & ~(255 << 8)))
11030 || (ix86_match_ccmode (insn, CCNOmode)
11031 && !(INTVAL (operands[3]) & ~(127 << 8))))"
11032 [(set (match_dup 0)
11036 (zero_extract:HI (match_dup 2)
11042 operands[2] = gen_lowpart (HImode, operands[2]);
11043 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, QImode);
11047 [(set (match_operand 0 "flags_reg_operand")
11048 (match_operator 1 "compare_operator"
11049 [(and (match_operand 2 "nonimmediate_operand")
11050 (match_operand 3 "const_int_operand"))
11053 && GET_MODE (operands[2]) != QImode
11054 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
11055 && ((ix86_match_ccmode (insn, CCZmode)
11056 && !(INTVAL (operands[3]) & ~255))
11057 || (ix86_match_ccmode (insn, CCNOmode)
11058 && !(INTVAL (operands[3]) & ~127)))"
11059 [(set (match_dup 0)
11060 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
11063 operands[2] = gen_lowpart (QImode, operands[2]);
11064 operands[3] = gen_int_mode (INTVAL (operands[3]), QImode);
11067 ;; Narrow test instructions with immediate operands that test
11068 ;; memory locations for zero. E.g. testl $0x00aa0000, mem can be
11069 ;; converted to testb $0xaa, mem+2. Reject volatile locations and
11070 ;; targets where reading (possibly unaligned) part of memory
11071 ;; location after a large write to the same address causes
11072 ;; store-to-load forwarding stall.
11074 [(set (reg:CCZ FLAGS_REG)
11076 (and:SWI248 (match_operand:SWI248 0 "memory_operand")
11077 (match_operand 1 "const_int_operand"))
11079 "!TARGET_PARTIAL_MEMORY_READ_STALL && !MEM_VOLATILE_P (operands[0])"
11080 [(set (reg:CCZ FLAGS_REG)
11081 (compare:CCZ (match_dup 2) (const_int 0)))]
11083 unsigned HOST_WIDE_INT ival = UINTVAL (operands[1]);
11084 int first_nonzero_byte, bitsize;
11085 rtx new_addr, new_const;
11086 machine_mode new_mode;
11091 /* Clear bits outside mode width. */
11092 ival &= GET_MODE_MASK (<MODE>mode);
11094 first_nonzero_byte = ctz_hwi (ival) / BITS_PER_UNIT;
11096 ival >>= first_nonzero_byte * BITS_PER_UNIT;
11098 bitsize = sizeof (ival) * BITS_PER_UNIT - clz_hwi (ival);
11100 if (bitsize <= GET_MODE_BITSIZE (QImode))
11102 else if (bitsize <= GET_MODE_BITSIZE (HImode))
11104 else if (bitsize <= GET_MODE_BITSIZE (SImode))
11109 if (GET_MODE_SIZE (new_mode) >= GET_MODE_SIZE (<MODE>mode))
11112 new_addr = adjust_address (operands[0], new_mode, first_nonzero_byte);
11113 new_const = gen_int_mode (ival, new_mode);
11115 operands[2] = gen_rtx_AND (new_mode, new_addr, new_const);
11118 ;; %%% This used to optimize known byte-wide and operations to memory,
11119 ;; and sometimes to QImode registers. If this is considered useful,
11120 ;; it should be done with splitters.
11122 (define_expand "and<mode>3"
11123 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
11124 (and:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
11125 (match_operand:SDWIM 2 "<general_szext_operand>")))]
11128 machine_mode mode = <MODE>mode;
11130 if (GET_MODE_SIZE (<MODE>mode) > UNITS_PER_WORD
11131 && !x86_64_hilo_general_operand (operands[2], <MODE>mode))
11132 operands[2] = force_reg (<MODE>mode, operands[2]);
11134 if (GET_MODE_SIZE (<MODE>mode) <= UNITS_PER_WORD
11135 && const_int_operand (operands[2], <MODE>mode)
11136 && register_operand (operands[0], <MODE>mode)
11137 && !(TARGET_ZERO_EXTEND_WITH_AND
11138 && optimize_function_for_speed_p (cfun)))
11140 unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
11142 if (ival == GET_MODE_MASK (SImode))
11144 else if (ival == GET_MODE_MASK (HImode))
11146 else if (ival == GET_MODE_MASK (QImode))
11150 if (mode != <MODE>mode)
11151 emit_insn (gen_extend_insn
11152 (operands[0], gen_lowpart (mode, operands[1]),
11153 <MODE>mode, mode, 1));
11155 ix86_expand_binary_operator (AND, <MODE>mode, operands);
11160 (define_insn_and_split "*and<dwi>3_doubleword"
11161 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
11163 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
11164 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
11165 (clobber (reg:CC FLAGS_REG))]
11166 "ix86_binary_operator_ok (AND, <DWI>mode, operands)"
11168 "&& reload_completed"
11169 [(const_int:DWIH 0)]
11171 bool emit_insn_deleted_note_p = false;
11173 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
11175 if (operands[2] == const0_rtx)
11176 emit_move_insn (operands[0], const0_rtx);
11177 else if (operands[2] == constm1_rtx)
11178 emit_insn_deleted_note_p = true;
11180 ix86_expand_binary_operator (AND, <MODE>mode, &operands[0]);
11182 if (operands[5] == const0_rtx)
11183 emit_move_insn (operands[3], const0_rtx);
11184 else if (operands[5] == constm1_rtx)
11186 if (emit_insn_deleted_note_p)
11187 emit_note (NOTE_INSN_DELETED);
11190 ix86_expand_binary_operator (AND, <MODE>mode, &operands[3]);
11195 (define_insn "*anddi_1"
11196 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,?k")
11198 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
11199 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m,L,k")))
11200 (clobber (reg:CC FLAGS_REG))]
11201 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
11203 and{l}\t{%k2, %k0|%k0, %k2}
11204 and{q}\t{%2, %0|%0, %2}
11205 and{q}\t{%2, %0|%0, %2}
11208 [(set_attr "isa" "x64,x64,x64,x64,avx512bw_512")
11209 (set_attr "type" "alu,alu,alu,imovx,msklog")
11210 (set_attr "length_immediate" "*,*,*,0,*")
11211 (set (attr "prefix_rex")
11213 (and (eq_attr "type" "imovx")
11214 (and (match_test "INTVAL (operands[2]) == 0xff")
11215 (match_operand 1 "ext_QIreg_operand")))
11217 (const_string "*")))
11218 (set_attr "mode" "SI,DI,DI,SI,DI")])
11220 (define_insn_and_split "*anddi_1_btr"
11221 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11223 (match_operand:DI 1 "nonimmediate_operand" "%0")
11224 (match_operand:DI 2 "const_int_operand" "n")))
11225 (clobber (reg:CC FLAGS_REG))]
11226 "TARGET_64BIT && TARGET_USE_BT
11227 && ix86_binary_operator_ok (AND, DImode, operands)
11228 && IN_RANGE (exact_log2 (~INTVAL (operands[2])), 31, 63)"
11230 "&& reload_completed"
11231 [(parallel [(set (zero_extract:DI (match_dup 0)
11235 (clobber (reg:CC FLAGS_REG))])]
11236 "operands[3] = GEN_INT (exact_log2 (~INTVAL (operands[2])));"
11237 [(set_attr "type" "alu1")
11238 (set_attr "prefix_0f" "1")
11239 (set_attr "znver1_decode" "double")
11240 (set_attr "mode" "DI")])
11242 ;; Turn *anddi_1 into *andsi_1_zext if possible.
11244 [(set (match_operand:DI 0 "register_operand")
11245 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
11246 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
11247 (clobber (reg:CC FLAGS_REG))]
11249 [(parallel [(set (match_dup 0)
11250 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
11251 (clobber (reg:CC FLAGS_REG))])]
11253 if (GET_CODE (operands[2]) == SYMBOL_REF
11254 || GET_CODE (operands[2]) == LABEL_REF)
11256 operands[2] = shallow_copy_rtx (operands[2]);
11257 PUT_MODE (operands[2], SImode);
11259 else if (GET_CODE (operands[2]) == CONST)
11261 /* (const:DI (plus:DI (symbol_ref:DI ("...")) (const_int N))) */
11262 operands[2] = copy_rtx (operands[2]);
11263 PUT_MODE (operands[2], SImode);
11264 PUT_MODE (XEXP (operands[2], 0), SImode);
11265 PUT_MODE (XEXP (XEXP (operands[2], 0), 0), SImode);
11268 operands[2] = gen_lowpart (SImode, operands[2]);
11271 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
11272 (define_insn "*andsi_1_zext"
11273 [(set (match_operand:DI 0 "register_operand" "=r")
11275 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
11276 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
11277 (clobber (reg:CC FLAGS_REG))]
11278 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
11279 "and{l}\t{%2, %k0|%k0, %2}"
11280 [(set_attr "type" "alu")
11281 (set_attr "mode" "SI")])
11283 (define_insn "*and<mode>_1"
11284 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya,?k")
11285 (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm,k")
11286 (match_operand:SWI24 2 "<general_operand>" "r<i>,<m>,L,k")))
11287 (clobber (reg:CC FLAGS_REG))]
11288 "ix86_binary_operator_ok (AND, <MODE>mode, operands)"
11290 and{<imodesuffix>}\t{%2, %0|%0, %2}
11291 and{<imodesuffix>}\t{%2, %0|%0, %2}
11295 (cond [(eq_attr "alternative" "3")
11296 (if_then_else (eq_attr "mode" "SI")
11297 (const_string "avx512bw")
11298 (const_string "avx512f"))
11300 (const_string "*")))
11301 (set_attr "type" "alu,alu,imovx,msklog")
11302 (set_attr "length_immediate" "*,*,0,*")
11303 (set (attr "prefix_rex")
11305 (and (eq_attr "type" "imovx")
11306 (and (match_test "INTVAL (operands[2]) == 0xff")
11307 (match_operand 1 "ext_QIreg_operand")))
11309 (const_string "*")))
11310 (set_attr "mode" "<MODE>,<MODE>,SI,<MODE>")])
11312 (define_insn "*andqi_1"
11313 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,?k")
11314 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
11315 (match_operand:QI 2 "general_operand" "qn,m,rn,k")))
11316 (clobber (reg:CC FLAGS_REG))]
11317 "ix86_binary_operator_ok (AND, QImode, operands)"
11319 and{b}\t{%2, %0|%0, %2}
11320 and{b}\t{%2, %0|%0, %2}
11321 and{l}\t{%k2, %k0|%k0, %k2}
11323 [(set_attr "type" "alu,alu,alu,msklog")
11325 (cond [(eq_attr "alternative" "2")
11326 (const_string "SI")
11327 (and (eq_attr "alternative" "3")
11328 (match_test "!TARGET_AVX512DQ"))
11329 (const_string "HI")
11331 (const_string "QI")))
11332 ;; Potential partial reg stall on alternative 2.
11333 (set (attr "preferred_for_speed")
11334 (cond [(eq_attr "alternative" "2")
11335 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
11336 (symbol_ref "true")))])
11338 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
11339 (define_insn_and_split "*and<mode>_1_slp"
11340 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
11341 (and:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0,!<r>")
11342 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
11343 (clobber (reg:CC FLAGS_REG))]
11344 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
11346 and{<imodesuffix>}\t{%2, %0|%0, %2}
11348 "&& reload_completed"
11349 [(set (strict_low_part (match_dup 0)) (match_dup 1))
11351 [(set (strict_low_part (match_dup 0))
11352 (and:SWI12 (match_dup 0) (match_dup 2)))
11353 (clobber (reg:CC FLAGS_REG))])]
11355 [(set_attr "type" "alu")
11356 (set_attr "mode" "<MODE>")])
11359 [(set (match_operand:SWI248 0 "register_operand")
11360 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
11361 (match_operand:SWI248 2 "const_int_operand")))
11362 (clobber (reg:CC FLAGS_REG))]
11364 && (!REG_P (operands[1])
11365 || REGNO (operands[0]) != REGNO (operands[1]))"
11368 unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
11371 if (ival == GET_MODE_MASK (SImode))
11373 else if (ival == GET_MODE_MASK (HImode))
11375 else if (ival == GET_MODE_MASK (QImode))
11378 gcc_unreachable ();
11380 /* Zero extend to SImode to avoid partial register stalls. */
11381 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
11382 operands[0] = gen_lowpart (SImode, operands[0]);
11384 emit_insn (gen_extend_insn
11385 (operands[0], gen_lowpart (mode, operands[1]),
11386 GET_MODE (operands[0]), mode, 1));
11391 [(set (match_operand:SWI48 0 "register_operand")
11392 (and:SWI48 (match_dup 0)
11393 (const_int -65536)))
11394 (clobber (reg:CC FLAGS_REG))]
11395 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
11396 || optimize_function_for_size_p (cfun)"
11397 [(set (strict_low_part (match_dup 1)) (const_int 0))]
11398 "operands[1] = gen_lowpart (HImode, operands[0]);")
11401 [(set (match_operand:SWI248 0 "any_QIreg_operand")
11402 (and:SWI248 (match_dup 0)
11404 (clobber (reg:CC FLAGS_REG))]
11405 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11406 && reload_completed"
11407 [(set (strict_low_part (match_dup 1)) (const_int 0))]
11408 "operands[1] = gen_lowpart (QImode, operands[0]);")
11411 [(set (match_operand:SWI248 0 "QIreg_operand")
11412 (and:SWI248 (match_dup 0)
11413 (const_int -65281)))
11414 (clobber (reg:CC FLAGS_REG))]
11415 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11416 && reload_completed"
11418 [(set (zero_extract:HI (match_dup 0)
11424 (zero_extract:HI (match_dup 0)
11428 (zero_extract:HI (match_dup 0)
11430 (const_int 8)) 0)) 0))
11431 (clobber (reg:CC FLAGS_REG))])]
11432 "operands[0] = gen_lowpart (HImode, operands[0]);")
11434 (define_insn "*anddi_2"
11435 [(set (reg FLAGS_REG)
11438 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
11439 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m"))
11441 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
11442 (and:DI (match_dup 1) (match_dup 2)))]
11444 && ix86_match_ccmode
11446 /* If we are going to emit andl instead of andq, and the operands[2]
11447 constant might have the SImode sign bit set, make sure the sign
11448 flag isn't tested, because the instruction will set the sign flag
11449 based on bit 31 rather than bit 63. If it isn't CONST_INT,
11450 conservatively assume it might have bit 31 set. */
11451 (satisfies_constraint_Z (operands[2])
11452 && (!CONST_INT_P (operands[2])
11453 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
11454 ? CCZmode : CCNOmode)
11455 && ix86_binary_operator_ok (AND, DImode, operands)"
11457 and{l}\t{%k2, %k0|%k0, %k2}
11458 and{q}\t{%2, %0|%0, %2}
11459 and{q}\t{%2, %0|%0, %2}"
11460 [(set_attr "type" "alu")
11461 (set_attr "mode" "SI,DI,DI")])
11463 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
11464 (define_insn "*andsi_2_zext"
11465 [(set (reg FLAGS_REG)
11467 (match_operand:SI 1 "nonimmediate_operand" "%0")
11468 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
11470 (set (match_operand:DI 0 "register_operand" "=r")
11471 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
11472 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
11473 && ix86_binary_operator_ok (AND, SImode, operands)"
11474 "and{l}\t{%2, %k0|%k0, %2}"
11475 [(set_attr "type" "alu")
11476 (set_attr "mode" "SI")])
11478 (define_insn "*andqi_2_maybe_si"
11479 [(set (reg FLAGS_REG)
11481 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
11482 (match_operand:QI 2 "general_operand" "qn,m,n"))
11484 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
11485 (and:QI (match_dup 1) (match_dup 2)))]
11486 "ix86_binary_operator_ok (AND, QImode, operands)
11487 && ix86_match_ccmode (insn,
11488 CONST_INT_P (operands[2])
11489 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
11491 if (get_attr_mode (insn) == MODE_SI)
11493 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
11494 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
11495 return "and{l}\t{%2, %k0|%k0, %2}";
11497 return "and{b}\t{%2, %0|%0, %2}";
11499 [(set_attr "type" "alu")
11501 (cond [(eq_attr "alternative" "2")
11502 (const_string "SI")
11503 (and (match_test "optimize_insn_for_size_p ()")
11504 (and (match_operand 0 "ext_QIreg_operand")
11505 (match_operand 2 "const_0_to_127_operand")))
11506 (const_string "SI")
11508 (const_string "QI")))
11509 ;; Potential partial reg stall on alternative 2.
11510 (set (attr "preferred_for_speed")
11511 (cond [(eq_attr "alternative" "2")
11512 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
11513 (symbol_ref "true")))])
11515 (define_insn "*and<mode>_2"
11516 [(set (reg FLAGS_REG)
11517 (compare (and:SWI124
11518 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
11519 (match_operand:SWI124 2 "<general_operand>" "<r><i>,<m>"))
11521 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>m,<r>")
11522 (and:SWI124 (match_dup 1) (match_dup 2)))]
11523 "ix86_match_ccmode (insn, CCNOmode)
11524 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
11525 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
11526 [(set_attr "type" "alu")
11527 (set_attr "mode" "<MODE>")])
11529 (define_insn "*andqi_ext<mode>_0"
11530 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn")
11533 (match_operator:SWI248 3 "extract_operator"
11534 [(match_operand 2 "int248_register_operand" "Q")
11537 (match_operand:QI 1 "nonimmediate_operand" "0")))
11538 (clobber (reg:CC FLAGS_REG))]
11540 "and{b}\t{%h2, %0|%0, %h2}"
11541 [(set_attr "addr" "gpr8")
11542 (set_attr "type" "alu")
11543 (set_attr "mode" "QI")])
11545 (define_expand "andqi_ext_1"
11547 [(set (zero_extract:HI (match_operand:HI 0 "register_operand")
11553 (zero_extract:HI (match_operand:HI 1 "register_operand")
11556 (match_operand:QI 2 "const_int_operand")) 0))
11557 (clobber (reg:CC FLAGS_REG))])])
11559 (define_insn "*andqi_ext<mode>_1"
11560 [(set (zero_extract:SWI248
11561 (match_operand 0 "int248_register_operand" "+Q")
11567 (match_operator:SWI248 3 "extract_operator"
11568 [(match_operand 1 "int248_register_operand" "0")
11571 (match_operand:QI 2 "general_operand" "QnBn")) 0))
11572 (clobber (reg:CC FLAGS_REG))]
11573 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
11574 rtx_equal_p (operands[0], operands[1])"
11575 "and{b}\t{%2, %h0|%h0, %2}"
11576 [(set_attr "addr" "gpr8")
11577 (set_attr "type" "alu")
11578 (set_attr "mode" "QI")])
11580 ;; Generated by peephole translating test to and. This shows up
11581 ;; often in fp comparisons.
11582 (define_insn "*andqi_ext<mode>_1_cc"
11583 [(set (reg FLAGS_REG)
11587 (match_operator:SWI248 3 "extract_operator"
11588 [(match_operand 1 "int248_register_operand" "0")
11591 (match_operand:QI 2 "general_operand" "QnBn"))
11593 (set (zero_extract:SWI248
11594 (match_operand 0 "int248_register_operand" "+Q")
11604 (match_dup 2)) 0))]
11605 "ix86_match_ccmode (insn, CCNOmode)
11606 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
11607 && rtx_equal_p (operands[0], operands[1])"
11608 "and{b}\t{%2, %h0|%h0, %2}"
11609 [(set_attr "addr" "gpr8")
11610 (set_attr "type" "alu")
11611 (set_attr "mode" "QI")])
11613 (define_insn "*andqi_ext<mode>_2"
11614 [(set (zero_extract:SWI248
11615 (match_operand 0 "int248_register_operand" "+Q")
11621 (match_operator:SWI248 3 "extract_operator"
11622 [(match_operand 1 "int248_register_operand" "%0")
11626 (match_operator:SWI248 4 "extract_operator"
11627 [(match_operand 2 "int248_register_operand" "Q")
11629 (const_int 8)]) 0)) 0))
11630 (clobber (reg:CC FLAGS_REG))]
11631 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
11632 rtx_equal_p (operands[0], operands[1])
11633 || rtx_equal_p (operands[0], operands[2])"
11634 "and{b}\t{%h2, %h0|%h0, %h2}"
11635 [(set_attr "type" "alu")
11636 (set_attr "mode" "QI")])
11638 ;; *andqi_ext<mode>_3 is defined via *<code>qi_ext<mode>_3 below.
11640 ;; Convert wide AND instructions with immediate operand to shorter QImode
11641 ;; equivalents when possible.
11642 ;; Don't do the splitting with memory operands, since it introduces risk
11643 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
11644 ;; for size, but that can (should?) be handled by generic code instead.
11646 [(set (match_operand:SWI248 0 "QIreg_operand")
11647 (and:SWI248 (match_operand:SWI248 1 "register_operand")
11648 (match_operand:SWI248 2 "const_int_operand")))
11649 (clobber (reg:CC FLAGS_REG))]
11651 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11652 && !(~INTVAL (operands[2]) & ~(255 << 8))"
11654 [(set (zero_extract:HI (match_dup 0)
11660 (zero_extract:HI (match_dup 1)
11664 (clobber (reg:CC FLAGS_REG))])]
11666 operands[0] = gen_lowpart (HImode, operands[0]);
11667 operands[1] = gen_lowpart (HImode, operands[1]);
11668 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
11671 ;; Since AND can be encoded with sign extended immediate, this is only
11672 ;; profitable when 7th bit is not set.
11674 [(set (match_operand:SWI248 0 "any_QIreg_operand")
11675 (and:SWI248 (match_operand:SWI248 1 "general_operand")
11676 (match_operand:SWI248 2 "const_int_operand")))
11677 (clobber (reg:CC FLAGS_REG))]
11679 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11680 && !(~INTVAL (operands[2]) & ~255)
11681 && !(INTVAL (operands[2]) & 128)"
11682 [(parallel [(set (strict_low_part (match_dup 0))
11683 (and:QI (match_dup 1)
11685 (clobber (reg:CC FLAGS_REG))])]
11687 operands[0] = gen_lowpart (QImode, operands[0]);
11688 operands[1] = gen_lowpart (QImode, operands[1]);
11689 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
11692 (define_insn_and_split "*andn<dwi>3_doubleword_bmi"
11693 [(set (match_operand:<DWI> 0 "register_operand" "=&r,r,r")
11695 (not:<DWI> (match_operand:<DWI> 1 "register_operand" "r,0,r"))
11696 (match_operand:<DWI> 2 "nonimmediate_operand" "ro,ro,0")))
11697 (clobber (reg:CC FLAGS_REG))]
11700 "&& reload_completed"
11701 [(parallel [(set (match_dup 0)
11702 (and:DWIH (not:DWIH (match_dup 1)) (match_dup 2)))
11703 (clobber (reg:CC FLAGS_REG))])
11704 (parallel [(set (match_dup 3)
11705 (and:DWIH (not:DWIH (match_dup 4)) (match_dup 5)))
11706 (clobber (reg:CC FLAGS_REG))])]
11707 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
11709 (define_insn_and_split "*andn<mode>3_doubleword"
11710 [(set (match_operand:DWI 0 "register_operand")
11712 (not:DWI (match_operand:DWI 1 "register_operand"))
11713 (match_operand:DWI 2 "nonimmediate_operand")))
11714 (clobber (reg:CC FLAGS_REG))]
11716 && ix86_pre_reload_split ()"
11719 [(set (match_dup 3) (not:DWI (match_dup 1)))
11720 (parallel [(set (match_dup 0)
11721 (and:DWI (match_dup 3) (match_dup 2)))
11722 (clobber (reg:CC FLAGS_REG))])]
11723 "operands[3] = gen_reg_rtx (<MODE>mode);")
11725 (define_insn "*andn<mode>_1"
11726 [(set (match_operand:SWI48 0 "register_operand" "=r,r,?k")
11728 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r,k"))
11729 (match_operand:SWI48 2 "nonimmediate_operand" "r,m,k")))
11730 (clobber (reg:CC FLAGS_REG))]
11732 || (TARGET_AVX512BW && (<MODE>mode == SImode || TARGET_EVEX512))"
11734 andn\t{%2, %1, %0|%0, %1, %2}
11735 andn\t{%2, %1, %0|%0, %1, %2}
11737 [(set_attr "isa" "bmi,bmi,<kmov_isa>")
11738 (set_attr "type" "bitmanip,bitmanip,msklog")
11739 (set_attr "btver2_decode" "direct, double,*")
11740 (set_attr "mode" "<MODE>")])
11742 (define_insn "*andn<mode>_1"
11743 [(set (match_operand:SWI12 0 "register_operand" "=r,?k")
11745 (not:SWI12 (match_operand:SWI12 1 "register_operand" "r,k"))
11746 (match_operand:SWI12 2 "register_operand" "r,k")))
11747 (clobber (reg:CC FLAGS_REG))]
11748 "TARGET_BMI || TARGET_AVX512BW"
11750 andn\t{%k2, %k1, %k0|%k0, %k1, %k2}
11752 [(set_attr "isa" "bmi,avx512f")
11753 (set_attr "type" "bitmanip,msklog")
11754 (set_attr "btver2_decode" "direct,*")
11756 (cond [(eq_attr "alternative" "0")
11757 (const_string "SI")
11758 (and (eq_attr "alternative" "1")
11759 (match_test "!TARGET_AVX512DQ"))
11760 (const_string "HI")
11762 (const_string "<MODE>")))])
11764 (define_insn "*andn_<mode>_ccno"
11765 [(set (reg FLAGS_REG)
11768 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
11769 (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
11771 (clobber (match_scratch:SWI48 0 "=r,r"))]
11772 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
11773 "andn\t{%2, %1, %0|%0, %1, %2}"
11774 [(set_attr "type" "bitmanip")
11775 (set_attr "btver2_decode" "direct, double")
11776 (set_attr "mode" "<MODE>")])
11778 ;; Split *andnsi_1 after reload with -Oz when not;and is shorter.
11780 [(set (match_operand:SI 0 "register_operand")
11781 (and:SI (not:SI (match_operand:SI 1 "register_operand"))
11782 (match_operand:SI 2 "nonimmediate_operand")))
11783 (clobber (reg:CC FLAGS_REG))]
11785 && optimize_insn_for_size_p () && optimize_size > 1
11786 && REGNO (operands[0]) == REGNO (operands[1])
11787 && LEGACY_INT_REG_P (operands[0])
11788 && !REX_INT_REG_P (operands[2])
11789 && !reg_overlap_mentioned_p (operands[0], operands[2])"
11790 [(set (match_dup 0) (not:SI (match_dup 1)))
11791 (parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
11792 (clobber (reg:CC FLAGS_REG))])])
11794 ;; Split *andn_si_ccno with -Oz when not;test is shorter.
11796 [(set (match_operand 0 "flags_reg_operand")
11797 (match_operator 1 "compare_operator"
11798 [(and:SI (not:SI (match_operand:SI 2 "general_reg_operand"))
11799 (match_operand:SI 3 "nonimmediate_operand"))
11801 (clobber (match_dup 2))]
11803 && optimize_insn_for_size_p () && optimize_size > 1
11804 && LEGACY_INT_REG_P (operands[2])
11805 && !REX_INT_REG_P (operands[3])
11806 && !reg_overlap_mentioned_p (operands[2], operands[3])"
11807 [(set (match_dup 2) (not:SI (match_dup 2)))
11808 (set (match_dup 0) (match_op_dup 1
11809 [(and:SI (match_dup 3) (match_dup 2))
11812 ;; Variant 1 of 4: Split ((A | B) ^ A) ^ C as (B & ~A) ^ C.
11814 [(set (match_operand:SWI48 0 "register_operand")
11817 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
11818 (match_operand:SWI48 2 "nonimmediate_operand"))
11820 (match_operand:SWI48 3 "nonimmediate_operand")))
11821 (clobber (reg:CC FLAGS_REG))]
11824 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 1)) (match_dup 2)))
11825 (clobber (reg:CC FLAGS_REG))])
11827 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
11828 (clobber (reg:CC FLAGS_REG))])]
11829 "operands[4] = gen_reg_rtx (<MODE>mode);")
11831 ;; Variant 2 of 4: Split ((A | B) ^ B) ^ C as (A & ~B) ^ C.
11833 [(set (match_operand:SWI48 0 "register_operand")
11836 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
11837 (match_operand:SWI48 2 "register_operand"))
11839 (match_operand:SWI48 3 "nonimmediate_operand")))
11840 (clobber (reg:CC FLAGS_REG))]
11843 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 2)) (match_dup 1)))
11844 (clobber (reg:CC FLAGS_REG))])
11846 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
11847 (clobber (reg:CC FLAGS_REG))])]
11848 "operands[4] = gen_reg_rtx (<MODE>mode);")
11850 ;; Variant 3 of 4: Split ((A | B) ^ C) ^ A as (B & ~A) ^ C.
11852 [(set (match_operand:SWI48 0 "register_operand")
11855 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
11856 (match_operand:SWI48 2 "nonimmediate_operand"))
11857 (match_operand:SWI48 3 "nonimmediate_operand"))
11859 (clobber (reg:CC FLAGS_REG))]
11862 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 1)) (match_dup 2)))
11863 (clobber (reg:CC FLAGS_REG))])
11865 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
11866 (clobber (reg:CC FLAGS_REG))])]
11867 "operands[4] = gen_reg_rtx (<MODE>mode);")
11869 ;; Variant 4 of 4: Split ((A | B) ^ C) ^ B as (A & ~B) ^ C.
11871 [(set (match_operand:SWI48 0 "register_operand")
11874 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
11875 (match_operand:SWI48 2 "register_operand"))
11876 (match_operand:SWI48 3 "nonimmediate_operand"))
11878 (clobber (reg:CC FLAGS_REG))]
11881 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 2)) (match_dup 1)))
11882 (clobber (reg:CC FLAGS_REG))])
11884 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
11885 (clobber (reg:CC FLAGS_REG))])]
11886 "operands[4] = gen_reg_rtx (<MODE>mode);")
11888 ;; Logical inclusive and exclusive OR instructions
11890 ;; %%% This used to optimize known byte-wide and operations to memory.
11891 ;; If this is considered useful, it should be done with splitters.
11893 (define_expand "<code><mode>3"
11894 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
11895 (any_or:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
11896 (match_operand:SDWIM 2 "<general_operand>")))]
11899 if (GET_MODE_SIZE (<MODE>mode) > UNITS_PER_WORD
11900 && !x86_64_hilo_general_operand (operands[2], <MODE>mode))
11901 operands[2] = force_reg (<MODE>mode, operands[2]);
11903 ix86_expand_binary_operator (<CODE>, <MODE>mode, operands);
11907 (define_insn_and_split "*<code><dwi>3_doubleword"
11908 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
11910 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
11911 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
11912 (clobber (reg:CC FLAGS_REG))]
11913 "ix86_binary_operator_ok (<CODE>, <DWI>mode, operands)"
11915 "&& reload_completed"
11916 [(const_int:DWIH 0)]
11918 /* This insn may disappear completely when operands[2] == const0_rtx
11919 and operands[0] == operands[1], which requires a NOTE_INSN_DELETED. */
11920 bool emit_insn_deleted_note_p = false;
11922 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
11924 if (operands[2] == const0_rtx)
11925 emit_insn_deleted_note_p = true;
11926 else if (operands[2] == constm1_rtx)
11929 emit_move_insn (operands[0], constm1_rtx);
11931 ix86_expand_unary_operator (NOT, <MODE>mode, &operands[0]);
11934 ix86_expand_binary_operator (<CODE>, <MODE>mode, &operands[0]);
11936 if (operands[5] == const0_rtx)
11938 if (emit_insn_deleted_note_p)
11939 emit_note (NOTE_INSN_DELETED);
11941 else if (operands[5] == constm1_rtx)
11944 emit_move_insn (operands[3], constm1_rtx);
11946 ix86_expand_unary_operator (NOT, <MODE>mode, &operands[3]);
11949 ix86_expand_binary_operator (<CODE>, <MODE>mode, &operands[3]);
11954 (define_insn "*<code><mode>_1"
11955 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,?k")
11957 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,k")
11958 (match_operand:SWI248 2 "<general_operand>" "r<i>,<m>,k")))
11959 (clobber (reg:CC FLAGS_REG))]
11960 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11962 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
11963 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
11965 [(set_attr "isa" "*,*,<kmov_isa>")
11966 (set_attr "type" "alu, alu, msklog")
11967 (set_attr "mode" "<MODE>")])
11969 (define_insn_and_split "*notxor<mode>_1"
11970 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,?k")
11973 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,k")
11974 (match_operand:SWI248 2 "<general_operand>" "r<i>,<m>,k"))))
11975 (clobber (reg:CC FLAGS_REG))]
11976 "ix86_binary_operator_ok (XOR, <MODE>mode, operands)"
11978 "&& reload_completed"
11980 [(set (match_dup 0)
11981 (xor:SWI248 (match_dup 1) (match_dup 2)))
11982 (clobber (reg:CC FLAGS_REG))])
11984 (not:SWI248 (match_dup 0)))]
11986 if (MASK_REG_P (operands[0]))
11988 emit_insn (gen_kxnor<mode> (operands[0], operands[1], operands[2]));
11992 [(set_attr "isa" "*,*,<kmov_isa>")
11993 (set_attr "type" "alu, alu, msklog")
11994 (set_attr "mode" "<MODE>")])
11996 (define_insn_and_split "*iordi_1_bts"
11997 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11999 (match_operand:DI 1 "nonimmediate_operand" "%0")
12000 (match_operand:DI 2 "const_int_operand" "n")))
12001 (clobber (reg:CC FLAGS_REG))]
12002 "TARGET_64BIT && TARGET_USE_BT
12003 && ix86_binary_operator_ok (IOR, DImode, operands)
12004 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
12006 "&& reload_completed"
12007 [(parallel [(set (zero_extract:DI (match_dup 0)
12011 (clobber (reg:CC FLAGS_REG))])]
12012 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
12013 [(set_attr "type" "alu1")
12014 (set_attr "prefix_0f" "1")
12015 (set_attr "znver1_decode" "double")
12016 (set_attr "mode" "DI")])
12018 (define_insn_and_split "*xordi_1_btc"
12019 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12021 (match_operand:DI 1 "nonimmediate_operand" "%0")
12022 (match_operand:DI 2 "const_int_operand" "n")))
12023 (clobber (reg:CC FLAGS_REG))]
12024 "TARGET_64BIT && TARGET_USE_BT
12025 && ix86_binary_operator_ok (XOR, DImode, operands)
12026 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
12028 "&& reload_completed"
12029 [(parallel [(set (zero_extract:DI (match_dup 0)
12032 (not:DI (zero_extract:DI (match_dup 0)
12035 (clobber (reg:CC FLAGS_REG))])]
12036 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
12037 [(set_attr "type" "alu1")
12038 (set_attr "prefix_0f" "1")
12039 (set_attr "znver1_decode" "double")
12040 (set_attr "mode" "DI")])
12042 ;; Optimize a ^ ((a ^ b) & mask) to (~mask & a) | (b & mask)
12043 (define_insn_and_split "*xor2andn"
12044 [(set (match_operand:SWI248 0 "register_operand")
12048 (match_operand:SWI248 1 "nonimmediate_operand")
12049 (match_operand:SWI248 2 "nonimmediate_operand"))
12050 (match_operand:SWI248 3 "nonimmediate_operand"))
12052 (clobber (reg:CC FLAGS_REG))]
12053 "TARGET_BMI && ix86_pre_reload_split ()"
12056 [(parallel [(set (match_dup 4)
12061 (clobber (reg:CC FLAGS_REG))])
12062 (parallel [(set (match_dup 5)
12066 (clobber (reg:CC FLAGS_REG))])
12067 (parallel [(set (match_dup 0)
12071 (clobber (reg:CC FLAGS_REG))])]
12073 operands[1] = force_reg (<MODE>mode, operands[1]);
12074 operands[3] = force_reg (<MODE>mode, operands[3]);
12075 operands[4] = gen_reg_rtx (<MODE>mode);
12076 operands[5] = gen_reg_rtx (<MODE>mode);
12079 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
12080 (define_insn "*<code>si_1_zext"
12081 [(set (match_operand:DI 0 "register_operand" "=r")
12083 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
12084 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
12085 (clobber (reg:CC FLAGS_REG))]
12086 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12087 "<logic>{l}\t{%2, %k0|%k0, %2}"
12088 [(set_attr "type" "alu")
12089 (set_attr "mode" "SI")])
12091 (define_insn "*<code>si_1_zext_imm"
12092 [(set (match_operand:DI 0 "register_operand" "=r")
12094 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
12095 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
12096 (clobber (reg:CC FLAGS_REG))]
12097 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12098 "<logic>{l}\t{%2, %k0|%k0, %2}"
12099 [(set_attr "type" "alu")
12100 (set_attr "mode" "SI")])
12102 (define_insn "*<code>qi_1"
12103 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,?k")
12104 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
12105 (match_operand:QI 2 "general_operand" "qn,m,rn,k")))
12106 (clobber (reg:CC FLAGS_REG))]
12107 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
12109 <logic>{b}\t{%2, %0|%0, %2}
12110 <logic>{b}\t{%2, %0|%0, %2}
12111 <logic>{l}\t{%k2, %k0|%k0, %k2}
12113 [(set_attr "isa" "*,*,*,avx512f")
12114 (set_attr "type" "alu,alu,alu,msklog")
12116 (cond [(eq_attr "alternative" "2")
12117 (const_string "SI")
12118 (and (eq_attr "alternative" "3")
12119 (match_test "!TARGET_AVX512DQ"))
12120 (const_string "HI")
12122 (const_string "QI")))
12123 ;; Potential partial reg stall on alternative 2.
12124 (set (attr "preferred_for_speed")
12125 (cond [(eq_attr "alternative" "2")
12126 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
12127 (symbol_ref "true")))])
12129 (define_insn_and_split "*notxorqi_1"
12130 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,?k")
12132 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
12133 (match_operand:QI 2 "general_operand" "qn,m,rn,k"))))
12134 (clobber (reg:CC FLAGS_REG))]
12135 "ix86_binary_operator_ok (XOR, QImode, operands)"
12137 "&& reload_completed"
12139 [(set (match_dup 0)
12140 (xor:QI (match_dup 1) (match_dup 2)))
12141 (clobber (reg:CC FLAGS_REG))])
12143 (not:QI (match_dup 0)))]
12145 if (mask_reg_operand (operands[0], QImode))
12147 emit_insn (gen_kxnorqi (operands[0], operands[1], operands[2]));
12151 [(set_attr "isa" "*,*,*,avx512f")
12152 (set_attr "type" "alu,alu,alu,msklog")
12154 (cond [(eq_attr "alternative" "2")
12155 (const_string "SI")
12156 (and (eq_attr "alternative" "3")
12157 (match_test "!TARGET_AVX512DQ"))
12158 (const_string "HI")
12160 (const_string "QI")))
12161 ;; Potential partial reg stall on alternative 2.
12162 (set (attr "preferred_for_speed")
12163 (cond [(eq_attr "alternative" "2")
12164 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
12165 (symbol_ref "true")))])
12167 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
12168 (define_insn_and_split "*<code><mode>_1_slp"
12169 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
12170 (any_or:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0,!<r>")
12171 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
12172 (clobber (reg:CC FLAGS_REG))]
12173 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
12175 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
12177 "&& reload_completed"
12178 [(set (strict_low_part (match_dup 0)) (match_dup 1))
12180 [(set (strict_low_part (match_dup 0))
12181 (any_or:SWI12 (match_dup 0) (match_dup 2)))
12182 (clobber (reg:CC FLAGS_REG))])]
12184 [(set_attr "type" "alu")
12185 (set_attr "mode" "<MODE>")])
12187 ;; convert (sign_extend:WIDE (any_logic:NARROW (memory, immediate)))
12188 ;; to (any_logic:WIDE (sign_extend (memory)), (sign_extend (immediate))).
12189 ;; This eliminates sign extension after logic operation.
12192 [(set (match_operand:SWI248 0 "register_operand")
12193 (sign_extend:SWI248
12194 (any_logic:QI (match_operand:QI 1 "memory_operand")
12195 (match_operand:QI 2 "const_int_operand"))))]
12197 [(set (match_dup 3) (sign_extend:SWI248 (match_dup 1)))
12198 (set (match_dup 0) (any_logic:SWI248 (match_dup 3) (match_dup 2)))]
12199 "operands[3] = gen_reg_rtx (<MODE>mode);")
12202 [(set (match_operand:SWI48 0 "register_operand")
12204 (any_logic:HI (match_operand:HI 1 "memory_operand")
12205 (match_operand:HI 2 "const_int_operand"))))]
12207 [(set (match_dup 3) (sign_extend:SWI48 (match_dup 1)))
12208 (set (match_dup 0) (any_logic:SWI48 (match_dup 3) (match_dup 2)))]
12209 "operands[3] = gen_reg_rtx (<MODE>mode);")
12212 [(set (match_operand:DI 0 "register_operand")
12214 (any_logic:SI (match_operand:SI 1 "memory_operand")
12215 (match_operand:SI 2 "const_int_operand"))))]
12217 [(set (match_dup 3) (sign_extend:DI (match_dup 1)))
12218 (set (match_dup 0) (any_logic:DI (match_dup 3) (match_dup 2)))]
12219 "operands[3] = gen_reg_rtx (DImode);")
12221 (define_insn "*<code><mode>_2"
12222 [(set (reg FLAGS_REG)
12223 (compare (any_or:SWI
12224 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
12225 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
12227 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
12228 (any_or:SWI (match_dup 1) (match_dup 2)))]
12229 "ix86_match_ccmode (insn, CCNOmode)
12230 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
12231 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
12232 [(set_attr "type" "alu")
12233 (set_attr "mode" "<MODE>")])
12235 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
12236 ;; ??? Special case for immediate operand is missing - it is tricky.
12237 (define_insn "*<code>si_2_zext"
12238 [(set (reg FLAGS_REG)
12239 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
12240 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
12242 (set (match_operand:DI 0 "register_operand" "=r")
12243 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
12244 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
12245 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12246 "<logic>{l}\t{%2, %k0|%k0, %2}"
12247 [(set_attr "type" "alu")
12248 (set_attr "mode" "SI")])
12250 (define_insn "*<code>si_2_zext_imm"
12251 [(set (reg FLAGS_REG)
12252 (compare (any_or:SI
12253 (match_operand:SI 1 "nonimmediate_operand" "%0")
12254 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
12256 (set (match_operand:DI 0 "register_operand" "=r")
12257 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12258 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
12259 && 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><mode>_3"
12265 [(set (reg FLAGS_REG)
12266 (compare (any_or:SWI
12267 (match_operand:SWI 1 "nonimmediate_operand" "%0")
12268 (match_operand:SWI 2 "<general_operand>" "<g>"))
12270 (clobber (match_scratch:SWI 0 "=<r>"))]
12271 "ix86_match_ccmode (insn, CCNOmode)
12272 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12273 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
12274 [(set_attr "type" "alu")
12275 (set_attr "mode" "<MODE>")])
12277 (define_insn "*<code>qi_ext<mode>_0"
12278 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn")
12281 (match_operator:SWI248 3 "extract_operator"
12282 [(match_operand 2 "int248_register_operand" "Q")
12285 (match_operand:QI 1 "nonimmediate_operand" "0")))
12286 (clobber (reg:CC FLAGS_REG))]
12288 "<logic>{b}\t{%h2, %0|%0, %h2}"
12289 [(set_attr "addr" "gpr8")
12290 (set_attr "type" "alu")
12291 (set_attr "mode" "QI")])
12293 (define_insn "*<code>qi_ext<mode>_1"
12294 [(set (zero_extract:SWI248
12295 (match_operand 0 "int248_register_operand" "+Q")
12301 (match_operator:SWI248 3 "extract_operator"
12302 [(match_operand 1 "int248_register_operand" "0")
12305 (match_operand:QI 2 "general_operand" "QnBn")) 0))
12306 (clobber (reg:CC FLAGS_REG))]
12307 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12308 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
12309 && rtx_equal_p (operands[0], operands[1])"
12310 "<logic>{b}\t{%2, %h0|%h0, %2}"
12311 [(set_attr "addr" "gpr8")
12312 (set_attr "type" "alu")
12313 (set_attr "mode" "QI")])
12315 (define_insn "*<code>qi_ext<mode>_2"
12316 [(set (zero_extract:SWI248
12317 (match_operand 0 "int248_register_operand" "+Q")
12323 (match_operator:SWI248 3 "extract_operator"
12324 [(match_operand 1 "int248_register_operand" "%0")
12328 (match_operator:SWI248 4 "extract_operator"
12329 [(match_operand 2 "int248_register_operand" "Q")
12331 (const_int 8)]) 0)) 0))
12332 (clobber (reg:CC FLAGS_REG))]
12333 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12334 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
12335 && (rtx_equal_p (operands[0], operands[1])
12336 || rtx_equal_p (operands[0], operands[2]))"
12337 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
12338 [(set_attr "type" "alu")
12339 (set_attr "mode" "QI")])
12341 (define_insn "*<code>qi_ext<mode>_3"
12342 [(set (zero_extract:SWI248
12343 (match_operand 0 "int248_register_operand" "+Q")
12346 (zero_extract:SWI248
12348 (match_operand 1 "int248_register_operand" "%0")
12349 (match_operand 2 "int248_register_operand" "Q"))
12352 (clobber (reg:CC FLAGS_REG))]
12353 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12354 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
12355 && (rtx_equal_p (operands[0], operands[1])
12356 || rtx_equal_p (operands[0], operands[2]))"
12357 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
12358 [(set_attr "type" "alu")
12359 (set_attr "mode" "QI")])
12361 ;; Convert wide OR instructions with immediate operand to shorter QImode
12362 ;; equivalents when possible.
12363 ;; Don't do the splitting with memory operands, since it introduces risk
12364 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
12365 ;; for size, but that can (should?) be handled by generic code instead.
12367 [(set (match_operand:SWI248 0 "QIreg_operand")
12368 (any_or:SWI248 (match_operand:SWI248 1 "register_operand")
12369 (match_operand:SWI248 2 "const_int_operand")))
12370 (clobber (reg:CC FLAGS_REG))]
12372 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12373 && !(INTVAL (operands[2]) & ~(255 << 8))"
12375 [(set (zero_extract:HI (match_dup 0)
12381 (zero_extract:HI (match_dup 1)
12385 (clobber (reg:CC FLAGS_REG))])]
12387 /* Handle the case where INTVAL (operands[2]) == 0. */
12388 if (operands[2] == const0_rtx)
12390 if (!rtx_equal_p (operands[0], operands[1]))
12391 emit_move_insn (operands[0], operands[1]);
12393 emit_note (NOTE_INSN_DELETED);
12396 operands[0] = gen_lowpart (HImode, operands[0]);
12397 operands[1] = gen_lowpart (HImode, operands[1]);
12398 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
12401 ;; Since OR can be encoded with sign extended immediate, this is only
12402 ;; profitable when 7th bit is set.
12404 [(set (match_operand:SWI248 0 "any_QIreg_operand")
12405 (any_or:SWI248 (match_operand:SWI248 1 "general_operand")
12406 (match_operand:SWI248 2 "const_int_operand")))
12407 (clobber (reg:CC FLAGS_REG))]
12409 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12410 && !(INTVAL (operands[2]) & ~255)
12411 && (INTVAL (operands[2]) & 128)"
12412 [(parallel [(set (strict_low_part (match_dup 0))
12413 (any_or:QI (match_dup 1)
12415 (clobber (reg:CC FLAGS_REG))])]
12417 operands[0] = gen_lowpart (QImode, operands[0]);
12418 operands[1] = gen_lowpart (QImode, operands[1]);
12419 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
12422 (define_expand "xorqi_ext_1_cc"
12424 [(set (reg:CCNO FLAGS_REG)
12428 (zero_extract:HI (match_operand:HI 1 "register_operand")
12431 (match_operand:QI 2 "const_int_operand"))
12433 (set (zero_extract:HI (match_operand:HI 0 "register_operand")
12439 (zero_extract:HI (match_dup 1)
12442 (match_dup 2)) 0))])])
12444 (define_insn "*xorqi_ext<mode>_1_cc"
12445 [(set (reg FLAGS_REG)
12449 (match_operator:SWI248 3 "extract_operator"
12450 [(match_operand 1 "int248_register_operand" "0")
12453 (match_operand:QI 2 "general_operand" "QnBn"))
12455 (set (zero_extract:SWI248
12456 (match_operand 0 "int248_register_operand" "+Q")
12466 (match_dup 2)) 0))]
12467 "ix86_match_ccmode (insn, CCNOmode)
12468 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
12469 && rtx_equal_p (operands[0], operands[1])"
12470 "xor{b}\t{%2, %h0|%h0, %2}"
12471 [(set_attr "addr" "gpr8")
12472 (set_attr "type" "alu")
12473 (set_attr "mode" "QI")])
12475 ;; Peephole2 rega = 0; rega op= regb into rega = regb.
12477 [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
12479 (clobber (reg:CC FLAGS_REG))])
12480 (parallel [(set (match_dup 0)
12481 (any_or_plus:SWI (match_dup 0)
12482 (match_operand:SWI 1 "<general_operand>")))
12483 (clobber (reg:CC FLAGS_REG))])]
12484 "!reg_mentioned_p (operands[0], operands[1])"
12485 [(set (match_dup 0) (match_dup 1))])
12487 ;; Peephole2 dead instruction in rega = 0; rega op= rega.
12489 [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
12491 (clobber (reg:CC FLAGS_REG))])
12492 (parallel [(set (match_dup 0)
12493 (any_or_plus:SWI (match_dup 0) (match_dup 0)))
12494 (clobber (reg:CC FLAGS_REG))])]
12496 [(parallel [(set (match_dup 0) (const_int 0))
12497 (clobber (reg:CC FLAGS_REG))])])
12499 ;; Split DST = (HI<<32)|LO early to minimize register usage.
12500 (define_insn_and_split "*concat<mode><dwi>3_1"
12501 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
12503 (ashift:<DWI> (match_operand:<DWI> 1 "register_operand" "r,r")
12504 (match_operand:QI 2 "const_int_operand"))
12506 (match_operand:DWIH 3 "nonimmediate_operand" "r,m"))))]
12507 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT"
12509 "&& reload_completed"
12512 split_double_concat (<DWI>mode, operands[0], operands[3],
12513 gen_lowpart (<MODE>mode, operands[1]));
12517 (define_insn_and_split "*concat<mode><dwi>3_2"
12518 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
12521 (match_operand:DWIH 1 "nonimmediate_operand" "r,m"))
12522 (ashift:<DWI> (match_operand:<DWI> 2 "register_operand" "r,r")
12523 (match_operand:QI 3 "const_int_operand"))))]
12524 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12526 "&& reload_completed"
12529 split_double_concat (<DWI>mode, operands[0], operands[1],
12530 gen_lowpart (<MODE>mode, operands[2]));
12534 (define_insn_and_split "*concat<mode><dwi>3_3"
12535 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,r,&r,x")
12539 (match_operand:DWIH 1 "nonimmediate_operand" "r,m,r,m,x"))
12540 (match_operand:QI 2 "const_int_operand"))
12542 (match_operand:DWIH 3 "nonimmediate_operand" "r,r,m,m,0"))))]
12543 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT"
12545 "&& reload_completed"
12548 if (SSE_REG_P (operands[0]))
12550 rtx tmp = gen_rtx_REG (V2DImode, REGNO (operands[0]));
12551 emit_insn (gen_vec_concatv2di (tmp, operands[3], operands[1]));
12554 split_double_concat (<DWI>mode, operands[0], operands[3], operands[1]);
12557 [(set_attr "isa" "*,*,*,x64,x64")])
12559 (define_insn_and_split "*concat<mode><dwi>3_4"
12560 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,r,&r")
12563 (match_operand:DWIH 1 "nonimmediate_operand" "r,m,r,m"))
12566 (match_operand:DWIH 2 "nonimmediate_operand" "r,r,m,m"))
12567 (match_operand:QI 3 "const_int_operand"))))]
12568 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12570 "&& reload_completed"
12573 split_double_concat (<DWI>mode, operands[0], operands[1], operands[2]);
12576 [(set_attr "isa" "*,*,*,x64")])
12578 (define_insn_and_split "*concat<half><mode>3_5"
12579 [(set (match_operand:DWI 0 "nonimmediate_operand" "=r,o,o")
12581 (ashift:DWI (match_operand:DWI 1 "register_operand" "r,r,r")
12582 (match_operand:QI 2 "const_int_operand"))
12583 (match_operand:DWI 3 "const_scalar_int_operand" "n,n,Wd")))]
12584 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT / 2
12585 && (<MODE>mode == DImode
12586 ? CONST_INT_P (operands[3])
12587 && (UINTVAL (operands[3]) & ~GET_MODE_MASK (SImode)) == 0
12588 : CONST_INT_P (operands[3])
12589 ? INTVAL (operands[3]) >= 0
12590 : CONST_WIDE_INT_NUNITS (operands[3]) == 2
12591 && CONST_WIDE_INT_ELT (operands[3], 1) == 0)
12592 && !(CONST_INT_P (operands[3])
12593 ? ix86_endbr_immediate_operand (operands[3], VOIDmode)
12594 : ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[3],
12598 "&& reload_completed"
12601 rtx op3 = simplify_subreg (<HALF>mode, operands[3], <MODE>mode, 0);
12602 split_double_concat (<MODE>mode, operands[0], op3,
12603 gen_lowpart (<HALF>mode, operands[1]));
12606 [(set_attr "isa" "*,nox64,x64")])
12608 (define_insn_and_split "*concat<mode><dwi>3_6"
12609 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,o,r")
12613 (match_operand:DWIH 1 "nonimmediate_operand" "r,r,r,m"))
12614 (match_operand:QI 2 "const_int_operand"))
12615 (match_operand:<DWI> 3 "const_scalar_int_operand" "n,n,Wd,n")))]
12616 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT
12617 && (<DWI>mode == DImode
12618 ? CONST_INT_P (operands[3])
12619 && (UINTVAL (operands[3]) & ~GET_MODE_MASK (SImode)) == 0
12620 : CONST_INT_P (operands[3])
12621 ? INTVAL (operands[3]) >= 0
12622 : CONST_WIDE_INT_NUNITS (operands[3]) == 2
12623 && CONST_WIDE_INT_ELT (operands[3], 1) == 0)
12624 && !(CONST_INT_P (operands[3])
12625 ? ix86_endbr_immediate_operand (operands[3], VOIDmode)
12626 : ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[3],
12630 "&& reload_completed"
12633 rtx op3 = simplify_subreg (<MODE>mode, operands[3], <DWI>mode, 0);
12634 split_double_concat (<DWI>mode, operands[0], op3, operands[1]);
12637 [(set_attr "isa" "*,nox64,x64,*")])
12639 (define_insn_and_split "*concat<mode><dwi>3_7"
12640 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,o,r")
12643 (match_operand:DWIH 1 "nonimmediate_operand" "r,r,r,m"))
12644 (match_operand:<DWI> 2 "const_scalar_int_operand" "n,n,Wd,n")))]
12645 "<DWI>mode == DImode
12646 ? CONST_INT_P (operands[2])
12647 && (UINTVAL (operands[2]) & GET_MODE_MASK (SImode)) == 0
12648 && !ix86_endbr_immediate_operand (operands[2], VOIDmode)
12649 : CONST_WIDE_INT_P (operands[2])
12650 && CONST_WIDE_INT_NUNITS (operands[2]) == 2
12651 && CONST_WIDE_INT_ELT (operands[2], 0) == 0
12652 && !ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[2],
12656 "&& reload_completed"
12660 if (<DWI>mode == DImode)
12661 op2 = gen_int_mode (INTVAL (operands[2]) >> 32, <MODE>mode);
12663 op2 = gen_int_mode (CONST_WIDE_INT_ELT (operands[2], 1), <MODE>mode);
12664 split_double_concat (<DWI>mode, operands[0], operands[1], op2);
12667 [(set_attr "isa" "*,nox64,x64,*")])
12669 ;; Negation instructions
12671 (define_expand "neg<mode>2"
12672 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
12673 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
12675 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
12677 (define_insn_and_split "*neg<dwi>2_doubleword"
12678 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
12679 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
12680 (clobber (reg:CC FLAGS_REG))]
12681 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
12683 "&& reload_completed"
12685 [(set (reg:CCC FLAGS_REG)
12686 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
12687 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
12689 [(set (match_dup 2)
12690 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
12693 (clobber (reg:CC FLAGS_REG))])
12695 [(set (match_dup 2)
12696 (neg:DWIH (match_dup 2)))
12697 (clobber (reg:CC FLAGS_REG))])]
12698 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
12711 [(set (match_operand:SWI48 0 "general_reg_operand")
12712 (match_operand:SWI48 1 "nonimmediate_gr_operand"))
12714 [(set (reg:CCC FLAGS_REG)
12715 (unspec:CCC [(match_operand:SWI48 2 "general_reg_operand")
12716 (const_int 0)] UNSPEC_CC_NE))
12717 (set (match_dup 2) (neg:SWI48 (match_dup 2)))])
12719 [(set (match_dup 0)
12720 (plus:SWI48 (plus:SWI48
12721 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
12724 (clobber (reg:CC FLAGS_REG))])
12726 [(set (match_dup 0)
12727 (neg:SWI48 (match_dup 0)))
12728 (clobber (reg:CC FLAGS_REG))])]
12729 "REGNO (operands[0]) != REGNO (operands[2])
12730 && !reg_mentioned_p (operands[0], operands[1])
12731 && !reg_mentioned_p (operands[2], operands[1])"
12733 [(set (reg:CCC FLAGS_REG)
12734 (unspec:CCC [(match_dup 2) (const_int 0)] UNSPEC_CC_NE))
12735 (set (match_dup 2) (neg:SWI48 (match_dup 2)))])
12737 [(set (match_dup 0)
12738 (minus:SWI48 (minus:SWI48
12740 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0)))
12742 (clobber (reg:CC FLAGS_REG))])]
12743 "ix86_expand_clear (operands[0]);")
12752 ;; sbbl %edx, %edx // *x86_mov<mode>cc_0_m1
12756 [(set (match_operand:SWI48 0 "general_reg_operand") (const_int 0))
12757 (clobber (reg:CC FLAGS_REG))])
12759 [(set (reg:CCC FLAGS_REG)
12760 (unspec:CCC [(match_operand:SWI48 1 "general_reg_operand")
12761 (const_int 0)] UNSPEC_CC_NE))
12762 (set (match_dup 1) (neg:SWI48 (match_dup 1)))])
12764 [(set (match_dup 0)
12765 (plus:SWI48 (plus:SWI48
12766 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
12769 (clobber (reg:CC FLAGS_REG))])
12771 [(set (match_dup 0)
12772 (neg:SWI48 (match_dup 0)))
12773 (clobber (reg:CC FLAGS_REG))])]
12774 "REGNO (operands[0]) != REGNO (operands[1])"
12776 [(set (reg:CCC FLAGS_REG)
12777 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
12778 (set (match_dup 1) (neg:SWI48 (match_dup 1)))])
12780 [(set (match_dup 0)
12781 (if_then_else:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
12784 (clobber (reg:CC FLAGS_REG))])])
12786 (define_insn "*neg<mode>_1"
12787 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
12788 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
12789 (clobber (reg:CC FLAGS_REG))]
12790 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
12791 "neg{<imodesuffix>}\t%0"
12792 [(set_attr "type" "negnot")
12793 (set_attr "mode" "<MODE>")])
12795 (define_insn "*negsi_1_zext"
12796 [(set (match_operand:DI 0 "register_operand" "=r")
12798 (neg:SI (match_operand:SI 1 "register_operand" "0"))))
12799 (clobber (reg:CC FLAGS_REG))]
12800 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
12802 [(set_attr "type" "negnot")
12803 (set_attr "mode" "SI")])
12805 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
12806 (define_insn_and_split "*neg<mode>_1_slp"
12807 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
12808 (neg:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")))
12809 (clobber (reg:CC FLAGS_REG))]
12810 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
12812 neg{<imodesuffix>}\t%0
12814 "&& reload_completed"
12815 [(set (strict_low_part (match_dup 0)) (match_dup 1))
12817 [(set (strict_low_part (match_dup 0))
12818 (neg:SWI12 (match_dup 0)))
12819 (clobber (reg:CC FLAGS_REG))])]
12821 [(set_attr "type" "negnot")
12822 (set_attr "mode" "<MODE>")])
12824 (define_insn "*neg<mode>_2"
12825 [(set (reg FLAGS_REG)
12827 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
12829 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
12830 (neg:SWI (match_dup 1)))]
12831 "ix86_match_ccmode (insn, CCGOCmode)
12832 && ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
12833 "neg{<imodesuffix>}\t%0"
12834 [(set_attr "type" "negnot")
12835 (set_attr "mode" "<MODE>")])
12837 (define_insn "*negsi_2_zext"
12838 [(set (reg FLAGS_REG)
12840 (neg:SI (match_operand:SI 1 "register_operand" "0"))
12842 (set (match_operand:DI 0 "register_operand" "=r")
12844 (neg:SI (match_dup 1))))]
12845 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12846 && ix86_unary_operator_ok (NEG, SImode, operands)"
12848 [(set_attr "type" "negnot")
12849 (set_attr "mode" "SI")])
12851 (define_insn "*neg<mode>_ccc_1"
12852 [(set (reg:CCC FLAGS_REG)
12854 [(match_operand:SWI 1 "nonimmediate_operand" "0")
12855 (const_int 0)] UNSPEC_CC_NE))
12856 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
12857 (neg:SWI (match_dup 1)))]
12859 "neg{<imodesuffix>}\t%0"
12860 [(set_attr "type" "negnot")
12861 (set_attr "mode" "<MODE>")])
12863 (define_insn "*neg<mode>_ccc_2"
12864 [(set (reg:CCC FLAGS_REG)
12866 [(match_operand:SWI 1 "nonimmediate_operand" "0")
12867 (const_int 0)] UNSPEC_CC_NE))
12868 (clobber (match_scratch:SWI 0 "=<r>"))]
12870 "neg{<imodesuffix>}\t%0"
12871 [(set_attr "type" "negnot")
12872 (set_attr "mode" "<MODE>")])
12874 (define_expand "x86_neg<mode>_ccc"
12876 [(set (reg:CCC FLAGS_REG)
12877 (unspec:CCC [(match_operand:SWI48 1 "register_operand")
12878 (const_int 0)] UNSPEC_CC_NE))
12879 (set (match_operand:SWI48 0 "register_operand")
12880 (neg:SWI48 (match_dup 1)))])])
12882 (define_insn "*negqi_ext<mode>_2"
12883 [(set (zero_extract:SWI248
12884 (match_operand 0 "int248_register_operand" "+Q")
12890 (match_operator:SWI248 2 "extract_operator"
12891 [(match_operand 1 "int248_register_operand" "0")
12893 (const_int 8)]) 0)) 0))
12894 (clobber (reg:CC FLAGS_REG))]
12895 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
12896 rtx_equal_p (operands[0], operands[1])"
12898 [(set_attr "type" "negnot")
12899 (set_attr "mode" "QI")])
12901 ;; Negate with jump on overflow.
12902 (define_expand "negv<mode>3"
12903 [(parallel [(set (reg:CCO FLAGS_REG)
12905 [(match_operand:SWI 1 "register_operand")
12906 (match_dup 3)] UNSPEC_CC_NE))
12907 (set (match_operand:SWI 0 "register_operand")
12908 (neg:SWI (match_dup 1)))])
12909 (set (pc) (if_then_else
12910 (eq (reg:CCO FLAGS_REG) (const_int 0))
12911 (label_ref (match_operand 2))
12916 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
12920 (define_insn "*negv<mode>3"
12921 [(set (reg:CCO FLAGS_REG)
12922 (unspec:CCO [(match_operand:SWI 1 "nonimmediate_operand" "0")
12923 (match_operand:SWI 2 "const_int_operand")]
12925 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
12926 (neg:SWI (match_dup 1)))]
12927 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
12928 && mode_signbit_p (<MODE>mode, operands[2])"
12929 "neg{<imodesuffix>}\t%0"
12930 [(set_attr "type" "negnot")
12931 (set_attr "mode" "<MODE>")])
12933 ;; Optimize *negsi_1 followed by *cmpsi_ccno_1 (PR target/91384)
12935 [(set (match_operand:SWI 0 "general_reg_operand")
12936 (match_operand:SWI 1 "general_reg_operand"))
12937 (parallel [(set (match_dup 0) (neg:SWI (match_dup 0)))
12938 (clobber (reg:CC FLAGS_REG))])
12939 (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))]
12941 [(set (match_dup 0) (match_dup 1))
12942 (parallel [(set (reg:CCZ FLAGS_REG)
12943 (compare:CCZ (neg:SWI (match_dup 0)) (const_int 0)))
12944 (set (match_dup 0) (neg:SWI (match_dup 0)))])])
12946 ;; Special expand pattern to handle integer mode abs
12948 (define_expand "abs<mode>2"
12950 [(set (match_operand:SDWIM 0 "register_operand")
12952 (match_operand:SDWIM 1 "general_operand")))
12953 (clobber (reg:CC FLAGS_REG))])]
12955 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)"
12957 if (TARGET_EXPAND_ABS)
12959 machine_mode mode = <MODE>mode;
12960 operands[1] = force_reg (mode, operands[1]);
12962 /* Generate rtx abs using:
12963 abs (x) = (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)) */
12965 rtx shift_amount = gen_int_mode (GET_MODE_PRECISION (mode) - 1, QImode);
12966 rtx shift_dst = expand_simple_binop (mode, ASHIFTRT, operands[1],
12967 shift_amount, NULL_RTX,
12969 rtx xor_dst = expand_simple_binop (mode, XOR, shift_dst, operands[1],
12970 operands[0], 0, OPTAB_DIRECT);
12971 rtx minus_dst = expand_simple_binop (mode, MINUS, xor_dst, shift_dst,
12972 operands[0], 0, OPTAB_DIRECT);
12973 if (!rtx_equal_p (minus_dst, operands[0]))
12974 emit_move_insn (operands[0], minus_dst);
12979 (define_insn_and_split "*abs<dwi>2_doubleword"
12980 [(set (match_operand:<DWI> 0 "register_operand")
12982 (match_operand:<DWI> 1 "general_operand")))
12983 (clobber (reg:CC FLAGS_REG))]
12985 && ix86_pre_reload_split ()"
12989 [(set (reg:CCC FLAGS_REG)
12990 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
12991 (set (match_dup 2) (neg:DWIH (match_dup 1)))])
12993 [(set (match_dup 5)
12994 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
12997 (clobber (reg:CC FLAGS_REG))])
12999 [(set (reg:CCGOC FLAGS_REG)
13001 (neg:DWIH (match_dup 5))
13004 (neg:DWIH (match_dup 5)))])
13007 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
13012 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
13016 operands[1] = force_reg (<DWI>mode, operands[1]);
13017 operands[2] = gen_reg_rtx (<DWI>mode);
13019 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
13022 (define_insn_and_split "*nabs<dwi>2_doubleword"
13023 [(set (match_operand:<DWI> 0 "register_operand")
13026 (match_operand:<DWI> 1 "general_operand"))))
13027 (clobber (reg:CC FLAGS_REG))]
13029 && ix86_pre_reload_split ()"
13033 [(set (reg:CCC FLAGS_REG)
13034 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
13035 (set (match_dup 2) (neg:DWIH (match_dup 1)))])
13037 [(set (match_dup 5)
13038 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
13041 (clobber (reg:CC FLAGS_REG))])
13043 [(set (reg:CCGOC FLAGS_REG)
13045 (neg:DWIH (match_dup 5))
13048 (neg:DWIH (match_dup 5)))])
13051 (lt (reg:CCGOC FLAGS_REG) (const_int 0))
13056 (lt (reg:CCGOC FLAGS_REG) (const_int 0))
13060 operands[1] = force_reg (<DWI>mode, operands[1]);
13061 operands[2] = gen_reg_rtx (<DWI>mode);
13063 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
13066 (define_insn_and_split "*abs<mode>2_1"
13067 [(set (match_operand:SWI 0 "register_operand")
13069 (match_operand:SWI 1 "general_operand")))
13070 (clobber (reg:CC FLAGS_REG))]
13072 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
13073 && ix86_pre_reload_split ()"
13077 [(set (reg:CCGOC FLAGS_REG)
13079 (neg:SWI (match_dup 1))
13082 (neg:SWI (match_dup 1)))])
13085 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
13089 operands[1] = force_reg (<MODE>mode, operands[1]);
13090 operands[2] = gen_reg_rtx (<MODE>mode);
13093 (define_insn_and_split "*nabs<mode>2_1"
13094 [(set (match_operand:SWI 0 "register_operand")
13097 (match_operand:SWI 1 "general_operand"))))
13098 (clobber (reg:CC FLAGS_REG))]
13100 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
13101 && ix86_pre_reload_split ()"
13105 [(set (reg:CCGOC FLAGS_REG)
13107 (neg:SWI (match_dup 1))
13110 (neg:SWI (match_dup 1)))])
13113 (lt (reg:CCGOC FLAGS_REG) (const_int 0))
13117 operands[1] = force_reg (<MODE>mode, operands[1]);
13118 operands[2] = gen_reg_rtx (<MODE>mode);
13121 (define_expand "<code>tf2"
13122 [(set (match_operand:TF 0 "register_operand")
13123 (absneg:TF (match_operand:TF 1 "register_operand")))]
13125 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
13127 (define_insn_and_split "*<code>tf2_1"
13128 [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
13130 (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m")))
13131 (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))]
13134 "&& reload_completed"
13135 [(set (match_dup 0)
13136 (<absneg_op>:TF (match_dup 1) (match_dup 2)))]
13140 if (MEM_P (operands[1]))
13141 std::swap (operands[1], operands[2]);
13145 if (operands_match_p (operands[0], operands[2]))
13146 std::swap (operands[1], operands[2]);
13149 [(set_attr "isa" "noavx,noavx,avx,avx")])
13151 (define_insn_and_split "*nabstf2_1"
13152 [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
13155 (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m"))))
13156 (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))]
13159 "&& reload_completed"
13160 [(set (match_dup 0)
13161 (ior:TF (match_dup 1) (match_dup 2)))]
13165 if (MEM_P (operands[1]))
13166 std::swap (operands[1], operands[2]);
13170 if (operands_match_p (operands[0], operands[2]))
13171 std::swap (operands[1], operands[2]);
13174 [(set_attr "isa" "noavx,noavx,avx,avx")])
13176 (define_expand "<code>hf2"
13177 [(set (match_operand:HF 0 "register_operand")
13178 (absneg:HF (match_operand:HF 1 "register_operand")))]
13179 "TARGET_AVX512FP16"
13180 "ix86_expand_fp_absneg_operator (<CODE>, HFmode, operands); DONE;")
13182 (define_expand "<code><mode>2"
13183 [(set (match_operand:X87MODEF 0 "register_operand")
13184 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
13185 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13186 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
13188 ;; Changing of sign for FP values is doable using integer unit too.
13189 (define_insn "*<code><mode>2_i387_1"
13190 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
13192 (match_operand:X87MODEF 1 "register_operand" "0,0")))
13193 (clobber (reg:CC FLAGS_REG))]
13194 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13198 [(set (match_operand:X87MODEF 0 "fp_register_operand")
13199 (absneg:X87MODEF (match_operand:X87MODEF 1 "fp_register_operand")))
13200 (clobber (reg:CC FLAGS_REG))]
13201 "TARGET_80387 && reload_completed"
13202 [(set (match_dup 0) (absneg:X87MODEF (match_dup 1)))])
13205 [(set (match_operand:X87MODEF 0 "general_reg_operand")
13206 (absneg:X87MODEF (match_operand:X87MODEF 1 "general_reg_operand")))
13207 (clobber (reg:CC FLAGS_REG))]
13208 "TARGET_80387 && reload_completed"
13210 "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
13212 (define_insn_and_split "*<code>hf2_1"
13213 [(set (match_operand:HF 0 "register_operand" "=Yv")
13215 (match_operand:HF 1 "register_operand" "Yv")))
13216 (use (match_operand:V8HF 2 "vector_operand" "Yvm"))
13217 (clobber (reg:CC FLAGS_REG))]
13218 "TARGET_AVX512FP16"
13220 "&& reload_completed"
13221 [(set (match_dup 0)
13222 (<absneg_op>:V8HF (match_dup 1) (match_dup 2)))]
13224 operands[0] = lowpart_subreg (V8HFmode, operands[0], HFmode);
13225 operands[1] = lowpart_subreg (V8HFmode, operands[1], HFmode);
13228 (define_insn "*<code><mode>2_1"
13229 [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv,f,!r")
13231 (match_operand:MODEF 1 "register_operand" "0,x,Yv,0,0")))
13232 (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm,X,X"))
13233 (clobber (reg:CC FLAGS_REG))]
13234 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13236 [(set_attr "isa" "noavx,noavx,avx,*,*")
13237 (set (attr "enabled")
13239 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
13241 (eq_attr "alternative" "3,4")
13242 (symbol_ref "TARGET_MIX_SSE_I387")
13243 (const_string "*"))
13245 (eq_attr "alternative" "3,4")
13246 (symbol_ref "true")
13247 (symbol_ref "false"))))])
13250 [(set (match_operand:MODEF 0 "sse_reg_operand")
13252 (match_operand:MODEF 1 "sse_reg_operand")))
13253 (use (match_operand:<ssevecmodef> 2 "vector_operand"))
13254 (clobber (reg:CC FLAGS_REG))]
13255 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13256 && reload_completed"
13257 [(set (match_dup 0)
13258 (<absneg_op>:<ssevecmodef> (match_dup 1) (match_dup 2)))]
13260 machine_mode mode = <MODE>mode;
13261 machine_mode vmode = <ssevecmodef>mode;
13263 operands[0] = lowpart_subreg (vmode, operands[0], mode);
13264 operands[1] = lowpart_subreg (vmode, operands[1], mode);
13266 if (!TARGET_AVX && operands_match_p (operands[0], operands[2]))
13267 std::swap (operands[1], operands[2]);
13271 [(set (match_operand:MODEF 0 "fp_register_operand")
13272 (absneg:MODEF (match_operand:MODEF 1 "fp_register_operand")))
13273 (use (match_operand 2))
13274 (clobber (reg:CC FLAGS_REG))]
13275 "TARGET_80387 && reload_completed"
13276 [(set (match_dup 0) (absneg:MODEF (match_dup 1)))])
13279 [(set (match_operand:MODEF 0 "general_reg_operand")
13280 (absneg:MODEF (match_operand:MODEF 1 "general_reg_operand")))
13281 (use (match_operand 2))
13282 (clobber (reg:CC FLAGS_REG))]
13283 "TARGET_80387 && reload_completed"
13285 "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
13287 (define_insn_and_split "*nabs<mode>2_1"
13288 [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv")
13291 (match_operand:MODEF 1 "register_operand" "0,x,Yv"))))
13292 (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm"))]
13293 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13295 "&& reload_completed"
13296 [(set (match_dup 0)
13297 (ior:<ssevecmodef> (match_dup 1) (match_dup 2)))]
13299 machine_mode mode = <MODE>mode;
13300 machine_mode vmode = <ssevecmodef>mode;
13302 operands[0] = lowpart_subreg (vmode, operands[0], mode);
13303 operands[1] = lowpart_subreg (vmode, operands[1], mode);
13305 if (!TARGET_AVX && operands_match_p (operands[0], operands[2]))
13306 std::swap (operands[1], operands[2]);
13308 [(set_attr "isa" "noavx,noavx,avx")])
13310 ;; Conditionalize these after reload. If they match before reload, we
13311 ;; lose the clobber and ability to use integer instructions.
13313 (define_insn "*<code><mode>2_i387"
13314 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
13315 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
13316 "TARGET_80387 && reload_completed"
13317 "<absneg_mnemonic>"
13318 [(set_attr "type" "fsgn")
13319 (set_attr "mode" "<MODE>")])
13321 ;; Copysign instructions
13323 (define_expand "copysign<mode>3"
13324 [(match_operand:SSEMODEF 0 "register_operand")
13325 (match_operand:SSEMODEF 1 "nonmemory_operand")
13326 (match_operand:SSEMODEF 2 "register_operand")]
13327 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13328 || (TARGET_SSE && (<MODE>mode == TFmode))
13329 || (TARGET_AVX512FP16 && (<MODE>mode ==HFmode))"
13330 "ix86_expand_copysign (operands); DONE;")
13332 (define_expand "xorsign<mode>3"
13333 [(match_operand:MODEFH 0 "register_operand")
13334 (match_operand:MODEFH 1 "register_operand")
13335 (match_operand:MODEFH 2 "register_operand")]
13336 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13337 || <MODE>mode == HFmode"
13339 if (rtx_equal_p (operands[1], operands[2]))
13340 emit_insn (gen_abs<mode>2 (operands[0], operands[1]));
13342 ix86_expand_xorsign (operands);
13346 ;; One complement instructions
13348 (define_expand "one_cmpl<mode>2"
13349 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
13350 (not:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
13352 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
13354 (define_insn_and_split "*one_cmpl<dwi>2_doubleword"
13355 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
13356 (not:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))]
13357 "ix86_unary_operator_ok (NOT, <DWI>mode, operands)"
13359 "&& reload_completed"
13360 [(set (match_dup 0)
13361 (not:DWIH (match_dup 1)))
13363 (not:DWIH (match_dup 3)))]
13364 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
13366 (define_insn "*one_cmpl<mode>2_1"
13367 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,?k")
13368 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0,k")))]
13369 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
13371 not{<imodesuffix>}\t%0
13373 [(set_attr "isa" "*,<kmov_isa>")
13374 (set_attr "type" "negnot,msklog")
13375 (set_attr "mode" "<MODE>")])
13377 (define_insn "*one_cmplsi2_1_zext"
13378 [(set (match_operand:DI 0 "register_operand" "=r,?k")
13380 (not:SI (match_operand:SI 1 "register_operand" "0,k"))))]
13381 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
13385 [(set_attr "isa" "x64,avx512bw_512")
13386 (set_attr "type" "negnot,msklog")
13387 (set_attr "mode" "SI,SI")])
13389 (define_insn "*one_cmplqi2_1"
13390 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,?k")
13391 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
13392 "ix86_unary_operator_ok (NOT, QImode, operands)"
13397 [(set_attr "isa" "*,*,avx512f")
13398 (set_attr "type" "negnot,negnot,msklog")
13400 (cond [(eq_attr "alternative" "1")
13401 (const_string "SI")
13402 (and (eq_attr "alternative" "2")
13403 (match_test "!TARGET_AVX512DQ"))
13404 (const_string "HI")
13406 (const_string "QI")))
13407 ;; Potential partial reg stall on alternative 1.
13408 (set (attr "preferred_for_speed")
13409 (cond [(eq_attr "alternative" "1")
13410 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
13411 (symbol_ref "true")))])
13413 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
13414 (define_insn_and_split "*one_cmpl<mode>_1_slp"
13415 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
13416 (not:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")))]
13417 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
13419 not{<imodesuffix>}\t%0
13421 "&& reload_completed"
13422 [(set (strict_low_part (match_dup 0)) (match_dup 1))
13423 (set (strict_low_part (match_dup 0))
13424 (not:SWI12 (match_dup 0)))]
13426 [(set_attr "type" "negnot")
13427 (set_attr "mode" "<MODE>")])
13429 (define_insn "*one_cmpl<mode>2_2"
13430 [(set (reg FLAGS_REG)
13431 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
13433 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
13434 (not:SWI (match_dup 1)))]
13435 "ix86_match_ccmode (insn, CCNOmode)
13436 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
13438 [(set_attr "type" "alu1")
13439 (set_attr "mode" "<MODE>")])
13442 [(set (match_operand 0 "flags_reg_operand")
13443 (match_operator 2 "compare_operator"
13444 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
13446 (set (match_operand:SWI 1 "nonimmediate_operand")
13447 (not:SWI (match_dup 3)))]
13448 "ix86_match_ccmode (insn, CCNOmode)"
13449 [(parallel [(set (match_dup 0)
13450 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
13453 (xor:SWI (match_dup 3) (const_int -1)))])])
13455 (define_insn "*one_cmplsi2_2_zext"
13456 [(set (reg FLAGS_REG)
13457 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
13459 (set (match_operand:DI 0 "register_operand" "=r")
13460 (zero_extend:DI (not:SI (match_dup 1))))]
13461 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
13462 && ix86_unary_operator_ok (NOT, SImode, operands)"
13464 [(set_attr "type" "alu1")
13465 (set_attr "mode" "SI")])
13468 [(set (match_operand 0 "flags_reg_operand")
13469 (match_operator 2 "compare_operator"
13470 [(not:SI (match_operand:SI 3 "register_operand"))
13472 (set (match_operand:DI 1 "register_operand")
13473 (zero_extend:DI (not:SI (match_dup 3))))]
13474 "ix86_match_ccmode (insn, CCNOmode)"
13475 [(parallel [(set (match_dup 0)
13476 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
13479 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
13481 ;; Shift instructions
13483 ;; DImode shifts are implemented using the i386 "shift double" opcode,
13484 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
13485 ;; is variable, then the count is in %cl and the "imm" operand is dropped
13486 ;; from the assembler input.
13488 ;; This instruction shifts the target reg/mem as usual, but instead of
13489 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
13490 ;; is a left shift double, bits are taken from the high order bits of
13491 ;; reg, else if the insn is a shift right double, bits are taken from the
13492 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
13493 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
13495 ;; Since sh[lr]d does not change the `reg' operand, that is done
13496 ;; separately, making all shifts emit pairs of shift double and normal
13497 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
13498 ;; support a 63 bit shift, each shift where the count is in a reg expands
13499 ;; to a pair of shifts, a branch, a shift by 32 and a label.
13501 ;; If the shift count is a constant, we need never emit more than one
13502 ;; shift pair, instead using moves and sign extension for counts greater
13505 (define_expand "ashl<mode>3"
13506 [(set (match_operand:SDWIM 0 "<shift_operand>")
13507 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
13508 (match_operand:QI 2 "nonmemory_operand")))]
13510 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
13512 (define_insn_and_split "*ashl<dwi>3_doubleword_mask"
13513 [(set (match_operand:<DWI> 0 "register_operand")
13515 (match_operand:<DWI> 1 "register_operand")
13518 (match_operand 2 "int248_register_operand" "c")
13519 (match_operand 3 "const_int_operand")) 0)))
13520 (clobber (reg:CC FLAGS_REG))]
13521 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
13522 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
13523 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
13524 && ix86_pre_reload_split ()"
13528 [(set (match_dup 6)
13529 (ior:DWIH (ashift:DWIH (match_dup 6)
13530 (and:QI (match_dup 2) (match_dup 8)))
13532 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
13533 (minus:QI (match_dup 9)
13534 (and:QI (match_dup 2) (match_dup 8)))) 0)))
13535 (clobber (reg:CC FLAGS_REG))])
13537 [(set (match_dup 4)
13538 (ashift:DWIH (match_dup 5) (match_dup 2)))
13539 (clobber (reg:CC FLAGS_REG))])]
13541 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
13543 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
13544 operands[2] = gen_lowpart (QImode, operands[2]);
13545 emit_insn (gen_ashl<dwi>3_doubleword (operands[0], operands[1],
13550 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
13552 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
13553 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
13555 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13556 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13559 xops[0] = gen_reg_rtx (GET_MODE (operands[2]));
13560 xops[1] = operands[2];
13561 xops[2] = GEN_INT (INTVAL (operands[3])
13562 & ((<MODE_SIZE> * BITS_PER_UNIT) - 1));
13563 ix86_expand_binary_operator (AND, GET_MODE (operands[2]), xops);
13564 operands[2] = xops[0];
13567 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
13568 operands[2] = gen_lowpart (QImode, operands[2]);
13570 if (!rtx_equal_p (operands[6], operands[7]))
13571 emit_move_insn (operands[6], operands[7]);
13574 (define_insn_and_split "*ashl<dwi>3_doubleword_mask_1"
13575 [(set (match_operand:<DWI> 0 "register_operand")
13577 (match_operand:<DWI> 1 "register_operand")
13579 (match_operand:QI 2 "register_operand" "c")
13580 (match_operand:QI 3 "const_int_operand"))))
13581 (clobber (reg:CC FLAGS_REG))]
13582 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
13583 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
13584 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
13585 && ix86_pre_reload_split ()"
13589 [(set (match_dup 6)
13590 (ior:DWIH (ashift:DWIH (match_dup 6)
13591 (and:QI (match_dup 2) (match_dup 8)))
13593 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
13594 (minus:QI (match_dup 9)
13595 (and:QI (match_dup 2) (match_dup 8)))) 0)))
13596 (clobber (reg:CC FLAGS_REG))])
13598 [(set (match_dup 4)
13599 (ashift:DWIH (match_dup 5) (match_dup 2)))
13600 (clobber (reg:CC FLAGS_REG))])]
13602 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
13604 emit_insn (gen_ashl<dwi>3_doubleword (operands[0], operands[1],
13609 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
13611 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
13612 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
13614 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13615 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13617 rtx tem = gen_reg_rtx (QImode);
13618 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
13622 if (!rtx_equal_p (operands[6], operands[7]))
13623 emit_move_insn (operands[6], operands[7]);
13626 (define_insn "ashl<mode>3_doubleword"
13627 [(set (match_operand:DWI 0 "register_operand" "=&r")
13628 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n")
13629 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
13630 (clobber (reg:CC FLAGS_REG))]
13633 [(set_attr "type" "multi")])
13636 [(set (match_operand:DWI 0 "register_operand")
13637 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
13638 (match_operand:QI 2 "nonmemory_operand")))
13639 (clobber (reg:CC FLAGS_REG))]
13640 "epilogue_completed"
13642 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
13644 ;; By default we don't ask for a scratch register, because when DWImode
13645 ;; values are manipulated, registers are already at a premium. But if
13646 ;; we have one handy, we won't turn it away.
13649 [(match_scratch:DWIH 3 "r")
13650 (parallel [(set (match_operand:<DWI> 0 "register_operand")
13652 (match_operand:<DWI> 1 "nonmemory_operand")
13653 (match_operand:QI 2 "nonmemory_operand")))
13654 (clobber (reg:CC FLAGS_REG))])
13658 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
13660 (define_insn_and_split "*ashl<dwi>3_doubleword_highpart"
13661 [(set (match_operand:<DWI> 0 "register_operand" "=r")
13663 (any_extend:<DWI> (match_operand:DWIH 1 "nonimmediate_operand" "rm"))
13664 (match_operand:QI 2 "const_int_operand")))
13665 (clobber (reg:CC FLAGS_REG))]
13666 "INTVAL (operands[2]) >= <MODE_SIZE> * BITS_PER_UNIT
13667 && INTVAL (operands[2]) < <MODE_SIZE> * BITS_PER_UNIT * 2"
13669 "&& reload_completed"
13672 split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[3]);
13673 int bits = INTVAL (operands[2]) - (<MODE_SIZE> * BITS_PER_UNIT);
13674 if (!rtx_equal_p (operands[3], operands[1]))
13675 emit_move_insn (operands[3], operands[1]);
13677 emit_insn (gen_ashl<mode>3 (operands[3], operands[3], GEN_INT (bits)));
13678 ix86_expand_clear (operands[0]);
13682 (define_insn "x86_64_shld"
13683 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
13684 (ior:DI (ashift:DI (match_dup 0)
13685 (and:QI (match_operand:QI 2 "nonmemory_operand" "Jc")
13690 (match_operand:DI 1 "register_operand" "r"))
13691 (minus:QI (const_int 64)
13692 (and:QI (match_dup 2) (const_int 63)))) 0)))
13693 (clobber (reg:CC FLAGS_REG))]
13695 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
13696 [(set_attr "type" "ishift")
13697 (set_attr "prefix_0f" "1")
13698 (set_attr "mode" "DI")
13699 (set_attr "athlon_decode" "vector")
13700 (set_attr "amdfam10_decode" "vector")
13701 (set_attr "bdver1_decode" "vector")])
13703 (define_insn "x86_64_shld_1"
13704 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
13705 (ior:DI (ashift:DI (match_dup 0)
13706 (match_operand:QI 2 "const_0_to_63_operand"))
13710 (match_operand:DI 1 "register_operand" "r"))
13711 (match_operand:QI 3 "const_0_to_255_operand")) 0)))
13712 (clobber (reg:CC FLAGS_REG))]
13714 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])"
13715 "shld{q}\t{%2, %1, %0|%0, %1, %2}"
13716 [(set_attr "type" "ishift")
13717 (set_attr "prefix_0f" "1")
13718 (set_attr "mode" "DI")
13719 (set_attr "length_immediate" "1")
13720 (set_attr "athlon_decode" "vector")
13721 (set_attr "amdfam10_decode" "vector")
13722 (set_attr "bdver1_decode" "vector")])
13724 (define_insn_and_split "*x86_64_shld_shrd_1_nozext"
13725 [(set (match_operand:DI 0 "nonimmediate_operand")
13726 (ior:DI (ashift:DI (match_operand:DI 4 "nonimmediate_operand")
13727 (match_operand:QI 2 "const_0_to_63_operand"))
13729 (match_operand:DI 1 "nonimmediate_operand")
13730 (match_operand:QI 3 "const_0_to_63_operand"))))
13731 (clobber (reg:CC FLAGS_REG))]
13733 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])
13734 && ix86_pre_reload_split ()"
13739 if (rtx_equal_p (operands[4], operands[0]))
13741 operands[1] = force_reg (DImode, operands[1]);
13742 emit_insn (gen_x86_64_shld_1 (operands[0], operands[1], operands[2], operands[3]));
13744 else if (rtx_equal_p (operands[1], operands[0]))
13746 operands[4] = force_reg (DImode, operands[4]);
13747 emit_insn (gen_x86_64_shrd_1 (operands[0], operands[4], operands[3], operands[2]));
13751 operands[1] = force_reg (DImode, operands[1]);
13752 rtx tmp = gen_reg_rtx (DImode);
13753 emit_move_insn (tmp, operands[4]);
13754 emit_insn (gen_x86_64_shld_1 (tmp, operands[1], operands[2], operands[3]));
13755 emit_move_insn (operands[0], tmp);
13760 (define_insn_and_split "*x86_64_shld_2"
13761 [(set (match_operand:DI 0 "nonimmediate_operand")
13762 (ior:DI (ashift:DI (match_dup 0)
13763 (match_operand:QI 2 "nonmemory_operand"))
13764 (lshiftrt:DI (match_operand:DI 1 "register_operand")
13765 (minus:QI (const_int 64) (match_dup 2)))))
13766 (clobber (reg:CC FLAGS_REG))]
13767 "TARGET_64BIT && ix86_pre_reload_split ()"
13770 [(parallel [(set (match_dup 0)
13771 (ior:DI (ashift:DI (match_dup 0)
13772 (and:QI (match_dup 2) (const_int 63)))
13775 (zero_extend:TI (match_dup 1))
13776 (minus:QI (const_int 64)
13777 (and:QI (match_dup 2)
13778 (const_int 63)))) 0)))
13779 (clobber (reg:CC FLAGS_REG))])])
13781 (define_insn "x86_shld"
13782 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
13783 (ior:SI (ashift:SI (match_dup 0)
13784 (and:QI (match_operand:QI 2 "nonmemory_operand" "Ic")
13789 (match_operand:SI 1 "register_operand" "r"))
13790 (minus:QI (const_int 32)
13791 (and:QI (match_dup 2) (const_int 31)))) 0)))
13792 (clobber (reg:CC FLAGS_REG))]
13794 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
13795 [(set_attr "type" "ishift")
13796 (set_attr "prefix_0f" "1")
13797 (set_attr "mode" "SI")
13798 (set_attr "pent_pair" "np")
13799 (set_attr "athlon_decode" "vector")
13800 (set_attr "amdfam10_decode" "vector")
13801 (set_attr "bdver1_decode" "vector")])
13803 (define_insn "x86_shld_1"
13804 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
13805 (ior:SI (ashift:SI (match_dup 0)
13806 (match_operand:QI 2 "const_0_to_31_operand"))
13810 (match_operand:SI 1 "register_operand" "r"))
13811 (match_operand:QI 3 "const_0_to_63_operand")) 0)))
13812 (clobber (reg:CC FLAGS_REG))]
13813 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])"
13814 "shld{l}\t{%2, %1, %0|%0, %1, %2}"
13815 [(set_attr "type" "ishift")
13816 (set_attr "prefix_0f" "1")
13817 (set_attr "length_immediate" "1")
13818 (set_attr "mode" "SI")
13819 (set_attr "pent_pair" "np")
13820 (set_attr "athlon_decode" "vector")
13821 (set_attr "amdfam10_decode" "vector")
13822 (set_attr "bdver1_decode" "vector")])
13824 (define_insn_and_split "*x86_shld_shrd_1_nozext"
13825 [(set (match_operand:SI 0 "nonimmediate_operand")
13826 (ior:SI (ashift:SI (match_operand:SI 4 "nonimmediate_operand")
13827 (match_operand:QI 2 "const_0_to_31_operand"))
13829 (match_operand:SI 1 "nonimmediate_operand")
13830 (match_operand:QI 3 "const_0_to_31_operand"))))
13831 (clobber (reg:CC FLAGS_REG))]
13832 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])
13833 && ix86_pre_reload_split ()"
13838 if (rtx_equal_p (operands[4], operands[0]))
13840 operands[1] = force_reg (SImode, operands[1]);
13841 emit_insn (gen_x86_shld_1 (operands[0], operands[1], operands[2], operands[3]));
13843 else if (rtx_equal_p (operands[1], operands[0]))
13845 operands[4] = force_reg (SImode, operands[4]);
13846 emit_insn (gen_x86_shrd_1 (operands[0], operands[4], operands[3], operands[2]));
13850 operands[1] = force_reg (SImode, operands[1]);
13851 rtx tmp = gen_reg_rtx (SImode);
13852 emit_move_insn (tmp, operands[4]);
13853 emit_insn (gen_x86_shld_1 (tmp, operands[1], operands[2], operands[3]));
13854 emit_move_insn (operands[0], tmp);
13859 (define_insn_and_split "*x86_shld_2"
13860 [(set (match_operand:SI 0 "nonimmediate_operand")
13861 (ior:SI (ashift:SI (match_dup 0)
13862 (match_operand:QI 2 "nonmemory_operand"))
13863 (lshiftrt:SI (match_operand:SI 1 "register_operand")
13864 (minus:QI (const_int 32) (match_dup 2)))))
13865 (clobber (reg:CC FLAGS_REG))]
13866 "TARGET_64BIT && ix86_pre_reload_split ()"
13869 [(parallel [(set (match_dup 0)
13870 (ior:SI (ashift:SI (match_dup 0)
13871 (and:QI (match_dup 2) (const_int 31)))
13874 (zero_extend:DI (match_dup 1))
13875 (minus:QI (const_int 32)
13876 (and:QI (match_dup 2)
13877 (const_int 31)))) 0)))
13878 (clobber (reg:CC FLAGS_REG))])])
13880 (define_expand "@x86_shift<mode>_adj_1"
13881 [(set (reg:CCZ FLAGS_REG)
13882 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
13885 (set (match_operand:SWI48 0 "register_operand")
13886 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
13887 (match_operand:SWI48 1 "register_operand")
13890 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
13891 (match_operand:SWI48 3 "register_operand")
13894 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
13896 (define_expand "@x86_shift<mode>_adj_2"
13897 [(use (match_operand:SWI48 0 "register_operand"))
13898 (use (match_operand:SWI48 1 "register_operand"))
13899 (use (match_operand:QI 2 "register_operand"))]
13902 rtx_code_label *label = gen_label_rtx ();
13905 emit_insn (gen_testqi_ccz_1 (operands[2],
13906 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
13908 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
13909 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
13910 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
13911 gen_rtx_LABEL_REF (VOIDmode, label),
13913 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
13914 JUMP_LABEL (tmp) = label;
13916 emit_move_insn (operands[0], operands[1]);
13917 ix86_expand_clear (operands[1]);
13919 emit_label (label);
13920 LABEL_NUSES (label) = 1;
13925 ;; Avoid useless masking of count operand.
13926 (define_insn_and_split "*ashl<mode>3_mask"
13927 [(set (match_operand:SWI48 0 "nonimmediate_operand")
13929 (match_operand:SWI48 1 "nonimmediate_operand")
13932 (match_operand 2 "int248_register_operand" "c,r")
13933 (match_operand 3 "const_int_operand")) 0)))
13934 (clobber (reg:CC FLAGS_REG))]
13935 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
13936 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
13937 == GET_MODE_BITSIZE (<MODE>mode)-1
13938 && ix86_pre_reload_split ()"
13942 [(set (match_dup 0)
13943 (ashift:SWI48 (match_dup 1)
13945 (clobber (reg:CC FLAGS_REG))])]
13947 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
13948 operands[2] = gen_lowpart (QImode, operands[2]);
13950 [(set_attr "isa" "*,bmi2")])
13952 (define_insn_and_split "*ashl<mode>3_mask_1"
13953 [(set (match_operand:SWI48 0 "nonimmediate_operand")
13955 (match_operand:SWI48 1 "nonimmediate_operand")
13957 (match_operand:QI 2 "register_operand" "c,r")
13958 (match_operand:QI 3 "const_int_operand"))))
13959 (clobber (reg:CC FLAGS_REG))]
13960 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
13961 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
13962 == GET_MODE_BITSIZE (<MODE>mode)-1
13963 && ix86_pre_reload_split ()"
13967 [(set (match_dup 0)
13968 (ashift:SWI48 (match_dup 1)
13970 (clobber (reg:CC FLAGS_REG))])]
13972 [(set_attr "isa" "*,bmi2")])
13974 (define_insn "*bmi2_ashl<mode>3_1"
13975 [(set (match_operand:SWI48 0 "register_operand" "=r")
13976 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13977 (match_operand:SWI48 2 "register_operand" "r")))]
13979 "shlx\t{%2, %1, %0|%0, %1, %2}"
13980 [(set_attr "type" "ishiftx")
13981 (set_attr "mode" "<MODE>")])
13983 (define_insn "*ashl<mode>3_1"
13984 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,?k")
13985 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm,k")
13986 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r,<KS>")))
13987 (clobber (reg:CC FLAGS_REG))]
13988 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
13990 switch (get_attr_type (insn))
13998 gcc_assert (operands[2] == const1_rtx);
13999 gcc_assert (rtx_equal_p (operands[0], operands[1]));
14000 return "add{<imodesuffix>}\t%0, %0";
14003 if (operands[2] == const1_rtx
14004 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14005 return "sal{<imodesuffix>}\t%0";
14007 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14010 [(set_attr "isa" "*,*,bmi2,<kmov_isa>")
14012 (cond [(eq_attr "alternative" "1")
14013 (const_string "lea")
14014 (eq_attr "alternative" "2")
14015 (const_string "ishiftx")
14016 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14017 (match_operand 0 "register_operand"))
14018 (match_operand 2 "const1_operand"))
14019 (const_string "alu")
14020 (eq_attr "alternative" "3")
14021 (const_string "msklog")
14023 (const_string "ishift")))
14024 (set (attr "length_immediate")
14026 (ior (eq_attr "type" "alu")
14027 (and (eq_attr "type" "ishift")
14028 (and (match_operand 2 "const1_operand")
14029 (ior (match_test "TARGET_SHIFT1")
14030 (match_test "optimize_function_for_size_p (cfun)")))))
14032 (const_string "*")))
14033 (set_attr "mode" "<MODE>")])
14035 ;; Convert shift to the shiftx pattern to avoid flags dependency.
14037 [(set (match_operand:SWI48 0 "register_operand")
14038 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
14039 (match_operand:QI 2 "register_operand")))
14040 (clobber (reg:CC FLAGS_REG))]
14041 "TARGET_BMI2 && reload_completed"
14042 [(set (match_dup 0)
14043 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
14044 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
14046 (define_insn "*bmi2_ashlsi3_1_zext"
14047 [(set (match_operand:DI 0 "register_operand" "=r")
14049 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
14050 (match_operand:SI 2 "register_operand" "r"))))]
14051 "TARGET_64BIT && TARGET_BMI2"
14052 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
14053 [(set_attr "type" "ishiftx")
14054 (set_attr "mode" "SI")])
14056 (define_insn "*ashlsi3_1_zext"
14057 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
14059 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
14060 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
14061 (clobber (reg:CC FLAGS_REG))]
14062 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
14064 switch (get_attr_type (insn))
14071 gcc_assert (operands[2] == const1_rtx);
14072 return "add{l}\t%k0, %k0";
14075 if (operands[2] == const1_rtx
14076 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14077 return "sal{l}\t%k0";
14079 return "sal{l}\t{%2, %k0|%k0, %2}";
14082 [(set_attr "isa" "*,*,bmi2")
14084 (cond [(eq_attr "alternative" "1")
14085 (const_string "lea")
14086 (eq_attr "alternative" "2")
14087 (const_string "ishiftx")
14088 (and (match_test "TARGET_DOUBLE_WITH_ADD")
14089 (match_operand 2 "const1_operand"))
14090 (const_string "alu")
14092 (const_string "ishift")))
14093 (set (attr "length_immediate")
14095 (ior (eq_attr "type" "alu")
14096 (and (eq_attr "type" "ishift")
14097 (and (match_operand 2 "const1_operand")
14098 (ior (match_test "TARGET_SHIFT1")
14099 (match_test "optimize_function_for_size_p (cfun)")))))
14101 (const_string "*")))
14102 (set_attr "mode" "SI")])
14104 ;; Convert shift to the shiftx pattern to avoid flags dependency.
14106 [(set (match_operand:DI 0 "register_operand")
14108 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
14109 (match_operand:QI 2 "register_operand"))))
14110 (clobber (reg:CC FLAGS_REG))]
14111 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
14112 [(set (match_dup 0)
14113 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
14114 "operands[2] = gen_lowpart (SImode, operands[2]);")
14116 (define_insn "*ashlhi3_1"
14117 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp,?k")
14118 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l,k")
14119 (match_operand:QI 2 "nonmemory_operand" "cI,M,Ww")))
14120 (clobber (reg:CC FLAGS_REG))]
14121 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
14123 switch (get_attr_type (insn))
14130 gcc_assert (operands[2] == const1_rtx);
14131 return "add{w}\t%0, %0";
14134 if (operands[2] == const1_rtx
14135 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14136 return "sal{w}\t%0";
14138 return "sal{w}\t{%2, %0|%0, %2}";
14141 [(set_attr "isa" "*,*,avx512f")
14143 (cond [(eq_attr "alternative" "1")
14144 (const_string "lea")
14145 (eq_attr "alternative" "2")
14146 (const_string "msklog")
14147 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14148 (match_operand 0 "register_operand"))
14149 (match_operand 2 "const1_operand"))
14150 (const_string "alu")
14152 (const_string "ishift")))
14153 (set (attr "length_immediate")
14155 (ior (eq_attr "type" "alu")
14156 (and (eq_attr "type" "ishift")
14157 (and (match_operand 2 "const1_operand")
14158 (ior (match_test "TARGET_SHIFT1")
14159 (match_test "optimize_function_for_size_p (cfun)")))))
14161 (const_string "*")))
14162 (set_attr "mode" "HI,SI,HI")])
14164 (define_insn "*ashlqi3_1"
14165 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp,?k")
14166 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l,k")
14167 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M,Wb")))
14168 (clobber (reg:CC FLAGS_REG))]
14169 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
14171 switch (get_attr_type (insn))
14178 gcc_assert (operands[2] == const1_rtx);
14179 if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
14180 return "add{l}\t%k0, %k0";
14182 return "add{b}\t%0, %0";
14185 if (operands[2] == const1_rtx
14186 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14188 if (get_attr_mode (insn) == MODE_SI)
14189 return "sal{l}\t%k0";
14191 return "sal{b}\t%0";
14195 if (get_attr_mode (insn) == MODE_SI)
14196 return "sal{l}\t{%2, %k0|%k0, %2}";
14198 return "sal{b}\t{%2, %0|%0, %2}";
14202 [(set_attr "isa" "*,*,*,avx512dq")
14204 (cond [(eq_attr "alternative" "2")
14205 (const_string "lea")
14206 (eq_attr "alternative" "3")
14207 (const_string "msklog")
14208 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14209 (match_operand 0 "register_operand"))
14210 (match_operand 2 "const1_operand"))
14211 (const_string "alu")
14213 (const_string "ishift")))
14214 (set (attr "length_immediate")
14216 (ior (eq_attr "type" "alu")
14217 (and (eq_attr "type" "ishift")
14218 (and (match_operand 2 "const1_operand")
14219 (ior (match_test "TARGET_SHIFT1")
14220 (match_test "optimize_function_for_size_p (cfun)")))))
14222 (const_string "*")))
14223 (set_attr "mode" "QI,SI,SI,QI")
14224 ;; Potential partial reg stall on alternative 1.
14225 (set (attr "preferred_for_speed")
14226 (cond [(eq_attr "alternative" "1")
14227 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
14228 (symbol_ref "true")))])
14230 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
14231 (define_insn_and_split "*ashl<mode>3_1_slp"
14232 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
14233 (ashift:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
14234 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
14235 (clobber (reg:CC FLAGS_REG))]
14236 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
14238 if (which_alternative)
14241 switch (get_attr_type (insn))
14244 gcc_assert (operands[2] == const1_rtx);
14245 return "add{<imodesuffix>}\t%0, %0";
14248 if (operands[2] == const1_rtx
14249 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14250 return "sal{<imodesuffix>}\t%0";
14252 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14255 "&& reload_completed"
14256 [(set (strict_low_part (match_dup 0)) (match_dup 1))
14258 [(set (strict_low_part (match_dup 0))
14259 (ashift:SWI12 (match_dup 0) (match_dup 2)))
14260 (clobber (reg:CC FLAGS_REG))])]
14262 [(set (attr "type")
14263 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
14264 (match_operand 2 "const1_operand"))
14265 (const_string "alu")
14267 (const_string "ishift")))
14268 (set (attr "length_immediate")
14270 (ior (eq_attr "type" "alu")
14271 (and (eq_attr "type" "ishift")
14272 (and (match_operand 2 "const1_operand")
14273 (ior (match_test "TARGET_SHIFT1")
14274 (match_test "optimize_function_for_size_p (cfun)")))))
14276 (const_string "*")))
14277 (set_attr "mode" "<MODE>")])
14279 ;; Convert ashift to the lea pattern to avoid flags dependency.
14281 [(set (match_operand:SWI 0 "general_reg_operand")
14282 (ashift:SWI (match_operand:SWI 1 "index_reg_operand")
14283 (match_operand 2 "const_0_to_3_operand")))
14284 (clobber (reg:CC FLAGS_REG))]
14286 && REGNO (operands[0]) != REGNO (operands[1])"
14287 [(set (match_dup 0)
14288 (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
14290 if (<MODE>mode != <LEAMODE>mode)
14292 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
14293 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
14295 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
14298 ;; Convert ashift to the lea pattern to avoid flags dependency.
14300 [(set (match_operand:DI 0 "general_reg_operand")
14302 (ashift:SI (match_operand:SI 1 "index_reg_operand")
14303 (match_operand 2 "const_0_to_3_operand"))))
14304 (clobber (reg:CC FLAGS_REG))]
14305 "TARGET_64BIT && reload_completed
14306 && REGNO (operands[0]) != REGNO (operands[1])"
14307 [(set (match_dup 0)
14308 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
14310 operands[1] = gen_lowpart (SImode, operands[1]);
14311 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
14314 ;; This pattern can't accept a variable shift count, since shifts by
14315 ;; zero don't affect the flags. We assume that shifts by constant
14316 ;; zero are optimized away.
14317 (define_insn "*ashl<mode>3_cmp"
14318 [(set (reg FLAGS_REG)
14320 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
14321 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
14323 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
14324 (ashift:SWI (match_dup 1) (match_dup 2)))]
14325 "(optimize_function_for_size_p (cfun)
14326 || !TARGET_PARTIAL_FLAG_REG_STALL
14327 || (operands[2] == const1_rtx
14329 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
14330 && ix86_match_ccmode (insn, CCGOCmode)
14331 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
14333 switch (get_attr_type (insn))
14336 gcc_assert (operands[2] == const1_rtx);
14337 return "add{<imodesuffix>}\t%0, %0";
14340 if (operands[2] == const1_rtx
14341 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14342 return "sal{<imodesuffix>}\t%0";
14344 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14347 [(set (attr "type")
14348 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14349 (match_operand 0 "register_operand"))
14350 (match_operand 2 "const1_operand"))
14351 (const_string "alu")
14353 (const_string "ishift")))
14354 (set (attr "length_immediate")
14356 (ior (eq_attr "type" "alu")
14357 (and (eq_attr "type" "ishift")
14358 (and (match_operand 2 "const1_operand")
14359 (ior (match_test "TARGET_SHIFT1")
14360 (match_test "optimize_function_for_size_p (cfun)")))))
14362 (const_string "*")))
14363 (set_attr "mode" "<MODE>")])
14365 (define_insn "*ashlsi3_cmp_zext"
14366 [(set (reg FLAGS_REG)
14368 (ashift:SI (match_operand:SI 1 "register_operand" "0")
14369 (match_operand:QI 2 "const_1_to_31_operand"))
14371 (set (match_operand:DI 0 "register_operand" "=r")
14372 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
14374 && (optimize_function_for_size_p (cfun)
14375 || !TARGET_PARTIAL_FLAG_REG_STALL
14376 || (operands[2] == const1_rtx
14378 || TARGET_DOUBLE_WITH_ADD)))
14379 && ix86_match_ccmode (insn, CCGOCmode)
14380 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
14382 switch (get_attr_type (insn))
14385 gcc_assert (operands[2] == const1_rtx);
14386 return "add{l}\t%k0, %k0";
14389 if (operands[2] == const1_rtx
14390 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14391 return "sal{l}\t%k0";
14393 return "sal{l}\t{%2, %k0|%k0, %2}";
14396 [(set (attr "type")
14397 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
14398 (match_operand 2 "const1_operand"))
14399 (const_string "alu")
14401 (const_string "ishift")))
14402 (set (attr "length_immediate")
14404 (ior (eq_attr "type" "alu")
14405 (and (eq_attr "type" "ishift")
14406 (and (match_operand 2 "const1_operand")
14407 (ior (match_test "TARGET_SHIFT1")
14408 (match_test "optimize_function_for_size_p (cfun)")))))
14410 (const_string "*")))
14411 (set_attr "mode" "SI")])
14413 (define_insn "*ashl<mode>3_cconly"
14414 [(set (reg FLAGS_REG)
14416 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
14417 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
14419 (clobber (match_scratch:SWI 0 "=<r>"))]
14420 "(optimize_function_for_size_p (cfun)
14421 || !TARGET_PARTIAL_FLAG_REG_STALL
14422 || (operands[2] == const1_rtx
14424 || TARGET_DOUBLE_WITH_ADD)))
14425 && ix86_match_ccmode (insn, CCGOCmode)"
14427 switch (get_attr_type (insn))
14430 gcc_assert (operands[2] == const1_rtx);
14431 return "add{<imodesuffix>}\t%0, %0";
14434 if (operands[2] == const1_rtx
14435 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14436 return "sal{<imodesuffix>}\t%0";
14438 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14441 [(set (attr "type")
14442 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14443 (match_operand 0 "register_operand"))
14444 (match_operand 2 "const1_operand"))
14445 (const_string "alu")
14447 (const_string "ishift")))
14448 (set (attr "length_immediate")
14450 (ior (eq_attr "type" "alu")
14451 (and (eq_attr "type" "ishift")
14452 (and (match_operand 2 "const1_operand")
14453 (ior (match_test "TARGET_SHIFT1")
14454 (match_test "optimize_function_for_size_p (cfun)")))))
14456 (const_string "*")))
14457 (set_attr "mode" "<MODE>")])
14459 (define_insn "*ashlqi_ext<mode>_2"
14460 [(set (zero_extract:SWI248
14461 (match_operand 0 "int248_register_operand" "+Q")
14467 (match_operator:SWI248 3 "extract_operator"
14468 [(match_operand 1 "int248_register_operand" "0")
14471 (match_operand:QI 2 "nonmemory_operand" "cI")) 0))
14472 (clobber (reg:CC FLAGS_REG))]
14473 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
14474 rtx_equal_p (operands[0], operands[1])"
14476 switch (get_attr_type (insn))
14479 gcc_assert (operands[2] == const1_rtx);
14480 return "add{b}\t%h0, %h0";
14483 if (operands[2] == const1_rtx
14484 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14485 return "sal{b}\t%h0";
14487 return "sal{b}\t{%2, %h0|%h0, %2}";
14490 [(set (attr "type")
14491 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
14492 (match_operand 2 "const1_operand"))
14493 (const_string "alu")
14495 (const_string "ishift")))
14496 (set (attr "length_immediate")
14498 (ior (eq_attr "type" "alu")
14499 (and (eq_attr "type" "ishift")
14500 (and (match_operand 2 "const1_operand")
14501 (ior (match_test "TARGET_SHIFT1")
14502 (match_test "optimize_function_for_size_p (cfun)")))))
14504 (const_string "*")))
14505 (set_attr "mode" "QI")])
14507 ;; See comment above `ashl<mode>3' about how this works.
14509 (define_expand "<insn><mode>3"
14510 [(set (match_operand:SDWIM 0 "<shift_operand>")
14511 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
14512 (match_operand:QI 2 "nonmemory_operand")))]
14514 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
14516 ;; Avoid useless masking of count operand.
14517 (define_insn_and_split "*<insn><mode>3_mask"
14518 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14520 (match_operand:SWI48 1 "nonimmediate_operand")
14523 (match_operand 2 "int248_register_operand" "c,r")
14524 (match_operand 3 "const_int_operand")) 0)))
14525 (clobber (reg:CC FLAGS_REG))]
14526 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
14527 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
14528 == GET_MODE_BITSIZE (<MODE>mode)-1
14529 && ix86_pre_reload_split ()"
14533 [(set (match_dup 0)
14534 (any_shiftrt:SWI48 (match_dup 1)
14536 (clobber (reg:CC FLAGS_REG))])]
14538 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14539 operands[2] = gen_lowpart (QImode, operands[2]);
14541 [(set_attr "isa" "*,bmi2")])
14543 (define_insn_and_split "*<insn><mode>3_mask_1"
14544 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14546 (match_operand:SWI48 1 "nonimmediate_operand")
14548 (match_operand:QI 2 "register_operand" "c,r")
14549 (match_operand:QI 3 "const_int_operand"))))
14550 (clobber (reg:CC FLAGS_REG))]
14551 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
14552 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
14553 == GET_MODE_BITSIZE (<MODE>mode)-1
14554 && ix86_pre_reload_split ()"
14558 [(set (match_dup 0)
14559 (any_shiftrt:SWI48 (match_dup 1)
14561 (clobber (reg:CC FLAGS_REG))])]
14563 [(set_attr "isa" "*,bmi2")])
14565 (define_insn_and_split "*<insn><dwi>3_doubleword_mask"
14566 [(set (match_operand:<DWI> 0 "register_operand")
14568 (match_operand:<DWI> 1 "register_operand")
14571 (match_operand 2 "int248_register_operand" "c")
14572 (match_operand 3 "const_int_operand")) 0)))
14573 (clobber (reg:CC FLAGS_REG))]
14574 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
14575 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
14576 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
14577 && ix86_pre_reload_split ()"
14581 [(set (match_dup 4)
14582 (ior:DWIH (lshiftrt:DWIH (match_dup 4)
14583 (and:QI (match_dup 2) (match_dup 8)))
14585 (ashift:<DWI> (zero_extend:<DWI> (match_dup 7))
14586 (minus:QI (match_dup 9)
14587 (and:QI (match_dup 2) (match_dup 8)))) 0)))
14588 (clobber (reg:CC FLAGS_REG))])
14590 [(set (match_dup 6)
14591 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
14592 (clobber (reg:CC FLAGS_REG))])]
14594 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
14596 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14597 operands[2] = gen_lowpart (QImode, operands[2]);
14598 emit_insn (gen_<insn><dwi>3_doubleword (operands[0], operands[1],
14603 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
14605 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
14606 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
14608 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14609 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14612 xops[0] = gen_reg_rtx (GET_MODE (operands[2]));
14613 xops[1] = operands[2];
14614 xops[2] = GEN_INT (INTVAL (operands[3])
14615 & ((<MODE_SIZE> * BITS_PER_UNIT) - 1));
14616 ix86_expand_binary_operator (AND, GET_MODE (operands[2]), xops);
14617 operands[2] = xops[0];
14620 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14621 operands[2] = gen_lowpart (QImode, operands[2]);
14623 if (!rtx_equal_p (operands[4], operands[5]))
14624 emit_move_insn (operands[4], operands[5]);
14627 (define_insn_and_split "*<insn><dwi>3_doubleword_mask_1"
14628 [(set (match_operand:<DWI> 0 "register_operand")
14630 (match_operand:<DWI> 1 "register_operand")
14632 (match_operand:QI 2 "register_operand" "c")
14633 (match_operand:QI 3 "const_int_operand"))))
14634 (clobber (reg:CC FLAGS_REG))]
14635 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
14636 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
14637 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
14638 && ix86_pre_reload_split ()"
14642 [(set (match_dup 4)
14643 (ior:DWIH (lshiftrt:DWIH (match_dup 4)
14644 (and:QI (match_dup 2) (match_dup 8)))
14646 (ashift:<DWI> (zero_extend:<DWI> (match_dup 7))
14647 (minus:QI (match_dup 9)
14648 (and:QI (match_dup 2) (match_dup 8)))) 0)))
14649 (clobber (reg:CC FLAGS_REG))])
14651 [(set (match_dup 6)
14652 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
14653 (clobber (reg:CC FLAGS_REG))])]
14655 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
14657 emit_insn (gen_<insn><dwi>3_doubleword (operands[0], operands[1],
14662 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
14664 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
14665 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
14667 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14668 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14670 rtx tem = gen_reg_rtx (QImode);
14671 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
14675 if (!rtx_equal_p (operands[4], operands[5]))
14676 emit_move_insn (operands[4], operands[5]);
14679 (define_insn_and_split "<insn><mode>3_doubleword"
14680 [(set (match_operand:DWI 0 "register_operand" "=&r")
14681 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
14682 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
14683 (clobber (reg:CC FLAGS_REG))]
14686 "epilogue_completed"
14688 "ix86_split_<insn> (operands, NULL_RTX, <MODE>mode); DONE;"
14689 [(set_attr "type" "multi")])
14691 ;; By default we don't ask for a scratch register, because when DWImode
14692 ;; values are manipulated, registers are already at a premium. But if
14693 ;; we have one handy, we won't turn it away.
14696 [(match_scratch:DWIH 3 "r")
14697 (parallel [(set (match_operand:<DWI> 0 "register_operand")
14699 (match_operand:<DWI> 1 "register_operand")
14700 (match_operand:QI 2 "nonmemory_operand")))
14701 (clobber (reg:CC FLAGS_REG))])
14705 "ix86_split_<insn> (operands, operands[3], <DWI>mode); DONE;")
14707 (define_insn "x86_64_shrd"
14708 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
14709 (ior:DI (lshiftrt:DI (match_dup 0)
14710 (and:QI (match_operand:QI 2 "nonmemory_operand" "Jc")
14715 (match_operand:DI 1 "register_operand" "r"))
14716 (minus:QI (const_int 64)
14717 (and:QI (match_dup 2) (const_int 63)))) 0)))
14718 (clobber (reg:CC FLAGS_REG))]
14720 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
14721 [(set_attr "type" "ishift")
14722 (set_attr "prefix_0f" "1")
14723 (set_attr "mode" "DI")
14724 (set_attr "athlon_decode" "vector")
14725 (set_attr "amdfam10_decode" "vector")
14726 (set_attr "bdver1_decode" "vector")])
14728 (define_insn "x86_64_shrd_1"
14729 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
14730 (ior:DI (lshiftrt:DI (match_dup 0)
14731 (match_operand:QI 2 "const_0_to_63_operand"))
14735 (match_operand:DI 1 "register_operand" "r"))
14736 (match_operand:QI 3 "const_0_to_255_operand")) 0)))
14737 (clobber (reg:CC FLAGS_REG))]
14739 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])"
14740 "shrd{q}\t{%2, %1, %0|%0, %1, %2}"
14741 [(set_attr "type" "ishift")
14742 (set_attr "prefix_0f" "1")
14743 (set_attr "length_immediate" "1")
14744 (set_attr "mode" "DI")
14745 (set_attr "athlon_decode" "vector")
14746 (set_attr "amdfam10_decode" "vector")
14747 (set_attr "bdver1_decode" "vector")])
14749 (define_insn_and_split "*x86_64_shrd_shld_1_nozext"
14750 [(set (match_operand:DI 0 "nonimmediate_operand")
14751 (ior:DI (lshiftrt:DI (match_operand:DI 4 "nonimmediate_operand")
14752 (match_operand:QI 2 "const_0_to_63_operand"))
14754 (match_operand:DI 1 "nonimmediate_operand")
14755 (match_operand:QI 3 "const_0_to_63_operand"))))
14756 (clobber (reg:CC FLAGS_REG))]
14758 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])
14759 && ix86_pre_reload_split ()"
14764 if (rtx_equal_p (operands[4], operands[0]))
14766 operands[1] = force_reg (DImode, operands[1]);
14767 emit_insn (gen_x86_64_shrd_1 (operands[0], operands[1], operands[2], operands[3]));
14769 else if (rtx_equal_p (operands[1], operands[0]))
14771 operands[4] = force_reg (DImode, operands[4]);
14772 emit_insn (gen_x86_64_shld_1 (operands[0], operands[4], operands[3], operands[2]));
14776 operands[1] = force_reg (DImode, operands[1]);
14777 rtx tmp = gen_reg_rtx (DImode);
14778 emit_move_insn (tmp, operands[4]);
14779 emit_insn (gen_x86_64_shrd_1 (tmp, operands[1], operands[2], operands[3]));
14780 emit_move_insn (operands[0], tmp);
14785 (define_insn_and_split "*x86_64_shrd_2"
14786 [(set (match_operand:DI 0 "nonimmediate_operand")
14787 (ior:DI (lshiftrt:DI (match_dup 0)
14788 (match_operand:QI 2 "nonmemory_operand"))
14789 (ashift:DI (match_operand:DI 1 "register_operand")
14790 (minus:QI (const_int 64) (match_dup 2)))))
14791 (clobber (reg:CC FLAGS_REG))]
14792 "TARGET_64BIT && ix86_pre_reload_split ()"
14795 [(parallel [(set (match_dup 0)
14796 (ior:DI (lshiftrt:DI (match_dup 0)
14797 (and:QI (match_dup 2) (const_int 63)))
14800 (zero_extend:TI (match_dup 1))
14801 (minus:QI (const_int 64)
14802 (and:QI (match_dup 2)
14803 (const_int 63)))) 0)))
14804 (clobber (reg:CC FLAGS_REG))])])
14806 (define_insn "x86_shrd"
14807 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
14808 (ior:SI (lshiftrt:SI (match_dup 0)
14809 (and:QI (match_operand:QI 2 "nonmemory_operand" "Ic")
14814 (match_operand:SI 1 "register_operand" "r"))
14815 (minus:QI (const_int 32)
14816 (and:QI (match_dup 2) (const_int 31)))) 0)))
14817 (clobber (reg:CC FLAGS_REG))]
14819 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
14820 [(set_attr "type" "ishift")
14821 (set_attr "prefix_0f" "1")
14822 (set_attr "mode" "SI")
14823 (set_attr "pent_pair" "np")
14824 (set_attr "athlon_decode" "vector")
14825 (set_attr "amdfam10_decode" "vector")
14826 (set_attr "bdver1_decode" "vector")])
14828 (define_insn "x86_shrd_1"
14829 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
14830 (ior:SI (lshiftrt:SI (match_dup 0)
14831 (match_operand:QI 2 "const_0_to_31_operand"))
14835 (match_operand:SI 1 "register_operand" "r"))
14836 (match_operand:QI 3 "const_0_to_63_operand")) 0)))
14837 (clobber (reg:CC FLAGS_REG))]
14838 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])"
14839 "shrd{l}\t{%2, %1, %0|%0, %1, %2}"
14840 [(set_attr "type" "ishift")
14841 (set_attr "prefix_0f" "1")
14842 (set_attr "length_immediate" "1")
14843 (set_attr "mode" "SI")
14844 (set_attr "pent_pair" "np")
14845 (set_attr "athlon_decode" "vector")
14846 (set_attr "amdfam10_decode" "vector")
14847 (set_attr "bdver1_decode" "vector")])
14849 (define_insn_and_split "*x86_shrd_shld_1_nozext"
14850 [(set (match_operand:SI 0 "nonimmediate_operand")
14851 (ior:SI (lshiftrt:SI (match_operand:SI 4 "nonimmediate_operand")
14852 (match_operand:QI 2 "const_0_to_31_operand"))
14854 (match_operand:SI 1 "nonimmediate_operand")
14855 (match_operand:QI 3 "const_0_to_31_operand"))))
14856 (clobber (reg:CC FLAGS_REG))]
14857 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])
14858 && ix86_pre_reload_split ()"
14863 if (rtx_equal_p (operands[4], operands[0]))
14865 operands[1] = force_reg (SImode, operands[1]);
14866 emit_insn (gen_x86_shrd_1 (operands[0], operands[1], operands[2], operands[3]));
14868 else if (rtx_equal_p (operands[1], operands[0]))
14870 operands[4] = force_reg (SImode, operands[4]);
14871 emit_insn (gen_x86_shld_1 (operands[0], operands[4], operands[3], operands[2]));
14875 operands[1] = force_reg (SImode, operands[1]);
14876 rtx tmp = gen_reg_rtx (SImode);
14877 emit_move_insn (tmp, operands[4]);
14878 emit_insn (gen_x86_shrd_1 (tmp, operands[1], operands[2], operands[3]));
14879 emit_move_insn (operands[0], tmp);
14884 (define_insn_and_split "*x86_shrd_2"
14885 [(set (match_operand:SI 0 "nonimmediate_operand")
14886 (ior:SI (lshiftrt:SI (match_dup 0)
14887 (match_operand:QI 2 "nonmemory_operand"))
14888 (ashift:SI (match_operand:SI 1 "register_operand")
14889 (minus:QI (const_int 32) (match_dup 2)))))
14890 (clobber (reg:CC FLAGS_REG))]
14891 "TARGET_64BIT && ix86_pre_reload_split ()"
14894 [(parallel [(set (match_dup 0)
14895 (ior:SI (lshiftrt:SI (match_dup 0)
14896 (and:QI (match_dup 2) (const_int 31)))
14899 (zero_extend:DI (match_dup 1))
14900 (minus:QI (const_int 32)
14901 (and:QI (match_dup 2)
14902 (const_int 31)))) 0)))
14903 (clobber (reg:CC FLAGS_REG))])])
14905 ;; Base name for insn mnemonic.
14906 (define_mode_attr cvt_mnemonic
14907 [(SI "{cltd|cdq}") (DI "{cqto|cqo}")])
14909 (define_insn "ashr<mode>3_cvt"
14910 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=*d,rm")
14912 (match_operand:SWI48 1 "nonimmediate_operand" "*a,0")
14913 (match_operand:QI 2 "const_int_operand")))
14914 (clobber (reg:CC FLAGS_REG))]
14915 "INTVAL (operands[2]) == GET_MODE_BITSIZE (<MODE>mode)-1
14916 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
14917 && ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
14920 sar{<imodesuffix>}\t{%2, %0|%0, %2}"
14921 [(set_attr "type" "imovx,ishift")
14922 (set_attr "prefix_0f" "0,*")
14923 (set_attr "length_immediate" "0,*")
14924 (set_attr "modrm" "0,1")
14925 (set_attr "mode" "<MODE>")])
14927 (define_insn "*ashrsi3_cvt_zext"
14928 [(set (match_operand:DI 0 "register_operand" "=*d,r")
14930 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
14931 (match_operand:QI 2 "const_int_operand"))))
14932 (clobber (reg:CC FLAGS_REG))]
14933 "TARGET_64BIT && INTVAL (operands[2]) == 31
14934 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
14935 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
14938 sar{l}\t{%2, %k0|%k0, %2}"
14939 [(set_attr "type" "imovx,ishift")
14940 (set_attr "prefix_0f" "0,*")
14941 (set_attr "length_immediate" "0,*")
14942 (set_attr "modrm" "0,1")
14943 (set_attr "mode" "SI")])
14945 (define_expand "@x86_shift<mode>_adj_3"
14946 [(use (match_operand:SWI48 0 "register_operand"))
14947 (use (match_operand:SWI48 1 "register_operand"))
14948 (use (match_operand:QI 2 "register_operand"))]
14951 rtx_code_label *label = gen_label_rtx ();
14954 emit_insn (gen_testqi_ccz_1 (operands[2],
14955 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
14957 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
14958 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
14959 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
14960 gen_rtx_LABEL_REF (VOIDmode, label),
14962 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
14963 JUMP_LABEL (tmp) = label;
14965 emit_move_insn (operands[0], operands[1]);
14966 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
14967 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
14968 emit_label (label);
14969 LABEL_NUSES (label) = 1;
14974 (define_insn "*bmi2_<insn><mode>3_1"
14975 [(set (match_operand:SWI48 0 "register_operand" "=r")
14976 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14977 (match_operand:SWI48 2 "register_operand" "r")))]
14979 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
14980 [(set_attr "type" "ishiftx")
14981 (set_attr "mode" "<MODE>")])
14983 (define_insn "*ashr<mode>3_1"
14984 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
14986 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
14987 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
14988 (clobber (reg:CC FLAGS_REG))]
14989 "ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
14991 switch (get_attr_type (insn))
14997 if (operands[2] == const1_rtx
14998 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14999 return "sar{<imodesuffix>}\t%0";
15001 return "sar{<imodesuffix>}\t{%2, %0|%0, %2}";
15004 [(set_attr "isa" "*,bmi2")
15005 (set_attr "type" "ishift,ishiftx")
15006 (set (attr "length_immediate")
15008 (and (match_operand 2 "const1_operand")
15009 (ior (match_test "TARGET_SHIFT1")
15010 (match_test "optimize_function_for_size_p (cfun)")))
15012 (const_string "*")))
15013 (set_attr "mode" "<MODE>")])
15015 ;; Specialization of *lshr<mode>3_1 below, extracting the SImode
15016 ;; highpart of a DI to be extracted, but allowing it to be clobbered.
15017 (define_insn_and_split "*highpartdisi2"
15018 [(set (subreg:DI (match_operand:SI 0 "register_operand" "=r,x,?k") 0)
15019 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0,k")
15021 (clobber (reg:CC FLAGS_REG))]
15024 "&& reload_completed"
15026 [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 32)))
15027 (clobber (reg:CC FLAGS_REG))])]
15029 if (SSE_REG_P (operands[0]))
15031 rtx tmp = gen_rtx_REG (V4SImode, REGNO (operands[0]));
15032 emit_insn (gen_sse_shufps_v4si (tmp, tmp, tmp,
15033 const1_rtx, const1_rtx,
15034 GEN_INT (5), GEN_INT (5)));
15037 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
15040 (define_insn "*lshr<mode>3_1"
15041 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,?k")
15043 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm,k")
15044 (match_operand:QI 2 "nonmemory_operand" "c<S>,r,<KS>")))
15045 (clobber (reg:CC FLAGS_REG))]
15046 "ix86_binary_operator_ok (LSHIFTRT, <MODE>mode, operands)"
15048 switch (get_attr_type (insn))
15055 if (operands[2] == const1_rtx
15056 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15057 return "shr{<imodesuffix>}\t%0";
15059 return "shr{<imodesuffix>}\t{%2, %0|%0, %2}";
15062 [(set_attr "isa" "*,bmi2,<kmov_isa>")
15063 (set_attr "type" "ishift,ishiftx,msklog")
15064 (set (attr "length_immediate")
15066 (and (and (match_operand 2 "const1_operand")
15067 (eq_attr "alternative" "0"))
15068 (ior (match_test "TARGET_SHIFT1")
15069 (match_test "optimize_function_for_size_p (cfun)")))
15071 (const_string "*")))
15072 (set_attr "mode" "<MODE>")])
15074 ;; Convert shift to the shiftx pattern to avoid flags dependency.
15076 [(set (match_operand:SWI48 0 "register_operand")
15077 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
15078 (match_operand:QI 2 "register_operand")))
15079 (clobber (reg:CC FLAGS_REG))]
15080 "TARGET_BMI2 && reload_completed"
15081 [(set (match_dup 0)
15082 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
15083 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
15085 (define_insn "*bmi2_<insn>si3_1_zext"
15086 [(set (match_operand:DI 0 "register_operand" "=r")
15088 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
15089 (match_operand:SI 2 "register_operand" "r"))))]
15090 "TARGET_64BIT && TARGET_BMI2"
15091 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
15092 [(set_attr "type" "ishiftx")
15093 (set_attr "mode" "SI")])
15095 (define_insn "*<insn>si3_1_zext"
15096 [(set (match_operand:DI 0 "register_operand" "=r,r")
15098 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
15099 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
15100 (clobber (reg:CC FLAGS_REG))]
15101 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
15103 switch (get_attr_type (insn))
15109 if (operands[2] == const1_rtx
15110 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15111 return "<shift>{l}\t%k0";
15113 return "<shift>{l}\t{%2, %k0|%k0, %2}";
15116 [(set_attr "isa" "*,bmi2")
15117 (set_attr "type" "ishift,ishiftx")
15118 (set (attr "length_immediate")
15120 (and (match_operand 2 "const1_operand")
15121 (ior (match_test "TARGET_SHIFT1")
15122 (match_test "optimize_function_for_size_p (cfun)")))
15124 (const_string "*")))
15125 (set_attr "mode" "SI")])
15127 ;; Convert shift to the shiftx pattern to avoid flags dependency.
15129 [(set (match_operand:DI 0 "register_operand")
15131 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
15132 (match_operand:QI 2 "register_operand"))))
15133 (clobber (reg:CC FLAGS_REG))]
15134 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
15135 [(set (match_dup 0)
15136 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
15137 "operands[2] = gen_lowpart (SImode, operands[2]);")
15139 (define_insn "*ashr<mode>3_1"
15140 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
15142 (match_operand:SWI12 1 "nonimmediate_operand" "0")
15143 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
15144 (clobber (reg:CC FLAGS_REG))]
15145 "ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
15147 if (operands[2] == const1_rtx
15148 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15149 return "sar{<imodesuffix>}\t%0";
15151 return "sar{<imodesuffix>}\t{%2, %0|%0, %2}";
15153 [(set_attr "type" "ishift")
15154 (set (attr "length_immediate")
15156 (and (match_operand 2 "const1_operand")
15157 (ior (match_test "TARGET_SHIFT1")
15158 (match_test "optimize_function_for_size_p (cfun)")))
15160 (const_string "*")))
15161 (set_attr "mode" "<MODE>")])
15163 (define_insn "*lshrqi3_1"
15164 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,?k")
15166 (match_operand:QI 1 "nonimmediate_operand" "0, k")
15167 (match_operand:QI 2 "nonmemory_operand" "cI,Wb")))
15168 (clobber (reg:CC FLAGS_REG))]
15169 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
15171 switch (get_attr_type (insn))
15174 if (operands[2] == const1_rtx
15175 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15176 return "shr{b}\t%0";
15178 return "shr{b}\t{%2, %0|%0, %2}";
15182 gcc_unreachable ();
15185 [(set_attr "isa" "*,avx512dq")
15186 (set_attr "type" "ishift,msklog")
15187 (set (attr "length_immediate")
15189 (and (and (match_operand 2 "const1_operand")
15190 (eq_attr "alternative" "0"))
15191 (ior (match_test "TARGET_SHIFT1")
15192 (match_test "optimize_function_for_size_p (cfun)")))
15194 (const_string "*")))
15195 (set_attr "mode" "QI")])
15197 (define_insn "*lshrhi3_1"
15198 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm, ?k")
15200 (match_operand:HI 1 "nonimmediate_operand" "0, k")
15201 (match_operand:QI 2 "nonmemory_operand" "cI, Ww")))
15202 (clobber (reg:CC FLAGS_REG))]
15203 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
15205 switch (get_attr_type (insn))
15208 if (operands[2] == const1_rtx
15209 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15210 return "shr{w}\t%0";
15212 return "shr{w}\t{%2, %0|%0, %2}";
15216 gcc_unreachable ();
15219 [(set_attr "isa" "*, avx512f")
15220 (set_attr "type" "ishift,msklog")
15221 (set (attr "length_immediate")
15223 (and (and (match_operand 2 "const1_operand")
15224 (eq_attr "alternative" "0"))
15225 (ior (match_test "TARGET_SHIFT1")
15226 (match_test "optimize_function_for_size_p (cfun)")))
15228 (const_string "*")))
15229 (set_attr "mode" "HI")])
15231 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
15232 (define_insn_and_split "*<insn><mode>3_1_slp"
15233 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
15234 (any_shiftrt:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
15235 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
15236 (clobber (reg:CC FLAGS_REG))]
15237 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
15239 if (which_alternative)
15242 if (operands[2] == const1_rtx
15243 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15244 return "<shift>{<imodesuffix>}\t%0";
15246 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
15248 "&& reload_completed"
15249 [(set (strict_low_part (match_dup 0)) (match_dup 1))
15251 [(set (strict_low_part (match_dup 0))
15252 (any_shiftrt:SWI12 (match_dup 0) (match_dup 2)))
15253 (clobber (reg:CC FLAGS_REG))])]
15255 [(set_attr "type" "ishift")
15256 (set (attr "length_immediate")
15258 (and (match_operand 2 "const1_operand")
15259 (ior (match_test "TARGET_SHIFT1")
15260 (match_test "optimize_function_for_size_p (cfun)")))
15262 (const_string "*")))
15263 (set_attr "mode" "<MODE>")])
15265 ;; This pattern can't accept a variable shift count, since shifts by
15266 ;; zero don't affect the flags. We assume that shifts by constant
15267 ;; zero are optimized away.
15268 (define_insn "*<insn><mode>3_cmp"
15269 [(set (reg FLAGS_REG)
15272 (match_operand:SWI 1 "nonimmediate_operand" "0")
15273 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
15275 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
15276 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
15277 "(optimize_function_for_size_p (cfun)
15278 || !TARGET_PARTIAL_FLAG_REG_STALL
15279 || (operands[2] == const1_rtx
15281 && ix86_match_ccmode (insn, CCGOCmode)
15282 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
15284 if (operands[2] == const1_rtx
15285 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15286 return "<shift>{<imodesuffix>}\t%0";
15288 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
15290 [(set_attr "type" "ishift")
15291 (set (attr "length_immediate")
15293 (and (match_operand 2 "const1_operand")
15294 (ior (match_test "TARGET_SHIFT1")
15295 (match_test "optimize_function_for_size_p (cfun)")))
15297 (const_string "*")))
15298 (set_attr "mode" "<MODE>")])
15300 (define_insn "*<insn>si3_cmp_zext"
15301 [(set (reg FLAGS_REG)
15303 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
15304 (match_operand:QI 2 "const_1_to_31_operand"))
15306 (set (match_operand:DI 0 "register_operand" "=r")
15307 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
15309 && (optimize_function_for_size_p (cfun)
15310 || !TARGET_PARTIAL_FLAG_REG_STALL
15311 || (operands[2] == const1_rtx
15313 && ix86_match_ccmode (insn, CCGOCmode)
15314 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
15316 if (operands[2] == const1_rtx
15317 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15318 return "<shift>{l}\t%k0";
15320 return "<shift>{l}\t{%2, %k0|%k0, %2}";
15322 [(set_attr "type" "ishift")
15323 (set (attr "length_immediate")
15325 (and (match_operand 2 "const1_operand")
15326 (ior (match_test "TARGET_SHIFT1")
15327 (match_test "optimize_function_for_size_p (cfun)")))
15329 (const_string "*")))
15330 (set_attr "mode" "SI")])
15332 (define_insn "*<insn><mode>3_cconly"
15333 [(set (reg FLAGS_REG)
15336 (match_operand:SWI 1 "register_operand" "0")
15337 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
15339 (clobber (match_scratch:SWI 0 "=<r>"))]
15340 "(optimize_function_for_size_p (cfun)
15341 || !TARGET_PARTIAL_FLAG_REG_STALL
15342 || (operands[2] == const1_rtx
15344 && ix86_match_ccmode (insn, CCGOCmode)"
15346 if (operands[2] == const1_rtx
15347 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15348 return "<shift>{<imodesuffix>}\t%0";
15350 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
15352 [(set_attr "type" "ishift")
15353 (set (attr "length_immediate")
15355 (and (match_operand 2 "const1_operand")
15356 (ior (match_test "TARGET_SHIFT1")
15357 (match_test "optimize_function_for_size_p (cfun)")))
15359 (const_string "*")))
15360 (set_attr "mode" "<MODE>")])
15362 (define_insn "*<insn>qi_ext<mode>_2"
15363 [(set (zero_extract:SWI248
15364 (match_operand 0 "int248_register_operand" "+Q")
15370 (match_operator:SWI248 3 "extract_operator"
15371 [(match_operand 1 "int248_register_operand" "0")
15374 (match_operand:QI 2 "nonmemory_operand" "cI")) 0))
15375 (clobber (reg:CC FLAGS_REG))]
15376 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
15377 rtx_equal_p (operands[0], operands[1])"
15379 if (operands[2] == const1_rtx
15380 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15381 return "<shift>{b}\t%h0";
15383 return "<shift>{b}\t{%2, %h0|%h0, %2}";
15385 [(set_attr "type" "ishift")
15386 (set (attr "length_immediate")
15388 (and (match_operand 2 "const1_operand")
15389 (ior (match_test "TARGET_SHIFT1")
15390 (match_test "optimize_function_for_size_p (cfun)")))
15392 (const_string "*")))
15393 (set_attr "mode" "QI")])
15395 (define_insn_and_split "*extend<dwi>2_doubleword_highpart"
15396 [(set (match_operand:<DWI> 0 "register_operand" "=r")
15398 (ashift:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")
15399 (match_operand:QI 2 "const_int_operand"))
15400 (match_operand:QI 3 "const_int_operand")))
15401 (clobber (reg:CC FLAGS_REG))]
15402 "INTVAL (operands[2]) == INTVAL (operands[3])
15403 && UINTVAL (operands[2]) < <MODE_SIZE> * BITS_PER_UNIT"
15405 "&& reload_completed"
15406 [(parallel [(set (match_dup 4)
15407 (ashift:DWIH (match_dup 4) (match_dup 2)))
15408 (clobber (reg:CC FLAGS_REG))])
15409 (parallel [(set (match_dup 4)
15410 (ashiftrt:DWIH (match_dup 4) (match_dup 2)))
15411 (clobber (reg:CC FLAGS_REG))])]
15412 "split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[4]);")
15414 (define_insn_and_split "*extendv2di2_highpart_stv"
15415 [(set (match_operand:V2DI 0 "register_operand" "=v")
15417 (ashift:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "vm")
15418 (match_operand:QI 2 "const_int_operand"))
15419 (match_operand:QI 3 "const_int_operand")))]
15420 "!TARGET_64BIT && TARGET_STV && TARGET_AVX512VL
15421 && INTVAL (operands[2]) == INTVAL (operands[3])
15422 && UINTVAL (operands[2]) < 32"
15424 "&& reload_completed"
15425 [(set (match_dup 0)
15426 (ashift:V2DI (match_dup 1) (match_dup 2)))
15428 (ashiftrt:V2DI (match_dup 0) (match_dup 2)))])
15430 ;; Rotate instructions
15432 (define_expand "<insn>ti3"
15433 [(set (match_operand:TI 0 "register_operand")
15434 (any_rotate:TI (match_operand:TI 1 "register_operand")
15435 (match_operand:QI 2 "nonmemory_operand")))]
15438 if (const_1_to_63_operand (operands[2], VOIDmode))
15439 emit_insn (gen_ix86_<insn>ti3_doubleword
15440 (operands[0], operands[1], operands[2]));
15441 else if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 64)
15443 operands[1] = force_reg (TImode, operands[1]);
15444 emit_insn (gen_<insn>64ti2_doubleword (operands[0], operands[1]));
15448 rtx amount = force_reg (QImode, operands[2]);
15449 rtx src_lo = gen_lowpart (DImode, operands[1]);
15450 rtx src_hi = gen_highpart (DImode, operands[1]);
15451 rtx tmp_lo = gen_reg_rtx (DImode);
15452 rtx tmp_hi = gen_reg_rtx (DImode);
15453 emit_move_insn (tmp_lo, src_lo);
15454 emit_move_insn (tmp_hi, src_hi);
15455 rtx (*shiftd) (rtx, rtx, rtx)
15456 = (<CODE> == ROTATE) ? gen_x86_64_shld : gen_x86_64_shrd;
15457 emit_insn (shiftd (tmp_lo, src_hi, amount));
15458 emit_insn (shiftd (tmp_hi, src_lo, amount));
15459 rtx dst_lo = gen_lowpart (DImode, operands[0]);
15460 rtx dst_hi = gen_highpart (DImode, operands[0]);
15461 emit_move_insn (dst_lo, tmp_lo);
15462 emit_move_insn (dst_hi, tmp_hi);
15463 emit_insn (gen_x86_shiftdi_adj_1 (dst_lo, dst_hi, amount, tmp_lo));
15468 (define_expand "<insn>di3"
15469 [(set (match_operand:DI 0 "shiftdi_operand")
15470 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
15471 (match_operand:QI 2 "nonmemory_operand")))]
15475 ix86_expand_binary_operator (<CODE>, DImode, operands);
15476 else if (const_1_to_31_operand (operands[2], VOIDmode))
15477 emit_insn (gen_ix86_<insn>di3_doubleword
15478 (operands[0], operands[1], operands[2]));
15479 else if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 32)
15481 operands[1] = force_reg (DImode, operands[1]);
15482 emit_insn (gen_<insn>32di2_doubleword (operands[0], operands[1]));
15490 (define_expand "<insn><mode>3"
15491 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
15492 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
15493 (match_operand:QI 2 "nonmemory_operand")))]
15495 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
15497 ;; Avoid useless masking of count operand.
15498 (define_insn_and_split "*<insn><mode>3_mask"
15499 [(set (match_operand:SWI 0 "nonimmediate_operand")
15501 (match_operand:SWI 1 "nonimmediate_operand")
15504 (match_operand 2 "int248_register_operand" "c")
15505 (match_operand 3 "const_int_operand")) 0)))
15506 (clobber (reg:CC FLAGS_REG))]
15507 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
15508 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15509 == GET_MODE_BITSIZE (<MODE>mode)-1
15510 && ix86_pre_reload_split ()"
15514 [(set (match_dup 0)
15515 (any_rotate:SWI (match_dup 1)
15517 (clobber (reg:CC FLAGS_REG))])]
15519 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
15520 operands[2] = gen_lowpart (QImode, operands[2]);
15524 [(set (match_operand:SWI 0 "register_operand")
15526 (match_operand:SWI 1 "const_int_operand")
15529 (match_operand 2 "int248_register_operand")
15530 (match_operand 3 "const_int_operand")) 0)))]
15531 "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode) - 1))
15532 == GET_MODE_BITSIZE (<MODE>mode) - 1"
15533 [(set (match_dup 4) (match_dup 1))
15535 (any_rotate:SWI (match_dup 4)
15536 (subreg:QI (match_dup 2) 0)))]
15537 "operands[4] = gen_reg_rtx (<MODE>mode);")
15539 (define_insn_and_split "*<insn><mode>3_mask_1"
15540 [(set (match_operand:SWI 0 "nonimmediate_operand")
15542 (match_operand:SWI 1 "nonimmediate_operand")
15544 (match_operand:QI 2 "register_operand" "c")
15545 (match_operand:QI 3 "const_int_operand"))))
15546 (clobber (reg:CC FLAGS_REG))]
15547 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
15548 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15549 == GET_MODE_BITSIZE (<MODE>mode)-1
15550 && ix86_pre_reload_split ()"
15554 [(set (match_dup 0)
15555 (any_rotate:SWI (match_dup 1)
15557 (clobber (reg:CC FLAGS_REG))])])
15560 [(set (match_operand:SWI 0 "register_operand")
15562 (match_operand:SWI 1 "const_int_operand")
15564 (match_operand:QI 2 "register_operand")
15565 (match_operand:QI 3 "const_int_operand"))))]
15566 "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode) - 1))
15567 == GET_MODE_BITSIZE (<MODE>mode) - 1"
15568 [(set (match_dup 4) (match_dup 1))
15570 (any_rotate:SWI (match_dup 4) (match_dup 2)))]
15571 "operands[4] = gen_reg_rtx (<MODE>mode);")
15573 ;; Implement rotation using two double-precision
15574 ;; shift instructions and a scratch register.
15576 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
15577 [(set (match_operand:<DWI> 0 "register_operand" "=r")
15578 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
15579 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
15580 (clobber (reg:CC FLAGS_REG))
15581 (clobber (match_scratch:DWIH 3 "=&r"))]
15585 [(set (match_dup 3) (match_dup 4))
15587 [(set (match_dup 4)
15588 (ior:DWIH (ashift:DWIH (match_dup 4)
15589 (and:QI (match_dup 2) (match_dup 6)))
15591 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
15592 (minus:QI (match_dup 7)
15593 (and:QI (match_dup 2)
15594 (match_dup 6)))) 0)))
15595 (clobber (reg:CC FLAGS_REG))])
15597 [(set (match_dup 5)
15598 (ior:DWIH (ashift:DWIH (match_dup 5)
15599 (and:QI (match_dup 2) (match_dup 6)))
15601 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 3))
15602 (minus:QI (match_dup 7)
15603 (and:QI (match_dup 2)
15604 (match_dup 6)))) 0)))
15605 (clobber (reg:CC FLAGS_REG))])]
15607 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
15608 operands[7] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
15610 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
15613 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
15614 [(set (match_operand:<DWI> 0 "register_operand" "=r")
15615 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
15616 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
15617 (clobber (reg:CC FLAGS_REG))
15618 (clobber (match_scratch:DWIH 3 "=&r"))]
15622 [(set (match_dup 3) (match_dup 4))
15624 [(set (match_dup 4)
15625 (ior:DWIH (lshiftrt:DWIH (match_dup 4)
15626 (and:QI (match_dup 2) (match_dup 6)))
15628 (ashift:<DWI> (zero_extend:<DWI> (match_dup 5))
15629 (minus:QI (match_dup 7)
15630 (and:QI (match_dup 2)
15631 (match_dup 6)))) 0)))
15632 (clobber (reg:CC FLAGS_REG))])
15634 [(set (match_dup 5)
15635 (ior:DWIH (lshiftrt:DWIH (match_dup 5)
15636 (and:QI (match_dup 2) (match_dup 6)))
15638 (ashift:<DWI> (zero_extend:<DWI> (match_dup 3))
15639 (minus:QI (match_dup 7)
15640 (and:QI (match_dup 2)
15641 (match_dup 6)))) 0)))
15642 (clobber (reg:CC FLAGS_REG))])]
15644 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
15645 operands[7] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
15647 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
15650 (define_insn_and_split "<insn>32di2_doubleword"
15651 [(set (match_operand:DI 0 "register_operand" "=r,r")
15652 (any_rotate:DI (match_operand:DI 1 "register_operand" "0,r")
15656 "&& reload_completed"
15657 [(set (match_dup 0) (match_dup 3))
15658 (set (match_dup 2) (match_dup 1))]
15660 split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);
15661 if (rtx_equal_p (operands[0], operands[1]))
15663 emit_insn (gen_swapsi (operands[0], operands[2]));
15668 (define_insn_and_split "<insn>64ti2_doubleword"
15669 [(set (match_operand:TI 0 "register_operand" "=r,r")
15670 (any_rotate:TI (match_operand:TI 1 "register_operand" "0,r")
15674 "&& reload_completed"
15675 [(set (match_dup 0) (match_dup 3))
15676 (set (match_dup 2) (match_dup 1))]
15678 split_double_mode (TImode, &operands[0], 2, &operands[0], &operands[2]);
15679 if (rtx_equal_p (operands[0], operands[1]))
15681 emit_insn (gen_swapdi (operands[0], operands[2]));
15686 (define_mode_attr rorx_immediate_operand
15687 [(SI "const_0_to_31_operand")
15688 (DI "const_0_to_63_operand")])
15690 (define_insn "*bmi2_rorx<mode>3_1"
15691 [(set (match_operand:SWI48 0 "register_operand" "=r")
15693 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
15694 (match_operand:QI 2 "<rorx_immediate_operand>" "<S>")))]
15695 "TARGET_BMI2 && !optimize_function_for_size_p (cfun)"
15696 "rorx\t{%2, %1, %0|%0, %1, %2}"
15697 [(set_attr "type" "rotatex")
15698 (set_attr "mode" "<MODE>")])
15700 (define_insn "*<insn><mode>3_1"
15701 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
15703 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
15704 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
15705 (clobber (reg:CC FLAGS_REG))]
15706 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
15708 switch (get_attr_type (insn))
15714 if (operands[2] == const1_rtx
15715 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15716 return "<rotate>{<imodesuffix>}\t%0";
15718 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
15721 [(set_attr "isa" "*,bmi2")
15722 (set_attr "type" "rotate,rotatex")
15723 (set (attr "preferred_for_size")
15724 (cond [(eq_attr "alternative" "0")
15725 (symbol_ref "true")]
15726 (symbol_ref "false")))
15727 (set (attr "length_immediate")
15729 (and (eq_attr "type" "rotate")
15730 (and (match_operand 2 "const1_operand")
15731 (ior (match_test "TARGET_SHIFT1")
15732 (match_test "optimize_function_for_size_p (cfun)"))))
15734 (const_string "*")))
15735 (set_attr "mode" "<MODE>")])
15737 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
15739 [(set (match_operand:SWI48 0 "register_operand")
15740 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
15741 (match_operand:QI 2 "const_int_operand")))
15742 (clobber (reg:CC FLAGS_REG))]
15743 "TARGET_BMI2 && reload_completed && !optimize_function_for_size_p (cfun)"
15744 [(set (match_dup 0)
15745 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
15747 int bitsize = GET_MODE_BITSIZE (<MODE>mode);
15749 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
15753 [(set (match_operand:SWI48 0 "register_operand")
15754 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
15755 (match_operand:QI 2 "const_int_operand")))
15756 (clobber (reg:CC FLAGS_REG))]
15757 "TARGET_BMI2 && reload_completed && !optimize_function_for_size_p (cfun)"
15758 [(set (match_dup 0)
15759 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
15761 (define_insn "*bmi2_rorxsi3_1_zext"
15762 [(set (match_operand:DI 0 "register_operand" "=r")
15764 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
15765 (match_operand:QI 2 "const_0_to_31_operand"))))]
15766 "TARGET_64BIT && TARGET_BMI2 && !optimize_function_for_size_p (cfun)"
15767 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
15768 [(set_attr "type" "rotatex")
15769 (set_attr "mode" "SI")])
15771 (define_insn "*<insn>si3_1_zext"
15772 [(set (match_operand:DI 0 "register_operand" "=r,r")
15774 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
15775 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
15776 (clobber (reg:CC FLAGS_REG))]
15777 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
15779 switch (get_attr_type (insn))
15785 if (operands[2] == const1_rtx
15786 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15787 return "<rotate>{l}\t%k0";
15789 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
15792 [(set_attr "isa" "*,bmi2")
15793 (set_attr "type" "rotate,rotatex")
15794 (set (attr "preferred_for_size")
15795 (cond [(eq_attr "alternative" "0")
15796 (symbol_ref "true")]
15797 (symbol_ref "false")))
15798 (set (attr "length_immediate")
15800 (and (eq_attr "type" "rotate")
15801 (and (match_operand 2 "const1_operand")
15802 (ior (match_test "TARGET_SHIFT1")
15803 (match_test "optimize_function_for_size_p (cfun)"))))
15805 (const_string "*")))
15806 (set_attr "mode" "SI")])
15808 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
15810 [(set (match_operand:DI 0 "register_operand")
15812 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
15813 (match_operand:QI 2 "const_int_operand"))))
15814 (clobber (reg:CC FLAGS_REG))]
15815 "TARGET_64BIT && TARGET_BMI2 && reload_completed
15816 && !optimize_function_for_size_p (cfun)"
15817 [(set (match_dup 0)
15818 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
15820 int bitsize = GET_MODE_BITSIZE (SImode);
15822 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
15826 [(set (match_operand:DI 0 "register_operand")
15828 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
15829 (match_operand:QI 2 "const_int_operand"))))
15830 (clobber (reg:CC FLAGS_REG))]
15831 "TARGET_64BIT && TARGET_BMI2 && reload_completed
15832 && !optimize_function_for_size_p (cfun)"
15833 [(set (match_dup 0)
15834 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
15836 (define_insn "*<insn><mode>3_1"
15837 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
15838 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
15839 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
15840 (clobber (reg:CC FLAGS_REG))]
15841 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
15843 if (operands[2] == const1_rtx
15844 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15845 return "<rotate>{<imodesuffix>}\t%0";
15847 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
15849 [(set_attr "type" "rotate")
15850 (set (attr "length_immediate")
15852 (and (match_operand 2 "const1_operand")
15853 (ior (match_test "TARGET_SHIFT1")
15854 (match_test "optimize_function_for_size_p (cfun)")))
15856 (const_string "*")))
15857 (set_attr "mode" "<MODE>")])
15859 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
15860 (define_insn_and_split "*<insn><mode>3_1_slp"
15861 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
15862 (any_rotate:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
15863 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
15864 (clobber (reg:CC FLAGS_REG))]
15865 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
15867 if (which_alternative)
15870 if (operands[2] == const1_rtx
15871 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15872 return "<rotate>{<imodesuffix>}\t%0";
15874 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
15876 "&& reload_completed"
15877 [(set (strict_low_part (match_dup 0)) (match_dup 1))
15879 [(set (strict_low_part (match_dup 0))
15880 (any_rotate:SWI12 (match_dup 0) (match_dup 2)))
15881 (clobber (reg:CC FLAGS_REG))])]
15883 [(set_attr "type" "rotate")
15884 (set (attr "length_immediate")
15886 (and (match_operand 2 "const1_operand")
15887 (ior (match_test "TARGET_SHIFT1")
15888 (match_test "optimize_function_for_size_p (cfun)")))
15890 (const_string "*")))
15891 (set_attr "mode" "<MODE>")])
15894 [(set (match_operand:HI 0 "QIreg_operand")
15895 (any_rotate:HI (match_dup 0) (const_int 8)))
15896 (clobber (reg:CC FLAGS_REG))]
15898 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
15899 [(parallel [(set (strict_low_part (match_dup 0))
15900 (bswap:HI (match_dup 0)))
15901 (clobber (reg:CC FLAGS_REG))])])
15903 ;; Rotations through carry flag
15904 (define_insn "rcrsi2"
15905 [(set (match_operand:SI 0 "register_operand" "=r")
15907 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
15909 (ashift:SI (ltu:SI (reg:CCC FLAGS_REG) (const_int 0))
15911 (clobber (reg:CC FLAGS_REG))]
15914 [(set_attr "type" "ishift1")
15915 (set_attr "memory" "none")
15916 (set_attr "length_immediate" "0")
15917 (set_attr "mode" "SI")])
15919 (define_insn "rcrdi2"
15920 [(set (match_operand:DI 0 "register_operand" "=r")
15922 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
15924 (ashift:DI (ltu:DI (reg:CCC FLAGS_REG) (const_int 0))
15926 (clobber (reg:CC FLAGS_REG))]
15929 [(set_attr "type" "ishift1")
15930 (set_attr "length_immediate" "0")
15931 (set_attr "mode" "DI")])
15933 ;; Versions of sar and shr that set the carry flag.
15934 (define_insn "<insn><mode>3_carry"
15935 [(set (reg:CCC FLAGS_REG)
15936 (unspec:CCC [(and:SWI48 (match_operand:SWI48 1 "register_operand" "0")
15938 (const_int 0)] UNSPEC_CC_NE))
15939 (set (match_operand:SWI48 0 "register_operand" "=r")
15940 (any_shiftrt:SWI48 (match_dup 1) (const_int 1)))]
15943 if (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
15944 return "<shift>{<imodesuffix>}\t%0";
15945 return "<shift>{<imodesuffix>}\t{1, %0|%0, 1}";
15947 [(set_attr "type" "ishift1")
15948 (set (attr "length_immediate")
15950 (ior (match_test "TARGET_SHIFT1")
15951 (match_test "optimize_function_for_size_p (cfun)"))
15953 (const_string "*")))
15954 (set_attr "mode" "<MODE>")])
15956 ;; Bit set / bit test instructions
15958 ;; %%% bts, btr, btc
15960 ;; These instructions are *slow* when applied to memory.
15962 (define_code_attr btsc [(ior "bts") (xor "btc")])
15964 (define_insn "*<btsc><mode>"
15965 [(set (match_operand:SWI48 0 "register_operand" "=r")
15967 (ashift:SWI48 (const_int 1)
15968 (match_operand:QI 2 "register_operand" "r"))
15969 (match_operand:SWI48 1 "register_operand" "0")))
15970 (clobber (reg:CC FLAGS_REG))]
15972 "<btsc>{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
15973 [(set_attr "type" "alu1")
15974 (set_attr "prefix_0f" "1")
15975 (set_attr "znver1_decode" "double")
15976 (set_attr "mode" "<MODE>")])
15978 ;; Avoid useless masking of count operand.
15979 (define_insn_and_split "*<btsc><mode>_mask"
15980 [(set (match_operand:SWI48 0 "register_operand")
15986 (match_operand 1 "int248_register_operand")
15987 (match_operand 2 "const_int_operand")) 0))
15988 (match_operand:SWI48 3 "register_operand")))
15989 (clobber (reg:CC FLAGS_REG))]
15991 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15992 == GET_MODE_BITSIZE (<MODE>mode)-1
15993 && ix86_pre_reload_split ()"
15997 [(set (match_dup 0)
15999 (ashift:SWI48 (const_int 1)
16002 (clobber (reg:CC FLAGS_REG))])]
16004 operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
16005 operands[1] = gen_lowpart (QImode, operands[1]);
16008 (define_insn_and_split "*<btsc><mode>_mask_1"
16009 [(set (match_operand:SWI48 0 "register_operand")
16014 (match_operand:QI 1 "register_operand")
16015 (match_operand:QI 2 "const_int_operand")))
16016 (match_operand:SWI48 3 "register_operand")))
16017 (clobber (reg:CC FLAGS_REG))]
16019 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16020 == GET_MODE_BITSIZE (<MODE>mode)-1
16021 && ix86_pre_reload_split ()"
16025 [(set (match_dup 0)
16027 (ashift:SWI48 (const_int 1)
16030 (clobber (reg:CC FLAGS_REG))])])
16032 (define_insn "*btr<mode>"
16033 [(set (match_operand:SWI48 0 "register_operand" "=r")
16035 (rotate:SWI48 (const_int -2)
16036 (match_operand:QI 2 "register_operand" "r"))
16037 (match_operand:SWI48 1 "register_operand" "0")))
16038 (clobber (reg:CC FLAGS_REG))]
16040 "btr{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
16041 [(set_attr "type" "alu1")
16042 (set_attr "prefix_0f" "1")
16043 (set_attr "znver1_decode" "double")
16044 (set_attr "mode" "<MODE>")])
16046 ;; Avoid useless masking of count operand.
16047 (define_insn_and_split "*btr<mode>_mask"
16048 [(set (match_operand:SWI48 0 "register_operand")
16054 (match_operand 1 "int248_register_operand")
16055 (match_operand 2 "const_int_operand")) 0))
16056 (match_operand:SWI48 3 "register_operand")))
16057 (clobber (reg:CC FLAGS_REG))]
16059 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16060 == GET_MODE_BITSIZE (<MODE>mode)-1
16061 && ix86_pre_reload_split ()"
16065 [(set (match_dup 0)
16067 (rotate:SWI48 (const_int -2)
16070 (clobber (reg:CC FLAGS_REG))])]
16072 operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
16073 operands[1] = gen_lowpart (QImode, operands[1]);
16076 (define_insn_and_split "*btr<mode>_mask_1"
16077 [(set (match_operand:SWI48 0 "register_operand")
16082 (match_operand:QI 1 "register_operand")
16083 (match_operand:QI 2 "const_int_operand")))
16084 (match_operand:SWI48 3 "register_operand")))
16085 (clobber (reg:CC FLAGS_REG))]
16087 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16088 == GET_MODE_BITSIZE (<MODE>mode)-1
16089 && ix86_pre_reload_split ()"
16093 [(set (match_dup 0)
16095 (rotate:SWI48 (const_int -2)
16098 (clobber (reg:CC FLAGS_REG))])])
16100 (define_insn_and_split "*btr<mode>_1"
16101 [(set (match_operand:SWI12 0 "register_operand")
16104 (rotate:SI (const_int -2)
16105 (match_operand:QI 2 "register_operand")) 0)
16106 (match_operand:SWI12 1 "nonimmediate_operand")))
16107 (clobber (reg:CC FLAGS_REG))]
16108 "TARGET_USE_BT && ix86_pre_reload_split ()"
16112 [(set (match_dup 0)
16113 (and:SI (rotate:SI (const_int -2) (match_dup 2))
16115 (clobber (reg:CC FLAGS_REG))])]
16117 operands[0] = lowpart_subreg (SImode, operands[0], <MODE>mode);
16118 operands[1] = force_reg (<MODE>mode, operands[1]);
16119 operands[1] = lowpart_subreg (SImode, operands[1], <MODE>mode);
16122 (define_insn_and_split "*btr<mode>_2"
16123 [(set (zero_extract:HI
16124 (match_operand:SWI12 0 "nonimmediate_operand")
16126 (match_operand:QI 1 "register_operand"))
16128 (clobber (reg:CC FLAGS_REG))]
16129 "TARGET_USE_BT && ix86_pre_reload_split ()"
16131 "&& MEM_P (operands[0])"
16132 [(set (match_dup 2) (match_dup 0))
16134 [(set (match_dup 3)
16135 (and:SI (rotate:SI (const_int -2) (match_dup 1))
16137 (clobber (reg:CC FLAGS_REG))])
16138 (set (match_dup 0) (match_dup 5))]
16140 operands[2] = gen_reg_rtx (<MODE>mode);
16141 operands[5] = gen_reg_rtx (<MODE>mode);
16142 operands[3] = lowpart_subreg (SImode, operands[5], <MODE>mode);
16143 operands[4] = lowpart_subreg (SImode, operands[2], <MODE>mode);
16147 [(set (zero_extract:HI
16148 (match_operand:SWI12 0 "register_operand")
16150 (match_operand:QI 1 "register_operand"))
16152 (clobber (reg:CC FLAGS_REG))]
16153 "TARGET_USE_BT && ix86_pre_reload_split ()"
16155 [(set (match_dup 0)
16156 (and:SI (rotate:SI (const_int -2) (match_dup 1))
16158 (clobber (reg:CC FLAGS_REG))])]
16160 operands[2] = lowpart_subreg (SImode, operands[0], <MODE>mode);
16161 operands[0] = lowpart_subreg (SImode, operands[0], <MODE>mode);
16164 ;; These instructions are never faster than the corresponding
16165 ;; and/ior/xor operations when using immediate operand, so with
16166 ;; 32-bit there's no point. But in 64-bit, we can't hold the
16167 ;; relevant immediates within the instruction itself, so operating
16168 ;; on bits in the high 32-bits of a register becomes easier.
16170 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
16171 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
16172 ;; negdf respectively, so they can never be disabled entirely.
16174 (define_insn "*btsq_imm"
16175 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
16177 (match_operand:QI 1 "const_0_to_63_operand"))
16179 (clobber (reg:CC FLAGS_REG))]
16180 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
16181 "bts{q}\t{%1, %0|%0, %1}"
16182 [(set_attr "type" "alu1")
16183 (set_attr "prefix_0f" "1")
16184 (set_attr "znver1_decode" "double")
16185 (set_attr "mode" "DI")])
16187 (define_insn "*btrq_imm"
16188 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
16190 (match_operand:QI 1 "const_0_to_63_operand"))
16192 (clobber (reg:CC FLAGS_REG))]
16193 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
16194 "btr{q}\t{%1, %0|%0, %1}"
16195 [(set_attr "type" "alu1")
16196 (set_attr "prefix_0f" "1")
16197 (set_attr "znver1_decode" "double")
16198 (set_attr "mode" "DI")])
16200 (define_insn "*btcq_imm"
16201 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
16203 (match_operand:QI 1 "const_0_to_63_operand"))
16204 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
16205 (clobber (reg:CC FLAGS_REG))]
16206 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
16207 "btc{q}\t{%1, %0|%0, %1}"
16208 [(set_attr "type" "alu1")
16209 (set_attr "prefix_0f" "1")
16210 (set_attr "znver1_decode" "double")
16211 (set_attr "mode" "DI")])
16213 ;; Allow Nocona to avoid these instructions if a register is available.
16216 [(match_scratch:DI 2 "r")
16217 (parallel [(set (zero_extract:DI
16218 (match_operand:DI 0 "nonimmediate_operand")
16220 (match_operand:QI 1 "const_0_to_63_operand"))
16222 (clobber (reg:CC FLAGS_REG))])]
16223 "TARGET_64BIT && !TARGET_USE_BT"
16224 [(parallel [(set (match_dup 0)
16225 (ior:DI (match_dup 0) (match_dup 3)))
16226 (clobber (reg:CC FLAGS_REG))])]
16228 int i = INTVAL (operands[1]);
16230 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
16232 if (!x86_64_immediate_operand (operands[3], DImode))
16234 emit_move_insn (operands[2], operands[3]);
16235 operands[3] = operands[2];
16240 [(match_scratch:DI 2 "r")
16241 (parallel [(set (zero_extract:DI
16242 (match_operand:DI 0 "nonimmediate_operand")
16244 (match_operand:QI 1 "const_0_to_63_operand"))
16246 (clobber (reg:CC FLAGS_REG))])]
16247 "TARGET_64BIT && !TARGET_USE_BT"
16248 [(parallel [(set (match_dup 0)
16249 (and:DI (match_dup 0) (match_dup 3)))
16250 (clobber (reg:CC FLAGS_REG))])]
16252 int i = INTVAL (operands[1]);
16254 operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
16256 if (!x86_64_immediate_operand (operands[3], DImode))
16258 emit_move_insn (operands[2], operands[3]);
16259 operands[3] = operands[2];
16264 [(match_scratch:DI 2 "r")
16265 (parallel [(set (zero_extract:DI
16266 (match_operand:DI 0 "nonimmediate_operand")
16268 (match_operand:QI 1 "const_0_to_63_operand"))
16269 (not:DI (zero_extract:DI
16270 (match_dup 0) (const_int 1) (match_dup 1))))
16271 (clobber (reg:CC FLAGS_REG))])]
16272 "TARGET_64BIT && !TARGET_USE_BT"
16273 [(parallel [(set (match_dup 0)
16274 (xor:DI (match_dup 0) (match_dup 3)))
16275 (clobber (reg:CC FLAGS_REG))])]
16277 int i = INTVAL (operands[1]);
16279 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
16281 if (!x86_64_immediate_operand (operands[3], DImode))
16283 emit_move_insn (operands[2], operands[3]);
16284 operands[3] = operands[2];
16290 (define_insn "*bt<mode>"
16291 [(set (reg:CCC FLAGS_REG)
16293 (zero_extract:SWI48
16294 (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
16296 (match_operand:QI 1 "nonmemory_operand" "q<S>,<S>"))
16300 switch (get_attr_mode (insn))
16303 return "bt{l}\t{%k1, %k0|%k0, %k1}";
16306 return "bt{q}\t{%q1, %0|%0, %q1}";
16309 gcc_unreachable ();
16312 [(set_attr "type" "alu1")
16313 (set_attr "prefix_0f" "1")
16316 (and (match_test "CONST_INT_P (operands[1])")
16317 (match_test "INTVAL (operands[1]) < 32"))
16318 (const_string "SI")
16319 (const_string "<MODE>")))])
16321 (define_insn_and_split "*bt<SWI48:mode>_mask"
16322 [(set (reg:CCC FLAGS_REG)
16324 (zero_extract:SWI48
16325 (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
16329 (match_operand:SWI248 1 "register_operand")
16330 (match_operand 2 "const_int_operand")) 0))
16333 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<SWI48:MODE>mode)-1))
16334 == GET_MODE_BITSIZE (<SWI48:MODE>mode)-1
16335 && ix86_pre_reload_split ()"
16338 [(set (reg:CCC FLAGS_REG)
16340 (zero_extract:SWI48 (match_dup 0) (const_int 1) (match_dup 1))
16342 "operands[1] = gen_lowpart (QImode, operands[1]);")
16344 (define_insn_and_split "*jcc_bt<mode>"
16346 (if_then_else (match_operator 0 "bt_comparison_operator"
16347 [(zero_extract:SWI48
16348 (match_operand:SWI48 1 "nonimmediate_operand")
16350 (match_operand:QI 2 "nonmemory_operand"))
16352 (label_ref (match_operand 3))
16354 (clobber (reg:CC FLAGS_REG))]
16355 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
16356 && (CONST_INT_P (operands[2])
16357 ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
16358 && INTVAL (operands[2])
16359 >= (optimize_function_for_size_p (cfun) ? 8 : 32))
16360 : !memory_operand (operands[1], <MODE>mode))
16361 && ix86_pre_reload_split ()"
16364 [(set (reg:CCC FLAGS_REG)
16366 (zero_extract:SWI48
16372 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16373 (label_ref (match_dup 3))
16376 operands[0] = shallow_copy_rtx (operands[0]);
16377 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16380 ;; Avoid useless masking of bit offset operand.
16381 (define_insn_and_split "*jcc_bt<mode>_mask"
16383 (if_then_else (match_operator 0 "bt_comparison_operator"
16384 [(zero_extract:SWI48
16385 (match_operand:SWI48 1 "register_operand")
16388 (match_operand:QI 2 "register_operand")
16389 (match_operand 3 "const_int_operand")))])
16390 (label_ref (match_operand 4))
16392 (clobber (reg:CC FLAGS_REG))]
16393 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
16394 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16395 == GET_MODE_BITSIZE (<MODE>mode)-1
16396 && ix86_pre_reload_split ()"
16399 [(set (reg:CCC FLAGS_REG)
16401 (zero_extract:SWI48
16407 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16408 (label_ref (match_dup 4))
16411 operands[0] = shallow_copy_rtx (operands[0]);
16412 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16415 ;; Avoid useless masking of bit offset operand.
16416 (define_insn_and_split "*jcc_bt<SWI48:mode>_mask_1"
16418 (if_then_else (match_operator 0 "bt_comparison_operator"
16419 [(zero_extract:SWI48
16420 (match_operand:SWI48 1 "register_operand")
16424 (match_operand:SWI248 2 "register_operand")
16425 (match_operand 3 "const_int_operand")) 0))])
16426 (label_ref (match_operand 4))
16428 (clobber (reg:CC FLAGS_REG))]
16429 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
16430 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<SWI48:MODE>mode)-1))
16431 == GET_MODE_BITSIZE (<SWI48:MODE>mode)-1
16432 && ix86_pre_reload_split ()"
16435 [(set (reg:CCC FLAGS_REG)
16437 (zero_extract:SWI48
16443 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16444 (label_ref (match_dup 4))
16447 operands[0] = shallow_copy_rtx (operands[0]);
16448 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16449 operands[2] = gen_lowpart (QImode, operands[2]);
16452 ;; Help combine recognize bt followed by cmov
16454 [(set (match_operand:SWI248 0 "register_operand")
16455 (if_then_else:SWI248
16456 (match_operator 5 "bt_comparison_operator"
16457 [(zero_extract:SWI48
16458 (match_operand:SWI48 1 "register_operand")
16460 (match_operand:QI 2 "register_operand"))
16462 (match_operand:SWI248 3 "nonimmediate_operand")
16463 (match_operand:SWI248 4 "nonimmediate_operand")))]
16464 "TARGET_USE_BT && TARGET_CMOVE
16465 && !(MEM_P (operands[3]) && MEM_P (operands[4]))
16466 && ix86_pre_reload_split ()"
16467 [(set (reg:CCC FLAGS_REG)
16469 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16472 (if_then_else:SWI248 (eq (reg:CCC FLAGS_REG) (const_int 0))
16476 if (GET_CODE (operands[5]) == EQ)
16477 std::swap (operands[3], operands[4]);
16480 ;; Help combine recognize bt followed by setc
16481 (define_insn_and_split "*bt<mode>_setcqi"
16482 [(set (subreg:SWI48 (match_operand:QI 0 "register_operand") 0)
16483 (zero_extract:SWI48
16484 (match_operand:SWI48 1 "register_operand")
16486 (match_operand:QI 2 "register_operand")))
16487 (clobber (reg:CC FLAGS_REG))]
16488 "TARGET_USE_BT && ix86_pre_reload_split ()"
16491 [(set (reg:CCC FLAGS_REG)
16493 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16496 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))])
16498 ;; Help combine recognize bt followed by setnc
16499 (define_insn_and_split "*bt<mode>_setncqi"
16500 [(set (match_operand:QI 0 "register_operand")
16504 (lshiftrt:SWI48 (match_operand:SWI48 1 "register_operand")
16505 (match_operand:QI 2 "register_operand")) 0))
16507 (clobber (reg:CC FLAGS_REG))]
16508 "TARGET_USE_BT && ix86_pre_reload_split ()"
16511 [(set (reg:CCC FLAGS_REG)
16513 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16516 (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))])
16518 (define_insn_and_split "*bt<mode>_setnc<mode>"
16519 [(set (match_operand:SWI48 0 "register_operand")
16522 (lshiftrt:SWI48 (match_operand:SWI48 1 "register_operand")
16523 (match_operand:QI 2 "register_operand")))
16525 (clobber (reg:CC FLAGS_REG))]
16526 "TARGET_USE_BT && ix86_pre_reload_split ()"
16529 [(set (reg:CCC FLAGS_REG)
16531 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16534 (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))
16535 (set (match_dup 0) (zero_extend:SWI48 (match_dup 3)))]
16536 "operands[3] = gen_reg_rtx (QImode);")
16538 ;; Help combine recognize bt followed by setnc (PR target/110588)
16539 (define_insn_and_split "*bt<mode>_setncqi_2"
16540 [(set (match_operand:QI 0 "register_operand")
16542 (zero_extract:SWI48
16543 (match_operand:SWI48 1 "register_operand")
16545 (match_operand:QI 2 "register_operand"))
16547 (clobber (reg:CC FLAGS_REG))]
16548 "TARGET_USE_BT && ix86_pre_reload_split ()"
16551 [(set (reg:CCC FLAGS_REG)
16553 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16556 (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))])
16558 ;; Help combine recognize bt followed by setc
16559 (define_insn_and_split "*bt<mode>_setc<mode>_mask"
16560 [(set (match_operand:SWI48 0 "register_operand")
16561 (zero_extract:SWI48
16562 (match_operand:SWI48 1 "register_operand")
16566 (match_operand:SWI48 2 "register_operand")
16567 (match_operand 3 "const_int_operand")) 0)))
16568 (clobber (reg:CC FLAGS_REG))]
16570 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16571 == GET_MODE_BITSIZE (<MODE>mode)-1
16572 && ix86_pre_reload_split ()"
16575 [(set (reg:CCC FLAGS_REG)
16577 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16580 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))
16581 (set (match_dup 0) (zero_extend:SWI48 (match_dup 3)))]
16583 operands[2] = gen_lowpart (QImode, operands[2]);
16584 operands[3] = gen_reg_rtx (QImode);
16587 ;; Store-flag instructions.
16590 [(set (match_operand:QI 0 "nonimmediate_operand")
16591 (match_operator:QI 1 "add_comparison_operator"
16592 [(not:SWI (match_operand:SWI 2 "register_operand"))
16593 (match_operand:SWI 3 "nonimmediate_operand")]))]
16595 [(set (reg:CCC FLAGS_REG)
16597 (plus:SWI (match_dup 2) (match_dup 3))
16600 (match_op_dup 1 [(reg:CCC FLAGS_REG) (const_int 0)]))])
16603 [(set (match_operand:QI 0 "nonimmediate_operand")
16604 (match_operator:QI 1 "shr_comparison_operator"
16605 [(match_operand:DI 2 "register_operand")
16606 (match_operand 3 "const_int_operand")]))]
16608 && IN_RANGE (exact_log2 (UINTVAL (operands[3]) + 1), 32, 63)"
16609 [(set (reg:CCZ FLAGS_REG)
16611 (lshiftrt:DI (match_dup 2) (match_dup 4))
16614 (match_op_dup 1 [(reg:CCZ FLAGS_REG) (const_int 0)]))]
16616 enum rtx_code new_code;
16618 operands[1] = shallow_copy_rtx (operands[1]);
16619 switch (GET_CODE (operands[1]))
16621 case GTU: new_code = NE; break;
16622 case LEU: new_code = EQ; break;
16623 default: gcc_unreachable ();
16625 PUT_CODE (operands[1], new_code);
16627 operands[4] = GEN_INT (exact_log2 (UINTVAL (operands[3]) + 1));
16630 ;; For all sCOND expanders, also expand the compare or test insn that
16631 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
16633 (define_insn_and_split "*setcc_di_1"
16634 [(set (match_operand:DI 0 "register_operand" "=q")
16635 (match_operator:DI 1 "ix86_comparison_operator"
16636 [(reg FLAGS_REG) (const_int 0)]))]
16637 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
16639 "&& reload_completed"
16640 [(set (match_dup 2) (match_dup 1))
16641 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
16643 operands[1] = shallow_copy_rtx (operands[1]);
16644 PUT_MODE (operands[1], QImode);
16645 operands[2] = gen_lowpart (QImode, operands[0]);
16648 (define_insn_and_split "*setcc_<mode>_1_and"
16649 [(set (match_operand:SWI24 0 "register_operand" "=q")
16650 (match_operator:SWI24 1 "ix86_comparison_operator"
16651 [(reg FLAGS_REG) (const_int 0)]))
16652 (clobber (reg:CC FLAGS_REG))]
16653 "!TARGET_PARTIAL_REG_STALL
16654 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
16656 "&& reload_completed"
16657 [(set (match_dup 2) (match_dup 1))
16658 (parallel [(set (match_dup 0) (zero_extend:SWI24 (match_dup 2)))
16659 (clobber (reg:CC FLAGS_REG))])]
16661 operands[1] = shallow_copy_rtx (operands[1]);
16662 PUT_MODE (operands[1], QImode);
16663 operands[2] = gen_lowpart (QImode, operands[0]);
16666 (define_insn_and_split "*setcc_<mode>_1_movzbl"
16667 [(set (match_operand:SWI24 0 "register_operand" "=q")
16668 (match_operator:SWI24 1 "ix86_comparison_operator"
16669 [(reg FLAGS_REG) (const_int 0)]))]
16670 "!TARGET_PARTIAL_REG_STALL
16671 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
16673 "&& reload_completed"
16674 [(set (match_dup 2) (match_dup 1))
16675 (set (match_dup 0) (zero_extend:SWI24 (match_dup 2)))]
16677 operands[1] = shallow_copy_rtx (operands[1]);
16678 PUT_MODE (operands[1], QImode);
16679 operands[2] = gen_lowpart (QImode, operands[0]);
16682 (define_insn "*setcc_qi"
16683 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
16684 (match_operator:QI 1 "ix86_comparison_operator"
16685 [(reg FLAGS_REG) (const_int 0)]))]
16688 [(set_attr "type" "setcc")
16689 (set_attr "mode" "QI")])
16691 (define_insn "*setcc_qi_slp"
16692 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+q"))
16693 (match_operator:QI 1 "ix86_comparison_operator"
16694 [(reg FLAGS_REG) (const_int 0)]))]
16697 [(set_attr "type" "setcc")
16698 (set_attr "mode" "QI")])
16700 ;; In general it is not safe to assume too much about CCmode registers,
16701 ;; so simplify-rtx stops when it sees a second one. Under certain
16702 ;; conditions this is safe on x86, so help combine not create
16709 [(set (match_operand:QI 0 "nonimmediate_operand")
16710 (ne:QI (match_operator 1 "ix86_comparison_operator"
16711 [(reg FLAGS_REG) (const_int 0)])
16714 [(set (match_dup 0) (match_dup 1))]
16716 operands[1] = shallow_copy_rtx (operands[1]);
16717 PUT_MODE (operands[1], QImode);
16721 [(set (strict_low_part (match_operand:QI 0 "register_operand"))
16722 (ne:QI (match_operator 1 "ix86_comparison_operator"
16723 [(reg FLAGS_REG) (const_int 0)])
16726 [(set (match_dup 0) (match_dup 1))]
16728 operands[1] = shallow_copy_rtx (operands[1]);
16729 PUT_MODE (operands[1], QImode);
16733 [(set (match_operand:QI 0 "nonimmediate_operand")
16734 (eq:QI (match_operator 1 "ix86_comparison_operator"
16735 [(reg FLAGS_REG) (const_int 0)])
16738 [(set (match_dup 0) (match_dup 1))]
16740 operands[1] = shallow_copy_rtx (operands[1]);
16741 PUT_MODE (operands[1], QImode);
16742 PUT_CODE (operands[1],
16743 ix86_reverse_condition (GET_CODE (operands[1]),
16744 GET_MODE (XEXP (operands[1], 0))));
16746 /* Make sure that (a) the CCmode we have for the flags is strong
16747 enough for the reversed compare or (b) we have a valid FP compare. */
16748 if (! ix86_comparison_operator (operands[1], VOIDmode))
16753 [(set (strict_low_part (match_operand:QI 0 "register_operand"))
16754 (eq:QI (match_operator 1 "ix86_comparison_operator"
16755 [(reg FLAGS_REG) (const_int 0)])
16758 [(set (match_dup 0) (match_dup 1))]
16760 operands[1] = shallow_copy_rtx (operands[1]);
16761 PUT_MODE (operands[1], QImode);
16762 PUT_CODE (operands[1],
16763 ix86_reverse_condition (GET_CODE (operands[1]),
16764 GET_MODE (XEXP (operands[1], 0))));
16766 /* Make sure that (a) the CCmode we have for the flags is strong
16767 enough for the reversed compare or (b) we have a valid FP compare. */
16768 if (! ix86_comparison_operator (operands[1], VOIDmode))
16772 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
16773 ;; subsequent logical operations are used to imitate conditional moves.
16774 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
16777 (define_insn "setcc_<mode>_sse"
16778 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16779 (match_operator:MODEF 3 "sse_comparison_operator"
16780 [(match_operand:MODEF 1 "register_operand" "0,x")
16781 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xjm")]))]
16782 "SSE_FLOAT_MODE_P (<MODE>mode)"
16784 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
16785 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16786 [(set_attr "isa" "noavx,avx")
16787 (set_attr "addr" "*,gpr16")
16788 (set_attr "type" "ssecmp")
16789 (set_attr "length_immediate" "1")
16790 (set_attr "prefix" "orig,vex")
16791 (set_attr "mode" "<MODE>")])
16793 (define_insn "setcc_hf_mask"
16794 [(set (match_operand:QI 0 "register_operand" "=k")
16796 [(match_operand:HF 1 "register_operand" "v")
16797 (match_operand:HF 2 "nonimmediate_operand" "vm")
16798 (match_operand:SI 3 "const_0_to_31_operand")]
16800 "TARGET_AVX512FP16"
16801 "vcmpsh\t{%3, %2, %1, %0|%0, %1, %2, %3}"
16802 [(set_attr "type" "ssecmp")
16803 (set_attr "prefix" "evex")
16804 (set_attr "mode" "HF")])
16807 ;; Basic conditional jump instructions.
16812 (match_operator 1 "add_comparison_operator"
16813 [(not:SWI (match_operand:SWI 2 "register_operand"))
16814 (match_operand:SWI 3 "nonimmediate_operand")])
16815 (label_ref (match_operand 0))
16818 [(set (reg:CCC FLAGS_REG)
16820 (plus:SWI (match_dup 2) (match_dup 3))
16823 (if_then_else (match_op_dup 1 [(reg:CCC FLAGS_REG) (const_int 0)])
16824 (label_ref (match_operand 0))
16830 (match_operator 1 "shr_comparison_operator"
16831 [(match_operand:DI 2 "register_operand")
16832 (match_operand 3 "const_int_operand")])
16833 (label_ref (match_operand 0))
16836 && IN_RANGE (exact_log2 (UINTVAL (operands[3]) + 1), 32, 63)"
16837 [(set (reg:CCZ FLAGS_REG)
16839 (lshiftrt:DI (match_dup 2) (match_dup 4))
16842 (if_then_else (match_op_dup 1 [(reg:CCZ FLAGS_REG) (const_int 0)])
16843 (label_ref (match_operand 0))
16846 enum rtx_code new_code;
16848 operands[1] = shallow_copy_rtx (operands[1]);
16849 switch (GET_CODE (operands[1]))
16851 case GTU: new_code = NE; break;
16852 case LEU: new_code = EQ; break;
16853 default: gcc_unreachable ();
16855 PUT_CODE (operands[1], new_code);
16857 operands[4] = GEN_INT (exact_log2 (UINTVAL (operands[3]) + 1));
16860 ;; We ignore the overflow flag for signed branch instructions.
16862 (define_insn "*jcc"
16864 (if_then_else (match_operator 1 "ix86_comparison_operator"
16865 [(reg FLAGS_REG) (const_int 0)])
16866 (label_ref (match_operand 0))
16870 [(set_attr "type" "ibr")
16871 (set_attr "modrm" "0")
16872 (set (attr "length")
16874 (and (ge (minus (match_dup 0) (pc))
16876 (lt (minus (match_dup 0) (pc))
16881 ;; In general it is not safe to assume too much about CCmode registers,
16882 ;; so simplify-rtx stops when it sees a second one. Under certain
16883 ;; conditions this is safe on x86, so help combine not create
16891 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
16892 [(reg FLAGS_REG) (const_int 0)])
16894 (label_ref (match_operand 1))
16898 (if_then_else (match_dup 0)
16899 (label_ref (match_dup 1))
16902 operands[0] = shallow_copy_rtx (operands[0]);
16903 PUT_MODE (operands[0], VOIDmode);
16908 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
16909 [(reg FLAGS_REG) (const_int 0)])
16911 (label_ref (match_operand 1))
16915 (if_then_else (match_dup 0)
16916 (label_ref (match_dup 1))
16919 operands[0] = shallow_copy_rtx (operands[0]);
16920 PUT_MODE (operands[0], VOIDmode);
16921 PUT_CODE (operands[0],
16922 ix86_reverse_condition (GET_CODE (operands[0]),
16923 GET_MODE (XEXP (operands[0], 0))));
16925 /* Make sure that (a) the CCmode we have for the flags is strong
16926 enough for the reversed compare or (b) we have a valid FP compare. */
16927 if (! ix86_comparison_operator (operands[0], VOIDmode))
16931 ;; Unconditional and other jump instructions
16933 (define_insn "jump"
16935 (label_ref (match_operand 0)))]
16938 [(set_attr "type" "ibr")
16939 (set_attr "modrm" "0")
16940 (set (attr "length")
16942 (and (ge (minus (match_dup 0) (pc))
16944 (lt (minus (match_dup 0) (pc))
16949 (define_expand "indirect_jump"
16950 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
16953 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
16954 operands[0] = convert_memory_address (word_mode, operands[0]);
16955 cfun->machine->has_local_indirect_jump = true;
16958 (define_insn "*indirect_jump"
16959 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
16961 "* return ix86_output_indirect_jmp (operands[0]);"
16962 [(set (attr "type")
16963 (if_then_else (match_test "(cfun->machine->indirect_branch_type
16964 != indirect_branch_keep)")
16965 (const_string "multi")
16966 (const_string "ibr")))
16967 (set_attr "length_immediate" "0")])
16969 (define_expand "tablejump"
16970 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
16971 (use (label_ref (match_operand 1)))])]
16974 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
16975 relative. Convert the relative address to an absolute address. */
16979 enum rtx_code code;
16981 /* We can't use @GOTOFF for text labels on VxWorks;
16982 see gotoff_operand. */
16983 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
16987 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
16989 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
16993 op1 = pic_offset_table_rtx;
16998 op0 = pic_offset_table_rtx;
17002 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
17006 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
17007 operands[0] = convert_memory_address (word_mode, operands[0]);
17008 cfun->machine->has_local_indirect_jump = true;
17011 (define_insn "*tablejump_1"
17012 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
17013 (use (label_ref (match_operand 1)))]
17015 "* return ix86_output_indirect_jmp (operands[0]);"
17016 [(set (attr "type")
17017 (if_then_else (match_test "(cfun->machine->indirect_branch_type
17018 != indirect_branch_keep)")
17019 (const_string "multi")
17020 (const_string "ibr")))
17021 (set_attr "length_immediate" "0")])
17023 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
17026 [(set (match_operand 4 "flags_reg_operand") (match_operand 0))
17027 (set (match_operand:QI 1 "register_operand")
17028 (match_operator:QI 2 "ix86_comparison_operator"
17029 [(reg FLAGS_REG) (const_int 0)]))
17030 (set (match_operand 3 "any_QIreg_operand")
17031 (zero_extend (match_dup 1)))]
17032 "(peep2_reg_dead_p (3, operands[1])
17033 || operands_match_p (operands[1], operands[3]))
17034 && ! reg_overlap_mentioned_p (operands[3], operands[0])
17035 && peep2_regno_dead_p (0, FLAGS_REG)"
17036 [(set (match_dup 4) (match_dup 0))
17037 (set (strict_low_part (match_dup 5))
17040 operands[5] = gen_lowpart (QImode, operands[3]);
17041 ix86_expand_clear (operands[3]);
17045 [(parallel [(set (match_operand 5 "flags_reg_operand") (match_operand 0))
17046 (match_operand 4)])
17047 (set (match_operand:QI 1 "register_operand")
17048 (match_operator:QI 2 "ix86_comparison_operator"
17049 [(reg FLAGS_REG) (const_int 0)]))
17050 (set (match_operand 3 "any_QIreg_operand")
17051 (zero_extend (match_dup 1)))]
17052 "(peep2_reg_dead_p (3, operands[1])
17053 || operands_match_p (operands[1], operands[3]))
17054 && ! reg_overlap_mentioned_p (operands[3], operands[0])
17055 && ! reg_overlap_mentioned_p (operands[3], operands[4])
17056 && ! reg_set_p (operands[3], operands[4])
17057 && peep2_regno_dead_p (0, FLAGS_REG)"
17058 [(parallel [(set (match_dup 5) (match_dup 0))
17060 (set (strict_low_part (match_dup 6))
17063 operands[6] = gen_lowpart (QImode, operands[3]);
17064 ix86_expand_clear (operands[3]);
17068 [(set (match_operand 6 "flags_reg_operand") (match_operand 0))
17069 (parallel [(set (match_operand 7 "flags_reg_operand") (match_operand 1))
17070 (match_operand 5)])
17071 (set (match_operand:QI 2 "register_operand")
17072 (match_operator:QI 3 "ix86_comparison_operator"
17073 [(reg FLAGS_REG) (const_int 0)]))
17074 (set (match_operand 4 "any_QIreg_operand")
17075 (zero_extend (match_dup 2)))]
17076 "(peep2_reg_dead_p (4, operands[2])
17077 || operands_match_p (operands[2], operands[4]))
17078 && ! reg_overlap_mentioned_p (operands[4], operands[0])
17079 && ! reg_overlap_mentioned_p (operands[4], operands[1])
17080 && ! reg_overlap_mentioned_p (operands[4], operands[5])
17081 && ! reg_set_p (operands[4], operands[5])
17082 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
17083 && peep2_regno_dead_p (0, FLAGS_REG)"
17084 [(set (match_dup 6) (match_dup 0))
17085 (parallel [(set (match_dup 7) (match_dup 1))
17087 (set (strict_low_part (match_dup 8))
17090 operands[8] = gen_lowpart (QImode, operands[4]);
17091 ix86_expand_clear (operands[4]);
17094 ;; Similar, but match zero extend with andsi3.
17097 [(set (match_operand 4 "flags_reg_operand") (match_operand 0))
17098 (set (match_operand:QI 1 "register_operand")
17099 (match_operator:QI 2 "ix86_comparison_operator"
17100 [(reg FLAGS_REG) (const_int 0)]))
17101 (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
17102 (and:SI (match_dup 3) (const_int 255)))
17103 (clobber (reg:CC FLAGS_REG))])]
17104 "REGNO (operands[1]) == REGNO (operands[3])
17105 && ! reg_overlap_mentioned_p (operands[3], operands[0])
17106 && peep2_regno_dead_p (0, FLAGS_REG)"
17107 [(set (match_dup 4) (match_dup 0))
17108 (set (strict_low_part (match_dup 5))
17111 operands[5] = gen_lowpart (QImode, operands[3]);
17112 ix86_expand_clear (operands[3]);
17116 [(parallel [(set (match_operand 5 "flags_reg_operand") (match_operand 0))
17117 (match_operand 4)])
17118 (set (match_operand:QI 1 "register_operand")
17119 (match_operator:QI 2 "ix86_comparison_operator"
17120 [(reg FLAGS_REG) (const_int 0)]))
17121 (parallel [(set (match_operand 3 "any_QIreg_operand")
17122 (zero_extend (match_dup 1)))
17123 (clobber (reg:CC FLAGS_REG))])]
17124 "(peep2_reg_dead_p (3, operands[1])
17125 || operands_match_p (operands[1], operands[3]))
17126 && ! reg_overlap_mentioned_p (operands[3], operands[0])
17127 && ! reg_overlap_mentioned_p (operands[3], operands[4])
17128 && ! reg_set_p (operands[3], operands[4])
17129 && peep2_regno_dead_p (0, FLAGS_REG)"
17130 [(parallel [(set (match_dup 5) (match_dup 0))
17132 (set (strict_low_part (match_dup 6))
17135 operands[6] = gen_lowpart (QImode, operands[3]);
17136 ix86_expand_clear (operands[3]);
17140 [(set (match_operand 6 "flags_reg_operand") (match_operand 0))
17141 (parallel [(set (match_operand 7 "flags_reg_operand") (match_operand 1))
17142 (match_operand 5)])
17143 (set (match_operand:QI 2 "register_operand")
17144 (match_operator:QI 3 "ix86_comparison_operator"
17145 [(reg FLAGS_REG) (const_int 0)]))
17146 (parallel [(set (match_operand 4 "any_QIreg_operand")
17147 (zero_extend (match_dup 2)))
17148 (clobber (reg:CC FLAGS_REG))])]
17149 "(peep2_reg_dead_p (4, operands[2])
17150 || operands_match_p (operands[2], operands[4]))
17151 && ! reg_overlap_mentioned_p (operands[4], operands[0])
17152 && ! reg_overlap_mentioned_p (operands[4], operands[1])
17153 && ! reg_overlap_mentioned_p (operands[4], operands[5])
17154 && ! reg_set_p (operands[4], operands[5])
17155 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
17156 && peep2_regno_dead_p (0, FLAGS_REG)"
17157 [(set (match_dup 6) (match_dup 0))
17158 (parallel [(set (match_dup 7) (match_dup 1))
17160 (set (strict_low_part (match_dup 8))
17163 operands[8] = gen_lowpart (QImode, operands[4]);
17164 ix86_expand_clear (operands[4]);
17167 ;; Call instructions.
17169 ;; The predicates normally associated with named expanders are not properly
17170 ;; checked for calls. This is a bug in the generic code, but it isn't that
17171 ;; easy to fix. Ignore it for now and be prepared to fix things up.
17173 ;; P6 processors will jump to the address after the decrement when %esp
17174 ;; is used as a call operand, so they will execute return address as a code.
17175 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
17177 ;; Register constraint for call instruction.
17178 (define_mode_attr c [(SI "l") (DI "r")])
17180 ;; Call subroutine returning no value.
17182 (define_expand "call"
17183 [(call (match_operand:QI 0)
17185 (use (match_operand 2))]
17188 ix86_expand_call (NULL, operands[0], operands[1],
17189 operands[2], NULL, false);
17193 (define_expand "sibcall"
17194 [(call (match_operand:QI 0)
17196 (use (match_operand 2))]
17199 ix86_expand_call (NULL, operands[0], operands[1],
17200 operands[2], NULL, true);
17204 (define_insn "*call"
17205 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
17206 (match_operand 1))]
17207 "!SIBLING_CALL_P (insn)"
17208 "* return ix86_output_call_insn (insn, operands[0]);"
17209 [(set_attr "type" "call")])
17211 ;; This covers both call and sibcall since only GOT slot is allowed.
17212 (define_insn "*call_got_x32"
17213 [(call (mem:QI (zero_extend:DI
17214 (match_operand:SI 0 "GOT_memory_operand" "Bg")))
17215 (match_operand 1))]
17218 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
17219 return ix86_output_call_insn (insn, fnaddr);
17221 [(set_attr "type" "call")])
17223 ;; Since sibcall never returns, we can only use call-clobbered register
17225 (define_insn "*sibcall_GOT_32"
17228 (match_operand:SI 0 "register_no_elim_operand" "U")
17229 (match_operand:SI 1 "GOT32_symbol_operand"))))
17230 (match_operand 2))]
17233 && !TARGET_INDIRECT_BRANCH_REGISTER
17234 && SIBLING_CALL_P (insn)"
17236 rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
17237 fnaddr = gen_const_mem (SImode, fnaddr);
17238 return ix86_output_call_insn (insn, fnaddr);
17240 [(set_attr "type" "call")])
17242 (define_insn "*sibcall"
17243 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
17244 (match_operand 1))]
17245 "SIBLING_CALL_P (insn)"
17246 "* return ix86_output_call_insn (insn, operands[0]);"
17247 [(set_attr "type" "call")])
17249 (define_insn "*sibcall_memory"
17250 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
17252 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17253 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
17254 "* return ix86_output_call_insn (insn, operands[0]);"
17255 [(set_attr "type" "call")])
17258 [(set (match_operand:W 0 "register_operand")
17259 (match_operand:W 1 "memory_operand"))
17260 (call (mem:QI (match_dup 0))
17261 (match_operand 3))]
17263 && !TARGET_INDIRECT_BRANCH_REGISTER
17264 && SIBLING_CALL_P (peep2_next_insn (1))
17265 && !reg_mentioned_p (operands[0],
17266 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17267 [(parallel [(call (mem:QI (match_dup 1))
17269 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17272 [(set (match_operand:W 0 "register_operand")
17273 (match_operand:W 1 "memory_operand"))
17274 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17275 (call (mem:QI (match_dup 0))
17276 (match_operand 3))]
17278 && !TARGET_INDIRECT_BRANCH_REGISTER
17279 && SIBLING_CALL_P (peep2_next_insn (2))
17280 && !reg_mentioned_p (operands[0],
17281 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17282 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17283 (parallel [(call (mem:QI (match_dup 1))
17285 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17287 (define_expand "call_pop"
17288 [(parallel [(call (match_operand:QI 0)
17289 (match_operand:SI 1))
17290 (set (reg:SI SP_REG)
17291 (plus:SI (reg:SI SP_REG)
17292 (match_operand:SI 3)))])]
17295 ix86_expand_call (NULL, operands[0], operands[1],
17296 operands[2], operands[3], false);
17300 (define_insn "*call_pop"
17301 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz"))
17303 (set (reg:SI SP_REG)
17304 (plus:SI (reg:SI SP_REG)
17305 (match_operand:SI 2 "immediate_operand" "i")))]
17306 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17307 "* return ix86_output_call_insn (insn, operands[0]);"
17308 [(set_attr "type" "call")])
17310 (define_insn "*sibcall_pop"
17311 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
17313 (set (reg:SI SP_REG)
17314 (plus:SI (reg:SI SP_REG)
17315 (match_operand:SI 2 "immediate_operand" "i")))]
17316 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17317 "* return ix86_output_call_insn (insn, operands[0]);"
17318 [(set_attr "type" "call")])
17320 (define_insn "*sibcall_pop_memory"
17321 [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs"))
17323 (set (reg:SI SP_REG)
17324 (plus:SI (reg:SI SP_REG)
17325 (match_operand:SI 2 "immediate_operand" "i")))
17326 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17328 "* return ix86_output_call_insn (insn, operands[0]);"
17329 [(set_attr "type" "call")])
17332 [(set (match_operand:SI 0 "register_operand")
17333 (match_operand:SI 1 "memory_operand"))
17334 (parallel [(call (mem:QI (match_dup 0))
17336 (set (reg:SI SP_REG)
17337 (plus:SI (reg:SI SP_REG)
17338 (match_operand:SI 4 "immediate_operand")))])]
17339 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
17340 && !reg_mentioned_p (operands[0],
17341 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17342 [(parallel [(call (mem:QI (match_dup 1))
17344 (set (reg:SI SP_REG)
17345 (plus:SI (reg:SI SP_REG)
17347 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17350 [(set (match_operand:SI 0 "register_operand")
17351 (match_operand:SI 1 "memory_operand"))
17352 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17353 (parallel [(call (mem:QI (match_dup 0))
17355 (set (reg:SI SP_REG)
17356 (plus:SI (reg:SI SP_REG)
17357 (match_operand:SI 4 "immediate_operand")))])]
17358 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
17359 && !reg_mentioned_p (operands[0],
17360 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17361 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17362 (parallel [(call (mem:QI (match_dup 1))
17364 (set (reg:SI SP_REG)
17365 (plus:SI (reg:SI SP_REG)
17367 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17369 ;; Combining simple memory jump instruction
17372 [(set (match_operand:W 0 "register_operand")
17373 (match_operand:W 1 "memory_operand"))
17374 (set (pc) (match_dup 0))]
17376 && !TARGET_INDIRECT_BRANCH_REGISTER
17377 && peep2_reg_dead_p (2, operands[0])"
17378 [(set (pc) (match_dup 1))])
17380 ;; Call subroutine, returning value in operand 0
17382 (define_expand "call_value"
17383 [(set (match_operand 0)
17384 (call (match_operand:QI 1)
17385 (match_operand 2)))
17386 (use (match_operand 3))]
17389 ix86_expand_call (operands[0], operands[1], operands[2],
17390 operands[3], NULL, false);
17394 (define_expand "sibcall_value"
17395 [(set (match_operand 0)
17396 (call (match_operand:QI 1)
17397 (match_operand 2)))
17398 (use (match_operand 3))]
17401 ix86_expand_call (operands[0], operands[1], operands[2],
17402 operands[3], NULL, true);
17406 (define_insn "*call_value"
17407 [(set (match_operand 0)
17408 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
17409 (match_operand 2)))]
17410 "!SIBLING_CALL_P (insn)"
17411 "* return ix86_output_call_insn (insn, operands[1]);"
17412 [(set_attr "type" "callv")])
17414 ;; This covers both call and sibcall since only GOT slot is allowed.
17415 (define_insn "*call_value_got_x32"
17416 [(set (match_operand 0)
17419 (match_operand:SI 1 "GOT_memory_operand" "Bg")))
17420 (match_operand 2)))]
17423 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
17424 return ix86_output_call_insn (insn, fnaddr);
17426 [(set_attr "type" "callv")])
17428 ;; Since sibcall never returns, we can only use call-clobbered register
17430 (define_insn "*sibcall_value_GOT_32"
17431 [(set (match_operand 0)
17434 (match_operand:SI 1 "register_no_elim_operand" "U")
17435 (match_operand:SI 2 "GOT32_symbol_operand"))))
17436 (match_operand 3)))]
17439 && !TARGET_INDIRECT_BRANCH_REGISTER
17440 && SIBLING_CALL_P (insn)"
17442 rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
17443 fnaddr = gen_const_mem (SImode, fnaddr);
17444 return ix86_output_call_insn (insn, fnaddr);
17446 [(set_attr "type" "callv")])
17448 (define_insn "*sibcall_value"
17449 [(set (match_operand 0)
17450 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
17451 (match_operand 2)))]
17452 "SIBLING_CALL_P (insn)"
17453 "* return ix86_output_call_insn (insn, operands[1]);"
17454 [(set_attr "type" "callv")])
17456 (define_insn "*sibcall_value_memory"
17457 [(set (match_operand 0)
17458 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
17459 (match_operand 2)))
17460 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17461 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
17462 "* return ix86_output_call_insn (insn, operands[1]);"
17463 [(set_attr "type" "callv")])
17466 [(set (match_operand:W 0 "register_operand")
17467 (match_operand:W 1 "memory_operand"))
17468 (set (match_operand 2)
17469 (call (mem:QI (match_dup 0))
17470 (match_operand 3)))]
17472 && !TARGET_INDIRECT_BRANCH_REGISTER
17473 && SIBLING_CALL_P (peep2_next_insn (1))
17474 && !reg_mentioned_p (operands[0],
17475 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17476 [(parallel [(set (match_dup 2)
17477 (call (mem:QI (match_dup 1))
17479 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17482 [(set (match_operand:W 0 "register_operand")
17483 (match_operand:W 1 "memory_operand"))
17484 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17485 (set (match_operand 2)
17486 (call (mem:QI (match_dup 0))
17487 (match_operand 3)))]
17489 && !TARGET_INDIRECT_BRANCH_REGISTER
17490 && SIBLING_CALL_P (peep2_next_insn (2))
17491 && !reg_mentioned_p (operands[0],
17492 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17493 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17494 (parallel [(set (match_dup 2)
17495 (call (mem:QI (match_dup 1))
17497 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17499 (define_expand "call_value_pop"
17500 [(parallel [(set (match_operand 0)
17501 (call (match_operand:QI 1)
17502 (match_operand:SI 2)))
17503 (set (reg:SI SP_REG)
17504 (plus:SI (reg:SI SP_REG)
17505 (match_operand:SI 4)))])]
17508 ix86_expand_call (operands[0], operands[1], operands[2],
17509 operands[3], operands[4], false);
17513 (define_insn "*call_value_pop"
17514 [(set (match_operand 0)
17515 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz"))
17516 (match_operand 2)))
17517 (set (reg:SI SP_REG)
17518 (plus:SI (reg:SI SP_REG)
17519 (match_operand:SI 3 "immediate_operand" "i")))]
17520 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17521 "* return ix86_output_call_insn (insn, operands[1]);"
17522 [(set_attr "type" "callv")])
17524 (define_insn "*sibcall_value_pop"
17525 [(set (match_operand 0)
17526 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
17527 (match_operand 2)))
17528 (set (reg:SI SP_REG)
17529 (plus:SI (reg:SI SP_REG)
17530 (match_operand:SI 3 "immediate_operand" "i")))]
17531 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17532 "* return ix86_output_call_insn (insn, operands[1]);"
17533 [(set_attr "type" "callv")])
17535 (define_insn "*sibcall_value_pop_memory"
17536 [(set (match_operand 0)
17537 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
17538 (match_operand 2)))
17539 (set (reg:SI SP_REG)
17540 (plus:SI (reg:SI SP_REG)
17541 (match_operand:SI 3 "immediate_operand" "i")))
17542 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17544 "* return ix86_output_call_insn (insn, operands[1]);"
17545 [(set_attr "type" "callv")])
17548 [(set (match_operand:SI 0 "register_operand")
17549 (match_operand:SI 1 "memory_operand"))
17550 (parallel [(set (match_operand 2)
17551 (call (mem:QI (match_dup 0))
17552 (match_operand 3)))
17553 (set (reg:SI SP_REG)
17554 (plus:SI (reg:SI SP_REG)
17555 (match_operand:SI 4 "immediate_operand")))])]
17556 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
17557 && !reg_mentioned_p (operands[0],
17558 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17559 [(parallel [(set (match_dup 2)
17560 (call (mem:QI (match_dup 1))
17562 (set (reg:SI SP_REG)
17563 (plus:SI (reg:SI SP_REG)
17565 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17568 [(set (match_operand:SI 0 "register_operand")
17569 (match_operand:SI 1 "memory_operand"))
17570 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17571 (parallel [(set (match_operand 2)
17572 (call (mem:QI (match_dup 0))
17573 (match_operand 3)))
17574 (set (reg:SI SP_REG)
17575 (plus:SI (reg:SI SP_REG)
17576 (match_operand:SI 4 "immediate_operand")))])]
17577 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
17578 && !reg_mentioned_p (operands[0],
17579 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17580 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17581 (parallel [(set (match_dup 2)
17582 (call (mem:QI (match_dup 1))
17584 (set (reg:SI SP_REG)
17585 (plus:SI (reg:SI SP_REG)
17587 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17589 ;; Call subroutine returning any type.
17591 (define_expand "untyped_call"
17592 [(parallel [(call (match_operand 0)
17595 (match_operand 2)])]
17600 /* In order to give reg-stack an easier job in validating two
17601 coprocessor registers as containing a possible return value,
17602 simply pretend the untyped call returns a complex long double
17605 We can't use SSE_REGPARM_MAX here since callee is unprototyped
17606 and should have the default ABI. */
17608 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
17609 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
17610 operands[0], const0_rtx,
17611 GEN_INT ((TARGET_64BIT
17612 ? (ix86_abi == SYSV_ABI
17613 ? X86_64_SSE_REGPARM_MAX
17614 : X86_64_MS_SSE_REGPARM_MAX)
17615 : X86_32_SSE_REGPARM_MAX)
17619 for (i = 0; i < XVECLEN (operands[2], 0); i++)
17621 rtx set = XVECEXP (operands[2], 0, i);
17622 emit_move_insn (SET_DEST (set), SET_SRC (set));
17625 /* The optimizer does not know that the call sets the function value
17626 registers we stored in the result block. We avoid problems by
17627 claiming that all hard registers are used and clobbered at this
17629 emit_insn (gen_blockage ());
17634 ;; Prologue and epilogue instructions
17636 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
17637 ;; all of memory. This blocks insns from being moved across this point.
17639 (define_insn "blockage"
17640 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
17643 [(set_attr "length" "0")])
17645 ;; Do not schedule instructions accessing memory across this point.
17647 (define_expand "memory_blockage"
17648 [(set (match_dup 0)
17649 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
17652 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
17653 MEM_VOLATILE_P (operands[0]) = 1;
17656 (define_insn "*memory_blockage"
17657 [(set (match_operand:BLK 0)
17658 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
17661 [(set_attr "length" "0")])
17663 ;; As USE insns aren't meaningful after reload, this is used instead
17664 ;; to prevent deleting instructions setting registers for PIC code
17665 (define_insn "prologue_use"
17666 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
17669 [(set_attr "length" "0")])
17671 ;; Insn emitted into the body of a function to return from a function.
17672 ;; This is only done if the function's epilogue is known to be simple.
17673 ;; See comments for ix86_can_use_return_insn_p in i386.cc.
17675 (define_expand "return"
17677 "ix86_can_use_return_insn_p ()"
17679 if (crtl->args.pops_args)
17681 rtx popc = GEN_INT (crtl->args.pops_args);
17682 emit_jump_insn (gen_simple_return_pop_internal (popc));
17687 ;; We need to disable this for TARGET_SEH, as otherwise
17688 ;; shrink-wrapped prologue gets enabled too. This might exceed
17689 ;; the maximum size of prologue in unwind information.
17690 ;; Also disallow shrink-wrapping if using stack slot to pass the
17691 ;; static chain pointer - the first instruction has to be pushl %esi
17692 ;; and it can't be moved around, as we use alternate entry points
17694 ;; Also disallow for ms_hook_prologue functions which have frame
17695 ;; pointer set up in function label which is correctly handled in
17696 ;; ix86_expand_{prologue|epligoue}() only.
17698 (define_expand "simple_return"
17700 "!TARGET_SEH && !ix86_static_chain_on_stack && !ix86_function_ms_hook_prologue (cfun->decl)"
17702 if (crtl->args.pops_args)
17704 rtx popc = GEN_INT (crtl->args.pops_args);
17705 emit_jump_insn (gen_simple_return_pop_internal (popc));
17710 (define_insn "simple_return_internal"
17713 "* return ix86_output_function_return (false);"
17714 [(set_attr "length" "1")
17715 (set_attr "atom_unit" "jeu")
17716 (set_attr "length_immediate" "0")
17717 (set_attr "modrm" "0")])
17719 (define_insn "interrupt_return"
17721 (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
17724 return TARGET_64BIT ? (TARGET_UINTR ? "uiret" : "iretq") : "iret";
17727 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
17728 ;; instruction Athlon and K8 have.
17730 (define_insn "simple_return_internal_long"
17732 (unspec [(const_int 0)] UNSPEC_REP)]
17734 "* return ix86_output_function_return (true);"
17735 [(set_attr "length" "2")
17736 (set_attr "atom_unit" "jeu")
17737 (set_attr "length_immediate" "0")
17738 (set_attr "prefix_rep" "1")
17739 (set_attr "modrm" "0")])
17741 (define_insn_and_split "simple_return_pop_internal"
17743 (use (match_operand:SI 0 "const_int_operand"))]
17746 "&& cfun->machine->function_return_type != indirect_branch_keep"
17748 "ix86_split_simple_return_pop_internal (operands[0]); DONE;"
17749 [(set_attr "length" "3")
17750 (set_attr "atom_unit" "jeu")
17751 (set_attr "length_immediate" "2")
17752 (set_attr "modrm" "0")])
17754 (define_expand "simple_return_indirect_internal"
17757 (use (match_operand 0 "register_operand"))])])
17759 (define_insn "*simple_return_indirect_internal<mode>"
17761 (use (match_operand:W 0 "register_operand" "r"))]
17763 "* return ix86_output_indirect_function_return (operands[0]);"
17764 [(set (attr "type")
17765 (if_then_else (match_test "(cfun->machine->indirect_branch_type
17766 != indirect_branch_keep)")
17767 (const_string "multi")
17768 (const_string "ibr")))
17769 (set_attr "length_immediate" "0")])
17775 [(set_attr "length" "1")
17776 (set_attr "length_immediate" "0")
17777 (set_attr "modrm" "0")])
17779 ;; Generate nops. Operand 0 is the number of nops, up to 8.
17780 (define_insn "nops"
17781 [(unspec_volatile [(match_operand 0 "const_int_operand")]
17785 int num = INTVAL (operands[0]);
17787 gcc_assert (IN_RANGE (num, 1, 8));
17790 fputs ("\tnop\n", asm_out_file);
17794 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
17795 (set_attr "length_immediate" "0")
17796 (set_attr "modrm" "0")])
17798 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
17799 ;; branch prediction penalty for the third jump in a 16-byte
17803 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
17806 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
17807 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
17809 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
17810 The align insn is used to avoid 3 jump instructions in the row to improve
17811 branch prediction and the benefits hardly outweigh the cost of extra 8
17812 nops on the average inserted by full alignment pseudo operation. */
17816 [(set_attr "length" "16")])
17818 (define_expand "prologue"
17821 "ix86_expand_prologue (); DONE;")
17823 (define_expand "set_got"
17825 [(set (match_operand:SI 0 "register_operand")
17826 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
17827 (clobber (reg:CC FLAGS_REG))])]
17830 if (flag_pic && !TARGET_VXWORKS_RTP)
17831 ix86_pc_thunk_call_expanded = true;
17834 (define_insn "*set_got"
17835 [(set (match_operand:SI 0 "register_operand" "=r")
17836 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
17837 (clobber (reg:CC FLAGS_REG))]
17839 "* return output_set_got (operands[0], NULL_RTX);"
17840 [(set_attr "type" "multi")
17841 (set_attr "length" "12")])
17843 (define_expand "set_got_labelled"
17845 [(set (match_operand:SI 0 "register_operand")
17846 (unspec:SI [(label_ref (match_operand 1))]
17848 (clobber (reg:CC FLAGS_REG))])]
17851 if (flag_pic && !TARGET_VXWORKS_RTP)
17852 ix86_pc_thunk_call_expanded = true;
17855 (define_insn "*set_got_labelled"
17856 [(set (match_operand:SI 0 "register_operand" "=r")
17857 (unspec:SI [(label_ref (match_operand 1))]
17859 (clobber (reg:CC FLAGS_REG))]
17861 "* return output_set_got (operands[0], operands[1]);"
17862 [(set_attr "type" "multi")
17863 (set_attr "length" "12")])
17865 (define_insn "set_got_rex64"
17866 [(set (match_operand:DI 0 "register_operand" "=r")
17867 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
17869 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
17870 [(set_attr "type" "lea")
17871 (set_attr "length_address" "4")
17872 (set_attr "mode" "DI")])
17874 (define_insn "set_rip_rex64"
17875 [(set (match_operand:DI 0 "register_operand" "=r")
17876 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
17878 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
17879 [(set_attr "type" "lea")
17880 (set_attr "length_address" "4")
17881 (set_attr "mode" "DI")])
17883 (define_insn "set_got_offset_rex64"
17884 [(set (match_operand:DI 0 "register_operand" "=r")
17886 [(label_ref (match_operand 1))]
17887 UNSPEC_SET_GOT_OFFSET))]
17889 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
17890 [(set_attr "type" "imov")
17891 (set_attr "length_immediate" "0")
17892 (set_attr "length_address" "8")
17893 (set_attr "mode" "DI")])
17895 (define_expand "epilogue"
17898 "ix86_expand_epilogue (1); DONE;")
17900 (define_expand "sibcall_epilogue"
17903 "ix86_expand_epilogue (0); DONE;")
17905 (define_expand "eh_return"
17906 [(use (match_operand 0 "register_operand"))]
17909 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
17911 /* Tricky bit: we write the address of the handler to which we will
17912 be returning into someone else's stack frame, one word below the
17913 stack address we wish to restore. */
17914 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
17915 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
17916 /* Return address is always in word_mode. */
17917 tmp = gen_rtx_MEM (word_mode, tmp);
17918 if (GET_MODE (ra) != word_mode)
17919 ra = convert_to_mode (word_mode, ra, 1);
17920 emit_move_insn (tmp, ra);
17922 emit_jump_insn (gen_eh_return_internal ());
17927 (define_insn_and_split "eh_return_internal"
17931 "epilogue_completed"
17933 "ix86_expand_epilogue (2); DONE;")
17935 (define_expand "@leave_<mode>"
17937 [(set (reg:W SP_REG) (plus:W (reg:W BP_REG) (match_dup 0)))
17938 (set (reg:W BP_REG) (mem:W (reg:W BP_REG)))
17939 (clobber (mem:BLK (scratch)))])]
17941 "operands[0] = GEN_INT (<MODE_SIZE>);")
17943 (define_insn "*leave"
17944 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
17945 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
17946 (clobber (mem:BLK (scratch)))]
17949 [(set_attr "type" "leave")])
17951 (define_insn "*leave_rex64"
17952 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
17953 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
17954 (clobber (mem:BLK (scratch)))]
17957 [(set_attr "type" "leave")])
17959 ;; Handle -fsplit-stack.
17961 (define_expand "split_stack_prologue"
17965 ix86_expand_split_stack_prologue ();
17969 ;; In order to support the call/return predictor, we use a return
17970 ;; instruction which the middle-end doesn't see.
17971 (define_insn "split_stack_return"
17972 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
17973 UNSPECV_SPLIT_STACK_RETURN)]
17976 if (operands[0] == const0_rtx)
17981 [(set_attr "atom_unit" "jeu")
17982 (set_attr "modrm" "0")
17983 (set (attr "length")
17984 (if_then_else (match_operand:SI 0 "const0_operand")
17987 (set (attr "length_immediate")
17988 (if_then_else (match_operand:SI 0 "const0_operand")
17992 ;; If there are operand 0 bytes available on the stack, jump to
17995 (define_expand "split_stack_space_check"
17996 [(set (pc) (if_then_else
17997 (ltu (minus (reg SP_REG)
17998 (match_operand 0 "register_operand"))
18000 (label_ref (match_operand 1))
18004 rtx reg = gen_reg_rtx (Pmode);
18006 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, operands[0]));
18008 operands[2] = ix86_split_stack_guard ();
18009 ix86_expand_branch (GEU, reg, operands[2], operands[1]);
18014 ;; Bit manipulation instructions.
18016 (define_expand "ffs<mode>2"
18017 [(set (match_dup 2) (const_int -1))
18018 (parallel [(set (match_dup 3) (match_dup 4))
18019 (set (match_operand:SWI48 0 "register_operand")
18021 (match_operand:SWI48 1 "nonimmediate_operand")))])
18022 (set (match_dup 0) (if_then_else:SWI48
18023 (eq (match_dup 3) (const_int 0))
18026 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
18027 (clobber (reg:CC FLAGS_REG))])]
18030 machine_mode flags_mode;
18032 if (<MODE>mode == SImode && !TARGET_CMOVE)
18034 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
18038 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
18040 operands[2] = gen_reg_rtx (<MODE>mode);
18041 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
18042 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
18045 (define_insn_and_split "ffssi2_no_cmove"
18046 [(set (match_operand:SI 0 "register_operand" "=r")
18047 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
18048 (clobber (match_scratch:SI 2 "=&q"))
18049 (clobber (reg:CC FLAGS_REG))]
18052 "&& reload_completed"
18053 [(parallel [(set (match_dup 4) (match_dup 5))
18054 (set (match_dup 0) (ctz:SI (match_dup 1)))])
18055 (set (strict_low_part (match_dup 3))
18056 (eq:QI (match_dup 4) (const_int 0)))
18057 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
18058 (clobber (reg:CC FLAGS_REG))])
18059 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
18060 (clobber (reg:CC FLAGS_REG))])
18061 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
18062 (clobber (reg:CC FLAGS_REG))])]
18064 machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
18066 operands[3] = gen_lowpart (QImode, operands[2]);
18067 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
18068 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
18070 ix86_expand_clear (operands[2]);
18073 (define_insn_and_split "*tzcnt<mode>_1"
18074 [(set (reg:CCC FLAGS_REG)
18075 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18077 (set (match_operand:SWI48 0 "register_operand" "=r")
18078 (ctz:SWI48 (match_dup 1)))]
18080 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
18081 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18082 && optimize_function_for_speed_p (cfun)
18083 && !reg_mentioned_p (operands[0], operands[1])"
18085 [(set (reg:CCC FLAGS_REG)
18086 (compare:CCC (match_dup 1) (const_int 0)))
18088 (ctz:SWI48 (match_dup 1)))
18089 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
18090 "ix86_expand_clear (operands[0]);"
18091 [(set_attr "type" "alu1")
18092 (set_attr "prefix_0f" "1")
18093 (set_attr "prefix_rep" "1")
18094 (set_attr "btver2_decode" "double")
18095 (set_attr "mode" "<MODE>")])
18097 ; False dependency happens when destination is only updated by tzcnt,
18098 ; lzcnt or popcnt. There is no false dependency when destination is
18099 ; also used in source.
18100 (define_insn "*tzcnt<mode>_1_falsedep"
18101 [(set (reg:CCC FLAGS_REG)
18102 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18104 (set (match_operand:SWI48 0 "register_operand" "=r")
18105 (ctz:SWI48 (match_dup 1)))
18106 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18107 UNSPEC_INSN_FALSE_DEP)]
18109 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
18110 [(set_attr "type" "alu1")
18111 (set_attr "prefix_0f" "1")
18112 (set_attr "prefix_rep" "1")
18113 (set_attr "btver2_decode" "double")
18114 (set_attr "mode" "<MODE>")])
18116 (define_insn "*bsf<mode>_1"
18117 [(set (reg:CCZ FLAGS_REG)
18118 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18120 (set (match_operand:SWI48 0 "register_operand" "=r")
18121 (ctz:SWI48 (match_dup 1)))]
18123 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
18124 [(set_attr "type" "alu1")
18125 (set_attr "prefix_0f" "1")
18126 (set_attr "btver2_decode" "double")
18127 (set_attr "znver1_decode" "vector")
18128 (set_attr "mode" "<MODE>")])
18130 (define_insn_and_split "ctz<mode>2"
18131 [(set (match_operand:SWI48 0 "register_operand" "=r")
18133 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18134 (clobber (reg:CC FLAGS_REG))]
18138 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
18139 else if (optimize_function_for_size_p (cfun))
18141 else if (TARGET_CPU_P (GENERIC))
18142 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
18143 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
18145 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
18147 "(TARGET_BMI || TARGET_CPU_P (GENERIC))
18148 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18149 && optimize_function_for_speed_p (cfun)
18150 && !reg_mentioned_p (operands[0], operands[1])"
18152 [(set (match_dup 0)
18153 (ctz:SWI48 (match_dup 1)))
18154 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18155 (clobber (reg:CC FLAGS_REG))])]
18156 "ix86_expand_clear (operands[0]);"
18157 [(set_attr "type" "alu1")
18158 (set_attr "prefix_0f" "1")
18159 (set (attr "prefix_rep")
18161 (ior (match_test "TARGET_BMI")
18162 (and (not (match_test "optimize_function_for_size_p (cfun)"))
18163 (match_test "TARGET_CPU_P (GENERIC)")))
18165 (const_string "0")))
18166 (set_attr "mode" "<MODE>")])
18168 ; False dependency happens when destination is only updated by tzcnt,
18169 ; lzcnt or popcnt. There is no false dependency when destination is
18170 ; also used in source.
18171 (define_insn "*ctz<mode>2_falsedep"
18172 [(set (match_operand:SWI48 0 "register_operand" "=r")
18174 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18175 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18176 UNSPEC_INSN_FALSE_DEP)
18177 (clobber (reg:CC FLAGS_REG))]
18181 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
18182 else if (TARGET_CPU_P (GENERIC))
18183 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
18184 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
18186 gcc_unreachable ();
18188 [(set_attr "type" "alu1")
18189 (set_attr "prefix_0f" "1")
18190 (set_attr "prefix_rep" "1")
18191 (set_attr "mode" "<MODE>")])
18193 (define_insn_and_split "*ctzsi2_zext"
18194 [(set (match_operand:DI 0 "register_operand" "=r")
18198 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
18200 (clobber (reg:CC FLAGS_REG))]
18201 "TARGET_BMI && TARGET_64BIT"
18202 "tzcnt{l}\t{%1, %k0|%k0, %1}"
18203 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18204 && optimize_function_for_speed_p (cfun)
18205 && !reg_mentioned_p (operands[0], operands[1])"
18207 [(set (match_dup 0)
18208 (and:DI (subreg:DI (ctz:SI (match_dup 1)) 0) (const_int 63)))
18209 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18210 (clobber (reg:CC FLAGS_REG))])]
18211 "ix86_expand_clear (operands[0]);"
18212 [(set_attr "type" "alu1")
18213 (set_attr "prefix_0f" "1")
18214 (set_attr "prefix_rep" "1")
18215 (set_attr "mode" "SI")])
18217 ; False dependency happens when destination is only updated by tzcnt,
18218 ; lzcnt or popcnt. There is no false dependency when destination is
18219 ; also used in source.
18220 (define_insn "*ctzsi2_zext_falsedep"
18221 [(set (match_operand:DI 0 "register_operand" "=r")
18225 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
18227 (unspec [(match_operand:DI 2 "register_operand" "0")]
18228 UNSPEC_INSN_FALSE_DEP)
18229 (clobber (reg:CC FLAGS_REG))]
18230 "TARGET_BMI && TARGET_64BIT"
18231 "tzcnt{l}\t{%1, %k0|%k0, %1}"
18232 [(set_attr "type" "alu1")
18233 (set_attr "prefix_0f" "1")
18234 (set_attr "prefix_rep" "1")
18235 (set_attr "mode" "SI")])
18237 (define_insn_and_split "*ctzsidi2_<s>ext"
18238 [(set (match_operand:DI 0 "register_operand" "=r")
18241 (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18242 (clobber (reg:CC FLAGS_REG))]
18246 return "tzcnt{l}\t{%1, %k0|%k0, %1}";
18247 else if (TARGET_CPU_P (GENERIC)
18248 && !optimize_function_for_size_p (cfun))
18249 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
18250 return "rep%; bsf{l}\t{%1, %k0|%k0, %1}";
18251 return "bsf{l}\t{%1, %k0|%k0, %1}";
18253 "(TARGET_BMI || TARGET_CPU_P (GENERIC))
18254 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18255 && optimize_function_for_speed_p (cfun)
18256 && !reg_mentioned_p (operands[0], operands[1])"
18258 [(set (match_dup 0)
18259 (any_extend:DI (ctz:SI (match_dup 1))))
18260 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18261 (clobber (reg:CC FLAGS_REG))])]
18262 "ix86_expand_clear (operands[0]);"
18263 [(set_attr "type" "alu1")
18264 (set_attr "prefix_0f" "1")
18265 (set (attr "prefix_rep")
18267 (ior (match_test "TARGET_BMI")
18268 (and (not (match_test "optimize_function_for_size_p (cfun)"))
18269 (match_test "TARGET_CPU_P (GENERIC)")))
18271 (const_string "0")))
18272 (set_attr "mode" "SI")])
18274 (define_insn "*ctzsidi2_<s>ext_falsedep"
18275 [(set (match_operand:DI 0 "register_operand" "=r")
18278 (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18279 (unspec [(match_operand:DI 2 "register_operand" "0")]
18280 UNSPEC_INSN_FALSE_DEP)
18281 (clobber (reg:CC FLAGS_REG))]
18285 return "tzcnt{l}\t{%1, %k0|%k0, %1}";
18286 else if (TARGET_CPU_P (GENERIC))
18287 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
18288 return "rep%; bsf{l}\t{%1, %k0|%k0, %1}";
18290 gcc_unreachable ();
18292 [(set_attr "type" "alu1")
18293 (set_attr "prefix_0f" "1")
18294 (set_attr "prefix_rep" "1")
18295 (set_attr "mode" "SI")])
18297 (define_insn "bsr_rex64"
18298 [(set (reg:CCZ FLAGS_REG)
18299 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
18301 (set (match_operand:DI 0 "register_operand" "=r")
18302 (minus:DI (const_int 63)
18303 (clz:DI (match_dup 1))))]
18305 "bsr{q}\t{%1, %0|%0, %1}"
18306 [(set_attr "type" "alu1")
18307 (set_attr "prefix_0f" "1")
18308 (set_attr "znver1_decode" "vector")
18309 (set_attr "mode" "DI")])
18311 (define_insn "bsr_rex64_1"
18312 [(set (match_operand:DI 0 "register_operand" "=r")
18313 (minus:DI (const_int 63)
18314 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
18315 (clobber (reg:CC FLAGS_REG))]
18316 "!TARGET_LZCNT && TARGET_64BIT"
18317 "bsr{q}\t{%1, %0|%0, %1}"
18318 [(set_attr "type" "alu1")
18319 (set_attr "prefix_0f" "1")
18320 (set_attr "znver1_decode" "vector")
18321 (set_attr "mode" "DI")])
18323 (define_insn "bsr_rex64_1_zext"
18324 [(set (match_operand:DI 0 "register_operand" "=r")
18326 (minus:SI (const_int 63)
18328 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
18330 (clobber (reg:CC FLAGS_REG))]
18331 "!TARGET_LZCNT && TARGET_64BIT"
18332 "bsr{q}\t{%1, %0|%0, %1}"
18333 [(set_attr "type" "alu1")
18334 (set_attr "prefix_0f" "1")
18335 (set_attr "znver1_decode" "vector")
18336 (set_attr "mode" "DI")])
18339 [(set (reg:CCZ FLAGS_REG)
18340 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
18342 (set (match_operand:SI 0 "register_operand" "=r")
18343 (minus:SI (const_int 31)
18344 (clz:SI (match_dup 1))))]
18346 "bsr{l}\t{%1, %0|%0, %1}"
18347 [(set_attr "type" "alu1")
18348 (set_attr "prefix_0f" "1")
18349 (set_attr "znver1_decode" "vector")
18350 (set_attr "mode" "SI")])
18352 (define_insn "bsr_1"
18353 [(set (match_operand:SI 0 "register_operand" "=r")
18354 (minus:SI (const_int 31)
18355 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18356 (clobber (reg:CC FLAGS_REG))]
18358 "bsr{l}\t{%1, %0|%0, %1}"
18359 [(set_attr "type" "alu1")
18360 (set_attr "prefix_0f" "1")
18361 (set_attr "znver1_decode" "vector")
18362 (set_attr "mode" "SI")])
18364 (define_insn "bsr_zext_1"
18365 [(set (match_operand:DI 0 "register_operand" "=r")
18369 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))))
18370 (clobber (reg:CC FLAGS_REG))]
18371 "!TARGET_LZCNT && TARGET_64BIT"
18372 "bsr{l}\t{%1, %k0|%k0, %1}"
18373 [(set_attr "type" "alu1")
18374 (set_attr "prefix_0f" "1")
18375 (set_attr "znver1_decode" "vector")
18376 (set_attr "mode" "SI")])
18378 ; As bsr is undefined behavior on zero and for other input
18379 ; values it is in range 0 to 63, we can optimize away sign-extends.
18380 (define_insn_and_split "*bsr_rex64_2"
18381 [(set (match_operand:DI 0 "register_operand")
18386 (subreg:SI (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
18389 (clobber (reg:CC FLAGS_REG))]
18390 "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
18393 [(parallel [(set (reg:CCZ FLAGS_REG)
18394 (compare:CCZ (match_dup 1) (const_int 0)))
18396 (minus:DI (const_int 63) (clz:DI (match_dup 1))))])
18397 (parallel [(set (match_dup 0)
18398 (zero_extend:DI (xor:SI (match_dup 3) (const_int 63))))
18399 (clobber (reg:CC FLAGS_REG))])]
18401 operands[2] = gen_reg_rtx (DImode);
18402 operands[3] = lowpart_subreg (SImode, operands[2], DImode);
18405 (define_insn_and_split "*bsr_2"
18406 [(set (match_operand:DI 0 "register_operand")
18411 (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
18413 (clobber (reg:CC FLAGS_REG))]
18414 "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
18417 [(parallel [(set (reg:CCZ FLAGS_REG)
18418 (compare:CCZ (match_dup 1) (const_int 0)))
18420 (minus:SI (const_int 31) (clz:SI (match_dup 1))))])
18421 (parallel [(set (match_dup 0)
18422 (zero_extend:DI (xor:SI (match_dup 2) (const_int 31))))
18423 (clobber (reg:CC FLAGS_REG))])]
18424 "operands[2] = gen_reg_rtx (SImode);")
18426 ; Splitters to optimize 64 - __builtin_clzl (x) or 32 - __builtin_clz (x).
18427 ; Again, as for !TARGET_LZCNT CLZ is UB at zero, CLZ is guaranteed to be
18428 ; in [0, 63] or [0, 31] range.
18430 [(set (match_operand:SI 0 "register_operand")
18432 (match_operand:SI 2 "const_int_operand")
18434 (minus:SI (const_int 63)
18436 (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
18439 "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
18440 [(set (match_dup 3)
18441 (minus:DI (const_int 63) (clz:DI (match_dup 1))))
18443 (plus:SI (match_dup 5) (match_dup 4)))]
18445 operands[3] = gen_reg_rtx (DImode);
18446 operands[5] = lowpart_subreg (SImode, operands[3], DImode);
18447 if (INTVAL (operands[2]) == 63)
18449 emit_insn (gen_bsr_rex64_1_zext (operands[3], operands[1]));
18450 emit_move_insn (operands[0], operands[5]);
18453 operands[4] = gen_int_mode (UINTVAL (operands[2]) - 63, SImode);
18457 [(set (match_operand:SI 0 "register_operand")
18459 (match_operand:SI 2 "const_int_operand")
18461 (minus:SI (const_int 31)
18462 (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
18464 "!TARGET_LZCNT && ix86_pre_reload_split ()"
18465 [(set (match_dup 3)
18466 (minus:SI (const_int 31) (clz:SI (match_dup 1))))
18468 (plus:SI (match_dup 3) (match_dup 4)))]
18470 if (INTVAL (operands[2]) == 31)
18472 emit_insn (gen_bsr_1 (operands[0], operands[1]));
18475 operands[3] = gen_reg_rtx (SImode);
18476 operands[4] = gen_int_mode (UINTVAL (operands[2]) - 31, SImode);
18480 [(set (match_operand:DI 0 "register_operand")
18482 (match_operand:DI 2 "const_int_operand")
18485 (minus:SI (const_int 63)
18487 (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
18492 && ix86_pre_reload_split ()
18493 && ((unsigned HOST_WIDE_INT)
18494 trunc_int_for_mode (UINTVAL (operands[2]) - 63, SImode)
18495 == UINTVAL (operands[2]) - 63)"
18496 [(set (match_dup 3)
18497 (minus:DI (const_int 63) (clz:DI (match_dup 1))))
18499 (plus:DI (match_dup 3) (match_dup 4)))]
18501 if (INTVAL (operands[2]) == 63)
18503 emit_insn (gen_bsr_rex64_1 (operands[0], operands[1]));
18506 operands[3] = gen_reg_rtx (DImode);
18507 operands[4] = GEN_INT (UINTVAL (operands[2]) - 63);
18511 [(set (match_operand:DI 0 "register_operand")
18513 (match_operand:DI 2 "const_int_operand")
18516 (minus:SI (const_int 31)
18517 (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
18518 (const_int 31)))))]
18521 && ix86_pre_reload_split ()
18522 && ((unsigned HOST_WIDE_INT)
18523 trunc_int_for_mode (UINTVAL (operands[2]) - 31, SImode)
18524 == UINTVAL (operands[2]) - 31)"
18525 [(set (match_dup 3)
18526 (zero_extend:DI (minus:SI (const_int 31) (clz:SI (match_dup 1)))))
18528 (plus:DI (match_dup 3) (match_dup 4)))]
18530 if (INTVAL (operands[2]) == 31)
18532 emit_insn (gen_bsr_zext_1 (operands[0], operands[1]));
18535 operands[3] = gen_reg_rtx (DImode);
18536 operands[4] = GEN_INT (UINTVAL (operands[2]) - 31);
18539 (define_expand "clz<mode>2"
18541 [(set (reg:CCZ FLAGS_REG)
18542 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18544 (set (match_dup 3) (minus:SWI48
18546 (clz:SWI48 (match_dup 1))))])
18548 [(set (match_operand:SWI48 0 "register_operand")
18549 (xor:SWI48 (match_dup 3) (match_dup 2)))
18550 (clobber (reg:CC FLAGS_REG))])]
18555 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
18558 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
18559 operands[3] = gen_reg_rtx (<MODE>mode);
18562 (define_insn_and_split "clz<mode>2_lzcnt"
18563 [(set (match_operand:SWI48 0 "register_operand" "=r")
18565 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18566 (clobber (reg:CC FLAGS_REG))]
18568 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
18569 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18570 && optimize_function_for_speed_p (cfun)
18571 && !reg_mentioned_p (operands[0], operands[1])"
18573 [(set (match_dup 0)
18574 (clz:SWI48 (match_dup 1)))
18575 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18576 (clobber (reg:CC FLAGS_REG))])]
18577 "ix86_expand_clear (operands[0]);"
18578 [(set_attr "prefix_rep" "1")
18579 (set_attr "type" "bitmanip")
18580 (set_attr "mode" "<MODE>")])
18582 ; False dependency happens when destination is only updated by tzcnt,
18583 ; lzcnt or popcnt. There is no false dependency when destination is
18584 ; also used in source.
18585 (define_insn "*clz<mode>2_lzcnt_falsedep"
18586 [(set (match_operand:SWI48 0 "register_operand" "=r")
18588 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18589 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18590 UNSPEC_INSN_FALSE_DEP)
18591 (clobber (reg:CC FLAGS_REG))]
18593 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
18594 [(set_attr "prefix_rep" "1")
18595 (set_attr "type" "bitmanip")
18596 (set_attr "mode" "<MODE>")])
18598 (define_insn_and_split "*clzsi2_lzcnt_zext"
18599 [(set (match_operand:DI 0 "register_operand" "=r")
18603 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
18605 (clobber (reg:CC FLAGS_REG))]
18606 "TARGET_LZCNT && TARGET_64BIT"
18607 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18608 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18609 && optimize_function_for_speed_p (cfun)
18610 && !reg_mentioned_p (operands[0], operands[1])"
18612 [(set (match_dup 0)
18613 (and:DI (subreg:DI (clz:SI (match_dup 1)) 0) (const_int 63)))
18614 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18615 (clobber (reg:CC FLAGS_REG))])]
18616 "ix86_expand_clear (operands[0]);"
18617 [(set_attr "prefix_rep" "1")
18618 (set_attr "type" "bitmanip")
18619 (set_attr "mode" "SI")])
18621 ; False dependency happens when destination is only updated by tzcnt,
18622 ; lzcnt or popcnt. There is no false dependency when destination is
18623 ; also used in source.
18624 (define_insn "*clzsi2_lzcnt_zext_falsedep"
18625 [(set (match_operand:DI 0 "register_operand" "=r")
18629 (match_operand:SWI48 1 "nonimmediate_operand" "rm")) 0)
18631 (unspec [(match_operand:DI 2 "register_operand" "0")]
18632 UNSPEC_INSN_FALSE_DEP)
18633 (clobber (reg:CC FLAGS_REG))]
18635 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18636 [(set_attr "prefix_rep" "1")
18637 (set_attr "type" "bitmanip")
18638 (set_attr "mode" "SI")])
18640 (define_insn_and_split "*clzsi2_lzcnt_zext_2"
18641 [(set (match_operand:DI 0 "register_operand" "=r")
18643 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18644 (clobber (reg:CC FLAGS_REG))]
18645 "TARGET_LZCNT && TARGET_64BIT"
18646 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18647 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18648 && optimize_function_for_speed_p (cfun)
18649 && !reg_mentioned_p (operands[0], operands[1])"
18651 [(set (match_dup 0)
18652 (zero_extend:DI (clz:SI (match_dup 1))))
18653 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18654 (clobber (reg:CC FLAGS_REG))])]
18655 "ix86_expand_clear (operands[0]);"
18656 [(set_attr "prefix_rep" "1")
18657 (set_attr "type" "bitmanip")
18658 (set_attr "mode" "SI")])
18660 ; False dependency happens when destination is only updated by tzcnt,
18661 ; lzcnt or popcnt. There is no false dependency when destination is
18662 ; also used in source.
18663 (define_insn "*clzsi2_lzcnt_zext_2_falsedep"
18664 [(set (match_operand:DI 0 "register_operand" "=r")
18666 (clz:SI (match_operand:SWI48 1 "nonimmediate_operand" "rm"))))
18667 (unspec [(match_operand:DI 2 "register_operand" "0")]
18668 UNSPEC_INSN_FALSE_DEP)
18669 (clobber (reg:CC FLAGS_REG))]
18671 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18672 [(set_attr "prefix_rep" "1")
18673 (set_attr "type" "bitmanip")
18674 (set_attr "mode" "SI")])
18676 (define_int_iterator LT_ZCNT
18677 [(UNSPEC_TZCNT "TARGET_BMI")
18678 (UNSPEC_LZCNT "TARGET_LZCNT")])
18680 (define_int_attr lt_zcnt
18681 [(UNSPEC_TZCNT "tzcnt")
18682 (UNSPEC_LZCNT "lzcnt")])
18684 (define_int_attr lt_zcnt_type
18685 [(UNSPEC_TZCNT "alu1")
18686 (UNSPEC_LZCNT "bitmanip")])
18688 ;; Version of lzcnt/tzcnt that is expanded from intrinsics. This version
18689 ;; provides operand size as output when source operand is zero.
18691 (define_insn_and_split "<lt_zcnt>_<mode>"
18692 [(set (match_operand:SWI48 0 "register_operand" "=r")
18694 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
18695 (clobber (reg:CC FLAGS_REG))]
18697 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
18698 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18699 && optimize_function_for_speed_p (cfun)
18700 && !reg_mentioned_p (operands[0], operands[1])"
18702 [(set (match_dup 0)
18703 (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
18704 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18705 (clobber (reg:CC FLAGS_REG))])]
18706 "ix86_expand_clear (operands[0]);"
18707 [(set_attr "type" "<lt_zcnt_type>")
18708 (set_attr "prefix_0f" "1")
18709 (set_attr "prefix_rep" "1")
18710 (set_attr "mode" "<MODE>")])
18712 ; False dependency happens when destination is only updated by tzcnt,
18713 ; lzcnt or popcnt. There is no false dependency when destination is
18714 ; also used in source.
18715 (define_insn "*<lt_zcnt>_<mode>_falsedep"
18716 [(set (match_operand:SWI48 0 "register_operand" "=r")
18718 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
18719 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18720 UNSPEC_INSN_FALSE_DEP)
18721 (clobber (reg:CC FLAGS_REG))]
18723 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
18724 [(set_attr "type" "<lt_zcnt_type>")
18725 (set_attr "prefix_0f" "1")
18726 (set_attr "prefix_rep" "1")
18727 (set_attr "mode" "<MODE>")])
18729 (define_insn "<lt_zcnt>_hi"
18730 [(set (match_operand:HI 0 "register_operand" "=r")
18732 [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT))
18733 (clobber (reg:CC FLAGS_REG))]
18735 "<lt_zcnt>{w}\t{%1, %0|%0, %1}"
18736 [(set_attr "type" "<lt_zcnt_type>")
18737 (set_attr "prefix_0f" "1")
18738 (set_attr "prefix_rep" "1")
18739 (set_attr "mode" "HI")])
18741 ;; BMI instructions.
18743 (define_insn "bmi_bextr_<mode>"
18744 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
18745 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
18746 (match_operand:SWI48 2 "register_operand" "r,r")]
18748 (clobber (reg:CC FLAGS_REG))]
18750 "bextr\t{%2, %1, %0|%0, %1, %2}"
18751 [(set_attr "type" "bitmanip")
18752 (set_attr "btver2_decode" "direct, double")
18753 (set_attr "mode" "<MODE>")])
18755 (define_insn "*bmi_bextr_<mode>_ccz"
18756 [(set (reg:CCZ FLAGS_REG)
18758 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
18759 (match_operand:SWI48 2 "register_operand" "r,r")]
18762 (clobber (match_scratch:SWI48 0 "=r,r"))]
18764 "bextr\t{%2, %1, %0|%0, %1, %2}"
18765 [(set_attr "type" "bitmanip")
18766 (set_attr "btver2_decode" "direct, double")
18767 (set_attr "mode" "<MODE>")])
18769 (define_insn "*bmi_blsi_<mode>"
18770 [(set (match_operand:SWI48 0 "register_operand" "=r")
18773 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
18775 (clobber (reg:CC FLAGS_REG))]
18777 "blsi\t{%1, %0|%0, %1}"
18778 [(set_attr "type" "bitmanip")
18779 (set_attr "btver2_decode" "double")
18780 (set_attr "mode" "<MODE>")])
18782 (define_insn "*bmi_blsi_<mode>_cmp"
18783 [(set (reg FLAGS_REG)
18786 (neg:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
18789 (set (match_operand:SWI48 0 "register_operand" "=r")
18790 (and:SWI48 (neg:SWI48 (match_dup 1)) (match_dup 1)))]
18791 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
18792 "blsi\t{%1, %0|%0, %1}"
18793 [(set_attr "type" "bitmanip")
18794 (set_attr "btver2_decode" "double")
18795 (set_attr "mode" "<MODE>")])
18797 (define_insn "*bmi_blsi_<mode>_ccno"
18798 [(set (reg FLAGS_REG)
18801 (neg:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
18804 (clobber (match_scratch:SWI48 0 "=r"))]
18805 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
18806 "blsi\t{%1, %0|%0, %1}"
18807 [(set_attr "type" "bitmanip")
18808 (set_attr "btver2_decode" "double")
18809 (set_attr "mode" "<MODE>")])
18811 (define_insn "*bmi_blsmsk_<mode>"
18812 [(set (match_operand:SWI48 0 "register_operand" "=r")
18815 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18818 (clobber (reg:CC FLAGS_REG))]
18820 "blsmsk\t{%1, %0|%0, %1}"
18821 [(set_attr "type" "bitmanip")
18822 (set_attr "btver2_decode" "double")
18823 (set_attr "mode" "<MODE>")])
18825 (define_insn "*bmi_blsr_<mode>"
18826 [(set (match_operand:SWI48 0 "register_operand" "=r")
18829 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18832 (clobber (reg:CC FLAGS_REG))]
18834 "blsr\t{%1, %0|%0, %1}"
18835 [(set_attr "type" "bitmanip")
18836 (set_attr "btver2_decode" "double")
18837 (set_attr "mode" "<MODE>")])
18839 (define_insn "*bmi_blsr_<mode>_cmp"
18840 [(set (reg:CCZ FLAGS_REG)
18844 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18848 (set (match_operand:SWI48 0 "register_operand" "=r")
18855 "blsr\t{%1, %0|%0, %1}"
18856 [(set_attr "type" "bitmanip")
18857 (set_attr "btver2_decode" "double")
18858 (set_attr "mode" "<MODE>")])
18860 (define_insn "*bmi_blsr_<mode>_ccz"
18861 [(set (reg:CCZ FLAGS_REG)
18865 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18869 (clobber (match_scratch:SWI48 0 "=r"))]
18871 "blsr\t{%1, %0|%0, %1}"
18872 [(set_attr "type" "bitmanip")
18873 (set_attr "btver2_decode" "double")
18874 (set_attr "mode" "<MODE>")])
18876 ;; BMI2 instructions.
18877 (define_expand "bmi2_bzhi_<mode>3"
18879 [(set (match_operand:SWI48 0 "register_operand")
18880 (if_then_else:SWI48
18881 (ne:QI (match_operand:QI 2 "register_operand")
18883 (zero_extract:SWI48
18884 (match_operand:SWI48 1 "nonimmediate_operand")
18885 (umin:QI (match_dup 2) (match_dup 3))
18888 (clobber (reg:CC FLAGS_REG))])]
18891 operands[2] = gen_lowpart (QImode, operands[2]);
18892 operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
18895 (define_insn "*bmi2_bzhi_<mode>3"
18896 [(set (match_operand:SWI48 0 "register_operand" "=r")
18897 (if_then_else:SWI48
18898 (ne:QI (match_operand:QI 2 "register_operand" "q")
18900 (zero_extract:SWI48
18901 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18902 (umin:QI (match_dup 2)
18903 (match_operand:QI 3 "const_int_operand"))
18906 (clobber (reg:CC FLAGS_REG))]
18907 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
18908 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
18909 [(set_attr "type" "bitmanip")
18910 (set_attr "prefix" "vex")
18911 (set_attr "mode" "<MODE>")])
18913 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
18914 [(set (reg:CCZ FLAGS_REG)
18916 (if_then_else:SWI48
18917 (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0))
18918 (zero_extract:SWI48
18919 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18920 (umin:QI (match_dup 2)
18921 (match_operand:QI 3 "const_int_operand"))
18925 (clobber (match_scratch:SWI48 0 "=r"))]
18926 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
18927 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
18928 [(set_attr "type" "bitmanip")
18929 (set_attr "prefix" "vex")
18930 (set_attr "mode" "<MODE>")])
18932 (define_insn "*bmi2_bzhi_<mode>3_2"
18933 [(set (match_operand:SWI48 0 "register_operand" "=r")
18936 (ashift:SWI48 (const_int 1)
18937 (match_operand:QI 2 "register_operand" "r"))
18939 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18940 (clobber (reg:CC FLAGS_REG))]
18942 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
18943 [(set_attr "type" "bitmanip")
18944 (set_attr "prefix" "vex")
18945 (set_attr "mode" "<MODE>")])
18947 (define_insn "*bmi2_bzhi_<mode>3_3"
18948 [(set (match_operand:SWI48 0 "register_operand" "=r")
18951 (ashift:SWI48 (const_int -1)
18952 (match_operand:QI 2 "register_operand" "r")))
18953 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18954 (clobber (reg:CC FLAGS_REG))]
18956 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
18957 [(set_attr "type" "bitmanip")
18958 (set_attr "prefix" "vex")
18959 (set_attr "mode" "<MODE>")])
18961 (define_insn "*bmi2_bzhi_zero_extendsidi_4"
18962 [(set (match_operand:DI 0 "register_operand" "=r")
18966 (ashift:SI (const_int 1)
18967 (match_operand:QI 2 "register_operand" "r"))
18969 (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18970 (clobber (reg:CC FLAGS_REG))]
18971 "TARGET_64BIT && TARGET_BMI2"
18972 "bzhi\t{%q2, %q1, %q0|%q0, %q1, %q2}"
18973 [(set_attr "type" "bitmanip")
18974 (set_attr "prefix" "vex")
18975 (set_attr "mode" "DI")])
18977 (define_insn "*bmi2_bzhi_zero_extendsidi_5"
18978 [(set (match_operand:DI 0 "register_operand" "=r")
18982 (ashift:SI (const_int 1)
18983 (match_operand:QI 2 "register_operand" "r"))
18985 (match_operand:DI 1 "nonimmediate_operand" "rm")))
18986 (clobber (reg:CC FLAGS_REG))]
18987 "TARGET_64BIT && TARGET_BMI2"
18988 "bzhi\t{%q2, %q1, %q0|%q0, %q1, %q2}"
18989 [(set_attr "type" "bitmanip")
18990 (set_attr "prefix" "vex")
18991 (set_attr "mode" "DI")])
18993 (define_insn "bmi2_pdep_<mode>3"
18994 [(set (match_operand:SWI48 0 "register_operand" "=r")
18995 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
18996 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
18999 "pdep\t{%2, %1, %0|%0, %1, %2}"
19000 [(set_attr "type" "bitmanip")
19001 (set_attr "prefix" "vex")
19002 (set_attr "mode" "<MODE>")])
19004 (define_insn "bmi2_pext_<mode>3"
19005 [(set (match_operand:SWI48 0 "register_operand" "=r")
19006 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
19007 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
19010 "pext\t{%2, %1, %0|%0, %1, %2}"
19011 [(set_attr "type" "bitmanip")
19012 (set_attr "prefix" "vex")
19013 (set_attr "mode" "<MODE>")])
19015 ;; TBM instructions.
19016 (define_insn "@tbm_bextri_<mode>"
19017 [(set (match_operand:SWI48 0 "register_operand" "=r")
19018 (zero_extract:SWI48
19019 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19020 (match_operand:QI 2 "const_0_to_255_operand")
19021 (match_operand:QI 3 "const_0_to_255_operand")))
19022 (clobber (reg:CC FLAGS_REG))]
19025 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
19026 return "bextr\t{%2, %1, %0|%0, %1, %2}";
19028 [(set_attr "type" "bitmanip")
19029 (set_attr "mode" "<MODE>")])
19031 (define_insn "*tbm_blcfill_<mode>"
19032 [(set (match_operand:SWI48 0 "register_operand" "=r")
19035 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19038 (clobber (reg:CC FLAGS_REG))]
19040 "blcfill\t{%1, %0|%0, %1}"
19041 [(set_attr "type" "bitmanip")
19042 (set_attr "mode" "<MODE>")])
19044 (define_insn "*tbm_blci_<mode>"
19045 [(set (match_operand:SWI48 0 "register_operand" "=r")
19049 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19052 (clobber (reg:CC FLAGS_REG))]
19054 "blci\t{%1, %0|%0, %1}"
19055 [(set_attr "type" "bitmanip")
19056 (set_attr "mode" "<MODE>")])
19058 (define_insn "*tbm_blcic_<mode>"
19059 [(set (match_operand:SWI48 0 "register_operand" "=r")
19062 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19066 (clobber (reg:CC FLAGS_REG))]
19068 "blcic\t{%1, %0|%0, %1}"
19069 [(set_attr "type" "bitmanip")
19070 (set_attr "mode" "<MODE>")])
19072 (define_insn "*tbm_blcmsk_<mode>"
19073 [(set (match_operand:SWI48 0 "register_operand" "=r")
19076 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19079 (clobber (reg:CC FLAGS_REG))]
19081 "blcmsk\t{%1, %0|%0, %1}"
19082 [(set_attr "type" "bitmanip")
19083 (set_attr "mode" "<MODE>")])
19085 (define_insn "*tbm_blcs_<mode>"
19086 [(set (match_operand:SWI48 0 "register_operand" "=r")
19089 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19092 (clobber (reg:CC FLAGS_REG))]
19094 "blcs\t{%1, %0|%0, %1}"
19095 [(set_attr "type" "bitmanip")
19096 (set_attr "mode" "<MODE>")])
19098 (define_insn "*tbm_blsfill_<mode>"
19099 [(set (match_operand:SWI48 0 "register_operand" "=r")
19102 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19105 (clobber (reg:CC FLAGS_REG))]
19107 "blsfill\t{%1, %0|%0, %1}"
19108 [(set_attr "type" "bitmanip")
19109 (set_attr "mode" "<MODE>")])
19111 (define_insn "*tbm_blsic_<mode>"
19112 [(set (match_operand:SWI48 0 "register_operand" "=r")
19115 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19119 (clobber (reg:CC FLAGS_REG))]
19121 "blsic\t{%1, %0|%0, %1}"
19122 [(set_attr "type" "bitmanip")
19123 (set_attr "mode" "<MODE>")])
19125 (define_insn "*tbm_t1mskc_<mode>"
19126 [(set (match_operand:SWI48 0 "register_operand" "=r")
19129 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19133 (clobber (reg:CC FLAGS_REG))]
19135 "t1mskc\t{%1, %0|%0, %1}"
19136 [(set_attr "type" "bitmanip")
19137 (set_attr "mode" "<MODE>")])
19139 (define_insn "*tbm_tzmsk_<mode>"
19140 [(set (match_operand:SWI48 0 "register_operand" "=r")
19143 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19147 (clobber (reg:CC FLAGS_REG))]
19149 "tzmsk\t{%1, %0|%0, %1}"
19150 [(set_attr "type" "bitmanip")
19151 (set_attr "mode" "<MODE>")])
19153 (define_insn_and_split "popcount<mode>2"
19154 [(set (match_operand:SWI48 0 "register_operand" "=r")
19156 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
19157 (clobber (reg:CC FLAGS_REG))]
19161 return "popcnt\t{%1, %0|%0, %1}";
19163 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
19166 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
19167 && optimize_function_for_speed_p (cfun)
19168 && !reg_mentioned_p (operands[0], operands[1])"
19170 [(set (match_dup 0)
19171 (popcount:SWI48 (match_dup 1)))
19172 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
19173 (clobber (reg:CC FLAGS_REG))])]
19174 "ix86_expand_clear (operands[0]);"
19175 [(set_attr "prefix_rep" "1")
19176 (set_attr "type" "bitmanip")
19177 (set_attr "mode" "<MODE>")])
19179 ; False dependency happens when destination is only updated by tzcnt,
19180 ; lzcnt or popcnt. There is no false dependency when destination is
19181 ; also used in source.
19182 (define_insn "*popcount<mode>2_falsedep"
19183 [(set (match_operand:SWI48 0 "register_operand" "=r")
19185 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
19186 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
19187 UNSPEC_INSN_FALSE_DEP)
19188 (clobber (reg:CC FLAGS_REG))]
19192 return "popcnt\t{%1, %0|%0, %1}";
19194 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
19197 [(set_attr "prefix_rep" "1")
19198 (set_attr "type" "bitmanip")
19199 (set_attr "mode" "<MODE>")])
19201 (define_insn_and_split "*popcountsi2_zext"
19202 [(set (match_operand:DI 0 "register_operand" "=r")
19206 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
19208 (clobber (reg:CC FLAGS_REG))]
19209 "TARGET_POPCNT && TARGET_64BIT"
19212 return "popcnt\t{%1, %k0|%k0, %1}";
19214 return "popcnt{l}\t{%1, %k0|%k0, %1}";
19217 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
19218 && optimize_function_for_speed_p (cfun)
19219 && !reg_mentioned_p (operands[0], operands[1])"
19221 [(set (match_dup 0)
19222 (and:DI (subreg:DI (popcount:SI (match_dup 1)) 0) (const_int 63)))
19223 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
19224 (clobber (reg:CC FLAGS_REG))])]
19225 "ix86_expand_clear (operands[0]);"
19226 [(set_attr "prefix_rep" "1")
19227 (set_attr "type" "bitmanip")
19228 (set_attr "mode" "SI")])
19230 ; False dependency happens when destination is only updated by tzcnt,
19231 ; lzcnt or popcnt. There is no false dependency when destination is
19232 ; also used in source.
19233 (define_insn "*popcountsi2_zext_falsedep"
19234 [(set (match_operand:DI 0 "register_operand" "=r")
19238 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
19240 (unspec [(match_operand:DI 2 "register_operand" "0")]
19241 UNSPEC_INSN_FALSE_DEP)
19242 (clobber (reg:CC FLAGS_REG))]
19243 "TARGET_POPCNT && TARGET_64BIT"
19246 return "popcnt\t{%1, %k0|%k0, %1}";
19248 return "popcnt{l}\t{%1, %k0|%k0, %1}";
19251 [(set_attr "prefix_rep" "1")
19252 (set_attr "type" "bitmanip")
19253 (set_attr "mode" "SI")])
19255 (define_insn_and_split "*popcountsi2_zext_2"
19256 [(set (match_operand:DI 0 "register_operand" "=r")
19258 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
19259 (clobber (reg:CC FLAGS_REG))]
19260 "TARGET_POPCNT && TARGET_64BIT"
19263 return "popcnt\t{%1, %k0|%k0, %1}";
19265 return "popcnt{l}\t{%1, %k0|%k0, %1}";
19268 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
19269 && optimize_function_for_speed_p (cfun)
19270 && !reg_mentioned_p (operands[0], operands[1])"
19272 [(set (match_dup 0)
19273 (zero_extend:DI (popcount:SI (match_dup 1))))
19274 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
19275 (clobber (reg:CC FLAGS_REG))])]
19276 "ix86_expand_clear (operands[0]);"
19277 [(set_attr "prefix_rep" "1")
19278 (set_attr "type" "bitmanip")
19279 (set_attr "mode" "SI")])
19281 ; False dependency happens when destination is only updated by tzcnt,
19282 ; lzcnt or popcnt. There is no false dependency when destination is
19283 ; also used in source.
19284 (define_insn "*popcountsi2_zext_2_falsedep"
19285 [(set (match_operand:DI 0 "register_operand" "=r")
19287 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
19288 (unspec [(match_operand:DI 2 "register_operand" "0")]
19289 UNSPEC_INSN_FALSE_DEP)
19290 (clobber (reg:CC FLAGS_REG))]
19291 "TARGET_POPCNT && TARGET_64BIT"
19294 return "popcnt\t{%1, %k0|%k0, %1}";
19296 return "popcnt{l}\t{%1, %k0|%k0, %1}";
19299 [(set_attr "prefix_rep" "1")
19300 (set_attr "type" "bitmanip")
19301 (set_attr "mode" "SI")])
19303 (define_insn_and_split "*popcounthi2_1"
19304 [(set (match_operand:SI 0 "register_operand")
19306 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
19307 (clobber (reg:CC FLAGS_REG))]
19309 && ix86_pre_reload_split ()"
19314 rtx tmp = gen_reg_rtx (HImode);
19316 emit_insn (gen_popcounthi2 (tmp, operands[1]));
19317 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
19321 (define_insn_and_split "*popcounthi2_2"
19322 [(set (match_operand:SI 0 "register_operand")
19324 (popcount:HI (match_operand:HI 1 "nonimmediate_operand"))))
19325 (clobber (reg:CC FLAGS_REG))]
19327 && ix86_pre_reload_split ()"
19332 rtx tmp = gen_reg_rtx (HImode);
19334 emit_insn (gen_popcounthi2 (tmp, operands[1]));
19335 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
19339 (define_insn "popcounthi2"
19340 [(set (match_operand:HI 0 "register_operand" "=r")
19342 (match_operand:HI 1 "nonimmediate_operand" "rm")))
19343 (clobber (reg:CC FLAGS_REG))]
19347 return "popcnt\t{%1, %0|%0, %1}";
19349 return "popcnt{w}\t{%1, %0|%0, %1}";
19352 [(set_attr "prefix_rep" "1")
19353 (set_attr "type" "bitmanip")
19354 (set_attr "mode" "HI")])
19356 (define_expand "bswapdi2"
19357 [(set (match_operand:DI 0 "register_operand")
19358 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
19362 operands[1] = force_reg (DImode, operands[1]);
19365 (define_expand "bswapsi2"
19366 [(set (match_operand:SI 0 "register_operand")
19367 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
19372 else if (TARGET_BSWAP)
19373 operands[1] = force_reg (SImode, operands[1]);
19376 rtx x = operands[0];
19378 emit_move_insn (x, operands[1]);
19379 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
19380 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
19381 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
19386 (define_insn "*bswap<mode>2_movbe"
19387 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
19388 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
19390 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
19393 movbe{<imodesuffix>}\t{%1, %0|%0, %1}
19394 movbe{<imodesuffix>}\t{%1, %0|%0, %1}"
19395 [(set_attr "type" "bitmanip,imov,imov")
19396 (set_attr "modrm" "0,1,1")
19397 (set_attr "prefix_0f" "*,1,1")
19398 (set_attr "prefix_extra" "*,1,1")
19399 (set_attr "mode" "<MODE>")])
19401 (define_insn "*bswap<mode>2"
19402 [(set (match_operand:SWI48 0 "register_operand" "=r")
19403 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
19406 [(set_attr "type" "bitmanip")
19407 (set_attr "modrm" "0")
19408 (set_attr "mode" "<MODE>")])
19410 (define_expand "bswaphi2"
19411 [(set (match_operand:HI 0 "register_operand")
19412 (bswap:HI (match_operand:HI 1 "nonimmediate_operand")))]
19415 (define_insn "*bswaphi2_movbe"
19416 [(set (match_operand:HI 0 "nonimmediate_operand" "=Q,r,m")
19417 (bswap:HI (match_operand:HI 1 "nonimmediate_operand" "0,m,r")))]
19419 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
19421 xchg{b}\t{%h0, %b0|%b0, %h0}
19422 movbe{w}\t{%1, %0|%0, %1}
19423 movbe{w}\t{%1, %0|%0, %1}"
19424 [(set_attr "type" "imov")
19425 (set_attr "modrm" "*,1,1")
19426 (set_attr "prefix_0f" "*,1,1")
19427 (set_attr "prefix_extra" "*,1,1")
19428 (set_attr "pent_pair" "np,*,*")
19429 (set_attr "athlon_decode" "vector,*,*")
19430 (set_attr "amdfam10_decode" "double,*,*")
19431 (set_attr "bdver1_decode" "double,*,*")
19432 (set_attr "mode" "QI,HI,HI")])
19435 [(set (match_operand:HI 0 "general_reg_operand")
19436 (bswap:HI (match_dup 0)))]
19438 && !(TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))
19439 && peep2_regno_dead_p (0, FLAGS_REG)"
19440 [(parallel [(set (match_dup 0) (rotate:HI (match_dup 0) (const_int 8)))
19441 (clobber (reg:CC FLAGS_REG))])])
19443 (define_insn "bswaphi_lowpart"
19444 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
19445 (bswap:HI (match_dup 0)))
19446 (clobber (reg:CC FLAGS_REG))]
19449 xchg{b}\t{%h0, %b0|%b0, %h0}
19450 rol{w}\t{$8, %0|%0, 8}"
19451 [(set (attr "preferred_for_size")
19452 (cond [(eq_attr "alternative" "0")
19453 (symbol_ref "true")]
19454 (symbol_ref "false")))
19455 (set (attr "preferred_for_speed")
19456 (cond [(eq_attr "alternative" "0")
19457 (symbol_ref "TARGET_USE_XCHGB")]
19458 (symbol_ref "!TARGET_USE_XCHGB")))
19459 (set_attr "length" "2,4")
19460 (set_attr "mode" "QI,HI")])
19462 (define_expand "paritydi2"
19463 [(set (match_operand:DI 0 "register_operand")
19464 (parity:DI (match_operand:DI 1 "register_operand")))]
19467 rtx scratch = gen_reg_rtx (QImode);
19468 rtx hipart1 = gen_reg_rtx (SImode);
19469 rtx lopart1 = gen_reg_rtx (SImode);
19470 rtx xor1 = gen_reg_rtx (SImode);
19471 rtx shift2 = gen_reg_rtx (SImode);
19472 rtx hipart2 = gen_reg_rtx (HImode);
19473 rtx lopart2 = gen_reg_rtx (HImode);
19474 rtx xor2 = gen_reg_rtx (HImode);
19478 rtx shift1 = gen_reg_rtx (DImode);
19479 emit_insn (gen_lshrdi3 (shift1, operands[1], GEN_INT (32)));
19480 emit_move_insn (hipart1, gen_lowpart (SImode, shift1));
19483 emit_move_insn (hipart1, gen_highpart (SImode, operands[1]));
19485 emit_move_insn (lopart1, gen_lowpart (SImode, operands[1]));
19486 emit_insn (gen_xorsi3 (xor1, hipart1, lopart1));
19488 emit_insn (gen_lshrsi3 (shift2, xor1, GEN_INT (16)));
19489 emit_move_insn (hipart2, gen_lowpart (HImode, shift2));
19490 emit_move_insn (lopart2, gen_lowpart (HImode, xor1));
19491 emit_insn (gen_xorhi3 (xor2, hipart2, lopart2));
19493 emit_insn (gen_parityhi2_cmp (xor2));
19495 ix86_expand_setcc (scratch, ORDERED,
19496 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19499 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
19502 rtx tmp = gen_reg_rtx (SImode);
19504 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
19505 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
19510 (define_expand "paritysi2"
19511 [(set (match_operand:SI 0 "register_operand")
19512 (parity:SI (match_operand:SI 1 "register_operand")))]
19515 rtx scratch = gen_reg_rtx (QImode);
19516 rtx shift = gen_reg_rtx (SImode);
19517 rtx hipart = gen_reg_rtx (HImode);
19518 rtx lopart = gen_reg_rtx (HImode);
19519 rtx tmp = gen_reg_rtx (HImode);
19521 emit_insn (gen_lshrsi3 (shift, operands[1], GEN_INT (16)));
19522 emit_move_insn (hipart, gen_lowpart (HImode, shift));
19523 emit_move_insn (lopart, gen_lowpart (HImode, operands[1]));
19524 emit_insn (gen_xorhi3 (tmp, hipart, lopart));
19526 emit_insn (gen_parityhi2_cmp (tmp));
19528 ix86_expand_setcc (scratch, ORDERED,
19529 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19531 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
19535 (define_expand "parityhi2"
19536 [(set (match_operand:HI 0 "register_operand")
19537 (parity:HI (match_operand:HI 1 "register_operand")))]
19540 rtx scratch = gen_reg_rtx (QImode);
19542 emit_insn (gen_parityhi2_cmp (operands[1]));
19544 ix86_expand_setcc (scratch, ORDERED,
19545 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19547 emit_insn (gen_zero_extendqihi2 (operands[0], scratch));
19551 (define_expand "parityqi2"
19552 [(set (match_operand:QI 0 "register_operand")
19553 (parity:QI (match_operand:QI 1 "register_operand")))]
19556 emit_insn (gen_parityqi2_cmp (operands[1]));
19558 ix86_expand_setcc (operands[0], ORDERED,
19559 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19563 (define_insn "parityhi2_cmp"
19564 [(set (reg:CC FLAGS_REG)
19565 (unspec:CC [(match_operand:HI 0 "register_operand" "+Q")]
19567 (clobber (match_dup 0))]
19569 "xor{b}\t{%h0, %b0|%b0, %h0}"
19570 [(set_attr "length" "2")
19571 (set_attr "mode" "QI")])
19573 (define_insn "parityqi2_cmp"
19574 [(set (reg:CC FLAGS_REG)
19575 (unspec:CC [(match_operand:QI 0 "register_operand" "q")]
19579 [(set_attr "mode" "QI")])
19581 ;; Replace zero_extend:HI followed by parityhi2_cmp with parityqi2_cmp
19583 [(set (match_operand:HI 0 "register_operand")
19584 (zero_extend:HI (match_operand:QI 1 "general_reg_operand")))
19585 (parallel [(set (reg:CC FLAGS_REG)
19586 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
19587 (clobber (match_dup 0))])]
19589 [(set (reg:CC FLAGS_REG)
19590 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))])
19592 ;; Eliminate QImode popcount&1 using parity flag
19594 [(set (match_operand:SI 0 "register_operand")
19595 (zero_extend:SI (match_operand:QI 1 "general_reg_operand")))
19596 (parallel [(set (match_operand:SI 2 "register_operand")
19597 (popcount:SI (match_dup 0)))
19598 (clobber (reg:CC FLAGS_REG))])
19599 (set (reg:CCZ FLAGS_REG)
19600 (compare:CCZ (and:QI (match_operand:QI 3 "register_operand")
19603 (set (pc) (if_then_else (match_operator 4 "bt_comparison_operator"
19604 [(reg:CCZ FLAGS_REG)
19606 (label_ref (match_operand 5))
19608 "REGNO (operands[2]) == REGNO (operands[3])
19609 && peep2_reg_dead_p (3, operands[0])
19610 && peep2_reg_dead_p (3, operands[2])
19611 && peep2_regno_dead_p (4, FLAGS_REG)"
19612 [(set (reg:CC FLAGS_REG)
19613 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
19614 (set (pc) (if_then_else (match_op_dup 4 [(reg:CC FLAGS_REG)
19616 (label_ref (match_dup 5))
19619 operands[4] = shallow_copy_rtx (operands[4]);
19620 PUT_CODE (operands[4], GET_CODE (operands[4]) == EQ ? UNORDERED : ORDERED);
19623 ;; Eliminate HImode popcount&1 using parity flag
19625 [(match_scratch:HI 0 "Q")
19626 (parallel [(set (match_operand:HI 1 "register_operand")
19628 (match_operand:HI 2 "nonimmediate_operand")))
19629 (clobber (reg:CC FLAGS_REG))])
19630 (set (match_operand 3 "register_operand")
19631 (zero_extend (match_dup 1)))
19632 (set (reg:CCZ FLAGS_REG)
19633 (compare:CCZ (and:QI (match_operand:QI 4 "register_operand")
19636 (set (pc) (if_then_else (match_operator 5 "bt_comparison_operator"
19637 [(reg:CCZ FLAGS_REG)
19639 (label_ref (match_operand 6))
19641 "REGNO (operands[3]) == REGNO (operands[4])
19642 && peep2_reg_dead_p (3, operands[1])
19643 && peep2_reg_dead_p (3, operands[3])
19644 && peep2_regno_dead_p (4, FLAGS_REG)"
19645 [(set (match_dup 0) (match_dup 2))
19646 (parallel [(set (reg:CC FLAGS_REG)
19647 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
19648 (clobber (match_dup 0))])
19649 (set (pc) (if_then_else (match_op_dup 5 [(reg:CC FLAGS_REG)
19651 (label_ref (match_dup 6))
19654 operands[5] = shallow_copy_rtx (operands[5]);
19655 PUT_CODE (operands[5], GET_CODE (operands[5]) == EQ ? UNORDERED : ORDERED);
19658 ;; Eliminate HImode popcount&1 using parity flag (variant 2)
19660 [(match_scratch:HI 0 "Q")
19661 (parallel [(set (match_operand:HI 1 "register_operand")
19663 (match_operand:HI 2 "nonimmediate_operand")))
19664 (clobber (reg:CC FLAGS_REG))])
19665 (set (reg:CCZ FLAGS_REG)
19666 (compare:CCZ (and:QI (match_operand:QI 3 "register_operand")
19669 (set (pc) (if_then_else (match_operator 4 "bt_comparison_operator"
19670 [(reg:CCZ FLAGS_REG)
19672 (label_ref (match_operand 5))
19674 "REGNO (operands[1]) == REGNO (operands[3])
19675 && peep2_reg_dead_p (2, operands[1])
19676 && peep2_reg_dead_p (2, operands[3])
19677 && peep2_regno_dead_p (3, FLAGS_REG)"
19678 [(set (match_dup 0) (match_dup 2))
19679 (parallel [(set (reg:CC FLAGS_REG)
19680 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
19681 (clobber (match_dup 0))])
19682 (set (pc) (if_then_else (match_op_dup 4 [(reg:CC FLAGS_REG)
19684 (label_ref (match_dup 5))
19687 operands[4] = shallow_copy_rtx (operands[4]);
19688 PUT_CODE (operands[4], GET_CODE (operands[4]) == EQ ? UNORDERED : ORDERED);
19692 ;; Thread-local storage patterns for ELF.
19694 ;; Note that these code sequences must appear exactly as shown
19695 ;; in order to allow linker relaxation.
19697 (define_insn "*tls_global_dynamic_32_gnu"
19698 [(set (match_operand:SI 0 "register_operand" "=a")
19700 [(match_operand:SI 1 "register_operand" "Yb")
19701 (match_operand 2 "tls_symbolic_operand")
19702 (match_operand 3 "constant_call_address_operand" "Bz")
19705 (clobber (match_scratch:SI 4 "=d"))
19706 (clobber (match_scratch:SI 5 "=c"))
19707 (clobber (reg:CC FLAGS_REG))]
19708 "!TARGET_64BIT && TARGET_GNU_TLS"
19710 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19712 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
19715 ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
19716 if (TARGET_SUN_TLS)
19717 #ifdef HAVE_AS_IX86_TLSGDPLT
19718 return "call\t%a2@tlsgdplt";
19720 return "call\t%p3@plt";
19722 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19723 return "call\t%P3";
19724 return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
19726 [(set_attr "type" "multi")
19727 (set_attr "length" "12")])
19729 (define_expand "tls_global_dynamic_32"
19731 [(set (match_operand:SI 0 "register_operand")
19732 (unspec:SI [(match_operand:SI 2 "register_operand")
19733 (match_operand 1 "tls_symbolic_operand")
19734 (match_operand 3 "constant_call_address_operand")
19737 (clobber (scratch:SI))
19738 (clobber (scratch:SI))
19739 (clobber (reg:CC FLAGS_REG))])]
19741 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
19743 (define_insn "*tls_global_dynamic_64_<mode>"
19744 [(set (match_operand:P 0 "register_operand" "=a")
19746 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
19747 (match_operand 3)))
19748 (unspec:P [(match_operand 1 "tls_symbolic_operand")
19754 /* The .loc directive has effect for 'the immediately following assembly
19755 instruction'. So for a sequence:
19759 the 'immediately following assembly instruction' is insn1.
19760 We want to emit an insn prefix here, but if we use .byte (as shown in
19761 'ELF Handling For Thread-Local Storage'), a preceding .loc will point
19762 inside the insn sequence, rather than to the start. After relaxation
19763 of the sequence by the linker, the .loc might point inside an insn.
19764 Use data16 prefix instead, which doesn't have this problem. */
19765 fputs ("\tdata16", asm_out_file);
19767 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
19768 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19769 fputs (ASM_SHORT "0x6666\n", asm_out_file);
19771 fputs (ASM_BYTE "0x66\n", asm_out_file);
19772 fputs ("\trex64\n", asm_out_file);
19773 if (TARGET_SUN_TLS)
19774 return "call\t%p2@plt";
19775 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19776 return "call\t%P2";
19777 return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
19779 [(set_attr "type" "multi")
19780 (set (attr "length")
19781 (symbol_ref "TARGET_X32 ? 15 : 16"))])
19783 (define_insn "*tls_global_dynamic_64_largepic"
19784 [(set (match_operand:DI 0 "register_operand" "=a")
19786 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
19787 (match_operand:DI 3 "immediate_operand" "i")))
19788 (match_operand 4)))
19789 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
19792 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
19793 && GET_CODE (operands[3]) == CONST
19794 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
19795 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
19798 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
19799 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
19800 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
19801 return "call\t{*%%rax|rax}";
19803 [(set_attr "type" "multi")
19804 (set_attr "length" "22")])
19806 (define_expand "@tls_global_dynamic_64_<mode>"
19808 [(set (match_operand:P 0 "register_operand")
19810 (mem:QI (match_operand 2))
19812 (unspec:P [(match_operand 1 "tls_symbolic_operand")
19816 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
19818 (define_insn "*tls_local_dynamic_base_32_gnu"
19819 [(set (match_operand:SI 0 "register_operand" "=a")
19821 [(match_operand:SI 1 "register_operand" "Yb")
19822 (match_operand 2 "constant_call_address_operand" "Bz")
19824 UNSPEC_TLS_LD_BASE))
19825 (clobber (match_scratch:SI 3 "=d"))
19826 (clobber (match_scratch:SI 4 "=c"))
19827 (clobber (reg:CC FLAGS_REG))]
19828 "!TARGET_64BIT && TARGET_GNU_TLS"
19831 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
19832 if (TARGET_SUN_TLS)
19834 if (HAVE_AS_IX86_TLSLDMPLT)
19835 return "call\t%&@tlsldmplt";
19837 return "call\t%p2@plt";
19839 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19840 return "call\t%P2";
19841 return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
19843 [(set_attr "type" "multi")
19844 (set_attr "length" "11")])
19846 (define_expand "tls_local_dynamic_base_32"
19848 [(set (match_operand:SI 0 "register_operand")
19850 [(match_operand:SI 1 "register_operand")
19851 (match_operand 2 "constant_call_address_operand")
19853 UNSPEC_TLS_LD_BASE))
19854 (clobber (scratch:SI))
19855 (clobber (scratch:SI))
19856 (clobber (reg:CC FLAGS_REG))])]
19858 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
19860 (define_insn "*tls_local_dynamic_base_64_<mode>"
19861 [(set (match_operand:P 0 "register_operand" "=a")
19863 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
19864 (match_operand 2)))
19865 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
19869 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
19870 if (TARGET_SUN_TLS)
19871 return "call\t%p1@plt";
19872 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19873 return "call\t%P1";
19874 return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
19876 [(set_attr "type" "multi")
19877 (set_attr "length" "12")])
19879 (define_insn "*tls_local_dynamic_base_64_largepic"
19880 [(set (match_operand:DI 0 "register_operand" "=a")
19882 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
19883 (match_operand:DI 2 "immediate_operand" "i")))
19884 (match_operand 3)))
19885 (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
19886 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
19887 && GET_CODE (operands[2]) == CONST
19888 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
19889 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
19892 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
19893 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
19894 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
19895 return "call\t{*%%rax|rax}";
19897 [(set_attr "type" "multi")
19898 (set_attr "length" "22")])
19900 (define_expand "@tls_local_dynamic_base_64_<mode>"
19902 [(set (match_operand:P 0 "register_operand")
19904 (mem:QI (match_operand 1))
19906 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
19908 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
19910 ;; Local dynamic of a single variable is a lose. Show combine how
19911 ;; to convert that back to global dynamic.
19913 (define_insn_and_split "*tls_local_dynamic_32_once"
19914 [(set (match_operand:SI 0 "register_operand" "=a")
19916 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
19917 (match_operand 2 "constant_call_address_operand" "Bz")
19919 UNSPEC_TLS_LD_BASE)
19920 (const:SI (unspec:SI
19921 [(match_operand 3 "tls_symbolic_operand")]
19923 (clobber (match_scratch:SI 4 "=d"))
19924 (clobber (match_scratch:SI 5 "=c"))
19925 (clobber (reg:CC FLAGS_REG))]
19930 [(set (match_dup 0)
19931 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
19934 (clobber (match_dup 4))
19935 (clobber (match_dup 5))
19936 (clobber (reg:CC FLAGS_REG))])])
19938 ;; Load and add the thread base pointer from %<tp_seg>:0.
19939 (define_expand "get_thread_pointer<mode>"
19940 [(set (match_operand:PTR 0 "register_operand")
19941 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
19944 /* targetm is not visible in the scope of the condition. */
19945 if (!targetm.have_tls)
19946 error ("%<__builtin_thread_pointer%> is not supported on this target");
19949 (define_insn_and_split "*load_tp_<mode>"
19950 [(set (match_operand:PTR 0 "register_operand" "=r")
19951 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
19955 [(set (match_dup 0)
19958 addr_space_t as = DEFAULT_TLS_SEG_REG;
19960 operands[1] = gen_const_mem (<MODE>mode, const0_rtx);
19961 set_mem_addr_space (operands[1], as);
19964 (define_insn_and_split "*load_tp_x32_zext"
19965 [(set (match_operand:DI 0 "register_operand" "=r")
19967 (unspec:SI [(const_int 0)] UNSPEC_TP)))]
19971 [(set (match_dup 0)
19972 (zero_extend:DI (match_dup 1)))]
19974 addr_space_t as = DEFAULT_TLS_SEG_REG;
19976 operands[1] = gen_const_mem (SImode, const0_rtx);
19977 set_mem_addr_space (operands[1], as);
19980 (define_insn_and_split "*add_tp_<mode>"
19981 [(set (match_operand:PTR 0 "register_operand" "=r")
19983 (unspec:PTR [(const_int 0)] UNSPEC_TP)
19984 (match_operand:PTR 1 "register_operand" "0")))
19985 (clobber (reg:CC FLAGS_REG))]
19990 [(set (match_dup 0)
19991 (plus:PTR (match_dup 1) (match_dup 2)))
19992 (clobber (reg:CC FLAGS_REG))])]
19994 addr_space_t as = DEFAULT_TLS_SEG_REG;
19996 operands[2] = gen_const_mem (<MODE>mode, const0_rtx);
19997 set_mem_addr_space (operands[2], as);
20000 (define_insn_and_split "*add_tp_x32_zext"
20001 [(set (match_operand:DI 0 "register_operand" "=r")
20003 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
20004 (match_operand:SI 1 "register_operand" "0"))))
20005 (clobber (reg:CC FLAGS_REG))]
20010 [(set (match_dup 0)
20012 (plus:SI (match_dup 1) (match_dup 2))))
20013 (clobber (reg:CC FLAGS_REG))])]
20015 addr_space_t as = DEFAULT_TLS_SEG_REG;
20017 operands[2] = gen_const_mem (SImode, const0_rtx);
20018 set_mem_addr_space (operands[2], as);
20021 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
20022 ;; %rax as destination of the initial executable code sequence.
20023 (define_insn "tls_initial_exec_64_sun"
20024 [(set (match_operand:DI 0 "register_operand" "=a")
20026 [(match_operand 1 "tls_symbolic_operand")]
20027 UNSPEC_TLS_IE_SUN))
20028 (clobber (reg:CC FLAGS_REG))]
20029 "TARGET_64BIT && TARGET_SUN_TLS"
20032 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
20033 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
20035 [(set_attr "type" "multi")])
20037 ;; GNU2 TLS patterns can be split.
20039 (define_expand "tls_dynamic_gnu2_32"
20040 [(set (match_dup 3)
20041 (plus:SI (match_operand:SI 2 "register_operand")
20043 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
20046 [(set (match_operand:SI 0 "register_operand")
20047 (unspec:SI [(match_dup 1) (match_dup 3)
20048 (match_dup 2) (reg:SI SP_REG)]
20050 (clobber (reg:CC FLAGS_REG))])]
20051 "!TARGET_64BIT && TARGET_GNU2_TLS"
20053 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
20054 ix86_tls_descriptor_calls_expanded_in_cfun = true;
20057 (define_insn "*tls_dynamic_gnu2_lea_32"
20058 [(set (match_operand:SI 0 "register_operand" "=r")
20059 (plus:SI (match_operand:SI 1 "register_operand" "b")
20061 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
20062 UNSPEC_TLSDESC))))]
20063 "!TARGET_64BIT && TARGET_GNU2_TLS"
20064 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
20065 [(set_attr "type" "lea")
20066 (set_attr "mode" "SI")
20067 (set_attr "length" "6")
20068 (set_attr "length_address" "4")])
20070 (define_insn "*tls_dynamic_gnu2_call_32"
20071 [(set (match_operand:SI 0 "register_operand" "=a")
20072 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
20073 (match_operand:SI 2 "register_operand" "0")
20074 ;; we have to make sure %ebx still points to the GOT
20075 (match_operand:SI 3 "register_operand" "b")
20078 (clobber (reg:CC FLAGS_REG))]
20079 "!TARGET_64BIT && TARGET_GNU2_TLS"
20080 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
20081 [(set_attr "type" "call")
20082 (set_attr "length" "2")
20083 (set_attr "length_address" "0")])
20085 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
20086 [(set (match_operand:SI 0 "register_operand" "=&a")
20088 (unspec:SI [(match_operand 3 "tls_modbase_operand")
20089 (match_operand:SI 4)
20090 (match_operand:SI 2 "register_operand" "b")
20093 (const:SI (unspec:SI
20094 [(match_operand 1 "tls_symbolic_operand")]
20096 (clobber (reg:CC FLAGS_REG))]
20097 "!TARGET_64BIT && TARGET_GNU2_TLS"
20100 [(set (match_dup 0) (match_dup 5))]
20102 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
20103 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
20106 (define_expand "@tls_dynamic_gnu2_64_<mode>"
20107 [(set (match_dup 2)
20108 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")]
20111 [(set (match_operand:PTR 0 "register_operand")
20112 (unspec:PTR [(match_dup 1) (match_dup 2) (reg:PTR SP_REG)]
20114 (clobber (reg:CC FLAGS_REG))])]
20115 "TARGET_64BIT && TARGET_GNU2_TLS"
20117 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (ptr_mode) : operands[0];
20118 ix86_tls_descriptor_calls_expanded_in_cfun = true;
20121 (define_insn "*tls_dynamic_gnu2_lea_64_<mode>"
20122 [(set (match_operand:PTR 0 "register_operand" "=r")
20123 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")]
20125 "TARGET_64BIT && TARGET_GNU2_TLS"
20126 "lea%z0\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
20127 [(set_attr "type" "lea")
20128 (set_attr "mode" "<MODE>")
20129 (set_attr "length" "7")
20130 (set_attr "length_address" "4")])
20132 (define_insn "*tls_dynamic_gnu2_call_64_<mode>"
20133 [(set (match_operand:PTR 0 "register_operand" "=a")
20134 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")
20135 (match_operand:PTR 2 "register_operand" "0")
20138 (clobber (reg:CC FLAGS_REG))]
20139 "TARGET_64BIT && TARGET_GNU2_TLS"
20140 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
20141 [(set_attr "type" "call")
20142 (set_attr "length" "2")
20143 (set_attr "length_address" "0")])
20145 (define_insn_and_split "*tls_dynamic_gnu2_combine_64_<mode>"
20146 [(set (match_operand:PTR 0 "register_operand" "=&a")
20148 (unspec:PTR [(match_operand 2 "tls_modbase_operand")
20149 (match_operand:PTR 3)
20152 (const:PTR (unspec:PTR
20153 [(match_operand 1 "tls_symbolic_operand")]
20155 (clobber (reg:CC FLAGS_REG))]
20156 "TARGET_64BIT && TARGET_GNU2_TLS"
20159 [(set (match_dup 0) (match_dup 4))]
20161 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (ptr_mode) : operands[0];
20162 emit_insn (gen_tls_dynamic_gnu2_64 (ptr_mode, operands[4], operands[1]));
20166 [(match_operand 0 "tls_address_pattern")]
20167 "TARGET_TLS_DIRECT_SEG_REFS"
20169 "operands[0] = ix86_rewrite_tls_address (operands[0]);")
20172 ;; These patterns match the binary 387 instructions for addM3, subM3,
20173 ;; mulM3 and divM3. There are three patterns for each of DFmode and
20174 ;; SFmode. The first is the normal insn, the second the same insn but
20175 ;; with one operand a conversion, and the third the same insn but with
20176 ;; the other operand a conversion. The conversion may be SFmode or
20177 ;; SImode if the target mode DFmode, but only SImode if the target mode
20180 ;; Gcc is slightly more smart about handling normal two address instructions
20181 ;; so use special patterns for add and mull.
20183 (define_insn "*fop_xf_comm_i387"
20184 [(set (match_operand:XF 0 "register_operand" "=f")
20185 (match_operator:XF 3 "binary_fp_operator"
20186 [(match_operand:XF 1 "register_operand" "%0")
20187 (match_operand:XF 2 "register_operand" "f")]))]
20189 && COMMUTATIVE_ARITH_P (operands[3])"
20190 "* return output_387_binary_op (insn, operands);"
20191 [(set (attr "type")
20192 (if_then_else (match_operand:XF 3 "mult_operator")
20193 (const_string "fmul")
20194 (const_string "fop")))
20195 (set_attr "mode" "XF")])
20197 (define_insn "*fop_<mode>_comm"
20198 [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
20199 (match_operator:MODEF 3 "binary_fp_operator"
20200 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
20201 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
20202 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20203 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
20204 && COMMUTATIVE_ARITH_P (operands[3])
20205 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
20206 "* return output_387_binary_op (insn, operands);"
20207 [(set (attr "type")
20208 (if_then_else (eq_attr "alternative" "1,2")
20209 (if_then_else (match_operand:MODEF 3 "mult_operator")
20210 (const_string "ssemul")
20211 (const_string "sseadd"))
20212 (if_then_else (match_operand:MODEF 3 "mult_operator")
20213 (const_string "fmul")
20214 (const_string "fop"))))
20215 (set_attr "isa" "*,noavx,avx")
20216 (set_attr "prefix" "orig,orig,vex")
20217 (set_attr "mode" "<MODE>")
20218 (set (attr "enabled")
20220 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
20222 (eq_attr "alternative" "0")
20223 (symbol_ref "TARGET_MIX_SSE_I387
20224 && X87_ENABLE_ARITH (<MODE>mode)")
20225 (const_string "*"))
20227 (eq_attr "alternative" "0")
20228 (symbol_ref "true")
20229 (symbol_ref "false"))))])
20231 (define_insn "*<insn>hf"
20232 [(set (match_operand:HF 0 "register_operand" "=v")
20233 (plusminusmultdiv:HF
20234 (match_operand:HF 1 "nonimmediate_operand" "<comm>v")
20235 (match_operand:HF 2 "nonimmediate_operand" "vm")))]
20237 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
20238 "v<insn>sh\t{%2, %1, %0|%0, %1, %2}"
20239 [(set_attr "prefix" "evex")
20240 (set_attr "mode" "HF")])
20242 (define_insn "*rcpsf2_sse"
20243 [(set (match_operand:SF 0 "register_operand" "=x,x,x,x")
20244 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m,ja")]
20246 "TARGET_SSE && TARGET_SSE_MATH"
20248 %vrcpss\t{%d1, %0|%0, %d1}
20249 %vrcpss\t{%d1, %0|%0, %d1}
20250 rcpss\t{%1, %d0|%d0, %1}
20251 vrcpss\t{%1, %d0|%d0, %1}"
20252 [(set_attr "isa" "*,*,noavx,avx")
20253 (set_attr "addr" "*,*,*,gpr16")
20254 (set_attr "type" "sse")
20255 (set_attr "atom_sse_attr" "rcp")
20256 (set_attr "btver2_sse_attr" "rcp")
20257 (set_attr "prefix" "maybe_vex")
20258 (set_attr "mode" "SF")
20259 (set_attr "avx_partial_xmm_update" "false,false,true,true")
20260 (set (attr "preferred_for_speed")
20261 (cond [(match_test "TARGET_AVX")
20262 (symbol_ref "true")
20263 (eq_attr "alternative" "1,2,3")
20264 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
20266 (symbol_ref "true")))])
20268 (define_insn "rcphf2"
20269 [(set (match_operand:HF 0 "register_operand" "=v,v")
20270 (unspec:HF [(match_operand:HF 1 "nonimmediate_operand" "v,m")]
20272 "TARGET_AVX512FP16"
20274 vrcpsh\t{%d1, %0|%0, %d1}
20275 vrcpsh\t{%1, %d0|%d0, %1}"
20276 [(set_attr "type" "sse")
20277 (set_attr "prefix" "evex")
20278 (set_attr "mode" "HF")
20279 (set_attr "avx_partial_xmm_update" "false,true")])
20281 (define_insn "*fop_xf_1_i387"
20282 [(set (match_operand:XF 0 "register_operand" "=f,f")
20283 (match_operator:XF 3 "binary_fp_operator"
20284 [(match_operand:XF 1 "register_operand" "0,f")
20285 (match_operand:XF 2 "register_operand" "f,0")]))]
20287 && !COMMUTATIVE_ARITH_P (operands[3])"
20288 "* return output_387_binary_op (insn, operands);"
20289 [(set (attr "type")
20290 (if_then_else (match_operand:XF 3 "div_operator")
20291 (const_string "fdiv")
20292 (const_string "fop")))
20293 (set_attr "mode" "XF")])
20295 (define_insn "*fop_<mode>_1"
20296 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
20297 (match_operator:MODEF 3 "binary_fp_operator"
20298 [(match_operand:MODEF 1
20299 "x87nonimm_ssenomem_operand" "0,fm,0,v")
20300 (match_operand:MODEF 2
20301 "nonimmediate_operand" "fm,0,xm,vm")]))]
20302 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20303 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
20304 && !COMMUTATIVE_ARITH_P (operands[3])
20305 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
20306 "* return output_387_binary_op (insn, operands);"
20307 [(set (attr "type")
20308 (if_then_else (eq_attr "alternative" "2,3")
20309 (if_then_else (match_operand:MODEF 3 "div_operator")
20310 (const_string "ssediv")
20311 (const_string "sseadd"))
20312 (if_then_else (match_operand:MODEF 3 "div_operator")
20313 (const_string "fdiv")
20314 (const_string "fop"))))
20315 (set_attr "isa" "*,*,noavx,avx")
20316 (set_attr "prefix" "orig,orig,orig,vex")
20317 (set_attr "mode" "<MODE>")
20318 (set (attr "enabled")
20320 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
20322 (eq_attr "alternative" "0,1")
20323 (symbol_ref "TARGET_MIX_SSE_I387
20324 && X87_ENABLE_ARITH (<MODE>mode)")
20325 (const_string "*"))
20327 (eq_attr "alternative" "0,1")
20328 (symbol_ref "true")
20329 (symbol_ref "false"))))])
20331 (define_insn "*fop_<X87MODEF:mode>_2_i387"
20332 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
20333 (match_operator:X87MODEF 3 "binary_fp_operator"
20335 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
20336 (match_operand:X87MODEF 2 "register_operand" "0")]))]
20337 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
20338 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
20339 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
20340 || optimize_function_for_size_p (cfun))"
20341 "* return output_387_binary_op (insn, operands);"
20342 [(set (attr "type")
20343 (cond [(match_operand:X87MODEF 3 "mult_operator")
20344 (const_string "fmul")
20345 (match_operand:X87MODEF 3 "div_operator")
20346 (const_string "fdiv")
20348 (const_string "fop")))
20349 (set_attr "fp_int_src" "true")
20350 (set_attr "mode" "<SWI24:MODE>")])
20352 (define_insn "*fop_<X87MODEF:mode>_3_i387"
20353 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
20354 (match_operator:X87MODEF 3 "binary_fp_operator"
20355 [(match_operand:X87MODEF 1 "register_operand" "0")
20357 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
20358 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
20359 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
20360 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
20361 || optimize_function_for_size_p (cfun))"
20362 "* return output_387_binary_op (insn, operands);"
20363 [(set (attr "type")
20364 (cond [(match_operand:X87MODEF 3 "mult_operator")
20365 (const_string "fmul")
20366 (match_operand:X87MODEF 3 "div_operator")
20367 (const_string "fdiv")
20369 (const_string "fop")))
20370 (set_attr "fp_int_src" "true")
20371 (set_attr "mode" "<SWI24:MODE>")])
20373 (define_insn "*fop_xf_4_i387"
20374 [(set (match_operand:XF 0 "register_operand" "=f,f")
20375 (match_operator:XF 3 "binary_fp_operator"
20377 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
20378 (match_operand:XF 2 "register_operand" "0,f")]))]
20380 "* return output_387_binary_op (insn, operands);"
20381 [(set (attr "type")
20382 (cond [(match_operand:XF 3 "mult_operator")
20383 (const_string "fmul")
20384 (match_operand:XF 3 "div_operator")
20385 (const_string "fdiv")
20387 (const_string "fop")))
20388 (set_attr "mode" "<MODE>")])
20390 (define_insn "*fop_df_4_i387"
20391 [(set (match_operand:DF 0 "register_operand" "=f,f")
20392 (match_operator:DF 3 "binary_fp_operator"
20394 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
20395 (match_operand:DF 2 "register_operand" "0,f")]))]
20396 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
20397 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
20398 "* return output_387_binary_op (insn, operands);"
20399 [(set (attr "type")
20400 (cond [(match_operand:DF 3 "mult_operator")
20401 (const_string "fmul")
20402 (match_operand:DF 3 "div_operator")
20403 (const_string "fdiv")
20405 (const_string "fop")))
20406 (set_attr "mode" "SF")])
20408 (define_insn "*fop_xf_5_i387"
20409 [(set (match_operand:XF 0 "register_operand" "=f,f")
20410 (match_operator:XF 3 "binary_fp_operator"
20411 [(match_operand:XF 1 "register_operand" "0,f")
20413 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
20415 "* return output_387_binary_op (insn, operands);"
20416 [(set (attr "type")
20417 (cond [(match_operand:XF 3 "mult_operator")
20418 (const_string "fmul")
20419 (match_operand:XF 3 "div_operator")
20420 (const_string "fdiv")
20422 (const_string "fop")))
20423 (set_attr "mode" "<MODE>")])
20425 (define_insn "*fop_df_5_i387"
20426 [(set (match_operand:DF 0 "register_operand" "=f,f")
20427 (match_operator:DF 3 "binary_fp_operator"
20428 [(match_operand:DF 1 "register_operand" "0,f")
20430 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
20431 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
20432 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
20433 "* return output_387_binary_op (insn, operands);"
20434 [(set (attr "type")
20435 (cond [(match_operand:DF 3 "mult_operator")
20436 (const_string "fmul")
20437 (match_operand:DF 3 "div_operator")
20438 (const_string "fdiv")
20440 (const_string "fop")))
20441 (set_attr "mode" "SF")])
20443 (define_insn "*fop_xf_6_i387"
20444 [(set (match_operand:XF 0 "register_operand" "=f,f")
20445 (match_operator:XF 3 "binary_fp_operator"
20447 (match_operand:MODEF 1 "register_operand" "0,f"))
20449 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
20451 "* return output_387_binary_op (insn, operands);"
20452 [(set (attr "type")
20453 (cond [(match_operand:XF 3 "mult_operator")
20454 (const_string "fmul")
20455 (match_operand:XF 3 "div_operator")
20456 (const_string "fdiv")
20458 (const_string "fop")))
20459 (set_attr "mode" "<MODE>")])
20461 (define_insn "*fop_df_6_i387"
20462 [(set (match_operand:DF 0 "register_operand" "=f,f")
20463 (match_operator:DF 3 "binary_fp_operator"
20465 (match_operand:SF 1 "register_operand" "0,f"))
20467 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
20468 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
20469 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
20470 "* return output_387_binary_op (insn, operands);"
20471 [(set (attr "type")
20472 (cond [(match_operand:DF 3 "mult_operator")
20473 (const_string "fmul")
20474 (match_operand:DF 3 "div_operator")
20475 (const_string "fdiv")
20477 (const_string "fop")))
20478 (set_attr "mode" "SF")])
20480 ;; FPU special functions.
20482 ;; This pattern implements a no-op XFmode truncation for
20483 ;; all fancy i386 XFmode math functions.
20485 (define_insn "truncxf<mode>2_i387_noop_unspec"
20486 [(set (match_operand:MODEF 0 "nonimmediate_operand" "=mf")
20487 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
20488 UNSPEC_TRUNC_NOOP))]
20489 "TARGET_USE_FANCY_MATH_387"
20490 "* return output_387_reg_move (insn, operands);"
20491 [(set_attr "type" "fmov")
20492 (set_attr "mode" "<MODE>")])
20494 (define_insn "sqrtxf2"
20495 [(set (match_operand:XF 0 "register_operand" "=f")
20496 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
20497 "TARGET_USE_FANCY_MATH_387"
20499 [(set_attr "type" "fpspc")
20500 (set_attr "mode" "XF")
20501 (set_attr "athlon_decode" "direct")
20502 (set_attr "amdfam10_decode" "direct")
20503 (set_attr "bdver1_decode" "direct")])
20505 (define_insn "*rsqrtsf2_sse"
20506 [(set (match_operand:SF 0 "register_operand" "=x,x,x,x")
20507 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m,ja")]
20509 "TARGET_SSE && TARGET_SSE_MATH"
20511 %vrsqrtss\t{%d1, %0|%0, %d1}
20512 %vrsqrtss\t{%d1, %0|%0, %d1}
20513 rsqrtss\t{%1, %d0|%d0, %1}
20514 vrsqrtss\t{%1, %d0|%d0, %1}"
20515 [(set_attr "isa" "*,*,noavx,avx")
20516 (set_attr "addr" "*,*,*,gpr16")
20517 (set_attr "type" "sse")
20518 (set_attr "atom_sse_attr" "rcp")
20519 (set_attr "btver2_sse_attr" "rcp")
20520 (set_attr "prefix" "maybe_vex")
20521 (set_attr "mode" "SF")
20522 (set_attr "avx_partial_xmm_update" "false,false,true,true")
20523 (set (attr "preferred_for_speed")
20524 (cond [(match_test "TARGET_AVX")
20525 (symbol_ref "true")
20526 (eq_attr "alternative" "1,2,3")
20527 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
20529 (symbol_ref "true")))])
20531 (define_expand "rsqrtsf2"
20532 [(set (match_operand:SF 0 "register_operand")
20533 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
20535 "TARGET_SSE && TARGET_SSE_MATH"
20537 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
20541 (define_insn "rsqrthf2"
20542 [(set (match_operand:HF 0 "register_operand" "=v,v")
20543 (unspec:HF [(match_operand:HF 1 "nonimmediate_operand" "v,m")]
20545 "TARGET_AVX512FP16"
20547 vrsqrtsh\t{%d1, %0|%0, %d1}
20548 vrsqrtsh\t{%1, %d0|%d0, %1}"
20549 [(set_attr "type" "sse")
20550 (set_attr "prefix" "evex")
20551 (set_attr "avx_partial_xmm_update" "false,true")
20552 (set_attr "mode" "HF")])
20554 (define_insn "sqrthf2"
20555 [(set (match_operand:HF 0 "register_operand" "=v,v")
20557 (match_operand:HF 1 "nonimmediate_operand" "v,m")))]
20558 "TARGET_AVX512FP16"
20560 vsqrtsh\t{%d1, %0|%0, %d1}
20561 vsqrtsh\t{%1, %d0|%d0, %1}"
20562 [(set_attr "type" "sse")
20563 (set_attr "prefix" "evex")
20564 (set_attr "avx_partial_xmm_update" "false,true")
20565 (set_attr "mode" "HF")])
20567 (define_insn "*sqrt<mode>2_sse"
20568 [(set (match_operand:MODEF 0 "register_operand" "=v,v,v")
20570 (match_operand:MODEF 1 "nonimmediate_operand" "0,v,m")))]
20571 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20573 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
20574 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
20575 %vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
20576 [(set_attr "type" "sse")
20577 (set_attr "atom_sse_attr" "sqrt")
20578 (set_attr "btver2_sse_attr" "sqrt")
20579 (set_attr "prefix" "maybe_vex")
20580 (set_attr "avx_partial_xmm_update" "false,false,true")
20581 (set_attr "mode" "<MODE>")
20582 (set (attr "preferred_for_speed")
20583 (cond [(match_test "TARGET_AVX")
20584 (symbol_ref "true")
20585 (eq_attr "alternative" "1,2")
20586 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
20588 (symbol_ref "true")))])
20590 (define_expand "sqrt<mode>2"
20591 [(set (match_operand:MODEF 0 "register_operand")
20593 (match_operand:MODEF 1 "nonimmediate_operand")))]
20594 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
20595 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
20597 if (<MODE>mode == SFmode
20598 && TARGET_SSE && TARGET_SSE_MATH
20599 && TARGET_RECIP_SQRT
20600 && !optimize_function_for_size_p (cfun)
20601 && flag_finite_math_only && !flag_trapping_math
20602 && flag_unsafe_math_optimizations)
20604 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
20608 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
20610 rtx op0 = gen_reg_rtx (XFmode);
20611 rtx op1 = gen_reg_rtx (XFmode);
20613 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20614 emit_insn (gen_sqrtxf2 (op0, op1));
20615 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
20620 (define_expand "hypot<mode>3"
20621 [(use (match_operand:MODEF 0 "register_operand"))
20622 (use (match_operand:MODEF 1 "general_operand"))
20623 (use (match_operand:MODEF 2 "general_operand"))]
20624 "TARGET_USE_FANCY_MATH_387
20625 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20626 || TARGET_MIX_SSE_I387)
20627 && flag_finite_math_only
20628 && flag_unsafe_math_optimizations"
20630 rtx op0 = gen_reg_rtx (XFmode);
20631 rtx op1 = gen_reg_rtx (XFmode);
20632 rtx op2 = gen_reg_rtx (XFmode);
20634 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20635 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20637 emit_insn (gen_mulxf3 (op1, op1, op1));
20638 emit_insn (gen_mulxf3 (op2, op2, op2));
20639 emit_insn (gen_addxf3 (op0, op2, op1));
20640 emit_insn (gen_sqrtxf2 (op0, op0));
20642 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20646 (define_insn "x86_fnstsw_1"
20647 [(set (match_operand:HI 0 "register_operand" "=a")
20648 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
20651 [(set_attr "length" "2")
20652 (set_attr "mode" "SI")
20653 (set_attr "unit" "i387")])
20655 (define_insn "fpremxf4_i387"
20656 [(set (match_operand:XF 0 "register_operand" "=f")
20657 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
20658 (match_operand:XF 3 "register_operand" "1")]
20660 (set (match_operand:XF 1 "register_operand" "=f")
20661 (unspec:XF [(match_dup 2) (match_dup 3)]
20663 (set (reg:CCFP FPSR_REG)
20664 (unspec:CCFP [(match_dup 2) (match_dup 3)]
20666 "TARGET_USE_FANCY_MATH_387"
20668 [(set_attr "type" "fpspc")
20669 (set_attr "znver1_decode" "vector")
20670 (set_attr "mode" "XF")])
20672 (define_expand "fmodxf3"
20673 [(use (match_operand:XF 0 "register_operand"))
20674 (use (match_operand:XF 1 "general_operand"))
20675 (use (match_operand:XF 2 "general_operand"))]
20676 "TARGET_USE_FANCY_MATH_387"
20678 rtx_code_label *label = gen_label_rtx ();
20680 rtx op1 = gen_reg_rtx (XFmode);
20681 rtx op2 = gen_reg_rtx (XFmode);
20683 emit_move_insn (op2, operands[2]);
20684 emit_move_insn (op1, operands[1]);
20686 emit_label (label);
20687 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
20688 ix86_emit_fp_unordered_jump (label);
20689 LABEL_NUSES (label) = 1;
20691 emit_move_insn (operands[0], op1);
20695 (define_expand "fmod<mode>3"
20696 [(use (match_operand:MODEF 0 "register_operand"))
20697 (use (match_operand:MODEF 1 "general_operand"))
20698 (use (match_operand:MODEF 2 "general_operand"))]
20699 "TARGET_USE_FANCY_MATH_387"
20701 rtx (*gen_truncxf) (rtx, rtx);
20703 rtx_code_label *label = gen_label_rtx ();
20705 rtx op1 = gen_reg_rtx (XFmode);
20706 rtx op2 = gen_reg_rtx (XFmode);
20708 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20709 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20711 emit_label (label);
20712 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
20713 ix86_emit_fp_unordered_jump (label);
20714 LABEL_NUSES (label) = 1;
20716 /* Truncate the result properly for strict SSE math. */
20717 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
20718 && !TARGET_MIX_SSE_I387)
20719 gen_truncxf = gen_truncxf<mode>2;
20721 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
20723 emit_insn (gen_truncxf (operands[0], op1));
20727 (define_insn "fprem1xf4_i387"
20728 [(set (match_operand:XF 0 "register_operand" "=f")
20729 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
20730 (match_operand:XF 3 "register_operand" "1")]
20732 (set (match_operand:XF 1 "register_operand" "=f")
20733 (unspec:XF [(match_dup 2) (match_dup 3)]
20735 (set (reg:CCFP FPSR_REG)
20736 (unspec:CCFP [(match_dup 2) (match_dup 3)]
20738 "TARGET_USE_FANCY_MATH_387"
20740 [(set_attr "type" "fpspc")
20741 (set_attr "znver1_decode" "vector")
20742 (set_attr "mode" "XF")])
20744 (define_expand "remainderxf3"
20745 [(use (match_operand:XF 0 "register_operand"))
20746 (use (match_operand:XF 1 "general_operand"))
20747 (use (match_operand:XF 2 "general_operand"))]
20748 "TARGET_USE_FANCY_MATH_387"
20750 rtx_code_label *label = gen_label_rtx ();
20752 rtx op1 = gen_reg_rtx (XFmode);
20753 rtx op2 = gen_reg_rtx (XFmode);
20755 emit_move_insn (op2, operands[2]);
20756 emit_move_insn (op1, operands[1]);
20758 emit_label (label);
20759 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
20760 ix86_emit_fp_unordered_jump (label);
20761 LABEL_NUSES (label) = 1;
20763 emit_move_insn (operands[0], op1);
20767 (define_expand "remainder<mode>3"
20768 [(use (match_operand:MODEF 0 "register_operand"))
20769 (use (match_operand:MODEF 1 "general_operand"))
20770 (use (match_operand:MODEF 2 "general_operand"))]
20771 "TARGET_USE_FANCY_MATH_387"
20773 rtx (*gen_truncxf) (rtx, rtx);
20775 rtx_code_label *label = gen_label_rtx ();
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_label (label);
20785 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
20786 ix86_emit_fp_unordered_jump (label);
20787 LABEL_NUSES (label) = 1;
20789 /* Truncate the result properly for strict SSE math. */
20790 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
20791 && !TARGET_MIX_SSE_I387)
20792 gen_truncxf = gen_truncxf<mode>2;
20794 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
20796 emit_insn (gen_truncxf (operands[0], op1));
20800 (define_int_iterator SINCOS
20804 (define_int_attr sincos
20805 [(UNSPEC_SIN "sin")
20806 (UNSPEC_COS "cos")])
20808 (define_insn "<sincos>xf2"
20809 [(set (match_operand:XF 0 "register_operand" "=f")
20810 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
20812 "TARGET_USE_FANCY_MATH_387
20813 && flag_unsafe_math_optimizations"
20815 [(set_attr "type" "fpspc")
20816 (set_attr "znver1_decode" "vector")
20817 (set_attr "mode" "XF")])
20819 (define_expand "<sincos><mode>2"
20820 [(set (match_operand:MODEF 0 "register_operand")
20821 (unspec:MODEF [(match_operand:MODEF 1 "general_operand")]
20823 "TARGET_USE_FANCY_MATH_387
20824 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20825 || TARGET_MIX_SSE_I387)
20826 && flag_unsafe_math_optimizations"
20828 rtx op0 = gen_reg_rtx (XFmode);
20829 rtx op1 = gen_reg_rtx (XFmode);
20831 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20832 emit_insn (gen_<sincos>xf2 (op0, op1));
20833 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20837 (define_insn "sincosxf3"
20838 [(set (match_operand:XF 0 "register_operand" "=f")
20839 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
20840 UNSPEC_SINCOS_COS))
20841 (set (match_operand:XF 1 "register_operand" "=f")
20842 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
20843 "TARGET_USE_FANCY_MATH_387
20844 && flag_unsafe_math_optimizations"
20846 [(set_attr "type" "fpspc")
20847 (set_attr "znver1_decode" "vector")
20848 (set_attr "mode" "XF")])
20850 (define_expand "sincos<mode>3"
20851 [(use (match_operand:MODEF 0 "register_operand"))
20852 (use (match_operand:MODEF 1 "register_operand"))
20853 (use (match_operand:MODEF 2 "general_operand"))]
20854 "TARGET_USE_FANCY_MATH_387
20855 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20856 || TARGET_MIX_SSE_I387)
20857 && flag_unsafe_math_optimizations"
20859 rtx op0 = gen_reg_rtx (XFmode);
20860 rtx op1 = gen_reg_rtx (XFmode);
20861 rtx op2 = gen_reg_rtx (XFmode);
20863 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20864 emit_insn (gen_sincosxf3 (op0, op1, op2));
20865 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20866 emit_insn (gen_truncxf<mode>2 (operands[1], op1));
20870 (define_insn "fptanxf4_i387"
20871 [(set (match_operand:SF 0 "register_operand" "=f")
20872 (match_operand:SF 3 "const1_operand"))
20873 (set (match_operand:XF 1 "register_operand" "=f")
20874 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
20876 "TARGET_USE_FANCY_MATH_387
20877 && flag_unsafe_math_optimizations"
20879 [(set_attr "type" "fpspc")
20880 (set_attr "znver1_decode" "vector")
20881 (set_attr "mode" "XF")])
20883 (define_expand "tanxf2"
20884 [(use (match_operand:XF 0 "register_operand"))
20885 (use (match_operand:XF 1 "register_operand"))]
20886 "TARGET_USE_FANCY_MATH_387
20887 && flag_unsafe_math_optimizations"
20889 rtx one = gen_reg_rtx (SFmode);
20890 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1],
20891 CONST1_RTX (SFmode)));
20895 (define_expand "tan<mode>2"
20896 [(use (match_operand:MODEF 0 "register_operand"))
20897 (use (match_operand:MODEF 1 "general_operand"))]
20898 "TARGET_USE_FANCY_MATH_387
20899 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20900 || TARGET_MIX_SSE_I387)
20901 && flag_unsafe_math_optimizations"
20903 rtx op0 = gen_reg_rtx (XFmode);
20904 rtx op1 = gen_reg_rtx (XFmode);
20906 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20907 emit_insn (gen_tanxf2 (op0, op1));
20908 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20912 (define_insn "atan2xf3"
20913 [(set (match_operand:XF 0 "register_operand" "=f")
20914 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
20915 (match_operand:XF 1 "register_operand" "f")]
20917 (clobber (match_scratch:XF 3 "=1"))]
20918 "TARGET_USE_FANCY_MATH_387
20919 && flag_unsafe_math_optimizations"
20921 [(set_attr "type" "fpspc")
20922 (set_attr "znver1_decode" "vector")
20923 (set_attr "mode" "XF")])
20925 (define_expand "atan2<mode>3"
20926 [(use (match_operand:MODEF 0 "register_operand"))
20927 (use (match_operand:MODEF 1 "general_operand"))
20928 (use (match_operand:MODEF 2 "general_operand"))]
20929 "TARGET_USE_FANCY_MATH_387
20930 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20931 || TARGET_MIX_SSE_I387)
20932 && flag_unsafe_math_optimizations"
20934 rtx op0 = gen_reg_rtx (XFmode);
20935 rtx op1 = gen_reg_rtx (XFmode);
20936 rtx op2 = gen_reg_rtx (XFmode);
20938 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20939 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20941 emit_insn (gen_atan2xf3 (op0, op1, op2));
20942 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20946 (define_expand "atanxf2"
20947 [(parallel [(set (match_operand:XF 0 "register_operand")
20948 (unspec:XF [(match_dup 2)
20949 (match_operand:XF 1 "register_operand")]
20951 (clobber (scratch:XF))])]
20952 "TARGET_USE_FANCY_MATH_387
20953 && flag_unsafe_math_optimizations"
20954 "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
20956 (define_expand "atan<mode>2"
20957 [(use (match_operand:MODEF 0 "register_operand"))
20958 (use (match_operand:MODEF 1 "general_operand"))]
20959 "TARGET_USE_FANCY_MATH_387
20960 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20961 || TARGET_MIX_SSE_I387)
20962 && flag_unsafe_math_optimizations"
20964 rtx op0 = gen_reg_rtx (XFmode);
20965 rtx op1 = gen_reg_rtx (XFmode);
20967 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20968 emit_insn (gen_atanxf2 (op0, op1));
20969 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20973 (define_expand "asinxf2"
20974 [(set (match_dup 2)
20975 (mult:XF (match_operand:XF 1 "register_operand")
20977 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
20978 (set (match_dup 5) (sqrt:XF (match_dup 4)))
20979 (parallel [(set (match_operand:XF 0 "register_operand")
20980 (unspec:XF [(match_dup 5) (match_dup 1)]
20982 (clobber (scratch:XF))])]
20983 "TARGET_USE_FANCY_MATH_387
20984 && flag_unsafe_math_optimizations"
20988 for (i = 2; i < 6; i++)
20989 operands[i] = gen_reg_rtx (XFmode);
20991 emit_move_insn (operands[3], CONST1_RTX (XFmode));
20994 (define_expand "asin<mode>2"
20995 [(use (match_operand:MODEF 0 "register_operand"))
20996 (use (match_operand:MODEF 1 "general_operand"))]
20997 "TARGET_USE_FANCY_MATH_387
20998 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20999 || TARGET_MIX_SSE_I387)
21000 && flag_unsafe_math_optimizations"
21002 rtx op0 = gen_reg_rtx (XFmode);
21003 rtx op1 = gen_reg_rtx (XFmode);
21005 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21006 emit_insn (gen_asinxf2 (op0, op1));
21007 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21011 (define_expand "acosxf2"
21012 [(set (match_dup 2)
21013 (mult:XF (match_operand:XF 1 "register_operand")
21015 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
21016 (set (match_dup 5) (sqrt:XF (match_dup 4)))
21017 (parallel [(set (match_operand:XF 0 "register_operand")
21018 (unspec:XF [(match_dup 1) (match_dup 5)]
21020 (clobber (scratch:XF))])]
21021 "TARGET_USE_FANCY_MATH_387
21022 && flag_unsafe_math_optimizations"
21026 for (i = 2; i < 6; i++)
21027 operands[i] = gen_reg_rtx (XFmode);
21029 emit_move_insn (operands[3], CONST1_RTX (XFmode));
21032 (define_expand "acos<mode>2"
21033 [(use (match_operand:MODEF 0 "register_operand"))
21034 (use (match_operand:MODEF 1 "general_operand"))]
21035 "TARGET_USE_FANCY_MATH_387
21036 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21037 || TARGET_MIX_SSE_I387)
21038 && flag_unsafe_math_optimizations"
21040 rtx op0 = gen_reg_rtx (XFmode);
21041 rtx op1 = gen_reg_rtx (XFmode);
21043 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21044 emit_insn (gen_acosxf2 (op0, op1));
21045 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21049 (define_expand "sinhxf2"
21050 [(use (match_operand:XF 0 "register_operand"))
21051 (use (match_operand:XF 1 "register_operand"))]
21052 "TARGET_USE_FANCY_MATH_387
21053 && flag_finite_math_only
21054 && flag_unsafe_math_optimizations"
21056 ix86_emit_i387_sinh (operands[0], operands[1]);
21060 (define_expand "sinh<mode>2"
21061 [(use (match_operand:MODEF 0 "register_operand"))
21062 (use (match_operand:MODEF 1 "general_operand"))]
21063 "TARGET_USE_FANCY_MATH_387
21064 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21065 || TARGET_MIX_SSE_I387)
21066 && flag_finite_math_only
21067 && flag_unsafe_math_optimizations"
21069 rtx op0 = gen_reg_rtx (XFmode);
21070 rtx op1 = gen_reg_rtx (XFmode);
21072 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21073 emit_insn (gen_sinhxf2 (op0, op1));
21074 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21078 (define_expand "coshxf2"
21079 [(use (match_operand:XF 0 "register_operand"))
21080 (use (match_operand:XF 1 "register_operand"))]
21081 "TARGET_USE_FANCY_MATH_387
21082 && flag_unsafe_math_optimizations"
21084 ix86_emit_i387_cosh (operands[0], operands[1]);
21088 (define_expand "cosh<mode>2"
21089 [(use (match_operand:MODEF 0 "register_operand"))
21090 (use (match_operand:MODEF 1 "general_operand"))]
21091 "TARGET_USE_FANCY_MATH_387
21092 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21093 || TARGET_MIX_SSE_I387)
21094 && flag_unsafe_math_optimizations"
21096 rtx op0 = gen_reg_rtx (XFmode);
21097 rtx op1 = gen_reg_rtx (XFmode);
21099 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21100 emit_insn (gen_coshxf2 (op0, op1));
21101 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21105 (define_expand "tanhxf2"
21106 [(use (match_operand:XF 0 "register_operand"))
21107 (use (match_operand:XF 1 "register_operand"))]
21108 "TARGET_USE_FANCY_MATH_387
21109 && flag_unsafe_math_optimizations"
21111 ix86_emit_i387_tanh (operands[0], operands[1]);
21115 (define_expand "tanh<mode>2"
21116 [(use (match_operand:MODEF 0 "register_operand"))
21117 (use (match_operand:MODEF 1 "general_operand"))]
21118 "TARGET_USE_FANCY_MATH_387
21119 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21120 || TARGET_MIX_SSE_I387)
21121 && flag_unsafe_math_optimizations"
21123 rtx op0 = gen_reg_rtx (XFmode);
21124 rtx op1 = gen_reg_rtx (XFmode);
21126 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21127 emit_insn (gen_tanhxf2 (op0, op1));
21128 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21132 (define_expand "asinhxf2"
21133 [(use (match_operand:XF 0 "register_operand"))
21134 (use (match_operand:XF 1 "register_operand"))]
21135 "TARGET_USE_FANCY_MATH_387
21136 && flag_finite_math_only
21137 && flag_unsafe_math_optimizations"
21139 ix86_emit_i387_asinh (operands[0], operands[1]);
21143 (define_expand "asinh<mode>2"
21144 [(use (match_operand:MODEF 0 "register_operand"))
21145 (use (match_operand:MODEF 1 "general_operand"))]
21146 "TARGET_USE_FANCY_MATH_387
21147 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21148 || TARGET_MIX_SSE_I387)
21149 && flag_finite_math_only
21150 && flag_unsafe_math_optimizations"
21152 rtx op0 = gen_reg_rtx (XFmode);
21153 rtx op1 = gen_reg_rtx (XFmode);
21155 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21156 emit_insn (gen_asinhxf2 (op0, op1));
21157 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21161 (define_expand "acoshxf2"
21162 [(use (match_operand:XF 0 "register_operand"))
21163 (use (match_operand:XF 1 "register_operand"))]
21164 "TARGET_USE_FANCY_MATH_387
21165 && flag_unsafe_math_optimizations"
21167 ix86_emit_i387_acosh (operands[0], operands[1]);
21171 (define_expand "acosh<mode>2"
21172 [(use (match_operand:MODEF 0 "register_operand"))
21173 (use (match_operand:MODEF 1 "general_operand"))]
21174 "TARGET_USE_FANCY_MATH_387
21175 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21176 || TARGET_MIX_SSE_I387)
21177 && flag_unsafe_math_optimizations"
21179 rtx op0 = gen_reg_rtx (XFmode);
21180 rtx op1 = gen_reg_rtx (XFmode);
21182 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21183 emit_insn (gen_acoshxf2 (op0, op1));
21184 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21188 (define_expand "atanhxf2"
21189 [(use (match_operand:XF 0 "register_operand"))
21190 (use (match_operand:XF 1 "register_operand"))]
21191 "TARGET_USE_FANCY_MATH_387
21192 && flag_unsafe_math_optimizations"
21194 ix86_emit_i387_atanh (operands[0], operands[1]);
21198 (define_expand "atanh<mode>2"
21199 [(use (match_operand:MODEF 0 "register_operand"))
21200 (use (match_operand:MODEF 1 "general_operand"))]
21201 "TARGET_USE_FANCY_MATH_387
21202 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21203 || TARGET_MIX_SSE_I387)
21204 && flag_unsafe_math_optimizations"
21206 rtx op0 = gen_reg_rtx (XFmode);
21207 rtx op1 = gen_reg_rtx (XFmode);
21209 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21210 emit_insn (gen_atanhxf2 (op0, op1));
21211 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21215 (define_insn "fyl2xxf3_i387"
21216 [(set (match_operand:XF 0 "register_operand" "=f")
21217 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
21218 (match_operand:XF 2 "register_operand" "f")]
21220 (clobber (match_scratch:XF 3 "=2"))]
21221 "TARGET_USE_FANCY_MATH_387
21222 && flag_unsafe_math_optimizations"
21224 [(set_attr "type" "fpspc")
21225 (set_attr "znver1_decode" "vector")
21226 (set_attr "mode" "XF")])
21228 (define_expand "logxf2"
21229 [(parallel [(set (match_operand:XF 0 "register_operand")
21230 (unspec:XF [(match_operand:XF 1 "register_operand")
21231 (match_dup 2)] UNSPEC_FYL2X))
21232 (clobber (scratch:XF))])]
21233 "TARGET_USE_FANCY_MATH_387
21234 && flag_unsafe_math_optimizations"
21237 = force_reg (XFmode, standard_80387_constant_rtx (4)); /* fldln2 */
21240 (define_expand "log<mode>2"
21241 [(use (match_operand:MODEF 0 "register_operand"))
21242 (use (match_operand:MODEF 1 "general_operand"))]
21243 "TARGET_USE_FANCY_MATH_387
21244 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21245 || TARGET_MIX_SSE_I387)
21246 && flag_unsafe_math_optimizations"
21248 rtx op0 = gen_reg_rtx (XFmode);
21249 rtx op1 = gen_reg_rtx (XFmode);
21251 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21252 emit_insn (gen_logxf2 (op0, op1));
21253 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21257 (define_expand "log10xf2"
21258 [(parallel [(set (match_operand:XF 0 "register_operand")
21259 (unspec:XF [(match_operand:XF 1 "register_operand")
21260 (match_dup 2)] UNSPEC_FYL2X))
21261 (clobber (scratch:XF))])]
21262 "TARGET_USE_FANCY_MATH_387
21263 && flag_unsafe_math_optimizations"
21266 = force_reg (XFmode, standard_80387_constant_rtx (3)); /* fldlg2 */
21269 (define_expand "log10<mode>2"
21270 [(use (match_operand:MODEF 0 "register_operand"))
21271 (use (match_operand:MODEF 1 "general_operand"))]
21272 "TARGET_USE_FANCY_MATH_387
21273 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21274 || TARGET_MIX_SSE_I387)
21275 && flag_unsafe_math_optimizations"
21277 rtx op0 = gen_reg_rtx (XFmode);
21278 rtx op1 = gen_reg_rtx (XFmode);
21280 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21281 emit_insn (gen_log10xf2 (op0, op1));
21282 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21286 (define_expand "log2xf2"
21287 [(parallel [(set (match_operand:XF 0 "register_operand")
21288 (unspec:XF [(match_operand:XF 1 "register_operand")
21289 (match_dup 2)] UNSPEC_FYL2X))
21290 (clobber (scratch:XF))])]
21291 "TARGET_USE_FANCY_MATH_387
21292 && flag_unsafe_math_optimizations"
21293 "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
21295 (define_expand "log2<mode>2"
21296 [(use (match_operand:MODEF 0 "register_operand"))
21297 (use (match_operand:MODEF 1 "general_operand"))]
21298 "TARGET_USE_FANCY_MATH_387
21299 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21300 || TARGET_MIX_SSE_I387)
21301 && flag_unsafe_math_optimizations"
21303 rtx op0 = gen_reg_rtx (XFmode);
21304 rtx op1 = gen_reg_rtx (XFmode);
21306 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21307 emit_insn (gen_log2xf2 (op0, op1));
21308 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21312 (define_insn "fyl2xp1xf3_i387"
21313 [(set (match_operand:XF 0 "register_operand" "=f")
21314 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
21315 (match_operand:XF 2 "register_operand" "f")]
21317 (clobber (match_scratch:XF 3 "=2"))]
21318 "TARGET_USE_FANCY_MATH_387
21319 && flag_unsafe_math_optimizations"
21321 [(set_attr "type" "fpspc")
21322 (set_attr "znver1_decode" "vector")
21323 (set_attr "mode" "XF")])
21325 (define_expand "log1pxf2"
21326 [(use (match_operand:XF 0 "register_operand"))
21327 (use (match_operand:XF 1 "register_operand"))]
21328 "TARGET_USE_FANCY_MATH_387
21329 && flag_unsafe_math_optimizations"
21331 ix86_emit_i387_log1p (operands[0], operands[1]);
21335 (define_expand "log1p<mode>2"
21336 [(use (match_operand:MODEF 0 "register_operand"))
21337 (use (match_operand:MODEF 1 "general_operand"))]
21338 "TARGET_USE_FANCY_MATH_387
21339 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21340 || TARGET_MIX_SSE_I387)
21341 && flag_unsafe_math_optimizations"
21343 rtx op0 = gen_reg_rtx (XFmode);
21344 rtx op1 = gen_reg_rtx (XFmode);
21346 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21347 emit_insn (gen_log1pxf2 (op0, op1));
21348 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21352 (define_insn "fxtractxf3_i387"
21353 [(set (match_operand:XF 0 "register_operand" "=f")
21354 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
21355 UNSPEC_XTRACT_FRACT))
21356 (set (match_operand:XF 1 "register_operand" "=f")
21357 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
21358 "TARGET_USE_FANCY_MATH_387
21359 && flag_unsafe_math_optimizations"
21361 [(set_attr "type" "fpspc")
21362 (set_attr "znver1_decode" "vector")
21363 (set_attr "mode" "XF")])
21365 (define_expand "logbxf2"
21366 [(parallel [(set (match_dup 2)
21367 (unspec:XF [(match_operand:XF 1 "register_operand")]
21368 UNSPEC_XTRACT_FRACT))
21369 (set (match_operand:XF 0 "register_operand")
21370 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
21371 "TARGET_USE_FANCY_MATH_387
21372 && flag_unsafe_math_optimizations"
21373 "operands[2] = gen_reg_rtx (XFmode);")
21375 (define_expand "logb<mode>2"
21376 [(use (match_operand:MODEF 0 "register_operand"))
21377 (use (match_operand:MODEF 1 "general_operand"))]
21378 "TARGET_USE_FANCY_MATH_387
21379 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21380 || TARGET_MIX_SSE_I387)
21381 && flag_unsafe_math_optimizations"
21383 rtx op0 = gen_reg_rtx (XFmode);
21384 rtx op1 = gen_reg_rtx (XFmode);
21386 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21387 emit_insn (gen_logbxf2 (op0, op1));
21388 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
21392 (define_expand "ilogbxf2"
21393 [(use (match_operand:SI 0 "register_operand"))
21394 (use (match_operand:XF 1 "register_operand"))]
21395 "TARGET_USE_FANCY_MATH_387
21396 && flag_unsafe_math_optimizations"
21400 if (optimize_insn_for_size_p ())
21403 op0 = gen_reg_rtx (XFmode);
21404 op1 = gen_reg_rtx (XFmode);
21406 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
21407 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
21411 (define_expand "ilogb<mode>2"
21412 [(use (match_operand:SI 0 "register_operand"))
21413 (use (match_operand:MODEF 1 "general_operand"))]
21414 "TARGET_USE_FANCY_MATH_387
21415 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21416 || TARGET_MIX_SSE_I387)
21417 && flag_unsafe_math_optimizations"
21421 if (optimize_insn_for_size_p ())
21424 op0 = gen_reg_rtx (XFmode);
21425 op1 = gen_reg_rtx (XFmode);
21426 op2 = gen_reg_rtx (XFmode);
21428 emit_insn (gen_extend<mode>xf2 (op2, operands[1]));
21429 emit_insn (gen_fxtractxf3_i387 (op0, op1, op2));
21430 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
21434 (define_insn "*f2xm1xf2_i387"
21435 [(set (match_operand:XF 0 "register_operand" "=f")
21436 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
21438 "TARGET_USE_FANCY_MATH_387
21439 && flag_unsafe_math_optimizations"
21441 [(set_attr "type" "fpspc")
21442 (set_attr "znver1_decode" "vector")
21443 (set_attr "mode" "XF")])
21445 (define_insn "fscalexf4_i387"
21446 [(set (match_operand:XF 0 "register_operand" "=f")
21447 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
21448 (match_operand:XF 3 "register_operand" "1")]
21449 UNSPEC_FSCALE_FRACT))
21450 (set (match_operand:XF 1 "register_operand" "=f")
21451 (unspec:XF [(match_dup 2) (match_dup 3)]
21452 UNSPEC_FSCALE_EXP))]
21453 "TARGET_USE_FANCY_MATH_387
21454 && flag_unsafe_math_optimizations"
21456 [(set_attr "type" "fpspc")
21457 (set_attr "znver1_decode" "vector")
21458 (set_attr "mode" "XF")])
21460 (define_expand "expNcorexf3"
21461 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
21462 (match_operand:XF 2 "register_operand")))
21463 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
21464 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
21465 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
21466 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
21467 (parallel [(set (match_operand:XF 0 "register_operand")
21468 (unspec:XF [(match_dup 8) (match_dup 4)]
21469 UNSPEC_FSCALE_FRACT))
21471 (unspec:XF [(match_dup 8) (match_dup 4)]
21472 UNSPEC_FSCALE_EXP))])]
21473 "TARGET_USE_FANCY_MATH_387
21474 && flag_unsafe_math_optimizations"
21478 for (i = 3; i < 10; i++)
21479 operands[i] = gen_reg_rtx (XFmode);
21481 emit_move_insn (operands[7], CONST1_RTX (XFmode));
21484 (define_expand "expxf2"
21485 [(use (match_operand:XF 0 "register_operand"))
21486 (use (match_operand:XF 1 "register_operand"))]
21487 "TARGET_USE_FANCY_MATH_387
21488 && flag_unsafe_math_optimizations"
21490 rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (5)); /* fldl2e */
21492 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
21496 (define_expand "exp<mode>2"
21497 [(use (match_operand:MODEF 0 "register_operand"))
21498 (use (match_operand:MODEF 1 "general_operand"))]
21499 "TARGET_USE_FANCY_MATH_387
21500 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21501 || TARGET_MIX_SSE_I387)
21502 && flag_unsafe_math_optimizations"
21504 rtx op0 = gen_reg_rtx (XFmode);
21505 rtx op1 = gen_reg_rtx (XFmode);
21507 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21508 emit_insn (gen_expxf2 (op0, op1));
21509 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21513 (define_expand "exp10xf2"
21514 [(use (match_operand:XF 0 "register_operand"))
21515 (use (match_operand:XF 1 "register_operand"))]
21516 "TARGET_USE_FANCY_MATH_387
21517 && flag_unsafe_math_optimizations"
21519 rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (6)); /* fldl2t */
21521 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
21525 (define_expand "exp10<mode>2"
21526 [(use (match_operand:MODEF 0 "register_operand"))
21527 (use (match_operand:MODEF 1 "general_operand"))]
21528 "TARGET_USE_FANCY_MATH_387
21529 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21530 || TARGET_MIX_SSE_I387)
21531 && flag_unsafe_math_optimizations"
21533 rtx op0 = gen_reg_rtx (XFmode);
21534 rtx op1 = gen_reg_rtx (XFmode);
21536 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21537 emit_insn (gen_exp10xf2 (op0, op1));
21538 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21542 (define_expand "exp2xf2"
21543 [(use (match_operand:XF 0 "register_operand"))
21544 (use (match_operand:XF 1 "register_operand"))]
21545 "TARGET_USE_FANCY_MATH_387
21546 && flag_unsafe_math_optimizations"
21548 rtx op2 = force_reg (XFmode, CONST1_RTX (XFmode));
21550 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
21554 (define_expand "exp2<mode>2"
21555 [(use (match_operand:MODEF 0 "register_operand"))
21556 (use (match_operand:MODEF 1 "general_operand"))]
21557 "TARGET_USE_FANCY_MATH_387
21558 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21559 || TARGET_MIX_SSE_I387)
21560 && flag_unsafe_math_optimizations"
21562 rtx op0 = gen_reg_rtx (XFmode);
21563 rtx op1 = gen_reg_rtx (XFmode);
21565 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21566 emit_insn (gen_exp2xf2 (op0, op1));
21567 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21571 (define_expand "expm1xf2"
21572 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
21574 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
21575 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
21576 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
21577 (parallel [(set (match_dup 7)
21578 (unspec:XF [(match_dup 6) (match_dup 4)]
21579 UNSPEC_FSCALE_FRACT))
21581 (unspec:XF [(match_dup 6) (match_dup 4)]
21582 UNSPEC_FSCALE_EXP))])
21583 (parallel [(set (match_dup 10)
21584 (unspec:XF [(match_dup 9) (match_dup 8)]
21585 UNSPEC_FSCALE_FRACT))
21586 (set (match_dup 11)
21587 (unspec:XF [(match_dup 9) (match_dup 8)]
21588 UNSPEC_FSCALE_EXP))])
21589 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
21590 (set (match_operand:XF 0 "register_operand")
21591 (plus:XF (match_dup 12) (match_dup 7)))]
21592 "TARGET_USE_FANCY_MATH_387
21593 && flag_unsafe_math_optimizations"
21597 for (i = 2; i < 13; i++)
21598 operands[i] = gen_reg_rtx (XFmode);
21600 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
21601 emit_move_insn (operands[9], CONST1_RTX (XFmode));
21604 (define_expand "expm1<mode>2"
21605 [(use (match_operand:MODEF 0 "register_operand"))
21606 (use (match_operand:MODEF 1 "general_operand"))]
21607 "TARGET_USE_FANCY_MATH_387
21608 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21609 || TARGET_MIX_SSE_I387)
21610 && flag_unsafe_math_optimizations"
21612 rtx op0 = gen_reg_rtx (XFmode);
21613 rtx op1 = gen_reg_rtx (XFmode);
21615 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21616 emit_insn (gen_expm1xf2 (op0, op1));
21617 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21621 (define_insn "avx512f_scalef<mode>2"
21622 [(set (match_operand:MODEF 0 "register_operand" "=v")
21624 [(match_operand:MODEF 1 "register_operand" "v")
21625 (match_operand:MODEF 2 "nonimmediate_operand" "vm")]
21628 "vscalef<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
21629 [(set_attr "prefix" "evex")
21630 (set_attr "mode" "<MODE>")])
21632 (define_expand "ldexpxf3"
21633 [(match_operand:XF 0 "register_operand")
21634 (match_operand:XF 1 "register_operand")
21635 (match_operand:SI 2 "register_operand")]
21636 "TARGET_USE_FANCY_MATH_387
21637 && flag_unsafe_math_optimizations"
21639 rtx tmp1 = gen_reg_rtx (XFmode);
21640 rtx tmp2 = gen_reg_rtx (XFmode);
21642 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
21643 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
21644 operands[1], tmp1));
21648 (define_expand "ldexp<mode>3"
21649 [(use (match_operand:MODEF 0 "register_operand"))
21650 (use (match_operand:MODEF 1 "general_operand"))
21651 (use (match_operand:SI 2 "register_operand"))]
21652 "((TARGET_USE_FANCY_MATH_387
21653 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21654 || TARGET_MIX_SSE_I387))
21655 || (TARGET_AVX512F && TARGET_SSE_MATH))
21656 && flag_unsafe_math_optimizations"
21658 /* Prefer avx512f version. */
21659 if (TARGET_AVX512F && TARGET_SSE_MATH)
21661 rtx op2 = gen_reg_rtx (<MODE>mode);
21662 operands[1] = force_reg (<MODE>mode, operands[1]);
21664 emit_insn (gen_floatsi<mode>2 (op2, operands[2]));
21665 emit_insn (gen_avx512f_scalef<mode>2 (operands[0], operands[1], op2));
21669 rtx op0 = gen_reg_rtx (XFmode);
21670 rtx op1 = gen_reg_rtx (XFmode);
21672 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21673 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
21674 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21679 (define_expand "scalbxf3"
21680 [(parallel [(set (match_operand:XF 0 " register_operand")
21681 (unspec:XF [(match_operand:XF 1 "register_operand")
21682 (match_operand:XF 2 "register_operand")]
21683 UNSPEC_FSCALE_FRACT))
21685 (unspec:XF [(match_dup 1) (match_dup 2)]
21686 UNSPEC_FSCALE_EXP))])]
21687 "TARGET_USE_FANCY_MATH_387
21688 && flag_unsafe_math_optimizations"
21689 "operands[3] = gen_reg_rtx (XFmode);")
21691 (define_expand "scalb<mode>3"
21692 [(use (match_operand:MODEF 0 "register_operand"))
21693 (use (match_operand:MODEF 1 "general_operand"))
21694 (use (match_operand:MODEF 2 "general_operand"))]
21695 "TARGET_USE_FANCY_MATH_387
21696 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21697 || TARGET_MIX_SSE_I387)
21698 && flag_unsafe_math_optimizations"
21700 rtx op0 = gen_reg_rtx (XFmode);
21701 rtx op1 = gen_reg_rtx (XFmode);
21702 rtx op2 = gen_reg_rtx (XFmode);
21704 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21705 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
21706 emit_insn (gen_scalbxf3 (op0, op1, op2));
21707 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21711 (define_expand "significandxf2"
21712 [(parallel [(set (match_operand:XF 0 "register_operand")
21713 (unspec:XF [(match_operand:XF 1 "register_operand")]
21714 UNSPEC_XTRACT_FRACT))
21716 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
21717 "TARGET_USE_FANCY_MATH_387
21718 && flag_unsafe_math_optimizations"
21719 "operands[2] = gen_reg_rtx (XFmode);")
21721 (define_expand "significand<mode>2"
21722 [(use (match_operand:MODEF 0 "register_operand"))
21723 (use (match_operand:MODEF 1 "general_operand"))]
21724 "TARGET_USE_FANCY_MATH_387
21725 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21726 || TARGET_MIX_SSE_I387)
21727 && flag_unsafe_math_optimizations"
21729 rtx op0 = gen_reg_rtx (XFmode);
21730 rtx op1 = gen_reg_rtx (XFmode);
21732 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21733 emit_insn (gen_significandxf2 (op0, op1));
21734 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21739 (define_insn "sse4_1_round<mode>2"
21740 [(set (match_operand:MODEFH 0 "register_operand" "=x,x,x,v,v")
21742 [(match_operand:MODEFH 1 "nonimmediate_operand" "0,x,jm,v,m")
21743 (match_operand:SI 2 "const_0_to_15_operand")]
21747 %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
21748 %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
21749 %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
21750 vrndscale<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
21751 vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
21752 [(set_attr "type" "ssecvt")
21753 (set_attr "prefix_extra" "1,1,1,*,*")
21754 (set_attr "length_immediate" "1")
21755 (set_attr "addr" "*,*,gpr16,*,*")
21756 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,evex,evex")
21757 (set_attr "isa" "noavx512f,noavx512f,noavx512f,avx512f,avx512f")
21758 (set_attr "avx_partial_xmm_update" "false,false,true,false,true")
21759 (set_attr "mode" "<MODE>")
21760 (set (attr "preferred_for_speed")
21761 (cond [(match_test "TARGET_AVX")
21762 (symbol_ref "true")
21763 (eq_attr "alternative" "1,2")
21764 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
21766 (symbol_ref "true")))])
21768 (define_insn "rintxf2"
21769 [(set (match_operand:XF 0 "register_operand" "=f")
21770 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
21772 "TARGET_USE_FANCY_MATH_387"
21774 [(set_attr "type" "fpspc")
21775 (set_attr "znver1_decode" "vector")
21776 (set_attr "mode" "XF")])
21778 (define_expand "rinthf2"
21779 [(match_operand:HF 0 "register_operand")
21780 (match_operand:HF 1 "nonimmediate_operand")]
21781 "TARGET_AVX512FP16"
21783 emit_insn (gen_sse4_1_roundhf2 (operands[0],
21785 GEN_INT (ROUND_MXCSR)));
21789 (define_expand "rint<mode>2"
21790 [(use (match_operand:MODEF 0 "register_operand"))
21791 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
21792 "TARGET_USE_FANCY_MATH_387
21793 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
21795 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21798 emit_insn (gen_sse4_1_round<mode>2
21799 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
21801 ix86_expand_rint (operands[0], operands[1]);
21805 rtx op0 = gen_reg_rtx (XFmode);
21806 rtx op1 = gen_reg_rtx (XFmode);
21808 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21809 emit_insn (gen_rintxf2 (op0, op1));
21810 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
21815 (define_expand "nearbyintxf2"
21816 [(set (match_operand:XF 0 "register_operand")
21817 (unspec:XF [(match_operand:XF 1 "register_operand")]
21819 "TARGET_USE_FANCY_MATH_387
21820 && !flag_trapping_math")
21822 (define_expand "nearbyinthf2"
21823 [(match_operand:HF 0 "register_operand")
21824 (match_operand:HF 1 "nonimmediate_operand")]
21825 "TARGET_AVX512FP16"
21827 emit_insn (gen_sse4_1_roundhf2 (operands[0],
21829 GEN_INT (ROUND_MXCSR | ROUND_NO_EXC)));
21833 (define_expand "nearbyint<mode>2"
21834 [(use (match_operand:MODEF 0 "register_operand"))
21835 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
21836 "(TARGET_USE_FANCY_MATH_387
21837 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21838 || TARGET_MIX_SSE_I387)
21839 && !flag_trapping_math)
21840 || (TARGET_SSE4_1 && TARGET_SSE_MATH)"
21842 if (TARGET_SSE4_1 && TARGET_SSE_MATH)
21843 emit_insn (gen_sse4_1_round<mode>2
21844 (operands[0], operands[1], GEN_INT (ROUND_MXCSR
21848 rtx op0 = gen_reg_rtx (XFmode);
21849 rtx op1 = gen_reg_rtx (XFmode);
21851 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21852 emit_insn (gen_nearbyintxf2 (op0, op1));
21853 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
21858 (define_expand "roundhf2"
21859 [(match_operand:HF 0 "register_operand")
21860 (match_operand:HF 1 "register_operand")]
21861 "TARGET_AVX512FP16 && !flag_trapping_math && !flag_rounding_math"
21863 ix86_expand_round_sse4 (operands[0], operands[1]);
21867 (define_expand "round<mode>2"
21868 [(match_operand:X87MODEF 0 "register_operand")
21869 (match_operand:X87MODEF 1 "nonimmediate_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
21874 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
21875 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
21876 && !flag_trapping_math && !flag_rounding_math)"
21878 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
21879 && !flag_trapping_math && !flag_rounding_math)
21883 operands[1] = force_reg (<MODE>mode, operands[1]);
21884 ix86_expand_round_sse4 (operands[0], operands[1]);
21886 else if (TARGET_64BIT || (<MODE>mode != DFmode))
21887 ix86_expand_round (operands[0], operands[1]);
21889 ix86_expand_rounddf_32 (operands[0], operands[1]);
21893 operands[1] = force_reg (<MODE>mode, operands[1]);
21894 ix86_emit_i387_round (operands[0], operands[1]);
21899 (define_insn "lrintxfdi2"
21900 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
21901 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
21903 (clobber (match_scratch:XF 2 "=&f"))]
21904 "TARGET_USE_FANCY_MATH_387"
21905 "* return output_fix_trunc (insn, operands, false);"
21906 [(set_attr "type" "fpspc")
21907 (set_attr "mode" "DI")])
21909 (define_insn "lrintxf<mode>2"
21910 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
21911 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
21913 "TARGET_USE_FANCY_MATH_387"
21914 "* return output_fix_trunc (insn, operands, false);"
21915 [(set_attr "type" "fpspc")
21916 (set_attr "mode" "<MODE>")])
21918 (define_expand "lroundhf<mode>2"
21919 [(set (match_operand:SWI248 0 "register_operand")
21920 (unspec:SWI248 [(match_operand:HF 1 "nonimmediate_operand")]
21921 UNSPEC_FIX_NOTRUNC))]
21922 "TARGET_AVX512FP16 && !flag_trapping_math && !flag_rounding_math"
21924 ix86_expand_lround (operands[0], operands[1]);
21928 (define_expand "lrinthf<mode>2"
21929 [(set (match_operand:SWI48 0 "register_operand")
21930 (unspec:SWI48 [(match_operand:HF 1 "nonimmediate_operand")]
21931 UNSPEC_FIX_NOTRUNC))]
21932 "TARGET_AVX512FP16")
21934 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
21935 [(set (match_operand:SWI48 0 "register_operand")
21936 (unspec:SWI48 [(match_operand:MODEF 1 "nonimmediate_operand")]
21937 UNSPEC_FIX_NOTRUNC))]
21938 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
21940 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
21941 [(match_operand:SWI248x 0 "nonimmediate_operand")
21942 (match_operand:X87MODEF 1 "register_operand")]
21943 "(TARGET_USE_FANCY_MATH_387
21944 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
21945 || TARGET_MIX_SSE_I387)
21946 && flag_unsafe_math_optimizations)
21947 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
21948 && <SWI248x:MODE>mode != HImode
21949 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
21950 && !flag_trapping_math && !flag_rounding_math)"
21952 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
21953 && <SWI248x:MODE>mode != HImode
21954 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
21955 && !flag_trapping_math && !flag_rounding_math)
21956 ix86_expand_lround (operands[0], operands[1]);
21958 ix86_emit_i387_round (operands[0], operands[1]);
21962 (define_int_iterator FRNDINT_ROUNDING
21963 [UNSPEC_FRNDINT_ROUNDEVEN
21964 UNSPEC_FRNDINT_FLOOR
21965 UNSPEC_FRNDINT_CEIL
21966 UNSPEC_FRNDINT_TRUNC])
21968 (define_int_iterator FIST_ROUNDING
21972 ;; Base name for define_insn
21973 (define_int_attr rounding_insn
21974 [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven")
21975 (UNSPEC_FRNDINT_FLOOR "floor")
21976 (UNSPEC_FRNDINT_CEIL "ceil")
21977 (UNSPEC_FRNDINT_TRUNC "btrunc")
21978 (UNSPEC_FIST_FLOOR "floor")
21979 (UNSPEC_FIST_CEIL "ceil")])
21981 (define_int_attr rounding
21982 [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven")
21983 (UNSPEC_FRNDINT_FLOOR "floor")
21984 (UNSPEC_FRNDINT_CEIL "ceil")
21985 (UNSPEC_FRNDINT_TRUNC "trunc")
21986 (UNSPEC_FIST_FLOOR "floor")
21987 (UNSPEC_FIST_CEIL "ceil")])
21989 (define_int_attr ROUNDING
21990 [(UNSPEC_FRNDINT_ROUNDEVEN "ROUNDEVEN")
21991 (UNSPEC_FRNDINT_FLOOR "FLOOR")
21992 (UNSPEC_FRNDINT_CEIL "CEIL")
21993 (UNSPEC_FRNDINT_TRUNC "TRUNC")
21994 (UNSPEC_FIST_FLOOR "FLOOR")
21995 (UNSPEC_FIST_CEIL "CEIL")])
21997 ;; Rounding mode control word calculation could clobber FLAGS_REG.
21998 (define_insn_and_split "frndintxf2_<rounding>"
21999 [(set (match_operand:XF 0 "register_operand")
22000 (unspec:XF [(match_operand:XF 1 "register_operand")]
22002 (clobber (reg:CC FLAGS_REG))]
22003 "TARGET_USE_FANCY_MATH_387
22004 && (flag_fp_int_builtin_inexact || !flag_trapping_math)
22005 && ix86_pre_reload_split ()"
22010 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
22012 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
22013 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
22015 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
22016 operands[2], operands[3]));
22019 [(set_attr "type" "frndint")
22020 (set_attr "i387_cw" "<rounding>")
22021 (set_attr "mode" "XF")])
22023 (define_insn "frndintxf2_<rounding>_i387"
22024 [(set (match_operand:XF 0 "register_operand" "=f")
22025 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
22027 (use (match_operand:HI 2 "memory_operand" "m"))
22028 (use (match_operand:HI 3 "memory_operand" "m"))]
22029 "TARGET_USE_FANCY_MATH_387
22030 && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
22031 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
22032 [(set_attr "type" "frndint")
22033 (set_attr "i387_cw" "<rounding>")
22034 (set_attr "mode" "XF")])
22036 (define_expand "<rounding_insn>xf2"
22037 [(parallel [(set (match_operand:XF 0 "register_operand")
22038 (unspec:XF [(match_operand:XF 1 "register_operand")]
22040 (clobber (reg:CC FLAGS_REG))])]
22041 "TARGET_USE_FANCY_MATH_387
22042 && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
22044 (define_expand "<rounding_insn>hf2"
22045 [(parallel [(set (match_operand:HF 0 "register_operand")
22046 (unspec:HF [(match_operand:HF 1 "register_operand")]
22048 (clobber (reg:CC FLAGS_REG))])]
22049 "TARGET_AVX512FP16"
22051 emit_insn (gen_sse4_1_roundhf2 (operands[0], operands[1],
22052 GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
22056 (define_expand "<rounding_insn><mode>2"
22057 [(parallel [(set (match_operand:MODEF 0 "register_operand")
22058 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
22060 (clobber (reg:CC FLAGS_REG))])]
22061 "(TARGET_USE_FANCY_MATH_387
22062 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22063 || TARGET_MIX_SSE_I387)
22064 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
22065 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
22067 || (ROUND_<ROUNDING> != ROUND_ROUNDEVEN
22068 && (flag_fp_int_builtin_inexact || !flag_trapping_math))))"
22070 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
22072 || (ROUND_<ROUNDING> != ROUND_ROUNDEVEN
22073 && (flag_fp_int_builtin_inexact || !flag_trapping_math))))
22076 emit_insn (gen_sse4_1_round<mode>2
22077 (operands[0], operands[1],
22078 GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
22079 else if (TARGET_64BIT || (<MODE>mode != DFmode))
22081 if (ROUND_<ROUNDING> == ROUND_FLOOR)
22082 ix86_expand_floorceil (operands[0], operands[1], true);
22083 else if (ROUND_<ROUNDING> == ROUND_CEIL)
22084 ix86_expand_floorceil (operands[0], operands[1], false);
22085 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
22086 ix86_expand_trunc (operands[0], operands[1]);
22088 gcc_unreachable ();
22092 if (ROUND_<ROUNDING> == ROUND_FLOOR)
22093 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
22094 else if (ROUND_<ROUNDING> == ROUND_CEIL)
22095 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
22096 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
22097 ix86_expand_truncdf_32 (operands[0], operands[1]);
22099 gcc_unreachable ();
22104 rtx op0 = gen_reg_rtx (XFmode);
22105 rtx op1 = gen_reg_rtx (XFmode);
22107 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22108 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
22109 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
22114 ;; Rounding mode control word calculation could clobber FLAGS_REG.
22115 (define_insn_and_split "*fist<mode>2_<rounding>_1"
22116 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
22117 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
22119 (clobber (reg:CC FLAGS_REG))]
22120 "TARGET_USE_FANCY_MATH_387
22121 && flag_unsafe_math_optimizations
22122 && ix86_pre_reload_split ()"
22127 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
22129 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
22130 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
22132 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
22133 operands[2], operands[3]));
22136 [(set_attr "type" "fistp")
22137 (set_attr "i387_cw" "<rounding>")
22138 (set_attr "mode" "<MODE>")])
22140 (define_insn "fistdi2_<rounding>"
22141 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
22142 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
22144 (use (match_operand:HI 2 "memory_operand" "m"))
22145 (use (match_operand:HI 3 "memory_operand" "m"))
22146 (clobber (match_scratch:XF 4 "=&f"))]
22147 "TARGET_USE_FANCY_MATH_387
22148 && flag_unsafe_math_optimizations"
22149 "* return output_fix_trunc (insn, operands, false);"
22150 [(set_attr "type" "fistp")
22151 (set_attr "i387_cw" "<rounding>")
22152 (set_attr "mode" "DI")])
22154 (define_insn "fist<mode>2_<rounding>"
22155 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
22156 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
22158 (use (match_operand:HI 2 "memory_operand" "m"))
22159 (use (match_operand:HI 3 "memory_operand" "m"))]
22160 "TARGET_USE_FANCY_MATH_387
22161 && flag_unsafe_math_optimizations"
22162 "* return output_fix_trunc (insn, operands, false);"
22163 [(set_attr "type" "fistp")
22164 (set_attr "i387_cw" "<rounding>")
22165 (set_attr "mode" "<MODE>")])
22167 (define_expand "l<rounding_insn>xf<mode>2"
22168 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
22169 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
22171 (clobber (reg:CC FLAGS_REG))])]
22172 "TARGET_USE_FANCY_MATH_387
22173 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
22174 && flag_unsafe_math_optimizations")
22176 (define_expand "l<rounding_insn>hf<mode>2"
22177 [(set (match_operand:SWI48 0 "nonimmediate_operand")
22178 (unspec:SWI48 [(match_operand:HF 1 "register_operand")]
22180 "TARGET_AVX512FP16"
22182 rtx tmp = gen_reg_rtx (HFmode);
22183 emit_insn (gen_sse4_1_roundhf2 (tmp, operands[1],
22184 GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
22185 emit_insn (gen_fix_trunchf<mode>2 (operands[0], tmp));
22189 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
22190 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
22191 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
22193 (clobber (reg:CC FLAGS_REG))])]
22194 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
22195 && (TARGET_SSE4_1 || !flag_trapping_math)"
22199 rtx tmp = gen_reg_rtx (<MODEF:MODE>mode);
22201 emit_insn (gen_sse4_1_round<MODEF:mode>2
22202 (tmp, operands[1], GEN_INT (ROUND_<ROUNDING>
22204 emit_insn (gen_fix_trunc<MODEF:mode><SWI48:mode>2
22205 (operands[0], tmp));
22207 else if (ROUND_<ROUNDING> == ROUND_FLOOR)
22208 ix86_expand_lfloorceil (operands[0], operands[1], true);
22209 else if (ROUND_<ROUNDING> == ROUND_CEIL)
22210 ix86_expand_lfloorceil (operands[0], operands[1], false);
22212 gcc_unreachable ();
22217 (define_insn "fxam<mode>2_i387"
22218 [(set (match_operand:HI 0 "register_operand" "=a")
22220 [(match_operand:X87MODEF 1 "register_operand" "f")]
22222 "TARGET_USE_FANCY_MATH_387"
22223 "fxam\n\tfnstsw\t%0"
22224 [(set_attr "type" "multi")
22225 (set_attr "length" "4")
22226 (set_attr "unit" "i387")
22227 (set_attr "mode" "<MODE>")])
22229 (define_expand "signbittf2"
22230 [(use (match_operand:SI 0 "register_operand"))
22231 (use (match_operand:TF 1 "register_operand"))]
22236 rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
22237 rtx scratch = gen_reg_rtx (QImode);
22239 emit_insn (gen_ptesttf2 (operands[1], mask));
22240 ix86_expand_setcc (scratch, NE,
22241 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
22243 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
22247 emit_insn (gen_sse_movmskps (operands[0],
22248 gen_lowpart (V4SFmode, operands[1])));
22249 emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8)));
22254 (define_expand "signbitxf2"
22255 [(use (match_operand:SI 0 "register_operand"))
22256 (use (match_operand:XF 1 "register_operand"))]
22257 "TARGET_USE_FANCY_MATH_387"
22259 rtx scratch = gen_reg_rtx (HImode);
22261 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
22262 emit_insn (gen_andsi3 (operands[0],
22263 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
22267 (define_insn "movmsk_df"
22268 [(set (match_operand:SI 0 "register_operand" "=r,jr")
22270 [(match_operand:DF 1 "register_operand" "x,x")]
22272 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
22273 "%vmovmskpd\t{%1, %0|%0, %1}"
22274 [(set_attr "isa" "noavx,avx")
22275 (set_attr "type" "ssemov")
22276 (set_attr "prefix" "maybe_evex")
22277 (set_attr "mode" "DF")])
22279 ;; Use movmskpd in SSE mode to avoid store forwarding stall
22280 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
22281 (define_expand "signbitdf2"
22282 [(use (match_operand:SI 0 "register_operand"))
22283 (use (match_operand:DF 1 "register_operand"))]
22284 "TARGET_USE_FANCY_MATH_387
22285 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
22287 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
22289 emit_insn (gen_movmsk_df (operands[0], operands[1]));
22290 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
22294 rtx scratch = gen_reg_rtx (HImode);
22296 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
22297 emit_insn (gen_andsi3 (operands[0],
22298 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
22303 (define_expand "signbitsf2"
22304 [(use (match_operand:SI 0 "register_operand"))
22305 (use (match_operand:SF 1 "register_operand"))]
22306 "TARGET_USE_FANCY_MATH_387
22307 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
22309 rtx scratch = gen_reg_rtx (HImode);
22311 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
22312 emit_insn (gen_andsi3 (operands[0],
22313 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
22317 ;; Block operation instructions
22320 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
22323 [(set_attr "length" "1")
22324 (set_attr "length_immediate" "0")
22325 (set_attr "modrm" "0")])
22327 (define_expand "cpymem<mode>"
22328 [(use (match_operand:BLK 0 "memory_operand"))
22329 (use (match_operand:BLK 1 "memory_operand"))
22330 (use (match_operand:SWI48 2 "nonmemory_operand"))
22331 (use (match_operand:SWI48 3 "const_int_operand"))
22332 (use (match_operand:SI 4 "const_int_operand"))
22333 (use (match_operand:SI 5 "const_int_operand"))
22334 (use (match_operand:SI 6 ""))
22335 (use (match_operand:SI 7 ""))
22336 (use (match_operand:SI 8 ""))]
22339 if (ix86_expand_set_or_cpymem (operands[0], operands[1],
22340 operands[2], NULL, operands[3],
22341 operands[4], operands[5],
22342 operands[6], operands[7],
22343 operands[8], false))
22349 ;; Most CPUs don't like single string operations
22350 ;; Handle this case here to simplify previous expander.
22352 (define_expand "strmov"
22353 [(set (match_dup 4) (match_operand 3 "memory_operand"))
22354 (set (match_operand 1 "memory_operand") (match_dup 4))
22355 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
22356 (clobber (reg:CC FLAGS_REG))])
22357 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
22358 (clobber (reg:CC FLAGS_REG))])]
22361 /* Can't use this for non-default address spaces. */
22362 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
22365 int piece_size = GET_MODE_SIZE (GET_MODE (operands[1]));
22367 /* If .md ever supports :P for Pmode, these can be directly
22368 in the pattern above. */
22369 operands[5] = plus_constant (Pmode, operands[0], piece_size);
22370 operands[6] = plus_constant (Pmode, operands[2], piece_size);
22372 /* Can't use this if the user has appropriated esi or edi. */
22373 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
22374 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
22376 emit_insn (gen_strmov_singleop (operands[0], operands[1],
22377 operands[2], operands[3],
22378 operands[5], operands[6]));
22382 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
22385 (define_expand "strmov_singleop"
22386 [(parallel [(set (match_operand 1 "memory_operand")
22387 (match_operand 3 "memory_operand"))
22388 (set (match_operand 0 "register_operand")
22390 (set (match_operand 2 "register_operand")
22391 (match_operand 5))])]
22395 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22398 (define_insn "*strmovdi_rex_1"
22399 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
22400 (mem:DI (match_operand:P 3 "register_operand" "1")))
22401 (set (match_operand:P 0 "register_operand" "=D")
22402 (plus:P (match_dup 2)
22404 (set (match_operand:P 1 "register_operand" "=S")
22405 (plus:P (match_dup 3)
22408 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22409 && ix86_check_no_addr_space (insn)"
22411 [(set_attr "type" "str")
22412 (set_attr "memory" "both")
22413 (set_attr "mode" "DI")])
22415 (define_insn "*strmovsi_1"
22416 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
22417 (mem:SI (match_operand:P 3 "register_operand" "1")))
22418 (set (match_operand:P 0 "register_operand" "=D")
22419 (plus:P (match_dup 2)
22421 (set (match_operand:P 1 "register_operand" "=S")
22422 (plus:P (match_dup 3)
22424 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22425 && ix86_check_no_addr_space (insn)"
22427 [(set_attr "type" "str")
22428 (set_attr "memory" "both")
22429 (set_attr "mode" "SI")])
22431 (define_insn "*strmovhi_1"
22432 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
22433 (mem:HI (match_operand:P 3 "register_operand" "1")))
22434 (set (match_operand:P 0 "register_operand" "=D")
22435 (plus:P (match_dup 2)
22437 (set (match_operand:P 1 "register_operand" "=S")
22438 (plus:P (match_dup 3)
22440 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22441 && ix86_check_no_addr_space (insn)"
22443 [(set_attr "type" "str")
22444 (set_attr "memory" "both")
22445 (set_attr "mode" "HI")])
22447 (define_insn "*strmovqi_1"
22448 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
22449 (mem:QI (match_operand:P 3 "register_operand" "1")))
22450 (set (match_operand:P 0 "register_operand" "=D")
22451 (plus:P (match_dup 2)
22453 (set (match_operand:P 1 "register_operand" "=S")
22454 (plus:P (match_dup 3)
22456 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22457 && ix86_check_no_addr_space (insn)"
22459 [(set_attr "type" "str")
22460 (set_attr "memory" "both")
22461 (set (attr "prefix_rex")
22463 (match_test "<P:MODE>mode == DImode")
22465 (const_string "*")))
22466 (set_attr "mode" "QI")])
22468 (define_expand "rep_mov"
22469 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
22470 (set (match_operand 0 "register_operand")
22472 (set (match_operand 2 "register_operand")
22474 (set (match_operand 1 "memory_operand")
22475 (match_operand 3 "memory_operand"))
22476 (use (match_dup 4))])]
22480 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22483 (define_insn "*rep_movdi_rex64"
22484 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
22485 (set (match_operand:P 0 "register_operand" "=D")
22486 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
22488 (match_operand:P 3 "register_operand" "0")))
22489 (set (match_operand:P 1 "register_operand" "=S")
22490 (plus:P (ashift:P (match_dup 5) (const_int 3))
22491 (match_operand:P 4 "register_operand" "1")))
22492 (set (mem:BLK (match_dup 3))
22493 (mem:BLK (match_dup 4)))
22494 (use (match_dup 5))]
22496 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22497 && ix86_check_no_addr_space (insn)"
22499 [(set_attr "type" "str")
22500 (set_attr "prefix_rep" "1")
22501 (set_attr "memory" "both")
22502 (set_attr "mode" "DI")])
22504 (define_insn "*rep_movsi"
22505 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
22506 (set (match_operand:P 0 "register_operand" "=D")
22507 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
22509 (match_operand:P 3 "register_operand" "0")))
22510 (set (match_operand:P 1 "register_operand" "=S")
22511 (plus:P (ashift:P (match_dup 5) (const_int 2))
22512 (match_operand:P 4 "register_operand" "1")))
22513 (set (mem:BLK (match_dup 3))
22514 (mem:BLK (match_dup 4)))
22515 (use (match_dup 5))]
22516 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22517 && ix86_check_no_addr_space (insn)"
22518 "%^rep{%;} movs{l|d}"
22519 [(set_attr "type" "str")
22520 (set_attr "prefix_rep" "1")
22521 (set_attr "memory" "both")
22522 (set_attr "mode" "SI")])
22524 (define_insn "*rep_movqi"
22525 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
22526 (set (match_operand:P 0 "register_operand" "=D")
22527 (plus:P (match_operand:P 3 "register_operand" "0")
22528 (match_operand:P 5 "register_operand" "2")))
22529 (set (match_operand:P 1 "register_operand" "=S")
22530 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
22531 (set (mem:BLK (match_dup 3))
22532 (mem:BLK (match_dup 4)))
22533 (use (match_dup 5))]
22534 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22535 && ix86_check_no_addr_space (insn)"
22537 [(set_attr "type" "str")
22538 (set_attr "prefix_rep" "1")
22539 (set_attr "memory" "both")
22540 (set_attr "mode" "QI")])
22542 (define_expand "setmem<mode>"
22543 [(use (match_operand:BLK 0 "memory_operand"))
22544 (use (match_operand:SWI48 1 "nonmemory_operand"))
22545 (use (match_operand:QI 2 "nonmemory_operand"))
22546 (use (match_operand 3 "const_int_operand"))
22547 (use (match_operand:SI 4 "const_int_operand"))
22548 (use (match_operand:SI 5 "const_int_operand"))
22549 (use (match_operand:SI 6 ""))
22550 (use (match_operand:SI 7 ""))
22551 (use (match_operand:SI 8 ""))]
22554 if (ix86_expand_set_or_cpymem (operands[0], NULL,
22555 operands[1], operands[2],
22556 operands[3], operands[4],
22557 operands[5], operands[6],
22558 operands[7], operands[8], true))
22564 ;; Most CPUs don't like single string operations
22565 ;; Handle this case here to simplify previous expander.
22567 (define_expand "strset"
22568 [(set (match_operand 1 "memory_operand")
22569 (match_operand 2 "register_operand"))
22570 (parallel [(set (match_operand 0 "register_operand")
22572 (clobber (reg:CC FLAGS_REG))])]
22575 /* Can't use this for non-default address spaces. */
22576 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
22579 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
22580 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
22582 /* If .md ever supports :P for Pmode, this can be directly
22583 in the pattern above. */
22584 operands[3] = plus_constant (Pmode, operands[0],
22585 GET_MODE_SIZE (GET_MODE (operands[2])));
22587 /* Can't use this if the user has appropriated eax or edi. */
22588 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
22589 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
22591 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
22597 (define_expand "strset_singleop"
22598 [(parallel [(set (match_operand 1 "memory_operand")
22599 (match_operand 2 "register_operand"))
22600 (set (match_operand 0 "register_operand")
22602 (unspec [(const_int 0)] UNSPEC_STOS)])]
22606 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22609 (define_insn "*strsetdi_rex_1"
22610 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
22611 (match_operand:DI 2 "register_operand" "a"))
22612 (set (match_operand:P 0 "register_operand" "=D")
22613 (plus:P (match_dup 1)
22615 (unspec [(const_int 0)] UNSPEC_STOS)]
22617 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22618 && ix86_check_no_addr_space (insn)"
22620 [(set_attr "type" "str")
22621 (set_attr "memory" "store")
22622 (set_attr "mode" "DI")])
22624 (define_insn "*strsetsi_1"
22625 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
22626 (match_operand:SI 2 "register_operand" "a"))
22627 (set (match_operand:P 0 "register_operand" "=D")
22628 (plus:P (match_dup 1)
22630 (unspec [(const_int 0)] UNSPEC_STOS)]
22631 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22632 && ix86_check_no_addr_space (insn)"
22634 [(set_attr "type" "str")
22635 (set_attr "memory" "store")
22636 (set_attr "mode" "SI")])
22638 (define_insn "*strsethi_1"
22639 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
22640 (match_operand:HI 2 "register_operand" "a"))
22641 (set (match_operand:P 0 "register_operand" "=D")
22642 (plus:P (match_dup 1)
22644 (unspec [(const_int 0)] UNSPEC_STOS)]
22645 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22646 && ix86_check_no_addr_space (insn)"
22648 [(set_attr "type" "str")
22649 (set_attr "memory" "store")
22650 (set_attr "mode" "HI")])
22652 (define_insn "*strsetqi_1"
22653 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
22654 (match_operand:QI 2 "register_operand" "a"))
22655 (set (match_operand:P 0 "register_operand" "=D")
22656 (plus:P (match_dup 1)
22658 (unspec [(const_int 0)] UNSPEC_STOS)]
22659 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22660 && ix86_check_no_addr_space (insn)"
22662 [(set_attr "type" "str")
22663 (set_attr "memory" "store")
22664 (set (attr "prefix_rex")
22666 (match_test "<P:MODE>mode == DImode")
22668 (const_string "*")))
22669 (set_attr "mode" "QI")])
22671 (define_expand "rep_stos"
22672 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
22673 (set (match_operand 0 "register_operand")
22675 (set (match_operand 2 "memory_operand") (const_int 0))
22676 (use (match_operand 3 "register_operand"))
22677 (use (match_dup 1))])]
22681 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22684 (define_insn "*rep_stosdi_rex64"
22685 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
22686 (set (match_operand:P 0 "register_operand" "=D")
22687 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
22689 (match_operand:P 3 "register_operand" "0")))
22690 (set (mem:BLK (match_dup 3))
22692 (use (match_operand:DI 2 "register_operand" "a"))
22693 (use (match_dup 4))]
22695 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
22696 && ix86_check_no_addr_space (insn)"
22698 [(set_attr "type" "str")
22699 (set_attr "prefix_rep" "1")
22700 (set_attr "memory" "store")
22701 (set_attr "mode" "DI")])
22703 (define_insn "*rep_stossi"
22704 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
22705 (set (match_operand:P 0 "register_operand" "=D")
22706 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
22708 (match_operand:P 3 "register_operand" "0")))
22709 (set (mem:BLK (match_dup 3))
22711 (use (match_operand:SI 2 "register_operand" "a"))
22712 (use (match_dup 4))]
22713 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
22714 && ix86_check_no_addr_space (insn)"
22715 "%^rep{%;} stos{l|d}"
22716 [(set_attr "type" "str")
22717 (set_attr "prefix_rep" "1")
22718 (set_attr "memory" "store")
22719 (set_attr "mode" "SI")])
22721 (define_insn "*rep_stosqi"
22722 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
22723 (set (match_operand:P 0 "register_operand" "=D")
22724 (plus:P (match_operand:P 3 "register_operand" "0")
22725 (match_operand:P 4 "register_operand" "1")))
22726 (set (mem:BLK (match_dup 3))
22728 (use (match_operand:QI 2 "register_operand" "a"))
22729 (use (match_dup 4))]
22730 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
22731 && ix86_check_no_addr_space (insn)"
22733 [(set_attr "type" "str")
22734 (set_attr "prefix_rep" "1")
22735 (set_attr "memory" "store")
22736 (set (attr "prefix_rex")
22738 (match_test "<P:MODE>mode == DImode")
22740 (const_string "*")))
22741 (set_attr "mode" "QI")])
22743 (define_expand "cmpmemsi"
22744 [(set (match_operand:SI 0 "register_operand" "")
22745 (compare:SI (match_operand:BLK 1 "memory_operand" "")
22746 (match_operand:BLK 2 "memory_operand" "") ) )
22747 (use (match_operand 3 "general_operand"))
22748 (use (match_operand 4 "immediate_operand"))]
22751 if (ix86_expand_cmpstrn_or_cmpmem (operands[0], operands[1],
22752 operands[2], operands[3],
22753 operands[4], false))
22759 (define_expand "cmpstrnsi"
22760 [(set (match_operand:SI 0 "register_operand")
22761 (compare:SI (match_operand:BLK 1 "general_operand")
22762 (match_operand:BLK 2 "general_operand")))
22763 (use (match_operand 3 "general_operand"))
22764 (use (match_operand 4 "immediate_operand"))]
22767 if (ix86_expand_cmpstrn_or_cmpmem (operands[0], operands[1],
22768 operands[2], operands[3],
22769 operands[4], true))
22775 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
22777 (define_expand "cmpintqi"
22778 [(set (match_dup 1)
22779 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
22781 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
22782 (parallel [(set (match_operand:QI 0 "register_operand")
22783 (minus:QI (match_dup 1)
22785 (clobber (reg:CC FLAGS_REG))])]
22788 operands[1] = gen_reg_rtx (QImode);
22789 operands[2] = gen_reg_rtx (QImode);
22792 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
22793 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
22795 (define_expand "cmpstrnqi_nz_1"
22796 [(parallel [(set (reg:CC FLAGS_REG)
22797 (compare:CC (match_operand 4 "memory_operand")
22798 (match_operand 5 "memory_operand")))
22799 (use (match_operand 2 "register_operand"))
22800 (use (match_operand:SI 3 "immediate_operand"))
22801 (clobber (match_operand 0 "register_operand"))
22802 (clobber (match_operand 1 "register_operand"))
22803 (clobber (match_dup 2))])]
22807 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22810 (define_insn "*cmpstrnqi_nz_1"
22811 [(set (reg:CC FLAGS_REG)
22812 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
22813 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
22814 (use (match_operand:P 6 "register_operand" "2"))
22815 (use (match_operand:SI 3 "immediate_operand" "i"))
22816 (clobber (match_operand:P 0 "register_operand" "=S"))
22817 (clobber (match_operand:P 1 "register_operand" "=D"))
22818 (clobber (match_operand:P 2 "register_operand" "=c"))]
22819 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22820 && ix86_check_no_addr_space (insn)"
22822 [(set_attr "type" "str")
22823 (set_attr "mode" "QI")
22824 (set (attr "prefix_rex")
22826 (match_test "<P:MODE>mode == DImode")
22828 (const_string "*")))
22829 (set_attr "prefix_rep" "1")])
22831 ;; The same, but the count is not known to not be zero.
22833 (define_expand "cmpstrnqi_1"
22834 [(parallel [(set (reg:CC FLAGS_REG)
22835 (if_then_else:CC (ne (match_operand 2 "register_operand")
22837 (compare:CC (match_operand 4 "memory_operand")
22838 (match_operand 5 "memory_operand"))
22840 (use (match_operand:SI 3 "immediate_operand"))
22841 (use (reg:CC FLAGS_REG))
22842 (clobber (match_operand 0 "register_operand"))
22843 (clobber (match_operand 1 "register_operand"))
22844 (clobber (match_dup 2))])]
22848 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22851 (define_insn "*cmpstrnqi_1"
22852 [(set (reg:CC FLAGS_REG)
22853 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
22855 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
22856 (mem:BLK (match_operand:P 5 "register_operand" "1")))
22858 (use (match_operand:SI 3 "immediate_operand" "i"))
22859 (use (reg:CC FLAGS_REG))
22860 (clobber (match_operand:P 0 "register_operand" "=S"))
22861 (clobber (match_operand:P 1 "register_operand" "=D"))
22862 (clobber (match_operand:P 2 "register_operand" "=c"))]
22863 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22864 && ix86_check_no_addr_space (insn)"
22866 [(set_attr "type" "str")
22867 (set_attr "mode" "QI")
22868 (set (attr "prefix_rex")
22870 (match_test "<P:MODE>mode == DImode")
22872 (const_string "*")))
22873 (set_attr "prefix_rep" "1")])
22875 (define_expand "strlen<mode>"
22876 [(set (match_operand:P 0 "register_operand")
22877 (unspec:P [(match_operand:BLK 1 "general_operand")
22878 (match_operand:QI 2 "immediate_operand")
22879 (match_operand 3 "immediate_operand")]
22883 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
22889 (define_expand "strlenqi_1"
22890 [(parallel [(set (match_operand 0 "register_operand")
22892 (clobber (match_operand 1 "register_operand"))
22893 (clobber (reg:CC FLAGS_REG))])]
22897 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22900 (define_insn "*strlenqi_1"
22901 [(set (match_operand:P 0 "register_operand" "=&c")
22902 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
22903 (match_operand:QI 2 "register_operand" "a")
22904 (match_operand:P 3 "immediate_operand" "i")
22905 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
22906 (clobber (match_operand:P 1 "register_operand" "=D"))
22907 (clobber (reg:CC FLAGS_REG))]
22908 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
22909 && ix86_check_no_addr_space (insn)"
22910 "%^repnz{%;} scasb"
22911 [(set_attr "type" "str")
22912 (set_attr "mode" "QI")
22913 (set (attr "prefix_rex")
22915 (match_test "<P:MODE>mode == DImode")
22917 (const_string "*")))
22918 (set_attr "prefix_rep" "1")])
22920 ;; Peephole optimizations to clean up after cmpstrn*. This should be
22921 ;; handled in combine, but it is not currently up to the task.
22922 ;; When used for their truth value, the cmpstrn* expanders generate
22931 ;; The intermediate three instructions are unnecessary.
22933 ;; This one handles cmpstrn*_nz_1...
22936 (set (reg:CC FLAGS_REG)
22937 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
22938 (mem:BLK (match_operand 5 "register_operand"))))
22939 (use (match_operand 6 "register_operand"))
22940 (use (match_operand:SI 3 "immediate_operand"))
22941 (clobber (match_operand 0 "register_operand"))
22942 (clobber (match_operand 1 "register_operand"))
22943 (clobber (match_operand 2 "register_operand"))])
22944 (set (match_operand:QI 7 "register_operand")
22945 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
22946 (set (match_operand:QI 8 "register_operand")
22947 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
22948 (set (reg FLAGS_REG)
22949 (compare (match_dup 7) (match_dup 8)))
22951 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
22953 (set (reg:CC FLAGS_REG)
22954 (compare:CC (mem:BLK (match_dup 4))
22955 (mem:BLK (match_dup 5))))
22956 (use (match_dup 6))
22957 (use (match_dup 3))
22958 (clobber (match_dup 0))
22959 (clobber (match_dup 1))
22960 (clobber (match_dup 2))])])
22962 ;; ...and this one handles cmpstrn*_1.
22965 (set (reg:CC FLAGS_REG)
22966 (if_then_else:CC (ne (match_operand 6 "register_operand")
22968 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
22969 (mem:BLK (match_operand 5 "register_operand")))
22971 (use (match_operand:SI 3 "immediate_operand"))
22972 (use (reg:CC FLAGS_REG))
22973 (clobber (match_operand 0 "register_operand"))
22974 (clobber (match_operand 1 "register_operand"))
22975 (clobber (match_operand 2 "register_operand"))])
22976 (set (match_operand:QI 7 "register_operand")
22977 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
22978 (set (match_operand:QI 8 "register_operand")
22979 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
22980 (set (reg FLAGS_REG)
22981 (compare (match_dup 7) (match_dup 8)))
22983 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
22985 (set (reg:CC FLAGS_REG)
22986 (if_then_else:CC (ne (match_dup 6)
22988 (compare:CC (mem:BLK (match_dup 4))
22989 (mem:BLK (match_dup 5)))
22991 (use (match_dup 3))
22992 (use (reg:CC FLAGS_REG))
22993 (clobber (match_dup 0))
22994 (clobber (match_dup 1))
22995 (clobber (match_dup 2))])])
22997 ;; Conditional move instructions.
22999 (define_expand "mov<mode>cc"
23000 [(set (match_operand:SWIM 0 "register_operand")
23001 (if_then_else:SWIM (match_operand 1 "comparison_operator")
23002 (match_operand:SWIM 2 "<general_operand>")
23003 (match_operand:SWIM 3 "<general_operand>")))]
23005 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
23007 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
23008 ;; the register first winds up with `sbbl $0,reg', which is also weird.
23009 ;; So just document what we're doing explicitly.
23011 (define_expand "x86_mov<mode>cc_0_m1"
23013 [(set (match_operand:SWI48 0 "register_operand")
23014 (if_then_else:SWI48
23015 (match_operator:SWI48 2 "ix86_carry_flag_operator"
23016 [(match_operand 1 "flags_reg_operand")
23020 (clobber (reg:CC FLAGS_REG))])])
23022 (define_insn "*x86_mov<mode>cc_0_m1"
23023 [(set (match_operand:SWI48 0 "register_operand" "=r")
23024 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
23025 [(reg FLAGS_REG) (const_int 0)])
23028 (clobber (reg:CC FLAGS_REG))]
23030 "sbb{<imodesuffix>}\t%0, %0"
23031 [(set_attr "type" "alu1")
23032 (set_attr "use_carry" "1")
23033 (set_attr "pent_pair" "pu")
23034 (set_attr "mode" "<MODE>")
23035 (set_attr "length_immediate" "0")])
23037 (define_insn "*x86_mov<mode>cc_0_m1_se"
23038 [(set (match_operand:SWI48 0 "register_operand" "=r")
23039 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
23040 [(reg FLAGS_REG) (const_int 0)])
23043 (clobber (reg:CC FLAGS_REG))]
23045 "sbb{<imodesuffix>}\t%0, %0"
23046 [(set_attr "type" "alu1")
23047 (set_attr "use_carry" "1")
23048 (set_attr "pent_pair" "pu")
23049 (set_attr "mode" "<MODE>")
23050 (set_attr "length_immediate" "0")])
23052 (define_insn "*x86_mov<mode>cc_0_m1_neg"
23053 [(set (match_operand:SWI 0 "register_operand" "=<r>")
23054 (neg:SWI (match_operator 1 "ix86_carry_flag_operator"
23055 [(reg FLAGS_REG) (const_int 0)])))
23056 (clobber (reg:CC FLAGS_REG))]
23058 "sbb{<imodesuffix>}\t%0, %0"
23059 [(set_attr "type" "alu1")
23060 (set_attr "use_carry" "1")
23061 (set_attr "pent_pair" "pu")
23062 (set_attr "mode" "<MODE>")
23063 (set_attr "length_immediate" "0")])
23065 (define_expand "x86_mov<mode>cc_0_m1_neg"
23067 [(set (match_operand:SWI48 0 "register_operand")
23068 (neg:SWI48 (ltu:SWI48 (reg:CCC FLAGS_REG) (const_int 0))))
23069 (clobber (reg:CC FLAGS_REG))])])
23072 [(set (match_operand:SWI48 0 "register_operand")
23075 (match_operand 1 "int_nonimmediate_operand")
23076 (match_operand 2 "const_int_operand"))))]
23077 "x86_64_immediate_operand (operands[2], VOIDmode)
23078 && INTVAL (operands[2]) != -1
23079 && INTVAL (operands[2]) != 2147483647"
23080 [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
23082 (neg:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))))]
23083 "operands[2] = GEN_INT (INTVAL (operands[2]) + 1);")
23086 [(set (match_operand:SWI 0 "register_operand")
23089 (match_operand 1 "int_nonimmediate_operand")
23092 [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (const_int 1)))
23094 (neg:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))))])
23097 [(set (match_operand:SWI 0 "register_operand")
23100 (match_operand 1 "int_nonimmediate_operand")
23103 [(set (reg:CCC FLAGS_REG)
23104 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
23106 (neg:SWI (ltu:SWI (reg:CCC FLAGS_REG) (const_int 0))))])
23108 (define_insn "*mov<mode>cc_noc"
23109 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
23110 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
23111 [(reg FLAGS_REG) (const_int 0)])
23112 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
23113 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
23114 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23116 cmov%O2%C1\t{%2, %0|%0, %2}
23117 cmov%O2%c1\t{%3, %0|%0, %3}"
23118 [(set_attr "type" "icmov")
23119 (set_attr "mode" "<MODE>")])
23121 (define_insn "*movsicc_noc_zext"
23122 [(set (match_operand:DI 0 "register_operand" "=r,r")
23123 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
23124 [(reg FLAGS_REG) (const_int 0)])
23126 (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
23128 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
23130 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23132 cmov%O2%C1\t{%2, %k0|%k0, %2}
23133 cmov%O2%c1\t{%3, %k0|%k0, %3}"
23134 [(set_attr "type" "icmov")
23135 (set_attr "mode" "SI")])
23137 (define_insn "*movsicc_noc_zext_1"
23138 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r")
23140 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
23141 [(reg FLAGS_REG) (const_int 0)])
23142 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
23143 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
23145 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23147 cmov%O2%C1\t{%2, %k0|%k0, %2}
23148 cmov%O2%c1\t{%3, %k0|%k0, %3}"
23149 [(set_attr "type" "icmov")
23150 (set_attr "mode" "SI")])
23153 ;; Don't do conditional moves with memory inputs. This splitter helps
23154 ;; register starved x86_32 by forcing inputs into registers before reload.
23156 [(set (match_operand:SWI248 0 "register_operand")
23157 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
23158 [(reg FLAGS_REG) (const_int 0)])
23159 (match_operand:SWI248 2 "nonimmediate_operand")
23160 (match_operand:SWI248 3 "nonimmediate_operand")))]
23161 "!TARGET_64BIT && TARGET_CMOVE
23162 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23163 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23164 && can_create_pseudo_p ()
23165 && optimize_insn_for_speed_p ()"
23166 [(set (match_dup 0)
23167 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
23169 operands[2] = force_reg (<MODE>mode, operands[2]);
23170 operands[3] = force_reg (<MODE>mode, operands[3]);
23173 (define_insn "*movqicc_noc"
23174 [(set (match_operand:QI 0 "register_operand" "=r,r")
23175 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
23176 [(reg FLAGS_REG) (const_int 0)])
23177 (match_operand:QI 2 "register_operand" "r,0")
23178 (match_operand:QI 3 "register_operand" "0,r")))]
23179 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
23181 [(set_attr "type" "icmov")
23182 (set_attr "mode" "QI")])
23185 [(set (match_operand:SWI12 0 "register_operand")
23186 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
23187 [(reg FLAGS_REG) (const_int 0)])
23188 (match_operand:SWI12 2 "register_operand")
23189 (match_operand:SWI12 3 "register_operand")))]
23190 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
23191 && reload_completed"
23192 [(set (match_dup 0)
23193 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
23195 operands[0] = gen_lowpart (SImode, operands[0]);
23196 operands[2] = gen_lowpart (SImode, operands[2]);
23197 operands[3] = gen_lowpart (SImode, operands[3]);
23200 ;; Don't do conditional moves with memory inputs
23202 [(match_scratch:SWI248 4 "r")
23203 (set (match_operand:SWI248 0 "register_operand")
23204 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
23205 [(reg FLAGS_REG) (const_int 0)])
23206 (match_operand:SWI248 2 "nonimmediate_operand")
23207 (match_operand:SWI248 3 "nonimmediate_operand")))]
23208 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23209 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23210 && optimize_insn_for_speed_p ()"
23211 [(set (match_dup 4) (match_dup 5))
23213 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
23215 if (MEM_P (operands[2]))
23217 operands[5] = operands[2];
23218 operands[2] = operands[4];
23220 else if (MEM_P (operands[3]))
23222 operands[5] = operands[3];
23223 operands[3] = operands[4];
23226 gcc_unreachable ();
23230 [(match_scratch:SI 4 "r")
23231 (set (match_operand:DI 0 "register_operand")
23232 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
23233 [(reg FLAGS_REG) (const_int 0)])
23235 (match_operand:SI 2 "nonimmediate_operand"))
23237 (match_operand:SI 3 "nonimmediate_operand"))))]
23239 && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23240 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23241 && optimize_insn_for_speed_p ()"
23242 [(set (match_dup 4) (match_dup 5))
23244 (if_then_else:DI (match_dup 1)
23245 (zero_extend:DI (match_dup 2))
23246 (zero_extend:DI (match_dup 3))))]
23248 if (MEM_P (operands[2]))
23250 operands[5] = operands[2];
23251 operands[2] = operands[4];
23253 else if (MEM_P (operands[3]))
23255 operands[5] = operands[3];
23256 operands[3] = operands[4];
23259 gcc_unreachable ();
23262 ;; Eliminate a reg-reg mov by inverting the condition of a cmov (#1).
23263 ;; mov r0,r1; dec r0; mov r2,r3; cmov r0,r2 -> dec r1; mov r0,r3; cmov r0, r1
23265 [(set (match_operand:SWI248 0 "general_reg_operand")
23266 (match_operand:SWI248 1 "general_reg_operand"))
23267 (parallel [(set (reg FLAGS_REG) (match_operand 5))
23268 (set (match_dup 0) (match_operand:SWI248 6))])
23269 (set (match_operand:SWI248 2 "general_reg_operand")
23270 (match_operand:SWI248 3 "general_gr_operand"))
23272 (if_then_else:SWI248 (match_operator 4 "ix86_comparison_operator"
23273 [(reg FLAGS_REG) (const_int 0)])
23277 && REGNO (operands[2]) != REGNO (operands[0])
23278 && REGNO (operands[2]) != REGNO (operands[1])
23279 && peep2_reg_dead_p (1, operands[1])
23280 && peep2_reg_dead_p (4, operands[2])
23281 && !reg_overlap_mentioned_p (operands[0], operands[3])"
23282 [(parallel [(set (match_dup 7) (match_dup 8))
23283 (set (match_dup 1) (match_dup 9))])
23284 (set (match_dup 0) (match_dup 3))
23285 (set (match_dup 0) (if_then_else:SWI248 (match_dup 4)
23289 operands[7] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
23291 = ix86_replace_reg_with_reg (operands[5], operands[0], operands[1]);
23293 = ix86_replace_reg_with_reg (operands[6], operands[0], operands[1]);
23296 ;; Eliminate a reg-reg mov by inverting the condition of a cmov (#2).
23297 ;; mov r2,r3; mov r0,r1; dec r0; cmov r0,r2 -> dec r1; mov r0,r3; cmov r0, r1
23299 [(set (match_operand:SWI248 2 "general_reg_operand")
23300 (match_operand:SWI248 3 "general_gr_operand"))
23301 (set (match_operand:SWI248 0 "general_reg_operand")
23302 (match_operand:SWI248 1 "general_reg_operand"))
23303 (parallel [(set (reg FLAGS_REG) (match_operand 5))
23304 (set (match_dup 0) (match_operand:SWI248 6))])
23306 (if_then_else:SWI248 (match_operator 4 "ix86_comparison_operator"
23307 [(reg FLAGS_REG) (const_int 0)])
23311 && REGNO (operands[2]) != REGNO (operands[0])
23312 && REGNO (operands[2]) != REGNO (operands[1])
23313 && peep2_reg_dead_p (2, operands[1])
23314 && peep2_reg_dead_p (4, operands[2])
23315 && !reg_overlap_mentioned_p (operands[0], operands[3])
23316 && !reg_mentioned_p (operands[2], operands[6])"
23317 [(parallel [(set (match_dup 7) (match_dup 8))
23318 (set (match_dup 1) (match_dup 9))])
23319 (set (match_dup 0) (match_dup 3))
23320 (set (match_dup 0) (if_then_else:SWI248 (match_dup 4)
23324 operands[7] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (2)), 0, 0));
23326 = ix86_replace_reg_with_reg (operands[5], operands[0], operands[1]);
23328 = ix86_replace_reg_with_reg (operands[6], operands[0], operands[1]);
23331 (define_insn "movhf_mask"
23332 [(set (match_operand:HF 0 "nonimmediate_operand" "=v,m,v")
23334 [(match_operand:HF 1 "nonimmediate_operand" "m,v,v")
23335 (match_operand:HF 2 "nonimm_or_0_operand" "0C,0C,0C")
23336 (match_operand:QI 3 "register_operand" "Yk,Yk,Yk")]
23337 UNSPEC_MOVCC_MASK))]
23338 "TARGET_AVX512FP16"
23340 vmovsh\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}
23341 vmovsh\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}
23342 vmovsh\t{%d1, %0%{%3%}%N2|%0%{%3%}%N2, %d1}"
23343 [(set_attr "type" "ssemov")
23344 (set_attr "prefix" "evex")
23345 (set_attr "mode" "HF")])
23347 (define_expand "movhfcc"
23348 [(set (match_operand:HF 0 "register_operand")
23350 (match_operand 1 "comparison_operator")
23351 (match_operand:HF 2 "register_operand")
23352 (match_operand:HF 3 "register_operand")))]
23353 "TARGET_AVX512FP16"
23354 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
23356 (define_expand "mov<mode>cc"
23357 [(set (match_operand:X87MODEF 0 "register_operand")
23358 (if_then_else:X87MODEF
23359 (match_operand 1 "comparison_operator")
23360 (match_operand:X87MODEF 2 "register_operand")
23361 (match_operand:X87MODEF 3 "register_operand")))]
23362 "(TARGET_80387 && TARGET_CMOVE)
23363 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
23364 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
23366 (define_insn "*movxfcc_1"
23367 [(set (match_operand:XF 0 "register_operand" "=f,f")
23368 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
23369 [(reg FLAGS_REG) (const_int 0)])
23370 (match_operand:XF 2 "register_operand" "f,0")
23371 (match_operand:XF 3 "register_operand" "0,f")))]
23372 "TARGET_80387 && TARGET_CMOVE"
23374 fcmov%F1\t{%2, %0|%0, %2}
23375 fcmov%f1\t{%3, %0|%0, %3}"
23376 [(set_attr "type" "fcmov")
23377 (set_attr "mode" "XF")])
23379 (define_insn "*movdfcc_1"
23380 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
23381 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
23382 [(reg FLAGS_REG) (const_int 0)])
23383 (match_operand:DF 2 "nonimmediate_operand"
23385 (match_operand:DF 3 "nonimmediate_operand"
23386 "0 ,f,0 ,rm,0, rm")))]
23387 "TARGET_80387 && TARGET_CMOVE
23388 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23390 fcmov%F1\t{%2, %0|%0, %2}
23391 fcmov%f1\t{%3, %0|%0, %3}
23394 cmov%O2%C1\t{%2, %0|%0, %2}
23395 cmov%O2%c1\t{%3, %0|%0, %3}"
23396 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
23397 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
23398 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
23401 [(set (match_operand:DF 0 "general_reg_operand")
23402 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
23403 [(reg FLAGS_REG) (const_int 0)])
23404 (match_operand:DF 2 "nonimmediate_operand")
23405 (match_operand:DF 3 "nonimmediate_operand")))]
23406 "!TARGET_64BIT && reload_completed"
23407 [(set (match_dup 2)
23408 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
23410 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
23412 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
23413 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
23416 (define_insn "*movsfcc_1_387"
23417 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
23418 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
23419 [(reg FLAGS_REG) (const_int 0)])
23420 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
23421 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
23422 "TARGET_80387 && TARGET_CMOVE
23423 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23425 fcmov%F1\t{%2, %0|%0, %2}
23426 fcmov%f1\t{%3, %0|%0, %3}
23427 cmov%O2%C1\t{%2, %0|%0, %2}
23428 cmov%O2%c1\t{%3, %0|%0, %3}"
23429 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
23430 (set_attr "mode" "SF,SF,SI,SI")])
23432 ;; Don't do conditional moves with memory inputs. This splitter helps
23433 ;; register starved x86_32 by forcing inputs into registers before reload.
23435 [(set (match_operand:MODEF 0 "register_operand")
23436 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
23437 [(reg FLAGS_REG) (const_int 0)])
23438 (match_operand:MODEF 2 "nonimmediate_operand")
23439 (match_operand:MODEF 3 "nonimmediate_operand")))]
23440 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
23441 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23442 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23443 && can_create_pseudo_p ()
23444 && optimize_insn_for_speed_p ()"
23445 [(set (match_dup 0)
23446 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
23448 operands[2] = force_reg (<MODE>mode, operands[2]);
23449 operands[3] = force_reg (<MODE>mode, operands[3]);
23452 ;; Don't do conditional moves with memory inputs
23454 [(match_scratch:MODEF 4 "r")
23455 (set (match_operand:MODEF 0 "general_reg_operand")
23456 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
23457 [(reg FLAGS_REG) (const_int 0)])
23458 (match_operand:MODEF 2 "nonimmediate_operand")
23459 (match_operand:MODEF 3 "nonimmediate_operand")))]
23460 "(<MODE>mode != DFmode || TARGET_64BIT)
23461 && TARGET_80387 && TARGET_CMOVE
23462 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23463 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23464 && optimize_insn_for_speed_p ()"
23465 [(set (match_dup 4) (match_dup 5))
23467 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
23469 if (MEM_P (operands[2]))
23471 operands[5] = operands[2];
23472 operands[2] = operands[4];
23474 else if (MEM_P (operands[3]))
23476 operands[5] = operands[3];
23477 operands[3] = operands[4];
23480 gcc_unreachable ();
23483 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
23484 ;; the scalar versions to have only XMM registers as operands.
23486 ;; XOP conditional move
23487 (define_insn "*xop_pcmov_<mode>"
23488 [(set (match_operand:MODEF 0 "register_operand" "=x")
23489 (if_then_else:MODEF
23490 (match_operand:MODEF 1 "register_operand" "x")
23491 (match_operand:MODEF 2 "register_operand" "x")
23492 (match_operand:MODEF 3 "register_operand" "x")))]
23494 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
23495 [(set_attr "type" "sse4arg")
23496 (set_attr "mode" "TI")])
23498 ;; These versions of the min/max patterns are intentionally ignorant of
23499 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
23500 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
23501 ;; are undefined in this condition, we're certain this is correct.
23503 (define_insn "<code><mode>3"
23504 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
23506 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
23507 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
23508 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
23510 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
23511 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
23512 [(set_attr "isa" "noavx,avx")
23513 (set_attr "prefix" "orig,vex")
23514 (set_attr "type" "sseadd")
23515 (set_attr "mode" "<MODE>")])
23517 (define_insn "<code>hf3"
23518 [(set (match_operand:HF 0 "register_operand" "=v")
23520 (match_operand:HF 1 "nonimmediate_operand" "%v")
23521 (match_operand:HF 2 "nonimmediate_operand" "vm")))]
23522 "TARGET_AVX512FP16"
23523 "v<maxmin_float>sh\t{%2, %1, %0|%0, %1, %2}"
23524 [(set_attr "prefix" "evex")
23525 (set_attr "type" "sseadd")
23526 (set_attr "mode" "HF")])
23528 ;; These versions of the min/max patterns implement exactly the operations
23529 ;; min = (op1 < op2 ? op1 : op2)
23530 ;; max = (!(op1 < op2) ? op1 : op2)
23531 ;; Their operands are not commutative, and thus they may be used in the
23532 ;; presence of -0.0 and NaN.
23534 (define_insn "*ieee_s<ieee_maxmin>hf3"
23535 [(set (match_operand:HF 0 "register_operand" "=v")
23537 [(match_operand:HF 1 "register_operand" "v")
23538 (match_operand:HF 2 "nonimmediate_operand" "vm")]
23540 "TARGET_AVX512FP16"
23541 "v<ieee_maxmin>sh\t{%2, %1, %0|%0, %1, %2}"
23542 [(set_attr "prefix" "evex")
23543 (set_attr "type" "sseadd")
23544 (set_attr "mode" "HF")])
23546 (define_insn "*ieee_s<ieee_maxmin><mode>3"
23547 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
23549 [(match_operand:MODEF 1 "register_operand" "0,v")
23550 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
23552 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
23554 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
23555 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
23556 [(set_attr "isa" "noavx,avx")
23557 (set_attr "prefix" "orig,maybe_evex")
23558 (set_attr "type" "sseadd")
23559 (set_attr "mode" "<MODE>")])
23561 ;; Operands order in min/max instruction matters for signed zero and NANs.
23562 (define_insn_and_split "*ieee_max<mode>3_1"
23563 [(set (match_operand:MODEF 0 "register_operand")
23565 [(match_operand:MODEF 1 "register_operand")
23566 (match_operand:MODEF 2 "register_operand")
23568 (match_operand:MODEF 3 "register_operand")
23569 (match_operand:MODEF 4 "register_operand"))]
23571 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
23572 && (rtx_equal_p (operands[1], operands[3])
23573 && rtx_equal_p (operands[2], operands[4]))
23574 && ix86_pre_reload_split ()"
23577 [(set (match_dup 0)
23581 UNSPEC_IEEE_MAX))])
23583 (define_insn_and_split "*ieee_min<mode>3_1"
23584 [(set (match_operand:MODEF 0 "register_operand")
23586 [(match_operand:MODEF 1 "register_operand")
23587 (match_operand:MODEF 2 "register_operand")
23589 (match_operand:MODEF 3 "register_operand")
23590 (match_operand:MODEF 4 "register_operand"))]
23592 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
23593 && (rtx_equal_p (operands[1], operands[4])
23594 && rtx_equal_p (operands[2], operands[3]))
23595 && ix86_pre_reload_split ()"
23598 [(set (match_dup 0)
23602 UNSPEC_IEEE_MIN))])
23604 ;; Make two stack loads independent:
23606 ;; fld %st(0) -> fld bb
23607 ;; fmul bb fmul %st(1), %st
23609 ;; Actually we only match the last two instructions for simplicity.
23612 [(set (match_operand 0 "fp_register_operand")
23613 (match_operand 1 "fp_register_operand"))
23615 (match_operator 2 "binary_fp_operator"
23617 (match_operand 3 "memory_operand")]))]
23618 "REGNO (operands[0]) != REGNO (operands[1])"
23619 [(set (match_dup 0) (match_dup 3))
23622 [(match_dup 5) (match_dup 4)]))]
23624 operands[4] = operands[0];
23625 operands[5] = operands[1];
23627 /* The % modifier is not operational anymore in peephole2's, so we have to
23628 swap the operands manually in the case of addition and multiplication. */
23629 if (COMMUTATIVE_ARITH_P (operands[2]))
23630 std::swap (operands[4], operands[5]);
23634 [(set (match_operand 0 "fp_register_operand")
23635 (match_operand 1 "fp_register_operand"))
23637 (match_operator 2 "binary_fp_operator"
23638 [(match_operand 3 "memory_operand")
23640 "REGNO (operands[0]) != REGNO (operands[1])"
23641 [(set (match_dup 0) (match_dup 3))
23644 [(match_dup 4) (match_dup 5)]))]
23646 operands[4] = operands[0];
23647 operands[5] = operands[1];
23649 /* The % modifier is not operational anymore in peephole2's, so we have to
23650 swap the operands manually in the case of addition and multiplication. */
23651 if (COMMUTATIVE_ARITH_P (operands[2]))
23652 std::swap (operands[4], operands[5]);
23655 ;; Conditional addition patterns
23656 (define_expand "add<mode>cc"
23657 [(match_operand:SWI 0 "register_operand")
23658 (match_operand 1 "ordered_comparison_operator")
23659 (match_operand:SWI 2 "register_operand")
23660 (match_operand:SWI 3 "const_int_operand")]
23662 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
23664 ;; min/max patterns
23666 (define_code_attr maxmin_rel
23667 [(smax "GE") (smin "LE") (umax "GEU") (umin "LEU")])
23669 (define_expand "<code><mode>3"
23671 [(set (match_operand:SDWIM 0 "register_operand")
23673 (match_operand:SDWIM 1 "register_operand")
23674 (match_operand:SDWIM 2 "general_operand")))
23675 (clobber (reg:CC FLAGS_REG))])]
23677 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)")
23679 (define_insn_and_split "*<code><dwi>3_doubleword"
23680 [(set (match_operand:<DWI> 0 "register_operand")
23682 (match_operand:<DWI> 1 "register_operand")
23683 (match_operand:<DWI> 2 "general_operand")))
23684 (clobber (reg:CC FLAGS_REG))]
23686 && ix86_pre_reload_split ()"
23689 [(set (match_dup 0)
23690 (if_then_else:DWIH (match_dup 6)
23694 (if_then_else:DWIH (match_dup 6)
23698 operands[2] = force_reg (<DWI>mode, operands[2]);
23700 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
23702 rtx cmplo[2] = { operands[1], operands[2] };
23703 rtx cmphi[2] = { operands[4], operands[5] };
23705 enum rtx_code code = <maxmin_rel>;
23710 std::swap (cmplo[0], cmplo[1]);
23711 std::swap (cmphi[0], cmphi[1]);
23712 code = swap_condition (code);
23717 bool uns = (code == GEU);
23718 rtx (*sbb_insn) (machine_mode, rtx, rtx, rtx)
23719 = uns ? gen_sub3_carry_ccc : gen_sub3_carry_ccgz;
23721 emit_insn (gen_cmp_1 (<MODE>mode, cmplo[0], cmplo[1]));
23723 rtx tmp = gen_rtx_SCRATCH (<MODE>mode);
23724 emit_insn (sbb_insn (<MODE>mode, tmp, cmphi[0], cmphi[1]));
23726 rtx flags = gen_rtx_REG (uns ? CCCmode : CCGZmode, FLAGS_REG);
23727 operands[6] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
23733 gcc_unreachable ();
23737 (define_insn_and_split "*<code><mode>3_1"
23738 [(set (match_operand:SWI 0 "register_operand")
23740 (match_operand:SWI 1 "register_operand")
23741 (match_operand:SWI 2 "general_operand")))
23742 (clobber (reg:CC FLAGS_REG))]
23744 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
23745 && ix86_pre_reload_split ()"
23748 [(set (match_dup 0)
23749 (if_then_else:SWI (match_dup 3)
23753 machine_mode mode = <MODE>mode;
23754 rtx cmp_op = operands[2];
23756 operands[2] = force_reg (mode, cmp_op);
23758 enum rtx_code code = <maxmin_rel>;
23760 if (cmp_op == const1_rtx)
23762 /* Convert smax (x, 1) into (x > 0 ? x : 1).
23763 Convert umax (x, 1) into (x != 0 ? x : 1).
23764 Convert ?min (x, 1) into (x <= 0 ? x : 1). */
23765 cmp_op = const0_rtx;
23768 else if (code == GEU)
23771 /* Convert smin (x, -1) into (x < 0 ? x : -1). */
23772 else if (cmp_op == constm1_rtx && code == LE)
23774 cmp_op = const0_rtx;
23777 /* Convert smax (x, -1) into (x >= 0 ? x : -1). */
23778 else if (cmp_op == constm1_rtx && code == GE)
23779 cmp_op = const0_rtx;
23780 else if (cmp_op != const0_rtx)
23781 cmp_op = operands[2];
23783 machine_mode cmpmode = SELECT_CC_MODE (code, operands[1], cmp_op);
23784 rtx flags = gen_rtx_REG (cmpmode, FLAGS_REG);
23786 rtx tmp = gen_rtx_COMPARE (cmpmode, operands[1], cmp_op);
23787 emit_insn (gen_rtx_SET (flags, tmp));
23789 operands[3] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
23792 ;; Avoid clearing a register between a flags setting comparison and its use,
23793 ;; i.e. prefer "xorl %eax,%eax; test/cmp" over "test/cmp; movl $0, %eax".
23795 [(set (reg FLAGS_REG) (match_operand 0))
23796 (set (match_operand:SWI 1 "general_reg_operand") (const_int 0))]
23797 "peep2_regno_dead_p (0, FLAGS_REG)
23798 && !reg_overlap_mentioned_p (operands[1], operands[0])"
23799 [(set (match_dup 2) (match_dup 0))]
23801 operands[2] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
23802 ix86_expand_clear (operands[1]);
23805 ;; When optimizing for size, zeroing memory should use a register.
23807 [(match_scratch:SWI48 0 "r")
23808 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
23809 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))
23810 (set (match_operand:SWI48 3 "memory_operand") (const_int 0))
23811 (set (match_operand:SWI48 4 "memory_operand") (const_int 0))]
23812 "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
23815 ix86_expand_clear (operands[0]);
23816 emit_move_insn (operands[1], operands[0]);
23817 emit_move_insn (operands[2], operands[0]);
23818 emit_move_insn (operands[3], operands[0]);
23819 ix86_last_zero_store_uid
23820 = INSN_UID (emit_move_insn (operands[4], operands[0]));
23825 [(match_scratch:SWI48 0 "r")
23826 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
23827 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))]
23828 "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
23831 ix86_expand_clear (operands[0]);
23832 emit_move_insn (operands[1], operands[0]);
23833 ix86_last_zero_store_uid
23834 = INSN_UID (emit_move_insn (operands[2], operands[0]));
23839 [(match_scratch:SWI48 0 "r")
23840 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))]
23841 "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
23844 ix86_expand_clear (operands[0]);
23845 ix86_last_zero_store_uid
23846 = INSN_UID (emit_move_insn (operands[1], operands[0]));
23851 [(set (match_operand:SWI48 5 "memory_operand")
23852 (match_operand:SWI48 0 "general_reg_operand"))
23853 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
23854 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))
23855 (set (match_operand:SWI48 3 "memory_operand") (const_int 0))
23856 (set (match_operand:SWI48 4 "memory_operand") (const_int 0))]
23857 "optimize_insn_for_size_p ()
23858 && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
23861 emit_move_insn (operands[5], operands[0]);
23862 emit_move_insn (operands[1], operands[0]);
23863 emit_move_insn (operands[2], operands[0]);
23864 emit_move_insn (operands[3], operands[0]);
23865 ix86_last_zero_store_uid
23866 = INSN_UID (emit_move_insn (operands[4], operands[0]));
23871 [(set (match_operand:SWI48 3 "memory_operand")
23872 (match_operand:SWI48 0 "general_reg_operand"))
23873 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
23874 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))]
23875 "optimize_insn_for_size_p ()
23876 && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
23879 emit_move_insn (operands[3], operands[0]);
23880 emit_move_insn (operands[1], operands[0]);
23881 ix86_last_zero_store_uid
23882 = INSN_UID (emit_move_insn (operands[2], operands[0]));
23887 [(set (match_operand:SWI48 2 "memory_operand")
23888 (match_operand:SWI48 0 "general_reg_operand"))
23889 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))]
23890 "optimize_insn_for_size_p ()
23891 && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
23894 emit_move_insn (operands[2], operands[0]);
23895 ix86_last_zero_store_uid
23896 = INSN_UID (emit_move_insn (operands[1], operands[0]));
23900 ;; Reload dislikes loading constants directly into class_likely_spilled
23901 ;; hard registers. Try to tidy things up here.
23903 [(set (match_operand:SWI 0 "general_reg_operand")
23904 (match_operand:SWI 1 "x86_64_general_operand"))
23905 (set (match_operand:SWI 2 "general_reg_operand")
23907 "peep2_reg_dead_p (2, operands[0])"
23908 [(set (match_dup 2) (match_dup 1))])
23910 ;; Misc patterns (?)
23912 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
23913 ;; Otherwise there will be nothing to keep
23915 ;; [(set (reg ebp) (reg esp))]
23916 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
23917 ;; (clobber (eflags)]
23918 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
23920 ;; in proper program order.
23922 (define_insn "@pro_epilogue_adjust_stack_add_<mode>"
23923 [(set (match_operand:P 0 "register_operand" "=r,r")
23924 (plus:P (match_operand:P 1 "register_operand" "0,r")
23925 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
23926 (clobber (reg:CC FLAGS_REG))
23927 (clobber (mem:BLK (scratch)))]
23930 switch (get_attr_type (insn))
23933 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
23936 gcc_assert (rtx_equal_p (operands[0], operands[1]));
23937 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
23938 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
23940 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
23943 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
23944 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
23947 [(set (attr "type")
23948 (cond [(and (eq_attr "alternative" "0")
23949 (not (match_test "TARGET_OPT_AGU")))
23950 (const_string "alu")
23951 (match_operand:<MODE> 2 "const0_operand")
23952 (const_string "imov")
23954 (const_string "lea")))
23955 (set (attr "length_immediate")
23956 (cond [(eq_attr "type" "imov")
23958 (and (eq_attr "type" "alu")
23959 (match_operand 2 "const128_operand"))
23962 (const_string "*")))
23963 (set_attr "mode" "<MODE>")])
23965 (define_insn "@pro_epilogue_adjust_stack_sub_<mode>"
23966 [(set (match_operand:P 0 "register_operand" "=r")
23967 (minus:P (match_operand:P 1 "register_operand" "0")
23968 (match_operand:P 2 "register_operand" "r")))
23969 (clobber (reg:CC FLAGS_REG))
23970 (clobber (mem:BLK (scratch)))]
23972 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
23973 [(set_attr "type" "alu")
23974 (set_attr "mode" "<MODE>")])
23976 (define_insn "@allocate_stack_worker_probe_<mode>"
23977 [(set (match_operand:P 0 "register_operand" "=a")
23978 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
23979 UNSPECV_STACK_PROBE))
23980 (clobber (reg:CC FLAGS_REG))]
23981 "ix86_target_stack_probe ()"
23982 "call\t___chkstk_ms"
23983 [(set_attr "type" "multi")
23984 (set_attr "length" "5")])
23986 (define_expand "allocate_stack"
23987 [(match_operand 0 "register_operand")
23988 (match_operand 1 "general_operand")]
23989 "ix86_target_stack_probe ()"
23993 #ifndef CHECK_STACK_LIMIT
23994 #define CHECK_STACK_LIMIT 0
23997 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
23998 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
24002 x = copy_to_mode_reg (Pmode, operands[1]);
24004 emit_insn (gen_allocate_stack_worker_probe (Pmode, x, x));
24007 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
24008 stack_pointer_rtx, 0, OPTAB_DIRECT);
24010 if (x != stack_pointer_rtx)
24011 emit_move_insn (stack_pointer_rtx, x);
24013 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
24017 (define_expand "probe_stack"
24018 [(match_operand 0 "memory_operand")]
24021 emit_insn (gen_probe_stack_1
24022 (word_mode, operands[0], const0_rtx));
24026 ;; Use OR for stack probes, this is shorter.
24027 (define_insn "@probe_stack_1_<mode>"
24028 [(set (match_operand:W 0 "memory_operand" "=m")
24029 (unspec:W [(match_operand:W 1 "const0_operand")]
24030 UNSPEC_PROBE_STACK))
24031 (clobber (reg:CC FLAGS_REG))]
24033 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
24034 [(set_attr "type" "alu1")
24035 (set_attr "mode" "<MODE>")
24036 (set_attr "length_immediate" "1")])
24038 (define_insn "@adjust_stack_and_probe_<mode>"
24039 [(set (match_operand:P 0 "register_operand" "=r")
24040 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
24041 UNSPECV_PROBE_STACK_RANGE))
24042 (set (reg:P SP_REG)
24043 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand")))
24044 (clobber (reg:CC FLAGS_REG))
24045 (clobber (mem:BLK (scratch)))]
24047 "* return output_adjust_stack_and_probe (operands[0]);"
24048 [(set_attr "type" "multi")])
24050 (define_insn "@probe_stack_range_<mode>"
24051 [(set (match_operand:P 0 "register_operand" "=r")
24052 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
24053 (match_operand:P 2 "const_int_operand")]
24054 UNSPECV_PROBE_STACK_RANGE))
24055 (clobber (reg:CC FLAGS_REG))]
24057 "* return output_probe_stack_range (operands[0], operands[2]);"
24058 [(set_attr "type" "multi")])
24060 (define_expand "builtin_setjmp_receiver"
24061 [(label_ref (match_operand 0))]
24062 "!TARGET_64BIT && flag_pic"
24068 rtx_code_label *label_rtx = gen_label_rtx ();
24069 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
24070 xops[0] = xops[1] = pic_offset_table_rtx;
24071 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
24072 ix86_expand_binary_operator (MINUS, SImode, xops);
24076 emit_insn (gen_set_got (pic_offset_table_rtx));
24080 (define_expand "save_stack_nonlocal"
24081 [(set (match_operand 0 "memory_operand")
24082 (match_operand 1 "register_operand"))]
24087 if (flag_cf_protection & CF_RETURN)
24089 /* Copy shadow stack pointer to the first slot
24090 and stack pointer to the second slot. */
24091 rtx ssp_slot = adjust_address (operands[0], word_mode, 0);
24092 stack_slot = adjust_address (operands[0], Pmode, UNITS_PER_WORD);
24094 rtx reg_ssp = force_reg (word_mode, const0_rtx);
24095 emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
24096 emit_move_insn (ssp_slot, reg_ssp);
24099 stack_slot = adjust_address (operands[0], Pmode, 0);
24100 emit_move_insn (stack_slot, operands[1]);
24104 (define_expand "restore_stack_nonlocal"
24105 [(set (match_operand 0 "register_operand" "")
24106 (match_operand 1 "memory_operand" ""))]
24111 if (flag_cf_protection & CF_RETURN)
24113 /* Restore shadow stack pointer from the first slot
24114 and stack pointer from the second slot. */
24115 rtx ssp_slot = adjust_address (operands[1], word_mode, 0);
24116 stack_slot = adjust_address (operands[1], Pmode, UNITS_PER_WORD);
24118 /* Get the current shadow stack pointer. The code below will check if
24119 SHSTK feature is enabled. If it is not enabled the RDSSP instruction
24121 rtx reg_ssp = force_reg (word_mode, const0_rtx);
24122 emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
24124 /* Compare through subtraction the saved and the current ssp
24125 to decide if ssp has to be adjusted. */
24126 reg_ssp = expand_simple_binop (word_mode, MINUS,
24128 reg_ssp, 1, OPTAB_DIRECT);
24130 /* Compare and jump over adjustment code. */
24131 rtx noadj_label = gen_label_rtx ();
24132 emit_cmp_and_jump_insns (reg_ssp, const0_rtx, EQ, NULL_RTX,
24133 word_mode, 1, noadj_label);
24135 /* Compute the number of frames to adjust. */
24136 rtx reg_adj = gen_lowpart (ptr_mode, reg_ssp);
24137 rtx reg_adj_neg = expand_simple_unop (ptr_mode, NEG, reg_adj,
24140 reg_adj = expand_simple_binop (ptr_mode, LSHIFTRT, reg_adj_neg,
24141 GEN_INT (exact_log2 (UNITS_PER_WORD)),
24142 reg_adj, 1, OPTAB_DIRECT);
24144 /* Check if number of frames <= 255 so no loop is needed. */
24145 rtx inc_label = gen_label_rtx ();
24146 emit_cmp_and_jump_insns (reg_adj, GEN_INT (255), LEU, NULL_RTX,
24147 ptr_mode, 1, inc_label);
24149 /* Adjust the ssp in a loop. */
24150 rtx loop_label = gen_label_rtx ();
24151 emit_label (loop_label);
24152 LABEL_NUSES (loop_label) = 1;
24154 rtx reg_255 = force_reg (word_mode, GEN_INT (255));
24155 emit_insn (gen_incssp (word_mode, reg_255));
24157 reg_adj = expand_simple_binop (ptr_mode, MINUS,
24158 reg_adj, GEN_INT (255),
24159 reg_adj, 1, OPTAB_DIRECT);
24161 /* Compare and jump to the loop label. */
24162 emit_cmp_and_jump_insns (reg_adj, GEN_INT (255), GTU, NULL_RTX,
24163 ptr_mode, 1, loop_label);
24165 emit_label (inc_label);
24166 LABEL_NUSES (inc_label) = 1;
24168 emit_insn (gen_incssp (word_mode, reg_ssp));
24170 emit_label (noadj_label);
24171 LABEL_NUSES (noadj_label) = 1;
24174 stack_slot = adjust_address (operands[1], Pmode, 0);
24175 emit_move_insn (operands[0], stack_slot);
24179 (define_expand "stack_protect_set"
24180 [(match_operand 0 "memory_operand")
24181 (match_operand 1 "memory_operand")]
24184 rtx scratch = gen_reg_rtx (word_mode);
24186 emit_insn (gen_stack_protect_set_1
24187 (ptr_mode, word_mode, operands[0], operands[1], scratch));
24191 (define_insn "@stack_protect_set_1_<PTR:mode>_<SWI48:mode>"
24192 [(set (match_operand:PTR 0 "memory_operand" "=m")
24193 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
24195 (set (match_operand:SWI48 2 "register_operand" "=&r") (const_int 0))
24196 (clobber (reg:CC FLAGS_REG))]
24199 output_asm_insn ("mov{<PTR:imodesuffix>}\t{%1, %<PTR:k>2|%<PTR:k>2, %1}",
24201 output_asm_insn ("mov{<PTR:imodesuffix>}\t{%<PTR:k>2, %0|%0, %<PTR:k>2}",
24203 return "xor{l}\t%k2, %k2";
24205 [(set_attr "type" "multi")])
24207 ;; Patterns and peephole2s to optimize stack_protect_set_1_<mode>
24208 ;; immediately followed by *mov{s,d}i_internal, where we can avoid
24209 ;; the xor{l} above. We don't split this, so that scheduling or
24210 ;; anything else doesn't separate the *stack_protect_set* pattern from
24211 ;; the set of the register that overwrites the register with a new value.
24214 [(parallel [(set (match_operand:PTR 0 "memory_operand")
24215 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
24217 (set (match_operand:W 2 "general_reg_operand") (const_int 0))
24218 (clobber (reg:CC FLAGS_REG))])
24219 (parallel [(set (match_operand:SWI48 3 "general_reg_operand")
24220 (match_operand:SWI48 4 "const0_operand"))
24221 (clobber (reg:CC FLAGS_REG))])]
24222 "peep2_reg_dead_p (0, operands[3])
24223 && peep2_reg_dead_p (1, operands[2])"
24224 [(parallel [(set (match_dup 0)
24225 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
24226 (set (match_dup 3) (const_int 0))
24227 (clobber (reg:CC FLAGS_REG))])])
24229 (define_insn "*stack_protect_set_2_<mode>_si"
24230 [(set (match_operand:PTR 0 "memory_operand" "=m")
24231 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
24233 (set (match_operand:SI 1 "register_operand" "=&r")
24234 (match_operand:SI 2 "general_operand" "g"))]
24237 output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
24238 output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
24239 if (pic_32bit_operand (operands[2], SImode)
24240 || ix86_use_lea_for_mov (insn, operands + 1))
24241 return "lea{l}\t{%E2, %1|%1, %E2}";
24243 return "mov{l}\t{%2, %1|%1, %2}";
24245 [(set_attr "type" "multi")
24246 (set_attr "length" "24")])
24248 (define_insn "*stack_protect_set_2_<mode>_di"
24249 [(set (match_operand:PTR 0 "memory_operand" "=m,m,m")
24250 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m,m,m")]
24252 (set (match_operand:DI 1 "register_operand" "=&r,&r,&r")
24253 (match_operand:DI 2 "general_operand" "Z,rem,i"))]
24254 "TARGET_64BIT && reload_completed"
24256 output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
24257 output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
24258 if (pic_32bit_operand (operands[2], DImode))
24259 return "lea{q}\t{%E2, %1|%1, %E2}";
24260 else if (which_alternative == 0)
24261 return "mov{l}\t{%k2, %k1|%k1, %k2}";
24262 else if (which_alternative == 2)
24263 return "movabs{q}\t{%2, %1|%1, %2}";
24264 else if (ix86_use_lea_for_mov (insn, operands + 1))
24265 return "lea{q}\t{%E2, %1|%1, %E2}";
24267 return "mov{q}\t{%2, %1|%1, %2}";
24269 [(set_attr "type" "multi")
24270 (set_attr "length" "24")])
24273 [(parallel [(set (match_operand:PTR 0 "memory_operand")
24274 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
24276 (set (match_operand:W 2 "general_reg_operand") (const_int 0))
24277 (clobber (reg:CC FLAGS_REG))])
24278 (set (match_operand:SWI48 3 "general_reg_operand")
24279 (match_operand:SWI48 4 "general_gr_operand"))]
24280 "peep2_reg_dead_p (0, operands[3])
24281 && peep2_reg_dead_p (1, operands[2])"
24282 [(parallel [(set (match_dup 0)
24283 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
24284 (set (match_dup 3) (match_dup 4))])])
24286 (define_expand "stack_protect_test"
24287 [(match_operand 0 "memory_operand")
24288 (match_operand 1 "memory_operand")
24292 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
24294 emit_insn (gen_stack_protect_test_1
24295 (ptr_mode, flags, operands[0], operands[1]));
24297 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
24298 flags, const0_rtx, operands[2]));
24302 (define_insn "@stack_protect_test_1_<mode>"
24303 [(set (match_operand:CCZ 0 "flags_reg_operand")
24304 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
24305 (match_operand:PTR 2 "memory_operand" "m")]
24307 (clobber (match_scratch:PTR 3 "=&r"))]
24310 output_asm_insn ("mov{<imodesuffix>}\t{%1, %3|%3, %1}", operands);
24311 return "sub{<imodesuffix>}\t{%2, %3|%3, %2}";
24313 [(set_attr "type" "multi")])
24315 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
24316 ;; Do not split instructions with mask registers.
24318 [(set (match_operand 0 "general_reg_operand")
24319 (match_operator 3 "promotable_binary_operator"
24320 [(match_operand 1 "general_reg_operand")
24321 (match_operand 2 "aligned_operand")]))
24322 (clobber (reg:CC FLAGS_REG))]
24323 "! TARGET_PARTIAL_REG_STALL && reload_completed
24324 && ((GET_MODE (operands[0]) == HImode
24325 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
24326 /* ??? next two lines just !satisfies_constraint_K (...) */
24327 || !CONST_INT_P (operands[2])
24328 || satisfies_constraint_K (operands[2])))
24329 || (GET_MODE (operands[0]) == QImode
24330 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
24331 [(parallel [(set (match_dup 0)
24332 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
24333 (clobber (reg:CC FLAGS_REG))])]
24335 operands[0] = gen_lowpart (SImode, operands[0]);
24336 operands[1] = gen_lowpart (SImode, operands[1]);
24337 if (GET_CODE (operands[3]) != ASHIFT)
24338 operands[2] = gen_lowpart (SImode, operands[2]);
24339 operands[3] = shallow_copy_rtx (operands[3]);
24340 PUT_MODE (operands[3], SImode);
24343 ; Promote the QImode tests, as i386 has encoding of the AND
24344 ; instruction with 32-bit sign-extended immediate and thus the
24345 ; instruction size is unchanged, except in the %eax case for
24346 ; which it is increased by one byte, hence the ! optimize_size.
24348 [(set (match_operand 0 "flags_reg_operand")
24349 (match_operator 2 "compare_operator"
24350 [(and (match_operand 3 "aligned_operand")
24351 (match_operand 4 "const_int_operand"))
24353 (set (match_operand 1 "register_operand")
24354 (and (match_dup 3) (match_dup 4)))]
24355 "! TARGET_PARTIAL_REG_STALL && reload_completed
24356 && optimize_insn_for_speed_p ()
24357 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
24358 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
24359 /* Ensure that the operand will remain sign-extended immediate. */
24360 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
24361 [(parallel [(set (match_dup 0)
24362 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
24365 (and:SI (match_dup 3) (match_dup 4)))])]
24368 = gen_int_mode (INTVAL (operands[4])
24369 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
24370 operands[1] = gen_lowpart (SImode, operands[1]);
24371 operands[3] = gen_lowpart (SImode, operands[3]);
24374 ; Don't promote the QImode tests, as i386 doesn't have encoding of
24375 ; the TEST instruction with 32-bit sign-extended immediate and thus
24376 ; the instruction size would at least double, which is not what we
24377 ; want even with ! optimize_size.
24379 [(set (match_operand 0 "flags_reg_operand")
24380 (match_operator 1 "compare_operator"
24381 [(and (match_operand:HI 2 "aligned_operand")
24382 (match_operand:HI 3 "const_int_operand"))
24384 "! TARGET_PARTIAL_REG_STALL && reload_completed
24385 && ! TARGET_FAST_PREFIX
24386 && optimize_insn_for_speed_p ()
24387 /* Ensure that the operand will remain sign-extended immediate. */
24388 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
24389 [(set (match_dup 0)
24390 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
24394 = gen_int_mode (INTVAL (operands[3])
24395 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
24396 operands[2] = gen_lowpart (SImode, operands[2]);
24400 [(set (match_operand 0 "register_operand")
24401 (neg (match_operand 1 "register_operand")))
24402 (clobber (reg:CC FLAGS_REG))]
24403 "! TARGET_PARTIAL_REG_STALL && reload_completed
24404 && (GET_MODE (operands[0]) == HImode
24405 || (GET_MODE (operands[0]) == QImode
24406 && (TARGET_PROMOTE_QImode
24407 || optimize_insn_for_size_p ())))"
24408 [(parallel [(set (match_dup 0)
24409 (neg:SI (match_dup 1)))
24410 (clobber (reg:CC FLAGS_REG))])]
24412 operands[0] = gen_lowpart (SImode, operands[0]);
24413 operands[1] = gen_lowpart (SImode, operands[1]);
24416 ;; Do not split instructions with mask regs.
24418 [(set (match_operand 0 "general_reg_operand")
24419 (not (match_operand 1 "general_reg_operand")))]
24420 "! TARGET_PARTIAL_REG_STALL && reload_completed
24421 && (GET_MODE (operands[0]) == HImode
24422 || (GET_MODE (operands[0]) == QImode
24423 && (TARGET_PROMOTE_QImode
24424 || optimize_insn_for_size_p ())))"
24425 [(set (match_dup 0)
24426 (not:SI (match_dup 1)))]
24428 operands[0] = gen_lowpart (SImode, operands[0]);
24429 operands[1] = gen_lowpart (SImode, operands[1]);
24432 ;; RTL Peephole optimizations, run before sched2. These primarily look to
24433 ;; transform a complex memory operation into two memory to register operations.
24435 ;; Don't push memory operands
24437 [(set (match_operand:SWI 0 "push_operand")
24438 (match_operand:SWI 1 "memory_operand"))
24439 (match_scratch:SWI 2 "<r>")]
24440 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
24441 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
24442 [(set (match_dup 2) (match_dup 1))
24443 (set (match_dup 0) (match_dup 2))])
24445 ;; We need to handle SFmode only, because DFmode and XFmode are split to
24448 [(set (match_operand:SF 0 "push_operand")
24449 (match_operand:SF 1 "memory_operand"))
24450 (match_scratch:SF 2 "r")]
24451 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
24452 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
24453 [(set (match_dup 2) (match_dup 1))
24454 (set (match_dup 0) (match_dup 2))])
24456 ;; Don't move an immediate directly to memory when the instruction
24457 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
24459 [(match_scratch:SWI124 1 "<r>")
24460 (set (match_operand:SWI124 0 "memory_operand")
24462 "optimize_insn_for_speed_p ()
24463 && ((<MODE>mode == HImode
24464 && TARGET_LCP_STALL)
24465 || (!TARGET_USE_MOV0
24466 && TARGET_SPLIT_LONG_MOVES
24467 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
24468 && peep2_regno_dead_p (0, FLAGS_REG)"
24469 [(parallel [(set (match_dup 2) (const_int 0))
24470 (clobber (reg:CC FLAGS_REG))])
24471 (set (match_dup 0) (match_dup 1))]
24472 "operands[2] = gen_lowpart (SImode, operands[1]);")
24475 [(match_scratch:SWI124 2 "<r>")
24476 (set (match_operand:SWI124 0 "memory_operand")
24477 (match_operand:SWI124 1 "immediate_operand"))]
24478 "optimize_insn_for_speed_p ()
24479 && ((<MODE>mode == HImode
24480 && TARGET_LCP_STALL)
24481 || (TARGET_SPLIT_LONG_MOVES
24482 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
24483 [(set (match_dup 2) (match_dup 1))
24484 (set (match_dup 0) (match_dup 2))])
24486 ;; Don't compare memory with zero, load and use a test instead.
24488 [(set (match_operand 0 "flags_reg_operand")
24489 (match_operator 1 "compare_operator"
24490 [(match_operand:SI 2 "memory_operand")
24492 (match_scratch:SI 3 "r")]
24493 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
24494 [(set (match_dup 3) (match_dup 2))
24495 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
24497 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
24498 ;; Don't split NOTs with a displacement operand, because resulting XOR
24499 ;; will not be pairable anyway.
24501 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
24502 ;; represented using a modRM byte. The XOR replacement is long decoded,
24503 ;; so this split helps here as well.
24505 ;; Note: Can't do this as a regular split because we can't get proper
24506 ;; lifetime information then.
24509 [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
24510 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
24511 "optimize_insn_for_speed_p ()
24512 && ((TARGET_NOT_UNPAIRABLE
24513 && (!MEM_P (operands[0])
24514 || !memory_displacement_operand (operands[0], <MODE>mode)))
24515 || (TARGET_NOT_VECTORMODE
24516 && long_memory_operand (operands[0], <MODE>mode)))
24517 && peep2_regno_dead_p (0, FLAGS_REG)"
24518 [(parallel [(set (match_dup 0)
24519 (xor:SWI124 (match_dup 1) (const_int -1)))
24520 (clobber (reg:CC FLAGS_REG))])])
24522 ;; Non pairable "test imm, reg" instructions can be translated to
24523 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
24524 ;; byte opcode instead of two, have a short form for byte operands),
24525 ;; so do it for other CPUs as well. Given that the value was dead,
24526 ;; this should not create any new dependencies. Pass on the sub-word
24527 ;; versions if we're concerned about partial register stalls.
24530 [(set (match_operand 0 "flags_reg_operand")
24531 (match_operator 1 "compare_operator"
24532 [(and:SI (match_operand:SI 2 "register_operand")
24533 (match_operand:SI 3 "immediate_operand"))
24535 "ix86_match_ccmode (insn, CCNOmode)
24536 && (REGNO (operands[2]) != AX_REG
24537 || satisfies_constraint_K (operands[3]))
24538 && peep2_reg_dead_p (1, operands[2])"
24540 [(set (match_dup 0)
24541 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
24544 (and:SI (match_dup 2) (match_dup 3)))])])
24546 ;; We don't need to handle HImode case, because it will be promoted to SImode
24547 ;; on ! TARGET_PARTIAL_REG_STALL
24550 [(set (match_operand 0 "flags_reg_operand")
24551 (match_operator 1 "compare_operator"
24552 [(and:QI (match_operand:QI 2 "register_operand")
24553 (match_operand:QI 3 "immediate_operand"))
24555 "! TARGET_PARTIAL_REG_STALL
24556 && ix86_match_ccmode (insn, CCNOmode)
24557 && REGNO (operands[2]) != AX_REG
24558 && peep2_reg_dead_p (1, operands[2])"
24560 [(set (match_dup 0)
24561 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
24564 (and:QI (match_dup 2) (match_dup 3)))])])
24567 [(set (match_operand 0 "flags_reg_operand")
24568 (match_operator 1 "compare_operator"
24571 (match_operator:SWI248 4 "extract_operator"
24572 [(match_operand 2 "int248_register_operand")
24575 (match_operand 3 "const_int_operand"))
24577 "! TARGET_PARTIAL_REG_STALL
24578 && ix86_match_ccmode (insn, CCNOmode)
24579 && REGNO (operands[2]) != AX_REG
24580 && peep2_reg_dead_p (1, operands[2])"
24582 [(set (match_dup 0)
24586 (match_op_dup 4 [(match_dup 2)
24591 (set (zero_extract:SWI248 (match_dup 2)
24597 (match_op_dup 4 [(match_dup 2)
24600 (match_dup 3)) 0))])])
24602 ;; Don't do logical operations with memory inputs.
24604 [(match_scratch:SWI 2 "<r>")
24605 (parallel [(set (match_operand:SWI 0 "register_operand")
24606 (match_operator:SWI 3 "arith_or_logical_operator"
24608 (match_operand:SWI 1 "memory_operand")]))
24609 (clobber (reg:CC FLAGS_REG))])]
24610 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
24611 [(set (match_dup 2) (match_dup 1))
24612 (parallel [(set (match_dup 0)
24613 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
24614 (clobber (reg:CC FLAGS_REG))])])
24617 [(match_scratch:SWI 2 "<r>")
24618 (parallel [(set (match_operand:SWI 0 "register_operand")
24619 (match_operator:SWI 3 "arith_or_logical_operator"
24620 [(match_operand:SWI 1 "memory_operand")
24622 (clobber (reg:CC FLAGS_REG))])]
24623 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
24624 [(set (match_dup 2) (match_dup 1))
24625 (parallel [(set (match_dup 0)
24626 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
24627 (clobber (reg:CC FLAGS_REG))])])
24629 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when
24630 ;; the memory address refers to the destination of the load!
24633 [(set (match_operand:SWI 0 "general_reg_operand")
24634 (match_operand:SWI 1 "general_reg_operand"))
24635 (parallel [(set (match_dup 0)
24636 (match_operator:SWI 3 "commutative_operator"
24638 (match_operand:SWI 2 "memory_operand")]))
24639 (clobber (reg:CC FLAGS_REG))])]
24640 "REGNO (operands[0]) != REGNO (operands[1])
24641 && (<MODE>mode != QImode
24642 || any_QIreg_operand (operands[1], QImode))"
24643 [(set (match_dup 0) (match_dup 4))
24644 (parallel [(set (match_dup 0)
24645 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
24646 (clobber (reg:CC FLAGS_REG))])]
24649 = ix86_replace_reg_with_reg (operands[2], operands[0], operands[1]);
24653 [(set (match_operand 0 "mmx_reg_operand")
24654 (match_operand 1 "mmx_reg_operand"))
24656 (match_operator 3 "commutative_operator"
24658 (match_operand 2 "memory_operand")]))]
24659 "REGNO (operands[0]) != REGNO (operands[1])"
24660 [(set (match_dup 0) (match_dup 2))
24662 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
24665 [(set (match_operand 0 "sse_reg_operand")
24666 (match_operand 1 "sse_reg_operand"))
24668 (match_operator 3 "commutative_operator"
24670 (match_operand 2 "memory_operand")]))]
24671 "REGNO (operands[0]) != REGNO (operands[1])
24672 /* Punt if operands[1] is %[xy]mm16+ and AVX512BW is not enabled,
24673 as EVEX encoded vpadd[bw], vpmullw, vpmin[su][bw] and vpmax[su][bw]
24674 instructions require AVX512BW and AVX512VL, but with the original
24675 instructions it might require just AVX512VL.
24676 AVX512VL is implied from TARGET_HARD_REGNO_MODE_OK. */
24677 && (!EXT_REX_SSE_REGNO_P (REGNO (operands[1]))
24679 || GET_MODE_SIZE (GET_MODE_INNER (GET_MODE (operands[0]))) > 2
24680 || logic_operator (operands[3], VOIDmode))"
24681 [(set (match_dup 0) (match_dup 2))
24683 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
24685 ; Don't do logical operations with memory outputs
24687 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
24688 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
24689 ; the same decoder scheduling characteristics as the original.
24692 [(match_scratch:SWI 2 "<r>")
24693 (parallel [(set (match_operand:SWI 0 "memory_operand")
24694 (match_operator:SWI 3 "arith_or_logical_operator"
24696 (match_operand:SWI 1 "<nonmemory_operand>")]))
24697 (clobber (reg:CC FLAGS_REG))])]
24698 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
24699 [(set (match_dup 2) (match_dup 0))
24700 (parallel [(set (match_dup 2)
24701 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
24702 (clobber (reg:CC FLAGS_REG))])
24703 (set (match_dup 0) (match_dup 2))])
24706 [(match_scratch:SWI 2 "<r>")
24707 (parallel [(set (match_operand:SWI 0 "memory_operand")
24708 (match_operator:SWI 3 "arith_or_logical_operator"
24709 [(match_operand:SWI 1 "<nonmemory_operand>")
24711 (clobber (reg:CC FLAGS_REG))])]
24712 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
24713 [(set (match_dup 2) (match_dup 0))
24714 (parallel [(set (match_dup 2)
24715 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
24716 (clobber (reg:CC FLAGS_REG))])
24717 (set (match_dup 0) (match_dup 2))])
24719 ;; Attempt to use arith or logical operations with memory outputs with
24720 ;; setting of flags.
24722 [(set (match_operand:SWI 0 "register_operand")
24723 (match_operand:SWI 1 "memory_operand"))
24724 (parallel [(set (match_dup 0)
24725 (match_operator:SWI 3 "plusminuslogic_operator"
24727 (match_operand:SWI 2 "<nonmemory_operand>")]))
24728 (clobber (reg:CC FLAGS_REG))])
24729 (set (match_dup 1) (match_dup 0))
24730 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
24731 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24732 && peep2_reg_dead_p (4, operands[0])
24733 && !reg_overlap_mentioned_p (operands[0], operands[1])
24734 && !reg_overlap_mentioned_p (operands[0], operands[2])
24735 && (<MODE>mode != QImode
24736 || immediate_operand (operands[2], QImode)
24737 || any_QIreg_operand (operands[2], QImode))
24738 && ix86_match_ccmode (peep2_next_insn (3),
24739 (GET_CODE (operands[3]) == PLUS
24740 || GET_CODE (operands[3]) == MINUS)
24741 ? CCGOCmode : CCNOmode)"
24742 [(parallel [(set (match_dup 4) (match_dup 6))
24743 (set (match_dup 1) (match_dup 5))])]
24745 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
24747 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
24748 copy_rtx (operands[1]),
24751 = gen_rtx_COMPARE (GET_MODE (operands[4]),
24752 copy_rtx (operands[5]),
24756 ;; Likewise for cmpelim optimized pattern.
24758 [(set (match_operand:SWI 0 "register_operand")
24759 (match_operand:SWI 1 "memory_operand"))
24760 (parallel [(set (reg FLAGS_REG)
24761 (compare (match_operator:SWI 3 "plusminuslogic_operator"
24763 (match_operand:SWI 2 "<nonmemory_operand>")])
24765 (set (match_dup 0) (match_dup 3))])
24766 (set (match_dup 1) (match_dup 0))]
24767 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24768 && peep2_reg_dead_p (3, operands[0])
24769 && !reg_overlap_mentioned_p (operands[0], operands[1])
24770 && !reg_overlap_mentioned_p (operands[0], operands[2])
24771 && ix86_match_ccmode (peep2_next_insn (1),
24772 (GET_CODE (operands[3]) == PLUS
24773 || GET_CODE (operands[3]) == MINUS)
24774 ? CCGOCmode : CCNOmode)"
24775 [(parallel [(set (match_dup 4) (match_dup 6))
24776 (set (match_dup 1) (match_dup 5))])]
24778 operands[4] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
24780 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
24781 copy_rtx (operands[1]), operands[2]);
24783 = gen_rtx_COMPARE (GET_MODE (operands[4]), copy_rtx (operands[5]),
24787 ;; Likewise for instances where we have a lea pattern.
24789 [(set (match_operand:SWI 0 "register_operand")
24790 (match_operand:SWI 1 "memory_operand"))
24791 (set (match_operand:<LEAMODE> 3 "register_operand")
24792 (plus:<LEAMODE> (match_operand:<LEAMODE> 4 "register_operand")
24793 (match_operand:<LEAMODE> 2 "<nonmemory_operand>")))
24794 (set (match_dup 1) (match_operand:SWI 5 "register_operand"))
24795 (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
24796 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24797 && REGNO (operands[4]) == REGNO (operands[0])
24798 && REGNO (operands[5]) == REGNO (operands[3])
24799 && peep2_reg_dead_p (4, operands[3])
24800 && ((REGNO (operands[0]) == REGNO (operands[3]))
24801 || peep2_reg_dead_p (2, operands[0]))
24802 && !reg_overlap_mentioned_p (operands[0], operands[1])
24803 && !reg_overlap_mentioned_p (operands[3], operands[1])
24804 && !reg_overlap_mentioned_p (operands[0], operands[2])
24805 && (<MODE>mode != QImode
24806 || immediate_operand (operands[2], QImode)
24807 || any_QIreg_operand (operands[2], QImode))
24808 && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
24809 [(parallel [(set (match_dup 6) (match_dup 8))
24810 (set (match_dup 1) (match_dup 7))])]
24812 operands[6] = SET_DEST (PATTERN (peep2_next_insn (3)));
24814 = gen_rtx_PLUS (<MODE>mode,
24815 copy_rtx (operands[1]),
24816 gen_lowpart (<MODE>mode, operands[2]));
24818 = gen_rtx_COMPARE (GET_MODE (operands[6]),
24819 copy_rtx (operands[7]),
24824 [(parallel [(set (match_operand:SWI 0 "register_operand")
24825 (match_operator:SWI 2 "plusminuslogic_operator"
24827 (match_operand:SWI 1 "memory_operand")]))
24828 (clobber (reg:CC FLAGS_REG))])
24829 (set (match_dup 1) (match_dup 0))
24830 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
24831 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24832 && COMMUTATIVE_ARITH_P (operands[2])
24833 && peep2_reg_dead_p (3, operands[0])
24834 && !reg_overlap_mentioned_p (operands[0], operands[1])
24835 && ix86_match_ccmode (peep2_next_insn (2),
24836 GET_CODE (operands[2]) == PLUS
24837 ? CCGOCmode : CCNOmode)"
24838 [(parallel [(set (match_dup 3) (match_dup 5))
24839 (set (match_dup 1) (match_dup 4))])]
24841 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
24843 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
24844 copy_rtx (operands[1]),
24847 = gen_rtx_COMPARE (GET_MODE (operands[3]),
24848 copy_rtx (operands[4]),
24852 ;; Likewise for cmpelim optimized pattern.
24854 [(parallel [(set (reg FLAGS_REG)
24855 (compare (match_operator:SWI 2 "plusminuslogic_operator"
24856 [(match_operand:SWI 0 "register_operand")
24857 (match_operand:SWI 1 "memory_operand")])
24859 (set (match_dup 0) (match_dup 2))])
24860 (set (match_dup 1) (match_dup 0))]
24861 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24862 && COMMUTATIVE_ARITH_P (operands[2])
24863 && peep2_reg_dead_p (2, operands[0])
24864 && !reg_overlap_mentioned_p (operands[0], operands[1])
24865 && ix86_match_ccmode (peep2_next_insn (0),
24866 GET_CODE (operands[2]) == PLUS
24867 ? CCGOCmode : CCNOmode)"
24868 [(parallel [(set (match_dup 3) (match_dup 5))
24869 (set (match_dup 1) (match_dup 4))])]
24871 operands[3] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (0)), 0, 0));
24873 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
24874 copy_rtx (operands[1]), operands[0]);
24876 = gen_rtx_COMPARE (GET_MODE (operands[3]), copy_rtx (operands[4]),
24881 [(set (match_operand:SWI12 0 "register_operand")
24882 (match_operand:SWI12 1 "memory_operand"))
24883 (parallel [(set (match_operand:SI 4 "register_operand")
24884 (match_operator:SI 3 "plusminuslogic_operator"
24886 (match_operand:SI 2 "nonmemory_operand")]))
24887 (clobber (reg:CC FLAGS_REG))])
24888 (set (match_dup 1) (match_dup 0))
24889 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
24890 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24891 && REGNO (operands[0]) == REGNO (operands[4])
24892 && peep2_reg_dead_p (4, operands[0])
24893 && (<MODE>mode != QImode
24894 || immediate_operand (operands[2], SImode)
24895 || any_QIreg_operand (operands[2], SImode))
24896 && !reg_overlap_mentioned_p (operands[0], operands[1])
24897 && !reg_overlap_mentioned_p (operands[0], operands[2])
24898 && ix86_match_ccmode (peep2_next_insn (3),
24899 (GET_CODE (operands[3]) == PLUS
24900 || GET_CODE (operands[3]) == MINUS)
24901 ? CCGOCmode : CCNOmode)"
24902 [(parallel [(set (match_dup 5) (match_dup 7))
24903 (set (match_dup 1) (match_dup 6))])]
24905 operands[5] = SET_DEST (PATTERN (peep2_next_insn (3)));
24907 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
24908 copy_rtx (operands[1]),
24909 gen_lowpart (<MODE>mode, operands[2]));
24911 = gen_rtx_COMPARE (GET_MODE (operands[5]),
24912 copy_rtx (operands[6]),
24916 ;; peephole2 comes before regcprop, so deal also with a case that
24917 ;; would be cleaned up by regcprop.
24919 [(set (match_operand:SWI 0 "register_operand")
24920 (match_operand:SWI 1 "memory_operand"))
24921 (parallel [(set (match_dup 0)
24922 (match_operator:SWI 3 "plusminuslogic_operator"
24924 (match_operand:SWI 2 "<nonmemory_operand>")]))
24925 (clobber (reg:CC FLAGS_REG))])
24926 (set (match_operand:SWI 4 "register_operand") (match_dup 0))
24927 (set (match_dup 1) (match_dup 4))
24928 (set (reg FLAGS_REG) (compare (match_dup 4) (const_int 0)))]
24929 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24930 && peep2_reg_dead_p (3, operands[0])
24931 && peep2_reg_dead_p (5, operands[4])
24932 && !reg_overlap_mentioned_p (operands[0], operands[1])
24933 && !reg_overlap_mentioned_p (operands[0], operands[2])
24934 && !reg_overlap_mentioned_p (operands[4], operands[1])
24935 && (<MODE>mode != QImode
24936 || immediate_operand (operands[2], QImode)
24937 || any_QIreg_operand (operands[2], QImode))
24938 && ix86_match_ccmode (peep2_next_insn (4),
24939 (GET_CODE (operands[3]) == PLUS
24940 || GET_CODE (operands[3]) == MINUS)
24941 ? CCGOCmode : CCNOmode)"
24942 [(parallel [(set (match_dup 5) (match_dup 7))
24943 (set (match_dup 1) (match_dup 6))])]
24945 operands[5] = SET_DEST (PATTERN (peep2_next_insn (4)));
24947 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
24948 copy_rtx (operands[1]),
24951 = gen_rtx_COMPARE (GET_MODE (operands[5]),
24952 copy_rtx (operands[6]),
24957 [(set (match_operand:SWI12 0 "register_operand")
24958 (match_operand:SWI12 1 "memory_operand"))
24959 (parallel [(set (match_operand:SI 4 "register_operand")
24960 (match_operator:SI 3 "plusminuslogic_operator"
24962 (match_operand:SI 2 "nonmemory_operand")]))
24963 (clobber (reg:CC FLAGS_REG))])
24964 (set (match_operand:SWI12 5 "register_operand") (match_dup 0))
24965 (set (match_dup 1) (match_dup 5))
24966 (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
24967 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24968 && REGNO (operands[0]) == REGNO (operands[4])
24969 && peep2_reg_dead_p (3, operands[0])
24970 && peep2_reg_dead_p (5, operands[5])
24971 && (<MODE>mode != QImode
24972 || immediate_operand (operands[2], SImode)
24973 || any_QIreg_operand (operands[2], SImode))
24974 && !reg_overlap_mentioned_p (operands[0], operands[1])
24975 && !reg_overlap_mentioned_p (operands[0], operands[2])
24976 && !reg_overlap_mentioned_p (operands[5], operands[1])
24977 && ix86_match_ccmode (peep2_next_insn (4),
24978 (GET_CODE (operands[3]) == PLUS
24979 || GET_CODE (operands[3]) == MINUS)
24980 ? CCGOCmode : CCNOmode)"
24981 [(parallel [(set (match_dup 6) (match_dup 8))
24982 (set (match_dup 1) (match_dup 7))])]
24984 operands[6] = SET_DEST (PATTERN (peep2_next_insn (4)));
24986 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
24987 copy_rtx (operands[1]),
24988 gen_lowpart (<MODE>mode, operands[2]));
24990 = gen_rtx_COMPARE (GET_MODE (operands[6]),
24991 copy_rtx (operands[7]),
24995 ;; Likewise for cmpelim optimized pattern.
24997 [(set (match_operand:SWI 0 "register_operand")
24998 (match_operand:SWI 1 "memory_operand"))
24999 (parallel [(set (reg FLAGS_REG)
25000 (compare (match_operator:SWI 3 "plusminuslogic_operator"
25002 (match_operand:SWI 2 "<nonmemory_operand>")])
25004 (set (match_dup 0) (match_dup 3))])
25005 (set (match_operand:SWI 4 "register_operand") (match_dup 0))
25006 (set (match_dup 1) (match_dup 4))]
25007 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25008 && peep2_reg_dead_p (3, operands[0])
25009 && peep2_reg_dead_p (4, operands[4])
25010 && !reg_overlap_mentioned_p (operands[0], operands[1])
25011 && !reg_overlap_mentioned_p (operands[0], operands[2])
25012 && !reg_overlap_mentioned_p (operands[4], operands[1])
25013 && ix86_match_ccmode (peep2_next_insn (1),
25014 (GET_CODE (operands[3]) == PLUS
25015 || GET_CODE (operands[3]) == MINUS)
25016 ? CCGOCmode : CCNOmode)"
25017 [(parallel [(set (match_dup 5) (match_dup 7))
25018 (set (match_dup 1) (match_dup 6))])]
25020 operands[5] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
25022 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
25023 copy_rtx (operands[1]), operands[2]);
25025 = gen_rtx_COMPARE (GET_MODE (operands[5]), copy_rtx (operands[6]),
25029 ;; Special cases for xor, where (x ^= y) != 0 is (misoptimized)
25030 ;; into x = z; x ^= y; x != z
25032 [(set (match_operand:SWI 0 "register_operand")
25033 (match_operand:SWI 1 "memory_operand"))
25034 (set (match_operand:SWI 3 "register_operand") (match_dup 0))
25035 (parallel [(set (match_operand:SWI 4 "register_operand")
25036 (xor:SWI (match_dup 4)
25037 (match_operand:SWI 2 "<nonmemory_operand>")))
25038 (clobber (reg:CC FLAGS_REG))])
25039 (set (match_dup 1) (match_dup 4))
25040 (set (reg:CCZ FLAGS_REG)
25041 (compare:CCZ (match_operand:SWI 5 "register_operand")
25042 (match_operand:SWI 6 "<nonmemory_operand>")))]
25043 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25044 && (REGNO (operands[4]) == REGNO (operands[0])
25045 || REGNO (operands[4]) == REGNO (operands[3]))
25046 && (rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
25047 ? 3 : 0], operands[5])
25048 ? rtx_equal_p (operands[2], operands[6])
25049 : rtx_equal_p (operands[2], operands[5])
25050 && rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
25051 ? 3 : 0], operands[6]))
25052 && peep2_reg_dead_p (4, operands[4])
25053 && peep2_reg_dead_p (5, operands[REGNO (operands[4]) == REGNO (operands[0])
25055 && !reg_overlap_mentioned_p (operands[0], operands[1])
25056 && !reg_overlap_mentioned_p (operands[0], operands[2])
25057 && !reg_overlap_mentioned_p (operands[3], operands[0])
25058 && !reg_overlap_mentioned_p (operands[3], operands[1])
25059 && !reg_overlap_mentioned_p (operands[3], operands[2])
25060 && (<MODE>mode != QImode
25061 || immediate_operand (operands[2], QImode)
25062 || any_QIreg_operand (operands[2], QImode))"
25063 [(parallel [(set (match_dup 7) (match_dup 9))
25064 (set (match_dup 1) (match_dup 8))])]
25066 operands[7] = SET_DEST (PATTERN (peep2_next_insn (4)));
25067 operands[8] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
25070 = gen_rtx_COMPARE (GET_MODE (operands[7]),
25071 copy_rtx (operands[8]),
25076 [(set (match_operand:SWI12 0 "register_operand")
25077 (match_operand:SWI12 1 "memory_operand"))
25078 (set (match_operand:SWI12 3 "register_operand") (match_dup 0))
25079 (parallel [(set (match_operand:SI 4 "register_operand")
25080 (xor:SI (match_dup 4)
25081 (match_operand:SI 2 "<nonmemory_operand>")))
25082 (clobber (reg:CC FLAGS_REG))])
25083 (set (match_dup 1) (match_operand:SWI12 5 "register_operand"))
25084 (set (reg:CCZ FLAGS_REG)
25085 (compare:CCZ (match_operand:SWI12 6 "register_operand")
25086 (match_operand:SWI12 7 "<nonmemory_operand>")))]
25087 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25088 && (REGNO (operands[5]) == REGNO (operands[0])
25089 || REGNO (operands[5]) == REGNO (operands[3]))
25090 && REGNO (operands[5]) == REGNO (operands[4])
25091 && (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
25092 ? 3 : 0], operands[6])
25093 ? (REG_P (operands[2])
25094 ? REG_P (operands[7]) && REGNO (operands[2]) == REGNO (operands[7])
25095 : rtx_equal_p (operands[2], operands[7]))
25096 : (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
25097 ? 3 : 0], operands[7])
25098 && REG_P (operands[2])
25099 && REGNO (operands[2]) == REGNO (operands[6])))
25100 && peep2_reg_dead_p (4, operands[5])
25101 && peep2_reg_dead_p (5, operands[REGNO (operands[5]) == REGNO (operands[0])
25103 && !reg_overlap_mentioned_p (operands[0], operands[1])
25104 && !reg_overlap_mentioned_p (operands[0], operands[2])
25105 && !reg_overlap_mentioned_p (operands[3], operands[0])
25106 && !reg_overlap_mentioned_p (operands[3], operands[1])
25107 && !reg_overlap_mentioned_p (operands[3], operands[2])
25108 && (<MODE>mode != QImode
25109 || immediate_operand (operands[2], SImode)
25110 || any_QIreg_operand (operands[2], SImode))"
25111 [(parallel [(set (match_dup 8) (match_dup 10))
25112 (set (match_dup 1) (match_dup 9))])]
25114 operands[8] = SET_DEST (PATTERN (peep2_next_insn (4)));
25115 operands[9] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
25116 gen_lowpart (<MODE>mode, operands[2]));
25118 = gen_rtx_COMPARE (GET_MODE (operands[8]),
25119 copy_rtx (operands[9]),
25123 ;; Attempt to optimize away memory stores of values the memory already
25124 ;; has. See PR79593.
25126 [(set (match_operand 0 "register_operand")
25127 (match_operand 1 "memory_operand"))
25128 (set (match_operand 2 "memory_operand") (match_dup 0))]
25129 "!MEM_VOLATILE_P (operands[1])
25130 && !MEM_VOLATILE_P (operands[2])
25131 && rtx_equal_p (operands[1], operands[2])
25132 && !reg_overlap_mentioned_p (operands[0], operands[2])"
25133 [(set (match_dup 0) (match_dup 1))])
25135 ;; Attempt to always use XOR for zeroing registers (including FP modes).
25137 [(set (match_operand 0 "general_reg_operand")
25138 (match_operand 1 "const0_operand"))]
25139 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
25140 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
25141 && peep2_regno_dead_p (0, FLAGS_REG)"
25142 [(parallel [(set (match_dup 0) (const_int 0))
25143 (clobber (reg:CC FLAGS_REG))])]
25144 "operands[0] = gen_lowpart (word_mode, operands[0]);")
25147 [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
25149 "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
25150 && peep2_regno_dead_p (0, FLAGS_REG)"
25151 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
25152 (clobber (reg:CC FLAGS_REG))])])
25154 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
25156 [(set (match_operand:SWI248 0 "general_reg_operand")
25158 "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
25159 && peep2_regno_dead_p (0, FLAGS_REG)"
25160 [(parallel [(set (match_dup 0) (const_int -1))
25161 (clobber (reg:CC FLAGS_REG))])]
25163 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
25164 operands[0] = gen_lowpart (SImode, operands[0]);
25167 ;; Attempt to convert simple lea to add/shift.
25168 ;; These can be created by move expanders.
25169 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
25170 ;; relevant lea instructions were already split.
25173 [(set (match_operand:SWI48 0 "register_operand")
25174 (plus:SWI48 (match_dup 0)
25175 (match_operand:SWI48 1 "<nonmemory_operand>")))]
25177 && peep2_regno_dead_p (0, FLAGS_REG)"
25178 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
25179 (clobber (reg:CC FLAGS_REG))])])
25182 [(set (match_operand:SWI48 0 "register_operand")
25183 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
25186 && peep2_regno_dead_p (0, FLAGS_REG)"
25187 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
25188 (clobber (reg:CC FLAGS_REG))])])
25191 [(set (match_operand:DI 0 "register_operand")
25193 (plus:SI (match_operand:SI 1 "register_operand")
25194 (match_operand:SI 2 "nonmemory_operand"))))]
25195 "TARGET_64BIT && !TARGET_OPT_AGU
25196 && REGNO (operands[0]) == REGNO (operands[1])
25197 && peep2_regno_dead_p (0, FLAGS_REG)"
25198 [(parallel [(set (match_dup 0)
25199 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
25200 (clobber (reg:CC FLAGS_REG))])])
25203 [(set (match_operand:DI 0 "register_operand")
25205 (plus:SI (match_operand:SI 1 "nonmemory_operand")
25206 (match_operand:SI 2 "register_operand"))))]
25207 "TARGET_64BIT && !TARGET_OPT_AGU
25208 && REGNO (operands[0]) == REGNO (operands[2])
25209 && peep2_regno_dead_p (0, FLAGS_REG)"
25210 [(parallel [(set (match_dup 0)
25211 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
25212 (clobber (reg:CC FLAGS_REG))])])
25215 [(set (match_operand:SWI48 0 "register_operand")
25216 (mult:SWI48 (match_dup 0)
25217 (match_operand:SWI48 1 "const_int_operand")))]
25218 "pow2p_hwi (INTVAL (operands[1]))
25219 && peep2_regno_dead_p (0, FLAGS_REG)"
25220 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
25221 (clobber (reg:CC FLAGS_REG))])]
25222 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
25225 [(set (match_operand:DI 0 "register_operand")
25227 (mult:SI (match_operand:SI 1 "register_operand")
25228 (match_operand:SI 2 "const_int_operand"))))]
25230 && pow2p_hwi (INTVAL (operands[2]))
25231 && REGNO (operands[0]) == REGNO (operands[1])
25232 && peep2_regno_dead_p (0, FLAGS_REG)"
25233 [(parallel [(set (match_dup 0)
25234 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
25235 (clobber (reg:CC FLAGS_REG))])]
25236 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
25238 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
25239 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
25240 ;; On many CPUs it is also faster, since special hardware to avoid esp
25241 ;; dependencies is present.
25243 ;; While some of these conversions may be done using splitters, we use
25244 ;; peepholes in order to allow combine_stack_adjustments pass to see
25245 ;; nonobfuscated RTL.
25247 ;; Convert prologue esp subtractions to push.
25248 ;; We need register to push. In order to keep verify_flow_info happy we have
25250 ;; - use scratch and clobber it in order to avoid dependencies
25251 ;; - use already live register
25252 ;; We can't use the second way right now, since there is no reliable way how to
25253 ;; verify that given register is live. First choice will also most likely in
25254 ;; fewer dependencies. On the place of esp adjustments it is very likely that
25255 ;; call clobbered registers are dead. We may want to use base pointer as an
25256 ;; alternative when no register is available later.
25259 [(match_scratch:W 1 "r")
25260 (parallel [(set (reg:P SP_REG)
25261 (plus:P (reg:P SP_REG)
25262 (match_operand:P 0 "const_int_operand")))
25263 (clobber (reg:CC FLAGS_REG))
25264 (clobber (mem:BLK (scratch)))])]
25265 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
25266 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
25267 && !ix86_red_zone_used"
25268 [(clobber (match_dup 1))
25269 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
25270 (clobber (mem:BLK (scratch)))])])
25273 [(match_scratch:W 1 "r")
25274 (parallel [(set (reg:P SP_REG)
25275 (plus:P (reg:P SP_REG)
25276 (match_operand:P 0 "const_int_operand")))
25277 (clobber (reg:CC FLAGS_REG))
25278 (clobber (mem:BLK (scratch)))])]
25279 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
25280 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
25281 && !ix86_red_zone_used"
25282 [(clobber (match_dup 1))
25283 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
25284 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
25285 (clobber (mem:BLK (scratch)))])])
25287 ;; Convert esp subtractions to push.
25289 [(match_scratch:W 1 "r")
25290 (parallel [(set (reg:P SP_REG)
25291 (plus:P (reg:P SP_REG)
25292 (match_operand:P 0 "const_int_operand")))
25293 (clobber (reg:CC FLAGS_REG))])]
25294 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
25295 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
25296 && !ix86_red_zone_used"
25297 [(clobber (match_dup 1))
25298 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
25301 [(match_scratch:W 1 "r")
25302 (parallel [(set (reg:P SP_REG)
25303 (plus:P (reg:P SP_REG)
25304 (match_operand:P 0 "const_int_operand")))
25305 (clobber (reg:CC FLAGS_REG))])]
25306 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
25307 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
25308 && !ix86_red_zone_used"
25309 [(clobber (match_dup 1))
25310 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
25311 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
25313 ;; Convert epilogue deallocator to pop.
25315 [(match_scratch:W 1 "r")
25316 (parallel [(set (reg:P SP_REG)
25317 (plus:P (reg:P SP_REG)
25318 (match_operand:P 0 "const_int_operand")))
25319 (clobber (reg:CC FLAGS_REG))
25320 (clobber (mem:BLK (scratch)))])]
25321 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
25322 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
25323 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25324 (clobber (mem:BLK (scratch)))])])
25326 ;; Two pops case is tricky, since pop causes dependency
25327 ;; on destination register. We use two registers if available.
25329 [(match_scratch:W 1 "r")
25330 (match_scratch:W 2 "r")
25331 (parallel [(set (reg:P SP_REG)
25332 (plus:P (reg:P SP_REG)
25333 (match_operand:P 0 "const_int_operand")))
25334 (clobber (reg:CC FLAGS_REG))
25335 (clobber (mem:BLK (scratch)))])]
25336 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
25337 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
25338 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25339 (clobber (mem:BLK (scratch)))])
25340 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
25343 [(match_scratch:W 1 "r")
25344 (parallel [(set (reg:P SP_REG)
25345 (plus:P (reg:P SP_REG)
25346 (match_operand:P 0 "const_int_operand")))
25347 (clobber (reg:CC FLAGS_REG))
25348 (clobber (mem:BLK (scratch)))])]
25349 "optimize_insn_for_size_p ()
25350 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
25351 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25352 (clobber (mem:BLK (scratch)))])
25353 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
25355 ;; Convert esp additions to pop.
25357 [(match_scratch:W 1 "r")
25358 (parallel [(set (reg:P SP_REG)
25359 (plus:P (reg:P SP_REG)
25360 (match_operand:P 0 "const_int_operand")))
25361 (clobber (reg:CC FLAGS_REG))])]
25362 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
25363 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
25365 ;; Two pops case is tricky, since pop causes dependency
25366 ;; on destination register. We use two registers if available.
25368 [(match_scratch:W 1 "r")
25369 (match_scratch:W 2 "r")
25370 (parallel [(set (reg:P SP_REG)
25371 (plus:P (reg:P SP_REG)
25372 (match_operand:P 0 "const_int_operand")))
25373 (clobber (reg:CC FLAGS_REG))])]
25374 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
25375 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25376 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
25379 [(match_scratch:W 1 "r")
25380 (parallel [(set (reg:P SP_REG)
25381 (plus:P (reg:P SP_REG)
25382 (match_operand:P 0 "const_int_operand")))
25383 (clobber (reg:CC FLAGS_REG))])]
25384 "optimize_insn_for_size_p ()
25385 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
25386 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25387 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
25389 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
25390 ;; required and register dies. Similarly for 128 to -128.
25392 [(set (match_operand 0 "flags_reg_operand")
25393 (match_operator 1 "compare_operator"
25394 [(match_operand 2 "register_operand")
25395 (match_operand 3 "const_int_operand")]))]
25396 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
25397 && incdec_operand (operands[3], GET_MODE (operands[3])))
25398 || (!TARGET_FUSE_CMP_AND_BRANCH
25399 && INTVAL (operands[3]) == 128))
25400 && ix86_match_ccmode (insn, CCGCmode)
25401 && peep2_reg_dead_p (1, operands[2])"
25402 [(parallel [(set (match_dup 0)
25403 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
25404 (clobber (match_dup 2))])])
25406 ;; Convert imul by three, five and nine into lea
25409 [(set (match_operand:SWI48 0 "register_operand")
25410 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
25411 (match_operand:SWI48 2 "const359_operand")))
25412 (clobber (reg:CC FLAGS_REG))])]
25413 "!TARGET_PARTIAL_REG_STALL
25414 || <MODE>mode == SImode
25415 || optimize_function_for_size_p (cfun)"
25416 [(set (match_dup 0)
25417 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
25419 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
25423 [(set (match_operand:SWI48 0 "register_operand")
25424 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
25425 (match_operand:SWI48 2 "const359_operand")))
25426 (clobber (reg:CC FLAGS_REG))])]
25427 "optimize_insn_for_speed_p ()
25428 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
25429 [(set (match_dup 0) (match_dup 1))
25431 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
25433 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
25435 ;; imul $32bit_imm, mem, reg is vector decoded, while
25436 ;; imul $32bit_imm, reg, reg is direct decoded.
25438 [(match_scratch:SWI48 3 "r")
25439 (parallel [(set (match_operand:SWI48 0 "register_operand")
25440 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
25441 (match_operand:SWI48 2 "immediate_operand")))
25442 (clobber (reg:CC FLAGS_REG))])]
25443 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
25444 && !satisfies_constraint_K (operands[2])"
25445 [(set (match_dup 3) (match_dup 1))
25446 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
25447 (clobber (reg:CC FLAGS_REG))])])
25450 [(match_scratch:SI 3 "r")
25451 (parallel [(set (match_operand:DI 0 "register_operand")
25453 (mult:SI (match_operand:SI 1 "memory_operand")
25454 (match_operand:SI 2 "immediate_operand"))))
25455 (clobber (reg:CC FLAGS_REG))])]
25457 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
25458 && !satisfies_constraint_K (operands[2])"
25459 [(set (match_dup 3) (match_dup 1))
25460 (parallel [(set (match_dup 0)
25461 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
25462 (clobber (reg:CC FLAGS_REG))])])
25464 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
25465 ;; Convert it into imul reg, reg
25466 ;; It would be better to force assembler to encode instruction using long
25467 ;; immediate, but there is apparently no way to do so.
25469 [(parallel [(set (match_operand:SWI248 0 "register_operand")
25471 (match_operand:SWI248 1 "nonimmediate_operand")
25472 (match_operand:SWI248 2 "const_int_operand")))
25473 (clobber (reg:CC FLAGS_REG))])
25474 (match_scratch:SWI248 3 "r")]
25475 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
25476 && satisfies_constraint_K (operands[2])"
25477 [(set (match_dup 3) (match_dup 2))
25478 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
25479 (clobber (reg:CC FLAGS_REG))])]
25481 if (!rtx_equal_p (operands[0], operands[1]))
25482 emit_move_insn (operands[0], operands[1]);
25485 ;; After splitting up read-modify operations, array accesses with memory
25486 ;; operands might end up in form:
25488 ;; movl 4(%esp), %edx
25490 ;; instead of pre-splitting:
25492 ;; addl 4(%esp), %eax
25494 ;; movl 4(%esp), %edx
25495 ;; leal (%edx,%eax,4), %eax
25498 [(match_scratch:W 5 "r")
25499 (parallel [(set (match_operand 0 "register_operand")
25500 (ashift (match_operand 1 "register_operand")
25501 (match_operand 2 "const_int_operand")))
25502 (clobber (reg:CC FLAGS_REG))])
25503 (parallel [(set (match_operand 3 "register_operand")
25504 (plus (match_dup 0)
25505 (match_operand 4 "x86_64_general_operand")))
25506 (clobber (reg:CC FLAGS_REG))])]
25507 "IN_RANGE (INTVAL (operands[2]), 1, 3)
25508 /* Validate MODE for lea. */
25509 && ((!TARGET_PARTIAL_REG_STALL
25510 && (GET_MODE (operands[0]) == QImode
25511 || GET_MODE (operands[0]) == HImode))
25512 || GET_MODE (operands[0]) == SImode
25513 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
25514 && (rtx_equal_p (operands[0], operands[3])
25515 || peep2_reg_dead_p (2, operands[0]))
25516 /* We reorder load and the shift. */
25517 && !reg_overlap_mentioned_p (operands[0], operands[4])"
25518 [(set (match_dup 5) (match_dup 4))
25519 (set (match_dup 0) (match_dup 1))]
25521 machine_mode op1mode = GET_MODE (operands[1]);
25522 machine_mode mode = op1mode == DImode ? DImode : SImode;
25523 int scale = 1 << INTVAL (operands[2]);
25524 rtx index = gen_lowpart (word_mode, operands[1]);
25525 rtx base = gen_lowpart (word_mode, operands[5]);
25526 rtx dest = gen_lowpart (mode, operands[3]);
25528 operands[1] = gen_rtx_PLUS (word_mode, base,
25529 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
25530 if (mode != word_mode)
25531 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
25533 operands[5] = base;
25534 if (op1mode != word_mode)
25535 operands[5] = gen_lowpart (op1mode, operands[5]);
25537 operands[0] = dest;
25540 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
25541 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
25542 ;; caught for use by garbage collectors and the like. Using an insn that
25543 ;; maps to SIGILL makes it more likely the program will rightfully die.
25544 ;; Keeping with tradition, "6" is in honor of #UD.
25545 (define_insn "trap"
25546 [(trap_if (const_int 1) (const_int 6))]
25549 #ifdef HAVE_AS_IX86_UD2
25552 return ASM_SHORT "0x0b0f";
25555 [(set_attr "length" "2")])
25558 [(unspec_volatile [(const_int 0)] UNSPECV_UD2)]
25561 #ifdef HAVE_AS_IX86_UD2
25564 return ASM_SHORT "0x0b0f";
25567 [(set_attr "length" "2")])
25569 (define_expand "prefetch"
25570 [(prefetch (match_operand 0 "address_operand")
25571 (match_operand:SI 1 "const_int_operand")
25572 (match_operand:SI 2 "const_int_operand"))]
25573 "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
25575 bool write = operands[1] != const0_rtx;
25576 int locality = INTVAL (operands[2]);
25578 gcc_assert (IN_RANGE (locality, 0, 3));
25580 /* Use 3dNOW prefetch in case we are asking for write prefetch not
25581 supported by SSE counterpart (non-SSE2 athlon machines) or the
25582 SSE prefetch is not available (K6 machines). Otherwise use SSE
25583 prefetch as it allows specifying of locality. */
25587 if (TARGET_PREFETCHWT1)
25588 operands[2] = GEN_INT (MAX (locality, 2));
25589 else if (TARGET_PRFCHW)
25590 operands[2] = GEN_INT (3);
25591 else if (TARGET_3DNOW && !TARGET_SSE2)
25592 operands[2] = GEN_INT (3);
25593 else if (TARGET_PREFETCH_SSE)
25594 operands[1] = const0_rtx;
25597 gcc_assert (TARGET_3DNOW);
25598 operands[2] = GEN_INT (3);
25603 if (TARGET_PREFETCH_SSE)
25607 gcc_assert (TARGET_3DNOW);
25608 operands[2] = GEN_INT (3);
25613 (define_insn "*prefetch_sse"
25614 [(prefetch (match_operand 0 "address_operand" "p")
25616 (match_operand:SI 1 "const_int_operand"))]
25617 "TARGET_PREFETCH_SSE"
25619 static const char * const patterns[4] = {
25620 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
25623 int locality = INTVAL (operands[1]);
25624 gcc_assert (IN_RANGE (locality, 0, 3));
25626 return patterns[locality];
25628 [(set_attr "type" "sse")
25629 (set_attr "atom_sse_attr" "prefetch")
25630 (set (attr "length_address")
25631 (symbol_ref "memory_address_length (operands[0], false)"))
25632 (set_attr "memory" "none")])
25634 (define_insn "*prefetch_3dnow"
25635 [(prefetch (match_operand 0 "address_operand" "p")
25636 (match_operand:SI 1 "const_int_operand")
25638 "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1"
25640 if (operands[1] == const0_rtx)
25641 return "prefetch\t%a0";
25643 return "prefetchw\t%a0";
25645 [(set_attr "type" "mmx")
25646 (set (attr "length_address")
25647 (symbol_ref "memory_address_length (operands[0], false)"))
25648 (set_attr "memory" "none")])
25650 (define_insn "*prefetch_prefetchwt1"
25651 [(prefetch (match_operand 0 "address_operand" "p")
25654 "TARGET_PREFETCHWT1"
25655 "prefetchwt1\t%a0";
25656 [(set_attr "type" "sse")
25657 (set (attr "length_address")
25658 (symbol_ref "memory_address_length (operands[0], false)"))
25659 (set_attr "memory" "none")])
25661 (define_insn "prefetchi"
25662 [(unspec_volatile [(match_operand 0 "local_func_symbolic_operand" "p")
25663 (match_operand:SI 1 "const_int_operand")]
25664 UNSPECV_PREFETCHI)]
25665 "TARGET_PREFETCHI && TARGET_64BIT"
25667 static const char * const patterns[2] = {
25668 "prefetchit1\t%0", "prefetchit0\t%0"
25671 int locality = INTVAL (operands[1]);
25672 gcc_assert (IN_RANGE (locality, 2, 3));
25674 return patterns[locality - 2];
25676 [(set_attr "type" "sse")
25677 (set (attr "length_address")
25678 (symbol_ref "memory_address_length (operands[0], false)"))
25679 (set_attr "memory" "none")])
25681 (define_insn "sse4_2_crc32<mode>"
25682 [(set (match_operand:SI 0 "register_operand" "=r")
25684 [(match_operand:SI 1 "register_operand" "0")
25685 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
25688 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
25689 [(set_attr "type" "sselog1")
25690 (set_attr "prefix_rep" "1")
25691 (set_attr "prefix_extra" "1")
25692 (set (attr "prefix_data16")
25693 (if_then_else (match_operand:HI 2)
25695 (const_string "*")))
25696 (set (attr "prefix_rex")
25697 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
25699 (const_string "*")))
25700 (set_attr "mode" "SI")])
25702 (define_insn "sse4_2_crc32di"
25703 [(set (match_operand:DI 0 "register_operand" "=r")
25706 [(match_operand:SI 1 "register_operand" "0")
25707 (match_operand:DI 2 "nonimmediate_operand" "rm")]
25709 "TARGET_64BIT && TARGET_CRC32"
25710 "crc32{q}\t{%2, %0|%0, %2}"
25711 [(set_attr "type" "sselog1")
25712 (set_attr "prefix_rep" "1")
25713 (set_attr "prefix_extra" "1")
25714 (set_attr "mode" "DI")])
25716 (define_insn "rdpmc"
25717 [(set (match_operand:DI 0 "register_operand" "=A")
25718 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
25722 [(set_attr "type" "other")
25723 (set_attr "length" "2")])
25725 (define_insn "rdpmc_rex64"
25726 [(set (match_operand:DI 0 "register_operand" "=a")
25727 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
25729 (set (match_operand:DI 1 "register_operand" "=d")
25730 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
25733 [(set_attr "type" "other")
25734 (set_attr "length" "2")])
25736 (define_insn "rdtsc"
25737 [(set (match_operand:DI 0 "register_operand" "=A")
25738 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
25741 [(set_attr "type" "other")
25742 (set_attr "length" "2")])
25744 (define_insn "rdtsc_rex64"
25745 [(set (match_operand:DI 0 "register_operand" "=a")
25746 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
25747 (set (match_operand:DI 1 "register_operand" "=d")
25748 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
25751 [(set_attr "type" "other")
25752 (set_attr "length" "2")])
25754 (define_insn "rdtscp"
25755 [(set (match_operand:DI 0 "register_operand" "=A")
25756 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
25757 (set (match_operand:SI 1 "register_operand" "=c")
25758 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
25761 [(set_attr "type" "other")
25762 (set_attr "length" "3")])
25764 (define_insn "rdtscp_rex64"
25765 [(set (match_operand:DI 0 "register_operand" "=a")
25766 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
25767 (set (match_operand:DI 1 "register_operand" "=d")
25768 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
25769 (set (match_operand:SI 2 "register_operand" "=c")
25770 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
25773 [(set_attr "type" "other")
25774 (set_attr "length" "3")])
25776 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25778 ;; FXSR, XSAVE and XSAVEOPT instructions
25780 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25782 (define_insn "fxsave"
25783 [(set (match_operand:BLK 0 "memory_operand" "=m")
25784 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
25787 [(set_attr "type" "other")
25788 (set_attr "memory" "store")
25789 (set (attr "length")
25790 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25792 (define_insn "fxsave64"
25793 [(set (match_operand:BLK 0 "memory_operand" "=jm")
25794 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
25795 "TARGET_64BIT && TARGET_FXSR"
25797 [(set_attr "type" "other")
25798 (set_attr "addr" "gpr16")
25799 (set_attr "memory" "store")
25800 (set (attr "length")
25801 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
25803 (define_insn "fxrstor"
25804 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
25808 [(set_attr "type" "other")
25809 (set_attr "memory" "load")
25810 (set (attr "length")
25811 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25813 (define_insn "fxrstor64"
25814 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "jm")]
25815 UNSPECV_FXRSTOR64)]
25816 "TARGET_64BIT && TARGET_FXSR"
25818 [(set_attr "type" "other")
25819 (set_attr "addr" "gpr16")
25820 (set_attr "memory" "load")
25821 (set (attr "length")
25822 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
25824 (define_int_iterator ANY_XSAVE
25826 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
25827 (UNSPECV_XSAVEC "TARGET_XSAVEC")
25828 (UNSPECV_XSAVES "TARGET_XSAVES")])
25830 (define_int_iterator ANY_XSAVE64
25832 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
25833 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
25834 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
25836 (define_int_attr xsave
25837 [(UNSPECV_XSAVE "xsave")
25838 (UNSPECV_XSAVE64 "xsave64")
25839 (UNSPECV_XSAVEOPT "xsaveopt")
25840 (UNSPECV_XSAVEOPT64 "xsaveopt64")
25841 (UNSPECV_XSAVEC "xsavec")
25842 (UNSPECV_XSAVEC64 "xsavec64")
25843 (UNSPECV_XSAVES "xsaves")
25844 (UNSPECV_XSAVES64 "xsaves64")])
25846 (define_int_iterator ANY_XRSTOR
25848 (UNSPECV_XRSTORS "TARGET_XSAVES")])
25850 (define_int_iterator ANY_XRSTOR64
25852 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
25854 (define_int_attr xrstor
25855 [(UNSPECV_XRSTOR "xrstor")
25856 (UNSPECV_XRSTOR64 "xrstor")
25857 (UNSPECV_XRSTORS "xrstors")
25858 (UNSPECV_XRSTORS64 "xrstors")])
25860 (define_insn "<xsave>"
25861 [(set (match_operand:BLK 0 "memory_operand" "=m")
25862 (unspec_volatile:BLK
25863 [(match_operand:DI 1 "register_operand" "A")]
25865 "!TARGET_64BIT && TARGET_XSAVE"
25867 [(set_attr "type" "other")
25868 (set_attr "memory" "store")
25869 (set (attr "length")
25870 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25872 (define_insn "<xsave>_rex64"
25873 [(set (match_operand:BLK 0 "memory_operand" "=jm")
25874 (unspec_volatile:BLK
25875 [(match_operand:SI 1 "register_operand" "a")
25876 (match_operand:SI 2 "register_operand" "d")]
25878 "TARGET_64BIT && TARGET_XSAVE"
25880 [(set_attr "type" "other")
25881 (set_attr "memory" "store")
25882 (set_attr "addr" "gpr16")
25883 (set (attr "length")
25884 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25886 (define_insn "<xsave>"
25887 [(set (match_operand:BLK 0 "memory_operand" "=jm")
25888 (unspec_volatile:BLK
25889 [(match_operand:SI 1 "register_operand" "a")
25890 (match_operand:SI 2 "register_operand" "d")]
25892 "TARGET_64BIT && TARGET_XSAVE"
25894 [(set_attr "type" "other")
25895 (set_attr "memory" "store")
25896 (set_attr "addr" "gpr16")
25897 (set (attr "length")
25898 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
25900 (define_insn "<xrstor>"
25901 [(unspec_volatile:BLK
25902 [(match_operand:BLK 0 "memory_operand" "m")
25903 (match_operand:DI 1 "register_operand" "A")]
25905 "!TARGET_64BIT && TARGET_XSAVE"
25907 [(set_attr "type" "other")
25908 (set_attr "memory" "load")
25909 (set (attr "length")
25910 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25912 (define_insn "<xrstor>_rex64"
25913 [(unspec_volatile:BLK
25914 [(match_operand:BLK 0 "memory_operand" "jm")
25915 (match_operand:SI 1 "register_operand" "a")
25916 (match_operand:SI 2 "register_operand" "d")]
25918 "TARGET_64BIT && TARGET_XSAVE"
25920 [(set_attr "type" "other")
25921 (set_attr "memory" "load")
25922 (set_attr "addr" "gpr16")
25923 (set (attr "length")
25924 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25926 (define_insn "<xrstor>64"
25927 [(unspec_volatile:BLK
25928 [(match_operand:BLK 0 "memory_operand" "jm")
25929 (match_operand:SI 1 "register_operand" "a")
25930 (match_operand:SI 2 "register_operand" "d")]
25932 "TARGET_64BIT && TARGET_XSAVE"
25934 [(set_attr "type" "other")
25935 (set_attr "memory" "load")
25936 (set_attr "addr" "gpr16")
25937 (set (attr "length")
25938 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
25940 (define_insn "xsetbv"
25941 [(unspec_volatile:SI
25942 [(match_operand:SI 0 "register_operand" "c")
25943 (match_operand:DI 1 "register_operand" "A")]
25945 "!TARGET_64BIT && TARGET_XSAVE"
25947 [(set_attr "type" "other")])
25949 (define_insn "xsetbv_rex64"
25950 [(unspec_volatile:SI
25951 [(match_operand:SI 0 "register_operand" "c")
25952 (match_operand:SI 1 "register_operand" "a")
25953 (match_operand:SI 2 "register_operand" "d")]
25955 "TARGET_64BIT && TARGET_XSAVE"
25957 [(set_attr "type" "other")])
25959 (define_insn "xgetbv"
25960 [(set (match_operand:DI 0 "register_operand" "=A")
25961 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
25963 "!TARGET_64BIT && TARGET_XSAVE"
25965 [(set_attr "type" "other")])
25967 (define_insn "xgetbv_rex64"
25968 [(set (match_operand:DI 0 "register_operand" "=a")
25969 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
25971 (set (match_operand:DI 1 "register_operand" "=d")
25972 (unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))]
25973 "TARGET_64BIT && TARGET_XSAVE"
25975 [(set_attr "type" "other")])
25977 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25979 ;; Floating-point instructions for atomic compound assignments
25981 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25983 ; Clobber all floating-point registers on environment save and restore
25984 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
25985 (define_insn "fnstenv"
25986 [(set (match_operand:BLK 0 "memory_operand" "=m")
25987 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
25988 (clobber (reg:XF ST0_REG))
25989 (clobber (reg:XF ST1_REG))
25990 (clobber (reg:XF ST2_REG))
25991 (clobber (reg:XF ST3_REG))
25992 (clobber (reg:XF ST4_REG))
25993 (clobber (reg:XF ST5_REG))
25994 (clobber (reg:XF ST6_REG))
25995 (clobber (reg:XF ST7_REG))]
25998 [(set_attr "type" "other")
25999 (set_attr "memory" "store")
26000 (set (attr "length")
26001 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
26003 (define_insn "fldenv"
26004 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
26006 (clobber (reg:XF ST0_REG))
26007 (clobber (reg:XF ST1_REG))
26008 (clobber (reg:XF ST2_REG))
26009 (clobber (reg:XF ST3_REG))
26010 (clobber (reg:XF ST4_REG))
26011 (clobber (reg:XF ST5_REG))
26012 (clobber (reg:XF ST6_REG))
26013 (clobber (reg:XF ST7_REG))]
26016 [(set_attr "type" "other")
26017 (set_attr "memory" "load")
26018 (set (attr "length")
26019 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
26021 (define_insn "fnstsw"
26022 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
26023 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
26026 [(set_attr "type" "other,other")
26027 (set_attr "memory" "none,store")
26028 (set (attr "length")
26029 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
26031 (define_insn "fnclex"
26032 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
26035 [(set_attr "type" "other")
26036 (set_attr "memory" "none")
26037 (set_attr "length" "2")])
26039 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26041 ;; LWP instructions
26043 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26045 (define_insn "@lwp_llwpcb<mode>"
26046 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
26047 UNSPECV_LLWP_INTRINSIC)]
26050 [(set_attr "type" "lwp")
26051 (set_attr "mode" "<MODE>")
26052 (set_attr "length" "5")])
26054 (define_insn "@lwp_slwpcb<mode>"
26055 [(set (match_operand:P 0 "register_operand" "=r")
26056 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
26059 [(set_attr "type" "lwp")
26060 (set_attr "mode" "<MODE>")
26061 (set_attr "length" "5")])
26063 (define_insn "@lwp_lwpval<mode>"
26064 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
26065 (match_operand:SI 1 "nonimmediate_operand" "rm")
26066 (match_operand:SI 2 "const_int_operand")]
26067 UNSPECV_LWPVAL_INTRINSIC)]
26069 "lwpval\t{%2, %1, %0|%0, %1, %2}"
26070 [(set_attr "type" "lwp")
26071 (set_attr "mode" "<MODE>")
26072 (set (attr "length")
26073 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
26075 (define_insn "@lwp_lwpins<mode>"
26076 [(set (reg:CCC FLAGS_REG)
26077 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
26078 (match_operand:SI 1 "nonimmediate_operand" "rm")
26079 (match_operand:SI 2 "const_int_operand")]
26080 UNSPECV_LWPINS_INTRINSIC))]
26082 "lwpins\t{%2, %1, %0|%0, %1, %2}"
26083 [(set_attr "type" "lwp")
26084 (set_attr "mode" "<MODE>")
26085 (set (attr "length")
26086 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
26088 (define_int_iterator RDFSGSBASE
26092 (define_int_iterator WRFSGSBASE
26096 (define_int_attr fsgs
26097 [(UNSPECV_RDFSBASE "fs")
26098 (UNSPECV_RDGSBASE "gs")
26099 (UNSPECV_WRFSBASE "fs")
26100 (UNSPECV_WRGSBASE "gs")])
26102 (define_insn "rd<fsgs>base<mode>"
26103 [(set (match_operand:SWI48 0 "register_operand" "=r")
26104 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
26105 "TARGET_64BIT && TARGET_FSGSBASE"
26107 [(set_attr "type" "other")
26108 (set_attr "prefix_0f" "1")
26109 (set_attr "prefix_rep" "1")])
26111 (define_insn "wr<fsgs>base<mode>"
26112 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
26114 "TARGET_64BIT && TARGET_FSGSBASE"
26116 [(set_attr "type" "other")
26117 (set_attr "prefix_0f" "1")
26118 (set_attr "prefix_rep" "1")])
26120 (define_insn "ptwrite<mode>"
26121 [(unspec_volatile [(match_operand:SWI48 0 "nonimmediate_operand" "rm")]
26125 [(set_attr "type" "other")
26126 (set_attr "prefix_0f" "1")
26127 (set_attr "prefix_rep" "1")])
26129 (define_insn "@rdrand<mode>"
26130 [(set (match_operand:SWI248 0 "register_operand" "=r")
26131 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
26132 (set (reg:CCC FLAGS_REG)
26133 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
26136 [(set_attr "type" "other")
26137 (set_attr "prefix_0f" "1")])
26139 (define_insn "@rdseed<mode>"
26140 [(set (match_operand:SWI248 0 "register_operand" "=r")
26141 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
26142 (set (reg:CCC FLAGS_REG)
26143 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
26146 [(set_attr "type" "other")
26147 (set_attr "prefix_0f" "1")])
26149 (define_expand "pause"
26150 [(set (match_dup 0)
26151 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
26154 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
26155 MEM_VOLATILE_P (operands[0]) = 1;
26158 ;; Use "rep; nop", instead of "pause", to support older assemblers.
26159 ;; They have the same encoding.
26160 (define_insn "*pause"
26161 [(set (match_operand:BLK 0)
26162 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
26165 [(set_attr "length" "2")
26166 (set_attr "memory" "unknown")])
26168 ;; CET instructions
26169 (define_insn "@rdssp<mode>"
26170 [(set (match_operand:SWI48 0 "register_operand" "=r")
26171 (unspec_volatile:SWI48 [(match_operand:SWI48 1 "register_operand" "0")]
26172 UNSPECV_NOP_RDSSP))]
26173 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
26174 "rdssp<mskmodesuffix>\t%0"
26175 [(set_attr "length" "6")
26176 (set_attr "type" "other")])
26178 (define_insn "@incssp<mode>"
26179 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
26181 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
26182 "incssp<mskmodesuffix>\t%0"
26183 [(set_attr "length" "4")
26184 (set_attr "type" "other")])
26186 (define_insn "saveprevssp"
26187 [(unspec_volatile [(const_int 0)] UNSPECV_SAVEPREVSSP)]
26190 [(set_attr "length" "5")
26191 (set_attr "type" "other")])
26193 (define_insn "rstorssp"
26194 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")]
26198 [(set_attr "length" "5")
26199 (set_attr "type" "other")])
26201 (define_insn "@wrss<mode>"
26202 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
26203 (match_operand:SWI48 1 "memory_operand" "m")]
26206 "wrss<mskmodesuffix>\t%0, %1"
26207 [(set_attr "length" "3")
26208 (set_attr "type" "other")])
26210 (define_insn "@wruss<mode>"
26211 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
26212 (match_operand:SWI48 1 "memory_operand" "m")]
26215 "wruss<mskmodesuffix>\t%0, %1"
26216 [(set_attr "length" "4")
26217 (set_attr "type" "other")])
26219 (define_insn "setssbsy"
26220 [(unspec_volatile [(const_int 0)] UNSPECV_SETSSBSY)]
26223 [(set_attr "length" "4")
26224 (set_attr "type" "other")])
26226 (define_insn "clrssbsy"
26227 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")]
26231 [(set_attr "length" "4")
26232 (set_attr "type" "other")])
26234 (define_insn "nop_endbr"
26235 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]
26236 "(flag_cf_protection & CF_BRANCH)"
26238 return TARGET_64BIT ? "endbr64" : "endbr32";
26240 [(set_attr "length" "4")
26241 (set_attr "length_immediate" "0")
26242 (set_attr "modrm" "0")])
26245 (define_expand "xbegin"
26246 [(set (match_operand:SI 0 "register_operand")
26247 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
26250 rtx_code_label *label = gen_label_rtx ();
26252 /* xbegin is emitted as jump_insn, so reload won't be able
26253 to reload its operand. Force the value into AX hard register. */
26254 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
26255 emit_move_insn (ax_reg, constm1_rtx);
26257 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
26259 emit_label (label);
26260 LABEL_NUSES (label) = 1;
26262 emit_move_insn (operands[0], ax_reg);
26267 (define_insn "xbegin_1"
26269 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
26271 (label_ref (match_operand 1))
26273 (set (match_operand:SI 0 "register_operand" "+a")
26274 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
26277 [(set_attr "type" "other")
26278 (set_attr "length" "6")])
26280 (define_insn "xend"
26281 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
26284 [(set_attr "type" "other")
26285 (set_attr "length" "3")])
26287 (define_insn "xabort"
26288 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand")]
26292 [(set_attr "type" "other")
26293 (set_attr "length" "3")])
26295 (define_expand "xtest"
26296 [(set (match_operand:QI 0 "register_operand")
26297 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
26300 emit_insn (gen_xtest_1 ());
26302 ix86_expand_setcc (operands[0], NE,
26303 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
26307 (define_insn "xtest_1"
26308 [(set (reg:CCZ FLAGS_REG)
26309 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
26312 [(set_attr "type" "other")
26313 (set_attr "length" "3")])
26315 (define_insn "clwb"
26316 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
26320 [(set_attr "type" "sse")
26321 (set_attr "atom_sse_attr" "fence")
26322 (set_attr "memory" "unknown")])
26324 (define_insn "clflushopt"
26325 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
26326 UNSPECV_CLFLUSHOPT)]
26327 "TARGET_CLFLUSHOPT"
26329 [(set_attr "type" "sse")
26330 (set_attr "atom_sse_attr" "fence")
26331 (set_attr "memory" "unknown")])
26333 ;; MONITORX and MWAITX
26334 (define_insn "mwaitx"
26335 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
26336 (match_operand:SI 1 "register_operand" "a")
26337 (match_operand:SI 2 "register_operand" "b")]
26340 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
26341 ;; Since 32bit register operands are implicitly zero extended to 64bit,
26342 ;; we only need to set up 32bit registers.
26344 [(set_attr "length" "3")])
26346 (define_insn "@monitorx_<mode>"
26347 [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
26348 (match_operand:SI 1 "register_operand" "c")
26349 (match_operand:SI 2 "register_operand" "d")]
26352 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
26353 ;; RCX and RDX are used. Since 32bit register operands are implicitly
26354 ;; zero extended to 64bit, we only need to set up 32bit registers.
26356 [(set (attr "length")
26357 (symbol_ref ("(Pmode != word_mode) + 3")))])
26360 (define_insn "@clzero_<mode>"
26361 [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
26365 [(set_attr "length" "3")
26366 (set_attr "memory" "unknown")])
26368 ;; RDPKRU and WRPKRU
26370 (define_expand "rdpkru"
26372 [(set (match_operand:SI 0 "register_operand")
26373 (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
26374 (set (match_dup 2) (const_int 0))])]
26377 operands[1] = force_reg (SImode, const0_rtx);
26378 operands[2] = gen_reg_rtx (SImode);
26381 (define_insn "*rdpkru"
26382 [(set (match_operand:SI 0 "register_operand" "=a")
26383 (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
26385 (set (match_operand:SI 1 "register_operand" "=d")
26389 [(set_attr "type" "other")])
26391 (define_expand "wrpkru"
26392 [(unspec_volatile:SI
26393 [(match_operand:SI 0 "register_operand")
26394 (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
26397 operands[1] = force_reg (SImode, const0_rtx);
26398 operands[2] = force_reg (SImode, const0_rtx);
26401 (define_insn "*wrpkru"
26402 [(unspec_volatile:SI
26403 [(match_operand:SI 0 "register_operand" "a")
26404 (match_operand:SI 1 "register_operand" "d")
26405 (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
26408 [(set_attr "type" "other")])
26410 (define_insn "rdpid"
26411 [(set (match_operand:SI 0 "register_operand" "=r")
26412 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDPID))]
26413 "!TARGET_64BIT && TARGET_RDPID"
26415 [(set_attr "type" "other")])
26417 (define_insn "rdpid_rex64"
26418 [(set (match_operand:DI 0 "register_operand" "=r")
26419 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPID))]
26420 "TARGET_64BIT && TARGET_RDPID"
26422 [(set_attr "type" "other")])
26424 ;; Intirinsics for > i486
26426 (define_insn "wbinvd"
26427 [(unspec_volatile [(const_int 0)] UNSPECV_WBINVD)]
26430 [(set_attr "type" "other")])
26432 (define_insn "wbnoinvd"
26433 [(unspec_volatile [(const_int 0)] UNSPECV_WBNOINVD)]
26436 [(set_attr "type" "other")])
26438 ;; MOVDIRI and MOVDIR64B
26440 (define_insn "movdiri<mode>"
26441 [(set (match_operand:SWI48 0 "memory_operand" "=m")
26442 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")]
26445 "movdiri\t{%1, %0|%0, %1}"
26446 [(set_attr "type" "other")])
26448 (define_insn "@movdir64b_<mode>"
26449 [(set (mem:XI (match_operand:P 0 "register_operand" "r"))
26450 (unspec:XI [(match_operand:XI 1 "memory_operand" "m")]
26451 UNSPEC_MOVDIR64B))]
26453 "movdir64b\t{%1, %0|%0, %1}"
26454 [(set_attr "type" "other")])
26457 (define_int_iterator TSXLDTRK [UNSPECV_XSUSLDTRK UNSPECV_XRESLDTRK])
26458 (define_int_attr tsxldtrk [(UNSPECV_XSUSLDTRK "xsusldtrk")
26459 (UNSPECV_XRESLDTRK "xresldtrk")])
26460 (define_insn "<tsxldtrk>"
26461 [(unspec_volatile [(const_int 0)] TSXLDTRK)]
26464 [(set_attr "type" "other")
26465 (set_attr "length" "4")])
26467 ;; ENQCMD and ENQCMDS
26469 (define_int_iterator ENQCMD [UNSPECV_ENQCMD UNSPECV_ENQCMDS])
26470 (define_int_attr enqcmd_sfx [(UNSPECV_ENQCMD "") (UNSPECV_ENQCMDS "s")])
26472 (define_insn "@enqcmd<enqcmd_sfx>_<mode>"
26473 [(set (reg:CCZ FLAGS_REG)
26474 (unspec_volatile:CCZ [(match_operand:P 0 "register_operand" "r")
26475 (match_operand:XI 1 "memory_operand" "m")]
26478 "enqcmd<enqcmd_sfx>\t{%1, %0|%0, %1}"
26479 [(set_attr "type" "other")])
26482 (define_int_iterator UINTR [UNSPECV_CLUI UNSPECV_STUI])
26483 (define_int_attr uintr [(UNSPECV_CLUI "clui") (UNSPECV_STUI "stui")])
26485 (define_insn "<uintr>"
26486 [(unspec_volatile [(const_int 0)] UINTR)]
26487 "TARGET_UINTR && TARGET_64BIT"
26489 [(set_attr "type" "other")
26490 (set_attr "length" "4")])
26492 (define_insn "testui"
26493 [(set (reg:CCC FLAGS_REG)
26494 (unspec_volatile:CCC [(const_int 0)] UNSPECV_TESTUI))]
26495 "TARGET_UINTR && TARGET_64BIT"
26497 [(set_attr "type" "other")
26498 (set_attr "length" "4")])
26500 (define_insn "senduipi"
26502 [(match_operand:DI 0 "register_operand" "r")]
26504 "TARGET_UINTR && TARGET_64BIT"
26506 [(set_attr "type" "other")
26507 (set_attr "length" "4")])
26511 (define_insn "umwait"
26512 [(set (reg:CCC FLAGS_REG)
26513 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26514 (match_operand:DI 1 "register_operand" "A")]
26516 "!TARGET_64BIT && TARGET_WAITPKG"
26518 [(set_attr "length" "3")])
26520 (define_insn "umwait_rex64"
26521 [(set (reg:CCC FLAGS_REG)
26522 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26523 (match_operand:SI 1 "register_operand" "a")
26524 (match_operand:SI 2 "register_operand" "d")]
26526 "TARGET_64BIT && TARGET_WAITPKG"
26528 [(set_attr "length" "3")])
26530 (define_insn "@umonitor_<mode>"
26531 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
26535 [(set (attr "length")
26536 (symbol_ref ("(Pmode != word_mode) + 3")))])
26538 (define_insn "tpause"
26539 [(set (reg:CCC FLAGS_REG)
26540 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26541 (match_operand:DI 1 "register_operand" "A")]
26543 "!TARGET_64BIT && TARGET_WAITPKG"
26545 [(set_attr "length" "3")])
26547 (define_insn "tpause_rex64"
26548 [(set (reg:CCC FLAGS_REG)
26549 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26550 (match_operand:SI 1 "register_operand" "a")
26551 (match_operand:SI 2 "register_operand" "d")]
26553 "TARGET_64BIT && TARGET_WAITPKG"
26555 [(set_attr "length" "3")])
26557 (define_insn "cldemote"
26558 [(unspec_volatile[(match_operand 0 "address_operand" "p")]
26562 [(set_attr "type" "other")
26563 (set_attr "memory" "unknown")])
26565 (define_insn "speculation_barrier"
26566 [(unspec_volatile [(const_int 0)] UNSPECV_SPECULATION_BARRIER)]
26569 [(set_attr "type" "other")
26570 (set_attr "length" "3")])
26572 (define_insn "serialize"
26573 [(unspec_volatile [(const_int 0)] UNSPECV_SERIALIZE)]
26576 [(set_attr "type" "other")
26577 (set_attr "length" "3")])
26579 (define_insn "patchable_area"
26580 [(unspec_volatile [(match_operand 0 "const_int_operand")
26581 (match_operand 1 "const_int_operand")]
26582 UNSPECV_PATCHABLE_AREA)]
26585 ix86_output_patchable_area (INTVAL (operands[0]),
26586 INTVAL (operands[1]) != 0);
26589 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
26590 (set_attr "length_immediate" "0")
26591 (set_attr "modrm" "0")])
26593 (define_insn "hreset"
26594 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")]
26598 [(set_attr "type" "other")
26599 (set_attr "length" "4")])
26601 ;; Spaceship optimization
26602 (define_expand "spaceship<mode>3"
26603 [(match_operand:SI 0 "register_operand")
26604 (match_operand:MODEF 1 "cmp_fp_expander_operand")
26605 (match_operand:MODEF 2 "cmp_fp_expander_operand")]
26606 "(TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
26607 && (TARGET_CMOVE || (TARGET_SAHF && TARGET_USE_SAHF))"
26609 ix86_expand_fp_spaceship (operands[0], operands[1], operands[2]);
26613 (define_expand "spaceshipxf3"
26614 [(match_operand:SI 0 "register_operand")
26615 (match_operand:XF 1 "nonmemory_operand")
26616 (match_operand:XF 2 "nonmemory_operand")]
26617 "TARGET_80387 && (TARGET_CMOVE || (TARGET_SAHF && TARGET_USE_SAHF))"
26619 ix86_expand_fp_spaceship (operands[0], operands[1], operands[2]);
26623 ;; Defined because the generic expand_builtin_issignaling for XFmode
26624 ;; only tests for sNaNs, but i387 treats also pseudo numbers as always
26626 (define_expand "issignalingxf2"
26627 [(match_operand:SI 0 "register_operand")
26628 (match_operand:XF 1 "general_operand")]
26631 rtx temp = operands[1];
26634 rtx mem = assign_stack_temp (XFmode, GET_MODE_SIZE (XFmode));
26635 emit_move_insn (mem, temp);
26638 rtx ex = adjust_address (temp, HImode, 8);
26639 rtx hi = adjust_address (temp, SImode, 4);
26640 rtx lo = adjust_address (temp, SImode, 0);
26641 rtx val = GEN_INT (HOST_WIDE_INT_M1U << 30);
26642 rtx mask = GEN_INT (0x7fff);
26643 rtx bit = GEN_INT (HOST_WIDE_INT_1U << 30);
26645 ((ex & mask) && (int) hi >= 0)
26646 || ((ex & mask) == mask && ((hi ^ bit) | ((lo | -lo) >> 31)) > val). */
26647 rtx nlo = expand_unop (SImode, neg_optab, lo, NULL_RTX, 0);
26648 lo = expand_binop (SImode, ior_optab, lo, nlo,
26649 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26650 lo = expand_shift (RSHIFT_EXPR, SImode, lo, 31, NULL_RTX, 1);
26651 temp = expand_binop (SImode, xor_optab, hi, bit,
26652 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26653 temp = expand_binop (SImode, ior_optab, temp, lo,
26654 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26655 temp = emit_store_flag_force (gen_reg_rtx (SImode), GTU, temp, val,
26657 ex = expand_binop (HImode, and_optab, ex, mask,
26658 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26659 rtx temp2 = emit_store_flag_force (gen_reg_rtx (SImode), NE,
26660 ex, const0_rtx, SImode, 1, 1);
26661 ex = emit_store_flag_force (gen_reg_rtx (SImode), EQ,
26662 ex, mask, HImode, 1, 1);
26663 temp = expand_binop (SImode, and_optab, temp, ex,
26664 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26665 rtx temp3 = emit_store_flag_force (gen_reg_rtx (SImode), GE,
26666 hi, const0_rtx, SImode, 0, 1);
26667 temp2 = expand_binop (SImode, and_optab, temp2, temp3,
26668 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26669 temp = expand_binop (SImode, ior_optab, temp, temp2,
26670 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26671 emit_move_insn (operands[0], temp);
26675 (define_insn "urdmsr"
26676 [(set (match_operand:DI 0 "register_operand" "=r")
26677 (unspec_volatile:DI
26678 [(match_operand:DI 1 "x86_64_szext_nonmemory_operand" "reZ")]
26680 "TARGET_USER_MSR && TARGET_64BIT"
26681 "urdmsr\t{%1, %0|%0, %1}"
26682 [(set_attr "prefix" "vex")
26683 (set_attr "type" "other")])
26685 (define_insn "uwrmsr"
26687 [(match_operand:DI 0 "x86_64_szext_nonmemory_operand" "reZ")
26688 (match_operand:DI 1 "register_operand" "r")]
26690 "TARGET_USER_MSR && TARGET_64BIT"
26691 "uwrmsr\t{%1, %0|%0, %1}"
26692 [(set_attr "prefix" "vex")
26693 (set_attr "type" "other")])
26697 (include "sync.md")