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:
213 (define_c_enum "unspecv" [
217 UNSPECV_PROBE_STACK_RANGE
220 UNSPECV_SPLIT_STACK_RETURN
226 UNSPECV_LLWP_INTRINSIC
227 UNSPECV_SLWP_INTRINSIC
228 UNSPECV_LWPVAL_INTRINSIC
229 UNSPECV_LWPINS_INTRINSIC
255 ;; For atomic compound assignments.
261 ;; For RDRAND support
264 ;; For RDSEED support
278 ;; For CLFLUSHOPT support
281 ;; For MONITORX and MWAITX support
285 ;; For CLZERO support
288 ;; For RDPKRU and WRPKRU support
305 ;; For TSXLDTRK support
309 ;; For WAITPKG support
320 ;; For CLDEMOTE support
323 ;; For Speculation Barrier support
324 UNSPECV_SPECULATION_BARRIER
328 ;; For ENQCMD and ENQCMDS support
332 ;; For SERIALIZE support
335 ;; For patchable area support
336 UNSPECV_PATCHABLE_AREA
338 ;; For HRESET support
341 ;; For PREFETCHI support
345 ;; Constants to represent rounding modes in the ROUND instruction
347 [(ROUND_ROUNDEVEN 0x0)
355 ;; Constants to represent AVX512F embeded rounding
357 [(ROUND_NEAREST_INT 0)
365 ;; Constants to represent pcomtrue/pcomfalse variants
375 ;; Constants used in the XOP pperm instruction
377 [(PPERM_SRC 0x00) /* copy source */
378 (PPERM_INVERT 0x20) /* invert source */
379 (PPERM_REVERSE 0x40) /* bit reverse source */
380 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
381 (PPERM_ZERO 0x80) /* all 0's */
382 (PPERM_ONES 0xa0) /* all 1's */
383 (PPERM_SIGN 0xc0) /* propagate sign bit */
384 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
385 (PPERM_SRC1 0x00) /* use first source byte */
386 (PPERM_SRC2 0x10) /* use second source byte */
389 ;; Registers by name.
467 (FIRST_PSEUDO_REG 76)
470 ;; Insn callee abi index.
476 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
479 ;; In C guard expressions, put expressions which may be compile-time
480 ;; constants first. This allows for better optimization. For
481 ;; example, write "TARGET_64BIT && reload_completed", not
482 ;; "reload_completed && TARGET_64BIT".
486 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
487 atom,slm,glm,haswell,generic,lujiazui,amdfam10,bdver1,
488 bdver2,bdver3,bdver4,btver2,znver1,znver2,znver3,znver4"
489 (const (symbol_ref "ix86_schedule")))
491 ;; A basic instruction type. Refinements due to arguments to be
492 ;; provided in other attributes.
495 alu,alu1,negnot,imov,imovx,lea,
496 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
497 imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
498 push,pop,call,callv,leave,
500 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
501 fxch,fistp,fisttp,frndint,
502 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
503 ssemul,sseimul,ssediv,sselog,sselog1,
504 sseishft,sseishft1,ssecmp,ssecomi,
505 ssecvt,ssecvt1,sseicvt,sseins,
506 sseshuf,sseshuf1,ssemuladd,sse4arg,
508 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
509 (const_string "other"))
511 ;; Main data type used by the insn
513 "unknown,none,QI,HI,SI,DI,TI,OI,XI,HF,BF,SF,DF,XF,TF,V32HF,V16HF,V8HF,
514 V16SF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF,V8DF,V4HF,V4BF,V2HF,V2BF"
515 (const_string "unknown"))
517 ;; The CPU unit operations uses.
518 (define_attr "unit" "integer,i387,sse,mmx,unknown"
519 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
520 fxch,fistp,fisttp,frndint")
521 (const_string "i387")
522 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
523 ssemul,sseimul,ssediv,sselog,sselog1,
524 sseishft,sseishft1,ssecmp,ssecomi,
525 ssecvt,ssecvt1,sseicvt,sseins,
526 sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
528 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
530 (eq_attr "type" "other")
531 (const_string "unknown")]
532 (const_string "integer")))
534 ;; The (bounding maximum) length of an instruction immediate.
535 (define_attr "length_immediate" ""
536 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
537 bitmanip,imulx,msklog,mskmov")
539 (eq_attr "unit" "i387,sse,mmx")
541 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
542 rotate,rotatex,rotate1,imul,icmp,push,pop")
543 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
544 (eq_attr "type" "imov,test")
545 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
546 (eq_attr "type" "call")
547 (if_then_else (match_operand 0 "constant_call_address_operand")
550 (eq_attr "type" "callv")
551 (if_then_else (match_operand 1 "constant_call_address_operand")
554 ;; We don't know the size before shorten_branches. Expect
555 ;; the instruction to fit for better scheduling.
556 (eq_attr "type" "ibr")
559 (symbol_ref "/* Update immediate_length and other attributes! */
560 gcc_unreachable (),1")))
562 ;; The (bounding maximum) length of an instruction address.
563 (define_attr "length_address" ""
564 (cond [(eq_attr "type" "str,other,multi,fxch")
566 (and (eq_attr "type" "call")
567 (match_operand 0 "constant_call_address_operand"))
569 (and (eq_attr "type" "callv")
570 (match_operand 1 "constant_call_address_operand"))
573 (symbol_ref "ix86_attr_length_address_default (insn)")))
575 ;; Set when length prefix is used.
576 (define_attr "prefix_data16" ""
577 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
579 (eq_attr "mode" "HI")
581 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
586 ;; Set when string REP prefix is used.
587 (define_attr "prefix_rep" ""
588 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
590 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
595 ;; Set when 0f opcode prefix is used.
596 (define_attr "prefix_0f" ""
598 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov")
599 (eq_attr "unit" "sse,mmx"))
603 ;; Set when REX opcode prefix is used.
604 (define_attr "prefix_rex" ""
605 (cond [(not (match_test "TARGET_64BIT"))
607 (and (eq_attr "mode" "DI")
608 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
609 (eq_attr "unit" "!mmx")))
611 (and (eq_attr "mode" "QI")
612 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
614 (match_test "x86_extended_reg_mentioned_p (insn)")
616 (and (eq_attr "type" "imovx")
617 (match_operand:QI 1 "ext_QIreg_operand"))
622 ;; There are also additional prefixes in 3DNOW, SSSE3.
623 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
624 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
625 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
626 (define_attr "prefix_extra" ""
627 (cond [(eq_attr "type" "ssemuladd,sse4arg")
629 (eq_attr "type" "sseiadd1,ssecvt1")
634 ;; Prefix used: original, VEX or maybe VEX.
635 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
636 (cond [(eq_attr "mode" "OI,V8SF,V4DF")
638 (eq_attr "mode" "XI,V16SF,V8DF")
639 (const_string "evex")
641 (const_string "orig")))
643 ;; VEX W bit is used.
644 (define_attr "prefix_vex_w" "" (const_int 0))
646 ;; The length of VEX prefix
647 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
648 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
649 ;; still prefix_0f 1, with prefix_extra 1.
650 (define_attr "length_vex" ""
651 (if_then_else (and (eq_attr "prefix_0f" "1")
652 (eq_attr "prefix_extra" "0"))
653 (if_then_else (eq_attr "prefix_vex_w" "1")
654 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
655 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
656 (if_then_else (eq_attr "prefix_vex_w" "1")
657 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
658 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
660 ;; 4-bytes evex prefix and 1 byte opcode.
661 (define_attr "length_evex" "" (const_int 5))
663 ;; Set when modrm byte is used.
664 (define_attr "modrm" ""
665 (cond [(eq_attr "type" "str,leave")
667 (eq_attr "unit" "i387")
669 (and (eq_attr "type" "incdec")
670 (and (not (match_test "TARGET_64BIT"))
671 (ior (match_operand:SI 1 "register_operand")
672 (match_operand:HI 1 "register_operand"))))
674 (and (eq_attr "type" "push")
675 (not (match_operand 1 "memory_operand")))
677 (and (eq_attr "type" "pop")
678 (not (match_operand 0 "memory_operand")))
680 (and (eq_attr "type" "imov")
681 (and (not (eq_attr "mode" "DI"))
682 (ior (and (match_operand 0 "register_operand")
683 (match_operand 1 "immediate_operand"))
684 (ior (and (match_operand 0 "ax_reg_operand")
685 (match_operand 1 "memory_displacement_only_operand"))
686 (and (match_operand 0 "memory_displacement_only_operand")
687 (match_operand 1 "ax_reg_operand"))))))
689 (and (eq_attr "type" "call")
690 (match_operand 0 "constant_call_address_operand"))
692 (and (eq_attr "type" "callv")
693 (match_operand 1 "constant_call_address_operand"))
695 (and (eq_attr "type" "alu,alu1,icmp,test")
696 (match_operand 0 "ax_reg_operand"))
697 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
701 ;; The (bounding maximum) length of an instruction in bytes.
702 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
703 ;; Later we may want to split them and compute proper length as for
705 (define_attr "length" ""
706 (cond [(eq_attr "type" "other,multi,fistp,frndint")
708 (eq_attr "type" "fcmp")
710 (eq_attr "unit" "i387")
712 (plus (attr "prefix_data16")
713 (attr "length_address")))
714 (ior (eq_attr "prefix" "evex")
715 (and (ior (eq_attr "prefix" "maybe_evex")
716 (eq_attr "prefix" "maybe_vex"))
717 (match_test "TARGET_AVX512F")))
718 (plus (attr "length_evex")
719 (plus (attr "length_immediate")
721 (attr "length_address"))))
722 (ior (eq_attr "prefix" "vex")
723 (and (ior (eq_attr "prefix" "maybe_vex")
724 (eq_attr "prefix" "maybe_evex"))
725 (match_test "TARGET_AVX")))
726 (plus (attr "length_vex")
727 (plus (attr "length_immediate")
729 (attr "length_address"))))]
730 (plus (plus (attr "modrm")
731 (plus (attr "prefix_0f")
732 (plus (attr "prefix_rex")
733 (plus (attr "prefix_extra")
735 (plus (attr "prefix_rep")
736 (plus (attr "prefix_data16")
737 (plus (attr "length_immediate")
738 (attr "length_address")))))))
740 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
741 ;; `store' if there is a simple memory reference therein, or `unknown'
742 ;; if the instruction is complex.
744 (define_attr "memory" "none,load,store,both,unknown"
745 (cond [(eq_attr "type" "other,multi,str,lwp")
746 (const_string "unknown")
747 (eq_attr "type" "lea,fcmov,fpspc")
748 (const_string "none")
749 (eq_attr "type" "fistp,leave")
750 (const_string "both")
751 (eq_attr "type" "frndint")
752 (const_string "load")
753 (eq_attr "type" "push")
754 (if_then_else (match_operand 1 "memory_operand")
755 (const_string "both")
756 (const_string "store"))
757 (eq_attr "type" "pop")
758 (if_then_else (match_operand 0 "memory_operand")
759 (const_string "both")
760 (const_string "load"))
761 (eq_attr "type" "setcc")
762 (if_then_else (match_operand 0 "memory_operand")
763 (const_string "store")
764 (const_string "none"))
765 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
766 (if_then_else (ior (match_operand 0 "memory_operand")
767 (match_operand 1 "memory_operand"))
768 (const_string "load")
769 (const_string "none"))
770 (eq_attr "type" "ibr")
771 (if_then_else (match_operand 0 "memory_operand")
772 (const_string "load")
773 (const_string "none"))
774 (eq_attr "type" "call")
775 (if_then_else (match_operand 0 "constant_call_address_operand")
776 (const_string "none")
777 (const_string "load"))
778 (eq_attr "type" "callv")
779 (if_then_else (match_operand 1 "constant_call_address_operand")
780 (const_string "none")
781 (const_string "load"))
782 (and (eq_attr "type" "alu1,negnot,ishift1,rotate1,sselog1,sseshuf1")
783 (match_operand 1 "memory_operand"))
784 (const_string "both")
785 (and (match_operand 0 "memory_operand")
786 (match_operand 1 "memory_operand"))
787 (const_string "both")
788 (match_operand 0 "memory_operand")
789 (const_string "store")
790 (match_operand 1 "memory_operand")
791 (const_string "load")
793 "!alu1,negnot,ishift1,rotate1,
794 imov,imovx,icmp,test,bitmanip,
796 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
797 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
798 mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog")
799 (match_operand 2 "memory_operand"))
800 (const_string "load")
801 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
802 (match_operand 3 "memory_operand"))
803 (const_string "load")
805 (const_string "none")))
807 ;; Indicates if an instruction has both an immediate and a displacement.
809 (define_attr "imm_disp" "false,true,unknown"
810 (cond [(eq_attr "type" "other,multi")
811 (const_string "unknown")
812 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
813 (and (match_operand 0 "memory_displacement_operand")
814 (match_operand 1 "immediate_operand")))
815 (const_string "true")
816 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
817 (and (match_operand 0 "memory_displacement_operand")
818 (match_operand 2 "immediate_operand")))
819 (const_string "true")
821 (const_string "false")))
823 ;; Indicates if an FP operation has an integer source.
825 (define_attr "fp_int_src" "false,true"
826 (const_string "false"))
828 ;; Defines rounding mode of an FP operation.
830 (define_attr "i387_cw" "roundeven,floor,ceil,trunc,uninitialized,any"
831 (const_string "any"))
833 ;; Define attribute to indicate AVX insns with partial XMM register update.
834 (define_attr "avx_partial_xmm_update" "false,true"
835 (const_string "false"))
837 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
838 (define_attr "use_carry" "0,1" (const_string "0"))
840 ;; Define attribute to indicate unaligned ssemov insns
841 (define_attr "movu" "0,1" (const_string "0"))
843 ;; Used to control the "enabled" attribute on a per-instruction basis.
844 (define_attr "isa" "base,x64,nox64,x64_sse2,x64_sse4,x64_sse4_noavx,
845 x64_avx,x64_avx512bw,x64_avx512dq,aes,
846 sse_noavx,sse2,sse2_noavx,sse3,sse3_noavx,sse4,sse4_noavx,
847 avx,noavx,avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
848 avx512bw,noavx512bw,avx512dq,noavx512dq,fma_or_avx512vl,
849 avx512vl,noavx512vl,avxvnni,avx512vnnivl,avx512fp16,avxifma,
850 avx512ifmavl,avxneconvert,avx512bf16vl,vpclmulqdqvl"
851 (const_string "base"))
853 ;; Define instruction set of MMX instructions
854 (define_attr "mmx_isa" "base,native,sse,sse_noavx,avx"
855 (const_string "base"))
857 (define_attr "enabled" ""
858 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
859 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
860 (eq_attr "isa" "x64_sse2")
861 (symbol_ref "TARGET_64BIT && TARGET_SSE2")
862 (eq_attr "isa" "x64_sse4")
863 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
864 (eq_attr "isa" "x64_sse4_noavx")
865 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
866 (eq_attr "isa" "x64_avx")
867 (symbol_ref "TARGET_64BIT && TARGET_AVX")
868 (eq_attr "isa" "x64_avx512bw")
869 (symbol_ref "TARGET_64BIT && TARGET_AVX512BW")
870 (eq_attr "isa" "x64_avx512dq")
871 (symbol_ref "TARGET_64BIT && TARGET_AVX512DQ")
872 (eq_attr "isa" "aes") (symbol_ref "TARGET_AES")
873 (eq_attr "isa" "sse_noavx")
874 (symbol_ref "TARGET_SSE && !TARGET_AVX")
875 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
876 (eq_attr "isa" "sse2_noavx")
877 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
878 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
879 (eq_attr "isa" "sse3_noavx")
880 (symbol_ref "TARGET_SSE3 && !TARGET_AVX")
881 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
882 (eq_attr "isa" "sse4_noavx")
883 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
884 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
885 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
886 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
887 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
888 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
889 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
890 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
891 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
892 (eq_attr "isa" "fma_or_avx512vl")
893 (symbol_ref "TARGET_FMA || TARGET_AVX512VL")
894 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
895 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
896 (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
897 (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
898 (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
899 (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
900 (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
901 (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
902 (eq_attr "isa" "avxvnni") (symbol_ref "TARGET_AVXVNNI")
903 (eq_attr "isa" "avx512vnnivl")
904 (symbol_ref "TARGET_AVX512VNNI && TARGET_AVX512VL")
905 (eq_attr "isa" "avx512fp16")
906 (symbol_ref "TARGET_AVX512FP16")
907 (eq_attr "isa" "avxifma") (symbol_ref "TARGET_AVXIFMA")
908 (eq_attr "isa" "avx512ifmavl")
909 (symbol_ref "TARGET_AVX512IFMA && TARGET_AVX512VL")
910 (eq_attr "isa" "avxneconvert") (symbol_ref "TARGET_AVXNECONVERT")
911 (eq_attr "isa" "avx512bf16vl")
912 (symbol_ref "TARGET_AVX512BF16 && TARGET_AVX512VL")
913 (eq_attr "isa" "vpclmulqdqvl")
914 (symbol_ref "TARGET_VPCLMULQDQ && TARGET_AVX512VL")
916 (eq_attr "mmx_isa" "native")
917 (symbol_ref "!TARGET_MMX_WITH_SSE")
918 (eq_attr "mmx_isa" "sse")
919 (symbol_ref "TARGET_MMX_WITH_SSE")
920 (eq_attr "mmx_isa" "sse_noavx")
921 (symbol_ref "TARGET_MMX_WITH_SSE && !TARGET_AVX")
922 (eq_attr "mmx_isa" "avx")
923 (symbol_ref "TARGET_MMX_WITH_SSE && TARGET_AVX")
927 (define_attr "preferred_for_size" "" (const_int 1))
928 (define_attr "preferred_for_speed" "" (const_int 1))
930 ;; Describe a user's asm statement.
931 (define_asm_attributes
932 [(set_attr "length" "128")
933 (set_attr "type" "multi")])
935 (define_code_iterator plusminus [plus minus])
936 (define_code_iterator plusminusmultdiv [plus minus mult div])
938 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
940 ;; Base name for insn mnemonic.
941 (define_code_attr plusminus_mnemonic
942 [(plus "add") (ss_plus "adds") (us_plus "addus")
943 (minus "sub") (ss_minus "subs") (us_minus "subus")])
945 (define_code_iterator multdiv [mult div])
947 (define_code_attr multdiv_mnemonic
948 [(mult "mul") (div "div")])
950 ;; Mark commutative operators as such in constraints.
951 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
952 (minus "") (ss_minus "") (us_minus "")
953 (mult "%") (div "")])
955 ;; Mapping of max and min
956 (define_code_iterator maxmin [smax smin umax umin])
958 ;; Mapping of signed max and min
959 (define_code_iterator smaxmin [smax smin])
961 ;; Mapping of unsigned max and min
962 (define_code_iterator umaxmin [umax umin])
964 ;; Base name for integer and FP insn mnemonic
965 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
966 (umax "maxu") (umin "minu")])
967 (define_code_attr maxmin_float [(smax "max") (smin "min")])
969 (define_int_iterator IEEE_MAXMIN
973 (define_int_attr ieee_maxmin
974 [(UNSPEC_IEEE_MAX "max")
975 (UNSPEC_IEEE_MIN "min")])
977 ;; Mapping of logic operators
978 (define_code_iterator any_logic [and ior xor])
979 (define_code_iterator any_or [ior xor])
980 (define_code_iterator fpint_logic [and xor])
982 ;; Base name for insn mnemonic.
983 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
985 ;; Mapping of logic-shift operators
986 (define_code_iterator any_lshift [ashift lshiftrt])
988 ;; Mapping of shift-right operators
989 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
991 ;; Mapping of all shift operators
992 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
994 ;; Base name for insn mnemonic.
995 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
996 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
998 ;; Mapping of rotate operators
999 (define_code_iterator any_rotate [rotate rotatert])
1001 ;; Base name for insn mnemonic.
1002 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
1004 ;; Mapping of abs neg operators
1005 (define_code_iterator absneg [abs neg])
1007 ;; Mapping of abs neg operators to logic operation
1008 (define_code_attr absneg_op [(abs "and") (neg "xor")])
1010 ;; Base name for x87 insn mnemonic.
1011 (define_code_attr absneg_mnemonic [(abs "fabs") (neg "fchs")])
1013 ;; Mapping of extend operators
1014 (define_code_iterator any_extend [sign_extend zero_extend])
1016 ;; Mapping of highpart multiply operators
1017 (define_code_iterator any_mul_highpart [smul_highpart umul_highpart])
1019 ;; Prefix for insn menmonic.
1020 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
1021 (smul_highpart "i") (umul_highpart "")
1022 (div "i") (udiv "")])
1023 ;; Prefix for define_insn
1024 (define_code_attr s [(sign_extend "s") (zero_extend "u")
1025 (smul_highpart "s") (umul_highpart "u")])
1026 (define_code_attr u [(sign_extend "") (zero_extend "u")
1027 (div "") (udiv "u")])
1028 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")
1029 (div "false") (udiv "true")])
1031 ;; Used in signed and unsigned truncations.
1032 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
1033 ;; Instruction suffix for truncations.
1034 (define_code_attr trunsuffix
1035 [(ss_truncate "s") (truncate "") (us_truncate "us")])
1037 ;; Instruction suffix for SSE sign and zero extensions.
1038 (define_code_attr extsuffix [(sign_extend "sx") (zero_extend "zx")])
1040 ;; Used in signed and unsigned fix.
1041 (define_code_iterator any_fix [fix unsigned_fix])
1042 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
1043 (define_code_attr fixunssuffix [(fix "") (unsigned_fix "uns")])
1044 (define_code_attr fixprefix [(fix "s") (unsigned_fix "u")])
1046 ;; Used in signed and unsigned float.
1047 (define_code_iterator any_float [float unsigned_float])
1048 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
1049 (define_code_attr floatunssuffix [(float "") (unsigned_float "uns")])
1050 (define_code_attr floatprefix [(float "s") (unsigned_float "u")])
1052 ;; Base name for expression
1053 (define_code_attr insn
1054 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
1055 (minus "sub") (ss_minus "sssub") (us_minus "ussub")
1056 (sign_extend "extend") (zero_extend "zero_extend")
1057 (ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")
1058 (rotate "rotl") (rotatert "rotr")
1059 (mult "mul") (div "div")])
1061 ;; All integer modes.
1062 (define_mode_iterator SWI1248x [QI HI SI DI])
1064 ;; All integer modes without QImode.
1065 (define_mode_iterator SWI248x [HI SI DI])
1067 ;; All integer modes without QImode and HImode.
1068 (define_mode_iterator SWI48x [SI DI])
1070 ;; All integer modes without SImode and DImode.
1071 (define_mode_iterator SWI12 [QI HI])
1073 ;; All integer modes without DImode.
1074 (define_mode_iterator SWI124 [QI HI SI])
1076 ;; All integer modes without QImode and DImode.
1077 (define_mode_iterator SWI24 [HI SI])
1079 ;; Single word integer modes.
1080 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
1082 ;; Single word integer modes without QImode.
1083 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
1085 ;; Single word integer modes without QImode and HImode.
1086 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
1088 ;; All math-dependant single and double word integer modes.
1089 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
1090 (HI "TARGET_HIMODE_MATH")
1091 SI DI (TI "TARGET_64BIT")])
1093 ;; Math-dependant single word integer modes.
1094 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
1095 (HI "TARGET_HIMODE_MATH")
1096 SI (DI "TARGET_64BIT")])
1098 ;; Math-dependant integer modes without DImode.
1099 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
1100 (HI "TARGET_HIMODE_MATH")
1103 ;; Math-dependant integer modes with DImode.
1104 (define_mode_iterator SWIM1248x
1105 [(QI "TARGET_QIMODE_MATH")
1106 (HI "TARGET_HIMODE_MATH")
1109 ;; Math-dependant single word integer modes without QImode.
1110 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
1111 SI (DI "TARGET_64BIT")])
1113 ;; Double word integer modes.
1114 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
1115 (TI "TARGET_64BIT")])
1117 ;; SWI and DWI together.
1118 (define_mode_iterator SWIDWI [QI HI SI DI (TI "TARGET_64BIT")])
1120 ;; SWI48 and DWI together.
1121 (define_mode_iterator SWI48DWI [SI DI (TI "TARGET_64BIT")])
1123 ;; GET_MODE_SIZE for selected modes. As GET_MODE_SIZE is not
1124 ;; compile time constant, it is faster to use <MODE_SIZE> than
1125 ;; GET_MODE_SIZE (<MODE>mode). For XFmode which depends on
1126 ;; command line options just use GET_MODE_SIZE macro.
1127 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8")
1128 (TI "16") (HF "2") (BF "2") (SF "4") (DF "8")
1129 (XF "GET_MODE_SIZE (XFmode)")
1130 (V16QI "16") (V32QI "32") (V64QI "64")
1131 (V8HI "16") (V16HI "32") (V32HI "64")
1132 (V4SI "16") (V8SI "32") (V16SI "64")
1133 (V2DI "16") (V4DI "32") (V8DI "64")
1134 (V1TI "16") (V2TI "32") (V4TI "64")
1135 (V2DF "16") (V4DF "32") (V8DF "64")
1136 (V4SF "16") (V8SF "32") (V16SF "64")
1137 (V8HF "16") (V16HF "32") (V32HF "64")
1138 (V4HF "8") (V2HF "4")
1139 (V8BF "16") (V16BF "32") (V32BF "64")
1140 (V4BF "8") (V2BF "4")])
1142 ;; Double word integer modes as mode attribute.
1143 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI") (TI "OI")])
1144 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti") (TI "oi")])
1146 ;; Half sized integer modes.
1147 (define_mode_attr HALF [(TI "DI") (DI "SI")])
1148 (define_mode_attr half [(TI "di") (DI "si")])
1150 ;; LEA mode corresponding to an integer mode
1151 (define_mode_attr LEAMODE [(QI "SI") (HI "SI") (SI "SI") (DI "DI")])
1153 ;; Half mode for double word integer modes.
1154 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1155 (DI "TARGET_64BIT")])
1157 ;; Instruction suffix for integer modes.
1158 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1160 ;; Instruction suffix for masks.
1161 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1163 ;; Pointer size prefix for integer modes (Intel asm dialect)
1164 (define_mode_attr iptrsize [(QI "BYTE")
1169 ;; Register class for integer modes.
1170 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1172 ;; Immediate operand constraint for integer modes.
1173 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1175 ;; General operand constraint for word modes.
1176 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1178 ;; Memory operand constraint for word modes.
1179 (define_mode_attr m [(QI "m") (HI "m") (SI "BM") (DI "BM")])
1181 ;; Immediate operand constraint for double integer modes.
1182 (define_mode_attr di [(SI "nF") (DI "Wd")])
1184 ;; Immediate operand constraint for shifts.
1185 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1186 (define_mode_attr KS [(QI "Wb") (HI "Ww") (SI "I") (DI "J")])
1188 ;; Print register name in the specified mode.
1189 (define_mode_attr k [(QI "b") (HI "w") (SI "k") (DI "q")])
1191 ;; General operand predicate for integer modes.
1192 (define_mode_attr general_operand
1193 [(QI "general_operand")
1194 (HI "general_operand")
1195 (SI "x86_64_general_operand")
1196 (DI "x86_64_general_operand")
1197 (TI "x86_64_general_operand")])
1199 ;; General operand predicate for integer modes, where for TImode
1200 ;; we need both words of the operand to be general operands.
1201 (define_mode_attr general_hilo_operand
1202 [(QI "general_operand")
1203 (HI "general_operand")
1204 (SI "x86_64_general_operand")
1205 (DI "x86_64_general_operand")
1206 (TI "x86_64_hilo_general_operand")])
1208 ;; General sign extend operand predicate for integer modes,
1209 ;; which disallows VOIDmode operands and thus it is suitable
1210 ;; for use inside sign_extend.
1211 (define_mode_attr general_sext_operand
1212 [(QI "sext_operand")
1214 (SI "x86_64_sext_operand")
1215 (DI "x86_64_sext_operand")])
1217 ;; General sign/zero extend operand predicate for integer modes.
1218 (define_mode_attr general_szext_operand
1219 [(QI "general_operand")
1220 (HI "general_operand")
1221 (SI "x86_64_szext_general_operand")
1222 (DI "x86_64_szext_general_operand")
1223 (TI "x86_64_hilo_general_operand")])
1225 (define_mode_attr nonmemory_szext_operand
1226 [(QI "nonmemory_operand")
1227 (HI "nonmemory_operand")
1228 (SI "x86_64_szext_nonmemory_operand")
1229 (DI "x86_64_szext_nonmemory_operand")])
1231 ;; Immediate operand predicate for integer modes.
1232 (define_mode_attr immediate_operand
1233 [(QI "immediate_operand")
1234 (HI "immediate_operand")
1235 (SI "x86_64_immediate_operand")
1236 (DI "x86_64_immediate_operand")])
1238 ;; Nonmemory operand predicate for integer modes.
1239 (define_mode_attr nonmemory_operand
1240 [(QI "nonmemory_operand")
1241 (HI "nonmemory_operand")
1242 (SI "x86_64_nonmemory_operand")
1243 (DI "x86_64_nonmemory_operand")])
1245 ;; Operand predicate for shifts.
1246 (define_mode_attr shift_operand
1247 [(QI "nonimmediate_operand")
1248 (HI "nonimmediate_operand")
1249 (SI "nonimmediate_operand")
1250 (DI "shiftdi_operand")
1251 (TI "register_operand")])
1253 ;; Operand predicate for shift argument.
1254 (define_mode_attr shift_immediate_operand
1255 [(QI "const_1_to_31_operand")
1256 (HI "const_1_to_31_operand")
1257 (SI "const_1_to_31_operand")
1258 (DI "const_1_to_63_operand")])
1260 ;; Input operand predicate for arithmetic left shifts.
1261 (define_mode_attr ashl_input_operand
1262 [(QI "nonimmediate_operand")
1263 (HI "nonimmediate_operand")
1264 (SI "nonimmediate_operand")
1265 (DI "ashldi_input_operand")
1266 (TI "reg_or_pm1_operand")])
1268 ;; SSE and x87 SFmode and DFmode floating point modes
1269 (define_mode_iterator MODEF [SF DF])
1271 ;; SSE floating point modes
1272 (define_mode_iterator MODEFH [(HF "TARGET_AVX512FP16") SF DF])
1274 ;; All x87 floating point modes
1275 (define_mode_iterator X87MODEF [SF DF XF])
1277 ;; All x87 floating point modes plus HFmode
1278 (define_mode_iterator X87MODEFH [HF SF DF XF BF])
1280 ;; All SSE floating point modes
1281 (define_mode_iterator SSEMODEF [HF SF DF TF])
1282 (define_mode_attr ssevecmodef [(HF "V8HF") (SF "V4SF") (DF "V2DF") (TF "TF")])
1284 ;; SSE instruction suffix for various modes
1285 (define_mode_attr ssemodesuffix
1286 [(HF "sh") (SF "ss") (DF "sd")
1287 (V32HF "ph") (V16SF "ps") (V8DF "pd")
1288 (V16HF "ph") (V16BF "bf") (V8SF "ps") (V4DF "pd")
1289 (V8HF "ph") (V8BF "bf") (V4SF "ps") (V2DF "pd")
1290 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1291 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1292 (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1294 ;; SSE vector suffix for floating point modes
1295 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1297 ;; SSE vector mode corresponding to a scalar mode
1298 (define_mode_attr ssevecmode
1299 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (HF "V8HF") (BF "V8BF") (SF "V4SF") (DF "V2DF")])
1300 (define_mode_attr ssevecmodelower
1301 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1303 ;; AVX512F vector mode corresponding to a scalar mode
1304 (define_mode_attr avx512fvecmode
1305 [(QI "V64QI") (HI "V32HI") (SI "V16SI") (DI "V8DI") (SF "V16SF") (DF "V8DF")])
1307 ;; Instruction suffix for REX 64bit operators.
1308 (define_mode_attr rex64suffix [(SI "{l}") (DI "{q}")])
1309 (define_mode_attr rex64namesuffix [(SI "") (DI "q")])
1311 ;; This mode iterator allows :P to be used for patterns that operate on
1312 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1313 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1315 ;; This mode iterator allows :W to be used for patterns that operate on
1316 ;; word_mode sized quantities.
1317 (define_mode_iterator W
1318 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1320 ;; This mode iterator allows :PTR to be used for patterns that operate on
1321 ;; ptr_mode sized quantities.
1322 (define_mode_iterator PTR
1323 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1325 ;; Scheduling descriptions
1327 (include "pentium.md")
1330 (include "athlon.md")
1331 (include "bdver1.md")
1332 (include "bdver3.md")
1333 (include "btver2.md")
1334 (include "znver.md")
1335 (include "znver4.md")
1336 (include "geode.md")
1340 (include "core2.md")
1341 (include "haswell.md")
1342 (include "lujiazui.md")
1345 ;; Operand and operator predicates and constraints
1347 (include "predicates.md")
1348 (include "constraints.md")
1351 ;; Compare and branch/compare and store instructions.
1353 (define_expand "cbranch<mode>4"
1354 [(set (reg:CC FLAGS_REG)
1355 (compare:CC (match_operand:SWIM1248x 1 "nonimmediate_operand")
1356 (match_operand:SWIM1248x 2 "<general_operand>")))
1357 (set (pc) (if_then_else
1358 (match_operator 0 "ordered_comparison_operator"
1359 [(reg:CC FLAGS_REG) (const_int 0)])
1360 (label_ref (match_operand 3))
1364 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1365 operands[1] = force_reg (<MODE>mode, operands[1]);
1366 ix86_expand_branch (GET_CODE (operands[0]),
1367 operands[1], operands[2], operands[3]);
1371 (define_expand "cbranchti4"
1372 [(set (reg:CC FLAGS_REG)
1373 (compare:CC (match_operand:TI 1 "nonimmediate_operand")
1374 (match_operand:TI 2 "ix86_timode_comparison_operand")))
1375 (set (pc) (if_then_else
1376 (match_operator 0 "ix86_timode_comparison_operator"
1377 [(reg:CC FLAGS_REG) (const_int 0)])
1378 (label_ref (match_operand 3))
1380 "TARGET_64BIT || TARGET_SSE4_1"
1382 ix86_expand_branch (GET_CODE (operands[0]),
1383 operands[1], operands[2], operands[3]);
1387 (define_expand "cbranchoi4"
1388 [(set (reg:CC FLAGS_REG)
1389 (compare:CC (match_operand:OI 1 "nonimmediate_operand")
1390 (match_operand:OI 2 "nonimmediate_operand")))
1391 (set (pc) (if_then_else
1392 (match_operator 0 "bt_comparison_operator"
1393 [(reg:CC FLAGS_REG) (const_int 0)])
1394 (label_ref (match_operand 3))
1398 ix86_expand_branch (GET_CODE (operands[0]),
1399 operands[1], operands[2], operands[3]);
1403 (define_expand "cstore<mode>4"
1404 [(set (reg:CC FLAGS_REG)
1405 (compare:CC (match_operand:SDWIM 2 "nonimmediate_operand")
1406 (match_operand:SDWIM 3 "<general_operand>")))
1407 (set (match_operand:QI 0 "register_operand")
1408 (match_operator 1 "ordered_comparison_operator"
1409 [(reg:CC FLAGS_REG) (const_int 0)]))]
1412 if (<MODE>mode == (TARGET_64BIT ? TImode : DImode))
1414 if (GET_CODE (operands[1]) != EQ
1415 && GET_CODE (operands[1]) != NE)
1418 else if (MEM_P (operands[2]) && MEM_P (operands[3]))
1419 operands[2] = force_reg (<MODE>mode, operands[2]);
1420 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1421 operands[2], operands[3]);
1425 (define_expand "@cmp<mode>_1"
1426 [(set (reg:CC FLAGS_REG)
1427 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1428 (match_operand:SWI48 1 "<general_operand>")))])
1430 (define_mode_iterator SWI1248_AVX512BWDQ_64
1431 [(QI "TARGET_AVX512DQ") HI
1432 (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW && TARGET_64BIT")])
1434 (define_insn "*cmp<mode>_ccz_1"
1435 [(set (reg FLAGS_REG)
1436 (compare (match_operand:SWI1248_AVX512BWDQ_64 0
1437 "nonimmediate_operand" "<r>,?m<r>,$k")
1438 (match_operand:SWI1248_AVX512BWDQ_64 1 "const0_operand")))]
1439 "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
1441 test{<imodesuffix>}\t%0, %0
1442 cmp{<imodesuffix>}\t{%1, %0|%0, %1}
1443 kortest<mskmodesuffix>\t%0, %0"
1444 [(set_attr "type" "test,icmp,msklog")
1445 (set_attr "length_immediate" "0,1,*")
1446 (set_attr "prefix" "*,*,vex")
1447 (set_attr "mode" "<MODE>")])
1449 (define_insn "*cmp<mode>_ccno_1"
1450 [(set (reg FLAGS_REG)
1451 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1452 (match_operand:SWI 1 "const0_operand")))]
1453 "ix86_match_ccmode (insn, CCNOmode)"
1455 test{<imodesuffix>}\t%0, %0
1456 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1457 [(set_attr "type" "test,icmp")
1458 (set_attr "length_immediate" "0,1")
1459 (set_attr "mode" "<MODE>")])
1461 (define_insn "*cmp<mode>_1"
1462 [(set (reg FLAGS_REG)
1463 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1464 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r><m>")))]
1465 "ix86_match_ccmode (insn, CCmode)"
1466 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1467 [(set_attr "type" "icmp")
1468 (set_attr "mode" "<MODE>")])
1470 (define_insn "*cmp<mode>_minus_1"
1471 [(set (reg FLAGS_REG)
1473 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1474 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r><m>"))
1476 "ix86_match_ccmode (insn, CCGOCmode)"
1477 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1478 [(set_attr "type" "icmp")
1479 (set_attr "mode" "<MODE>")])
1481 (define_insn "*cmpqi_ext<mode>_1_mem_rex64"
1482 [(set (reg FLAGS_REG)
1484 (match_operand:QI 0 "norex_memory_operand" "Bn")
1486 (match_operator:SWI248 2 "extract_operator"
1487 [(match_operand 1 "int248_register_operand" "Q")
1489 (const_int 8)]) 0)))]
1490 "TARGET_64BIT && reload_completed
1491 && ix86_match_ccmode (insn, CCmode)"
1492 "cmp{b}\t{%h1, %0|%0, %h1}"
1493 [(set_attr "type" "icmp")
1494 (set_attr "mode" "QI")])
1496 (define_insn "*cmpqi_ext<mode>_1"
1497 [(set (reg FLAGS_REG)
1499 (match_operand:QI 0 "nonimmediate_operand" "QBc,m")
1501 (match_operator:SWI248 2 "extract_operator"
1502 [(match_operand 1 "int248_register_operand" "Q,Q")
1504 (const_int 8)]) 0)))]
1505 "ix86_match_ccmode (insn, CCmode)"
1506 "cmp{b}\t{%h1, %0|%0, %h1}"
1507 [(set_attr "isa" "*,nox64")
1508 (set_attr "type" "icmp")
1509 (set_attr "mode" "QI")])
1512 [(set (match_operand:QI 0 "register_operand")
1513 (match_operand:QI 1 "norex_memory_operand"))
1514 (set (match_operand 3 "flags_reg_operand")
1515 (match_operator 4 "compare_operator"
1518 (match_operator:SWI248 5 "extract_operator"
1519 [(match_operand 2 "int248_register_operand")
1521 (const_int 8)]) 0)]))]
1523 && peep2_reg_dead_p (2, operands[0])"
1531 (const_int 8)]) 0)]))])
1533 (define_insn "*cmpqi_ext<mode>_2"
1534 [(set (reg FLAGS_REG)
1537 (match_operator:SWI248 2 "extract_operator"
1538 [(match_operand 0 "int248_register_operand" "Q")
1541 (match_operand:QI 1 "const0_operand")))]
1542 "ix86_match_ccmode (insn, CCNOmode)"
1544 [(set_attr "type" "test")
1545 (set_attr "length_immediate" "0")
1546 (set_attr "mode" "QI")])
1548 (define_expand "cmpqi_ext_3"
1549 [(set (reg:CC FLAGS_REG)
1553 (match_operand:HI 0 "register_operand")
1556 (match_operand:QI 1 "const_int_operand")))])
1558 (define_insn "*cmpqi_ext<mode>_3_mem_rex64"
1559 [(set (reg FLAGS_REG)
1562 (match_operator:SWI248 2 "extract_operator"
1563 [(match_operand 0 "int248_register_operand" "Q")
1566 (match_operand:QI 1 "norex_memory_operand" "Bn")))]
1567 "TARGET_64BIT && reload_completed
1568 && ix86_match_ccmode (insn, CCmode)"
1569 "cmp{b}\t{%1, %h0|%h0, %1}"
1570 [(set_attr "type" "icmp")
1571 (set_attr "mode" "QI")])
1573 (define_insn "*cmpqi_ext<mode>_3"
1574 [(set (reg FLAGS_REG)
1577 (match_operator:SWI248 2 "extract_operator"
1578 [(match_operand 0 "int248_register_operand" "Q,Q")
1581 (match_operand:QI 1 "general_operand" "QnBc,m")))]
1582 "ix86_match_ccmode (insn, CCmode)"
1583 "cmp{b}\t{%1, %h0|%h0, %1}"
1584 [(set_attr "isa" "*,nox64")
1585 (set_attr "type" "icmp")
1586 (set_attr "mode" "QI")])
1589 [(set (match_operand:QI 0 "register_operand")
1590 (match_operand:QI 1 "norex_memory_operand"))
1591 (set (match_operand 3 "flags_reg_operand")
1592 (match_operator 4 "compare_operator"
1594 (match_operator:SWI248 5 "extract_operator"
1595 [(match_operand 2 "int248_register_operand")
1600 && peep2_reg_dead_p (2, operands[0])"
1610 (define_insn "*cmpqi_ext<mode>_4"
1611 [(set (reg FLAGS_REG)
1614 (match_operator:SWI248 2 "extract_operator"
1615 [(match_operand 0 "int248_register_operand" "Q")
1619 (match_operator:SWI248 3 "extract_operator"
1620 [(match_operand 1 "int248_register_operand" "Q")
1622 (const_int 8)]) 0)))]
1623 "ix86_match_ccmode (insn, CCmode)"
1624 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1625 [(set_attr "type" "icmp")
1626 (set_attr "mode" "QI")])
1628 (define_insn_and_split "*cmp<dwi>_doubleword"
1629 [(set (reg:CCZ FLAGS_REG)
1630 (compare:CCZ (match_operand:<DWI> 0 "nonimmediate_operand")
1631 (match_operand:<DWI> 1 "general_operand")))]
1632 "ix86_pre_reload_split ()"
1635 [(parallel [(set (reg:CCZ FLAGS_REG)
1636 (compare:CCZ (ior:DWIH (match_dup 4) (match_dup 5))
1638 (set (match_dup 4) (ior:DWIH (match_dup 4) (match_dup 5)))])]
1640 split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);
1641 /* Placing the SUBREG pieces in pseudos helps reload. */
1642 for (int i = 0; i < 4; i++)
1643 if (SUBREG_P (operands[i]))
1644 operands[i] = force_reg (<MODE>mode, operands[i]);
1646 operands[4] = gen_reg_rtx (<MODE>mode);
1648 /* Special case comparisons against -1. */
1649 if (operands[1] == constm1_rtx && operands[3] == constm1_rtx)
1651 emit_insn (gen_and<mode>3 (operands[4], operands[0], operands[2]));
1652 emit_insn (gen_cmp_1 (<MODE>mode, operands[4], constm1_rtx));
1656 if (operands[1] == const0_rtx)
1657 emit_move_insn (operands[4], operands[0]);
1658 else if (operands[0] == const0_rtx)
1659 emit_move_insn (operands[4], operands[1]);
1660 else if (operands[1] == constm1_rtx)
1661 emit_insn (gen_one_cmpl<mode>2 (operands[4], operands[0]));
1662 else if (operands[0] == constm1_rtx)
1663 emit_insn (gen_one_cmpl<mode>2 (operands[4], operands[1]));
1666 if (CONST_SCALAR_INT_P (operands[1])
1667 && !x86_64_immediate_operand (operands[1], <MODE>mode))
1668 operands[1] = force_reg (<MODE>mode, operands[1]);
1669 emit_insn (gen_xor<mode>3 (operands[4], operands[0], operands[1]));
1672 if (operands[3] == const0_rtx)
1673 operands[5] = operands[2];
1674 else if (operands[2] == const0_rtx)
1675 operands[5] = operands[3];
1678 operands[5] = gen_reg_rtx (<MODE>mode);
1679 if (operands[3] == constm1_rtx)
1680 emit_insn (gen_one_cmpl<mode>2 (operands[5], operands[2]));
1681 else if (operands[2] == constm1_rtx)
1682 emit_insn (gen_one_cmpl<mode>2 (operands[5], operands[3]));
1685 if (CONST_SCALAR_INT_P (operands[3])
1686 && !x86_64_immediate_operand (operands[3], <MODE>mode))
1687 operands[3] = force_reg (<MODE>mode, operands[3]);
1688 emit_insn (gen_xor<mode>3 (operands[5], operands[2], operands[3]));
1693 ;; These implement float point compares.
1694 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1695 ;; which would allow mix and match FP modes on the compares. Which is what
1696 ;; the old patterns did, but with many more of them.
1698 (define_expand "cbranchxf4"
1699 [(set (reg:CC FLAGS_REG)
1700 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1701 (match_operand:XF 2 "nonmemory_operand")))
1702 (set (pc) (if_then_else
1703 (match_operator 0 "ix86_fp_comparison_operator"
1706 (label_ref (match_operand 3))
1710 ix86_expand_branch (GET_CODE (operands[0]),
1711 operands[1], operands[2], operands[3]);
1715 (define_expand "cstorexf4"
1716 [(set (reg:CC FLAGS_REG)
1717 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1718 (match_operand:XF 3 "nonmemory_operand")))
1719 (set (match_operand:QI 0 "register_operand")
1720 (match_operator 1 "ix86_fp_comparison_operator"
1725 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1726 operands[2], operands[3]);
1730 (define_expand "cbranchhf4"
1731 [(set (reg:CC FLAGS_REG)
1732 (compare:CC (match_operand:HF 1 "cmp_fp_expander_operand")
1733 (match_operand:HF 2 "cmp_fp_expander_operand")))
1734 (set (pc) (if_then_else
1735 (match_operator 0 "ix86_fp_comparison_operator"
1738 (label_ref (match_operand 3))
1742 ix86_expand_branch (GET_CODE (operands[0]),
1743 operands[1], operands[2], operands[3]);
1747 (define_expand "cbranch<mode>4"
1748 [(set (reg:CC FLAGS_REG)
1749 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1750 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1751 (set (pc) (if_then_else
1752 (match_operator 0 "ix86_fp_comparison_operator"
1755 (label_ref (match_operand 3))
1757 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1759 ix86_expand_branch (GET_CODE (operands[0]),
1760 operands[1], operands[2], operands[3]);
1764 (define_expand "cbranchbf4"
1765 [(set (reg:CC FLAGS_REG)
1766 (compare:CC (match_operand:BF 1 "cmp_fp_expander_operand")
1767 (match_operand:BF 2 "cmp_fp_expander_operand")))
1768 (set (pc) (if_then_else
1769 (match_operator 0 "comparison_operator"
1772 (label_ref (match_operand 3))
1774 "TARGET_80387 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
1776 rtx op1 = ix86_expand_fast_convert_bf_to_sf (operands[1]);
1777 rtx op2 = ix86_expand_fast_convert_bf_to_sf (operands[2]);
1778 do_compare_rtx_and_jump (op1, op2, GET_CODE (operands[0]), 0,
1779 SFmode, NULL_RTX, NULL,
1780 as_a <rtx_code_label *> (operands[3]),
1781 /* Unfortunately this isn't propagated. */
1782 profile_probability::even ());
1786 (define_expand "cstorehf4"
1787 [(set (reg:CC FLAGS_REG)
1788 (compare:CC (match_operand:HF 2 "cmp_fp_expander_operand")
1789 (match_operand:HF 3 "cmp_fp_expander_operand")))
1790 (set (match_operand:QI 0 "register_operand")
1791 (match_operator 1 "ix86_fp_comparison_operator"
1796 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1797 operands[2], operands[3]);
1801 (define_expand "cstorebf4"
1802 [(set (reg:CC FLAGS_REG)
1803 (compare:CC (match_operand:BF 2 "cmp_fp_expander_operand")
1804 (match_operand:BF 3 "cmp_fp_expander_operand")))
1805 (set (match_operand:QI 0 "register_operand")
1806 (match_operator 1 "comparison_operator"
1809 "TARGET_80387 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
1811 rtx op1 = ix86_expand_fast_convert_bf_to_sf (operands[2]);
1812 rtx op2 = ix86_expand_fast_convert_bf_to_sf (operands[3]);
1813 rtx res = emit_store_flag_force (operands[0], GET_CODE (operands[1]),
1814 op1, op2, SFmode, 0, 1);
1815 if (!rtx_equal_p (res, operands[0]))
1816 emit_move_insn (operands[0], res);
1820 (define_expand "cstore<mode>4"
1821 [(set (reg:CC FLAGS_REG)
1822 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1823 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1824 (set (match_operand:QI 0 "register_operand")
1825 (match_operator 1 "ix86_fp_comparison_operator"
1828 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1830 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1831 operands[2], operands[3]);
1835 (define_expand "cbranchcc4"
1836 [(set (pc) (if_then_else
1837 (match_operator 0 "comparison_operator"
1838 [(match_operand 1 "flags_reg_operand")
1839 (match_operand 2 "const0_operand")])
1840 (label_ref (match_operand 3))
1844 ix86_expand_branch (GET_CODE (operands[0]),
1845 operands[1], operands[2], operands[3]);
1849 (define_expand "cstorecc4"
1850 [(set (match_operand:QI 0 "register_operand")
1851 (match_operator 1 "comparison_operator"
1852 [(match_operand 2 "flags_reg_operand")
1853 (match_operand 3 "const0_operand")]))]
1856 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1857 operands[2], operands[3]);
1861 ;; FP compares, step 1:
1862 ;; Set the FP condition codes and move fpsr to ax.
1864 ;; We may not use "#" to split and emit these
1865 ;; due to reg-stack pops killing fpsr.
1867 (define_insn "*cmpxf_i387"
1868 [(set (match_operand:HI 0 "register_operand" "=a")
1871 (match_operand:XF 1 "register_operand" "f")
1872 (match_operand:XF 2 "reg_or_0_operand" "fC"))]
1875 "* return output_fp_compare (insn, operands, false, false);"
1876 [(set_attr "type" "multi")
1877 (set_attr "unit" "i387")
1878 (set_attr "mode" "XF")])
1880 (define_insn "*cmp<mode>_i387"
1881 [(set (match_operand:HI 0 "register_operand" "=a")
1884 (match_operand:MODEF 1 "register_operand" "f")
1885 (match_operand:MODEF 2 "nonimm_or_0_operand" "fmC"))]
1888 "* return output_fp_compare (insn, operands, false, false);"
1889 [(set_attr "type" "multi")
1890 (set_attr "unit" "i387")
1891 (set_attr "mode" "<MODE>")])
1893 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1894 [(set (match_operand:HI 0 "register_operand" "=a")
1897 (match_operand:X87MODEF 1 "register_operand" "f")
1899 (match_operand:SWI24 2 "nonimmediate_operand" "m")))]
1902 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1903 || optimize_function_for_size_p (cfun))"
1904 "* return output_fp_compare (insn, operands, false, false);"
1905 [(set_attr "type" "multi")
1906 (set_attr "unit" "i387")
1907 (set_attr "fp_int_src" "true")
1908 (set_attr "mode" "<SWI24:MODE>")])
1910 (define_insn "*cmpu<mode>_i387"
1911 [(set (match_operand:HI 0 "register_operand" "=a")
1915 (match_operand:X87MODEF 1 "register_operand" "f")
1916 (match_operand:X87MODEF 2 "register_operand" "f"))]
1920 "* return output_fp_compare (insn, operands, false, true);"
1921 [(set_attr "type" "multi")
1922 (set_attr "unit" "i387")
1923 (set_attr "mode" "<MODE>")])
1925 ;; FP compares, step 2:
1926 ;; Get ax into flags, general case.
1928 (define_insn "x86_sahf_1"
1929 [(set (reg:CC FLAGS_REG)
1930 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1934 #ifndef HAVE_AS_IX86_SAHF
1936 return ASM_BYTE "0x9e";
1941 [(set_attr "length" "1")
1942 (set_attr "athlon_decode" "vector")
1943 (set_attr "amdfam10_decode" "direct")
1944 (set_attr "bdver1_decode" "direct")
1945 (set_attr "mode" "SI")])
1947 ;; Pentium Pro can do both steps in one go.
1948 ;; (these instructions set flags directly)
1950 (define_subst_attr "unord" "unord_subst" "" "u")
1951 (define_subst_attr "unordered" "unord_subst" "false" "true")
1953 (define_subst "unord_subst"
1954 [(set (match_operand:CCFP 0)
1955 (match_operand:CCFP 1))]
1962 (define_insn "*cmpi<unord>xf_i387"
1963 [(set (reg:CCFP FLAGS_REG)
1965 (match_operand:XF 0 "register_operand" "f")
1966 (match_operand:XF 1 "register_operand" "f")))]
1967 "TARGET_80387 && TARGET_CMOVE"
1968 "* return output_fp_compare (insn, operands, true, <unordered>);"
1969 [(set_attr "type" "fcmp")
1970 (set_attr "mode" "XF")
1971 (set_attr "athlon_decode" "vector")
1972 (set_attr "amdfam10_decode" "direct")
1973 (set_attr "bdver1_decode" "double")
1974 (set_attr "znver1_decode" "double")])
1976 (define_insn "*cmpi<unord><MODEF:mode>"
1977 [(set (reg:CCFP FLAGS_REG)
1979 (match_operand:MODEF 0 "register_operand" "f,v")
1980 (match_operand:MODEF 1 "register_ssemem_operand" "f,vm")))]
1981 "(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
1982 || (TARGET_80387 && TARGET_CMOVE)"
1984 * return output_fp_compare (insn, operands, true, <unordered>);
1985 %v<unord>comi<MODEF:ssemodesuffix>\t{%1, %0|%0, %1}"
1986 [(set_attr "type" "fcmp,ssecomi")
1987 (set_attr "prefix" "orig,maybe_vex")
1988 (set_attr "mode" "<MODEF:MODE>")
1989 (set_attr "prefix_rep" "*,0")
1990 (set (attr "prefix_data16")
1991 (cond [(eq_attr "alternative" "0")
1993 (eq_attr "mode" "DF")
1996 (const_string "0")))
1997 (set_attr "athlon_decode" "vector")
1998 (set_attr "amdfam10_decode" "direct")
1999 (set_attr "bdver1_decode" "double")
2000 (set_attr "znver1_decode" "double")
2001 (set (attr "enabled")
2003 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
2005 (eq_attr "alternative" "0")
2006 (symbol_ref "TARGET_MIX_SSE_I387")
2007 (symbol_ref "true"))
2009 (eq_attr "alternative" "0")
2011 (symbol_ref "false"))))])
2013 (define_insn "*cmpi<unord>hf"
2014 [(set (reg:CCFP FLAGS_REG)
2016 (match_operand:HF 0 "register_operand" "v")
2017 (match_operand:HF 1 "nonimmediate_operand" "vm")))]
2019 "v<unord>comish\t{%1, %0|%0, %1}"
2020 [(set_attr "type" "ssecomi")
2021 (set_attr "prefix" "evex")
2022 (set_attr "mode" "HF")])
2025 (define_insn "x86_stc"
2026 [(set (reg:CCC FLAGS_REG) (unspec:CCC [(const_int 0)] UNSPEC_STC))]
2029 [(set_attr "length" "1")
2030 (set_attr "length_immediate" "0")
2031 (set_attr "modrm" "0")])
2033 ;; On Pentium 4, set the carry flag using mov $1,%al;addb $-1,%al.
2035 [(match_scratch:QI 0 "r")
2036 (set (reg:CCC FLAGS_REG) (unspec:CCC [(const_int 0)] UNSPEC_STC))]
2037 "TARGET_SLOW_STC && !optimize_insn_for_size_p ()"
2038 [(set (match_dup 0) (const_int 1))
2040 [(set (reg:CCC FLAGS_REG)
2041 (compare:CCC (plus:QI (match_dup 0) (const_int -1))
2043 (set (match_dup 0) (plus:QI (match_dup 0) (const_int -1)))])])
2045 ;; Complement carry flag.
2046 (define_insn "*x86_cmc"
2047 [(set (reg:CCC FLAGS_REG)
2048 (compare:CCC (neg:QI (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
2049 (geu:QI (reg:CCC FLAGS_REG) (const_int 0))))]
2052 [(set_attr "length" "1")
2053 (set_attr "length_immediate" "0")
2054 (set_attr "use_carry" "1")
2055 (set_attr "modrm" "0")])
2057 ;; On Pentium 4, cmc is replaced with setnc %al;addb $-1,%al.
2059 [(match_scratch:QI 0 "r")
2060 (set (reg:CCC FLAGS_REG)
2061 (compare:CCC (neg:QI (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
2062 (geu:QI (reg:CCC FLAGS_REG) (const_int 0))))]
2063 "TARGET_SLOW_STC && !optimize_insn_for_size_p ()"
2064 [(set (match_dup 0) (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))
2066 [(set (reg:CCC FLAGS_REG)
2067 (compare:CCC (plus:QI (match_dup 0) (const_int -1))
2069 (set (match_dup 0) (plus:QI (match_dup 0) (const_int -1)))])])
2071 ;; Push/pop instructions.
2073 (define_insn_and_split "*pushv1ti2"
2074 [(set (match_operand:V1TI 0 "push_operand" "=<")
2075 (match_operand:V1TI 1 "register_operand" "v"))]
2076 "TARGET_64BIT && TARGET_STV"
2078 "&& reload_completed"
2079 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2080 (set (match_dup 0) (match_dup 1))]
2082 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (V1TImode)));
2083 /* Preserve memory attributes. */
2084 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2086 [(set_attr "type" "multi")
2087 (set_attr "mode" "TI")])
2089 (define_insn "*push<mode>2"
2090 [(set (match_operand:DWI 0 "push_operand" "=<,<")
2091 (match_operand:DWI 1 "general_no_elim_operand" "riF*o,*v"))]
2094 [(set_attr "type" "multi")
2095 (set_attr "mode" "<MODE>")])
2098 [(set (match_operand:DWI 0 "push_operand")
2099 (match_operand:DWI 1 "general_gr_operand"))]
2102 "ix86_split_long_move (operands); DONE;")
2104 (define_insn "*pushdi2_rex64"
2105 [(set (match_operand:DI 0 "push_operand" "=<,<,!<")
2106 (match_operand:DI 1 "general_no_elim_operand" "re*m,*v,n"))]
2112 [(set_attr "type" "push,multi,multi")
2113 (set_attr "mode" "DI")])
2115 ;; Convert impossible pushes of immediate to existing instructions.
2116 ;; First try to get scratch register and go through it. In case this
2117 ;; fails, push sign extended lower part first and then overwrite
2118 ;; upper part by 32bit move.
2121 [(match_scratch:DI 2 "r")
2122 (set (match_operand:DI 0 "push_operand")
2123 (match_operand:DI 1 "immediate_operand"))]
2125 && !symbolic_operand (operands[1], DImode)
2126 && !x86_64_immediate_operand (operands[1], DImode)"
2127 [(set (match_dup 2) (match_dup 1))
2128 (set (match_dup 0) (match_dup 2))])
2131 [(set (match_operand:DI 0 "push_operand")
2132 (match_operand:DI 1 "immediate_operand"))]
2133 "TARGET_64BIT && epilogue_completed
2134 && !symbolic_operand (operands[1], DImode)
2135 && !x86_64_immediate_operand (operands[1], DImode)"
2136 [(set (match_dup 0) (match_dup 1))
2137 (set (match_dup 2) (match_dup 3))]
2139 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
2141 operands[1] = gen_lowpart (DImode, operands[2]);
2142 operands[2] = gen_rtx_MEM (SImode,
2143 plus_constant (Pmode, stack_pointer_rtx, 4));
2146 ;; For TARGET_64BIT we always round up to 8 bytes.
2147 (define_insn "*pushsi2_rex64"
2148 [(set (match_operand:SI 0 "push_operand" "=X,X")
2149 (match_operand:SI 1 "nonmemory_no_elim_operand" "re,*v"))]
2154 [(set_attr "type" "push,multi")
2155 (set_attr "mode" "DI")])
2157 (define_insn "*pushsi2"
2158 [(set (match_operand:SI 0 "push_operand" "=<,<")
2159 (match_operand:SI 1 "general_no_elim_operand" "ri*m,*v"))]
2164 [(set_attr "type" "push,multi")
2165 (set_attr "mode" "SI")])
2168 [(set (match_operand:SWI48DWI 0 "push_operand")
2169 (match_operand:SWI48DWI 1 "sse_reg_operand"))]
2170 "TARGET_SSE && reload_completed"
2171 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2172 (set (match_dup 0) (match_dup 1))]
2174 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (<SWI48DWI:MODE>mode)));
2175 /* Preserve memory attributes. */
2176 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2179 ;; emit_push_insn when it calls move_by_pieces requires an insn to
2180 ;; "push a byte/word". But actually we use push{l,q}, which has
2181 ;; the effect of rounding the amount pushed up to a word.
2183 (define_insn "*push<mode>2"
2184 [(set (match_operand:SWI12 0 "push_operand" "=X")
2185 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
2187 "* return TARGET_64BIT ? \"push{q}\t%q1\" : \"push{l}\t%k1\";"
2188 [(set_attr "type" "push")
2190 (if_then_else (match_test "TARGET_64BIT")
2192 (const_string "SI")))])
2194 (define_insn "*push<mode>2_prologue"
2195 [(set (match_operand:W 0 "push_operand" "=<")
2196 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
2197 (clobber (mem:BLK (scratch)))]
2199 "push{<imodesuffix>}\t%1"
2200 [(set_attr "type" "push")
2201 (set_attr "mode" "<MODE>")])
2203 (define_insn "*pop<mode>1"
2204 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
2205 (match_operand:W 1 "pop_operand" ">"))]
2207 "pop{<imodesuffix>}\t%0"
2208 [(set_attr "type" "pop")
2209 (set_attr "mode" "<MODE>")])
2211 (define_insn "*pop<mode>1_epilogue"
2212 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
2213 (match_operand:W 1 "pop_operand" ">"))
2214 (clobber (mem:BLK (scratch)))]
2216 "pop{<imodesuffix>}\t%0"
2217 [(set_attr "type" "pop")
2218 (set_attr "mode" "<MODE>")])
2220 (define_insn "*pushfl<mode>2"
2221 [(set (match_operand:W 0 "push_operand" "=<")
2222 (match_operand:W 1 "flags_reg_operand"))]
2224 "pushf{<imodesuffix>}"
2225 [(set_attr "type" "push")
2226 (set_attr "mode" "<MODE>")])
2228 (define_insn "*popfl<mode>1"
2229 [(set (match_operand:W 0 "flags_reg_operand")
2230 (match_operand:W 1 "pop_operand" ">"))]
2232 "popf{<imodesuffix>}"
2233 [(set_attr "type" "pop")
2234 (set_attr "mode" "<MODE>")])
2237 ;; Reload patterns to support multi-word load/store
2238 ;; with non-offsetable address.
2239 (define_expand "reload_noff_store"
2240 [(parallel [(match_operand 0 "memory_operand" "=m")
2241 (match_operand 1 "register_operand" "r")
2242 (match_operand:DI 2 "register_operand" "=&r")])]
2245 rtx mem = operands[0];
2246 rtx addr = XEXP (mem, 0);
2248 emit_move_insn (operands[2], addr);
2249 mem = replace_equiv_address_nv (mem, operands[2]);
2251 emit_insn (gen_rtx_SET (mem, operands[1]));
2255 (define_expand "reload_noff_load"
2256 [(parallel [(match_operand 0 "register_operand" "=r")
2257 (match_operand 1 "memory_operand" "m")
2258 (match_operand:DI 2 "register_operand" "=r")])]
2261 rtx mem = operands[1];
2262 rtx addr = XEXP (mem, 0);
2264 emit_move_insn (operands[2], addr);
2265 mem = replace_equiv_address_nv (mem, operands[2]);
2267 emit_insn (gen_rtx_SET (operands[0], mem));
2271 ;; Move instructions.
2273 (define_expand "movxi"
2274 [(set (match_operand:XI 0 "nonimmediate_operand")
2275 (match_operand:XI 1 "general_operand"))]
2277 "ix86_expand_vector_move (XImode, operands); DONE;")
2279 (define_expand "movoi"
2280 [(set (match_operand:OI 0 "nonimmediate_operand")
2281 (match_operand:OI 1 "general_operand"))]
2283 "ix86_expand_vector_move (OImode, operands); DONE;")
2285 (define_expand "movti"
2286 [(set (match_operand:TI 0 "nonimmediate_operand")
2287 (match_operand:TI 1 "general_operand"))]
2288 "TARGET_64BIT || TARGET_SSE"
2291 ix86_expand_move (TImode, operands);
2293 ix86_expand_vector_move (TImode, operands);
2297 ;; This expands to what emit_move_complex would generate if we didn't
2298 ;; have a movti pattern. Having this avoids problems with reload on
2299 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2300 ;; to have around all the time.
2301 (define_expand "movcdi"
2302 [(set (match_operand:CDI 0 "nonimmediate_operand")
2303 (match_operand:CDI 1 "general_operand"))]
2306 if (push_operand (operands[0], CDImode))
2307 emit_move_complex_push (CDImode, operands[0], operands[1]);
2309 emit_move_complex_parts (operands[0], operands[1]);
2313 (define_expand "mov<mode>"
2314 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
2315 (match_operand:SWI1248x 1 "general_operand"))]
2317 "ix86_expand_move (<MODE>mode, operands); DONE;")
2319 (define_insn "*mov<mode>_xor"
2320 [(set (match_operand:SWI48 0 "register_operand" "=r")
2321 (match_operand:SWI48 1 "const0_operand"))
2322 (clobber (reg:CC FLAGS_REG))]
2325 [(set_attr "type" "alu1")
2326 (set_attr "mode" "SI")
2327 (set_attr "length_immediate" "0")])
2329 (define_insn "*mov<mode>_and"
2330 [(set (match_operand:SWI248 0 "memory_operand" "=m")
2331 (match_operand:SWI248 1 "const0_operand"))
2332 (clobber (reg:CC FLAGS_REG))]
2334 "and{<imodesuffix>}\t{%1, %0|%0, %1}"
2335 [(set_attr "type" "alu1")
2336 (set_attr "mode" "<MODE>")
2337 (set_attr "length_immediate" "1")])
2339 (define_insn "*mov<mode>_or"
2340 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
2341 (match_operand:SWI248 1 "constm1_operand"))
2342 (clobber (reg:CC FLAGS_REG))]
2344 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
2345 [(set_attr "type" "alu1")
2346 (set_attr "mode" "<MODE>")
2347 (set_attr "length_immediate" "1")])
2349 (define_insn "*movxi_internal_avx512f"
2350 [(set (match_operand:XI 0 "nonimmediate_operand" "=v,v ,v ,m")
2351 (match_operand:XI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2353 && (register_operand (operands[0], XImode)
2354 || register_operand (operands[1], XImode))"
2356 switch (get_attr_type (insn))
2359 return standard_sse_constant_opcode (insn, operands);
2362 return ix86_output_ssemov (insn, operands);
2368 [(set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2369 (set_attr "prefix" "evex")
2370 (set_attr "mode" "XI")])
2372 (define_insn "*movoi_internal_avx"
2373 [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,v ,m")
2374 (match_operand:OI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2376 && (register_operand (operands[0], OImode)
2377 || register_operand (operands[1], OImode))"
2379 switch (get_attr_type (insn))
2382 return standard_sse_constant_opcode (insn, operands);
2385 return ix86_output_ssemov (insn, operands);
2391 [(set_attr "isa" "*,avx2,*,*")
2392 (set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2393 (set_attr "prefix" "vex")
2394 (set_attr "mode" "OI")])
2396 (define_insn "*movti_internal"
2397 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,v ,m,?r,?Yd")
2398 (match_operand:TI 1 "general_operand" "riFo,re,C,BC,vm,v,Yd,r"))]
2400 && !(MEM_P (operands[0]) && MEM_P (operands[1])))
2402 && nonimmediate_or_sse_const_operand (operands[1], TImode)
2403 && (register_operand (operands[0], TImode)
2404 || register_operand (operands[1], TImode)))"
2406 switch (get_attr_type (insn))
2412 return standard_sse_constant_opcode (insn, operands);
2415 return ix86_output_ssemov (insn, operands);
2422 (cond [(eq_attr "alternative" "0,1,6,7")
2423 (const_string "x64")
2424 (eq_attr "alternative" "3")
2425 (const_string "sse2")
2427 (const_string "*")))
2429 (cond [(eq_attr "alternative" "0,1,6,7")
2430 (const_string "multi")
2431 (eq_attr "alternative" "2,3")
2432 (const_string "sselog1")
2434 (const_string "ssemov")))
2435 (set (attr "prefix")
2436 (if_then_else (eq_attr "type" "sselog1,ssemov")
2437 (const_string "maybe_vex")
2438 (const_string "orig")))
2440 (cond [(eq_attr "alternative" "0,1")
2442 (match_test "TARGET_AVX")
2444 (ior (not (match_test "TARGET_SSE2"))
2445 (match_test "optimize_function_for_size_p (cfun)"))
2446 (const_string "V4SF")
2447 (and (eq_attr "alternative" "5")
2448 (match_test "TARGET_SSE_TYPELESS_STORES"))
2449 (const_string "V4SF")
2451 (const_string "TI")))
2452 (set (attr "preferred_for_speed")
2453 (cond [(eq_attr "alternative" "6")
2454 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2455 (eq_attr "alternative" "7")
2456 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2458 (symbol_ref "true")))])
2461 [(set (match_operand:TI 0 "sse_reg_operand")
2462 (match_operand:TI 1 "general_reg_operand"))]
2463 "TARGET_64BIT && TARGET_SSE4_1
2464 && reload_completed"
2467 (vec_duplicate:V2DI (match_dup 3))
2471 operands[2] = lowpart_subreg (V2DImode, operands[0], TImode);
2472 operands[3] = gen_highpart (DImode, operands[1]);
2474 emit_move_insn (gen_lowpart (DImode, operands[0]),
2475 gen_lowpart (DImode, operands[1]));
2478 (define_insn "*movdi_internal"
2479 [(set (match_operand:DI 0 "nonimmediate_operand"
2480 "=r ,o ,r,r ,r,m ,*y,*y,?*y,?m,?r,?*y,?v,?v,?v,m ,m,?r ,?*Yd,?r,?v,?*y,?*x,*k,*k ,*r,*m,*k")
2481 (match_operand:DI 1 "general_operand"
2482 "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"))]
2483 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2484 && ix86_hardreg_mov_ok (operands[0], operands[1])"
2486 switch (get_attr_type (insn))
2489 return "kmovq\t{%1, %0|%0, %1}";
2492 if (operands[1] == const0_rtx)
2493 return "kxorq\t%0, %0, %0";
2494 else if (operands[1] == constm1_rtx)
2495 return "kxnorq\t%0, %0, %0";
2502 return "pxor\t%0, %0";
2505 /* Handle broken assemblers that require movd instead of movq. */
2506 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2507 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2508 return "movd\t{%1, %0|%0, %1}";
2509 return "movq\t{%1, %0|%0, %1}";
2512 return standard_sse_constant_opcode (insn, operands);
2515 return ix86_output_ssemov (insn, operands);
2518 if (SSE_REG_P (operands[0]))
2519 return "movq2dq\t{%1, %0|%0, %1}";
2521 return "movdq2q\t{%1, %0|%0, %1}";
2524 return "lea{q}\t{%E1, %0|%0, %E1}";
2527 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2528 if (get_attr_mode (insn) == MODE_SI)
2529 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2530 else if (which_alternative == 4)
2531 return "movabs{q}\t{%1, %0|%0, %1}";
2532 else if (ix86_use_lea_for_mov (insn, operands))
2533 return "lea{q}\t{%E1, %0|%0, %E1}";
2535 return "mov{q}\t{%1, %0|%0, %1}";
2542 (cond [(eq_attr "alternative" "0,1,17,18")
2543 (const_string "nox64")
2544 (eq_attr "alternative" "2,3,4,5,10,11,23,25")
2545 (const_string "x64")
2546 (eq_attr "alternative" "19,20")
2547 (const_string "x64_sse2")
2548 (eq_attr "alternative" "21,22")
2549 (const_string "sse2")
2551 (const_string "*")))
2553 (cond [(eq_attr "alternative" "0,1,17,18")
2554 (const_string "multi")
2555 (eq_attr "alternative" "6")
2556 (const_string "mmx")
2557 (eq_attr "alternative" "7,8,9,10,11")
2558 (const_string "mmxmov")
2559 (eq_attr "alternative" "12")
2560 (const_string "sselog1")
2561 (eq_attr "alternative" "13,14,15,16,19,20")
2562 (const_string "ssemov")
2563 (eq_attr "alternative" "21,22")
2564 (const_string "ssecvt")
2565 (eq_attr "alternative" "23,24,25,26")
2566 (const_string "mskmov")
2567 (eq_attr "alternative" "27")
2568 (const_string "msklog")
2569 (and (match_operand 0 "register_operand")
2570 (match_operand 1 "pic_32bit_operand"))
2571 (const_string "lea")
2573 (const_string "imov")))
2576 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2578 (const_string "*")))
2579 (set (attr "length_immediate")
2581 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2583 (const_string "*")))
2584 (set (attr "prefix_rex")
2586 (eq_attr "alternative" "10,11,19,20")
2588 (const_string "*")))
2589 (set (attr "prefix")
2590 (if_then_else (eq_attr "type" "sselog1,ssemov")
2591 (const_string "maybe_vex")
2592 (const_string "orig")))
2593 (set (attr "prefix_data16")
2594 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2596 (const_string "*")))
2598 (cond [(eq_attr "alternative" "2")
2600 (eq_attr "alternative" "12,13")
2601 (cond [(match_test "TARGET_AVX")
2603 (ior (not (match_test "TARGET_SSE2"))
2604 (match_test "optimize_function_for_size_p (cfun)"))
2605 (const_string "V4SF")
2607 (const_string "TI"))
2609 (and (eq_attr "alternative" "14,15,16")
2610 (not (match_test "TARGET_SSE2")))
2611 (const_string "V2SF")
2613 (const_string "DI")))
2614 (set (attr "preferred_for_speed")
2615 (cond [(eq_attr "alternative" "10,17,19")
2616 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2617 (eq_attr "alternative" "11,18,20")
2618 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2620 (symbol_ref "true")))
2621 (set (attr "enabled")
2622 (cond [(eq_attr "alternative" "15")
2624 (match_test "TARGET_STV && TARGET_SSE2")
2625 (symbol_ref "false")
2627 (eq_attr "alternative" "16")
2629 (match_test "TARGET_STV && TARGET_SSE2")
2631 (symbol_ref "false"))
2633 (const_string "*")))])
2636 [(set (match_operand:<DWI> 0 "general_reg_operand")
2637 (match_operand:<DWI> 1 "sse_reg_operand"))]
2639 && reload_completed"
2643 (parallel [(const_int 1)])))]
2645 operands[2] = gen_highpart (<MODE>mode, operands[0]);
2646 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[1], <DWI>mode);
2648 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]),
2649 gen_lowpart (<MODE>mode, operands[1]));
2653 [(set (match_operand:DWI 0 "nonimmediate_gr_operand")
2654 (match_operand:DWI 1 "general_gr_operand"))]
2657 "ix86_split_long_move (operands); DONE;")
2660 [(set (match_operand:DI 0 "sse_reg_operand")
2661 (match_operand:DI 1 "general_reg_operand"))]
2662 "!TARGET_64BIT && TARGET_SSE4_1
2663 && reload_completed"
2666 (vec_duplicate:V4SI (match_dup 3))
2670 operands[2] = lowpart_subreg (V4SImode, operands[0], DImode);
2671 operands[3] = gen_highpart (SImode, operands[1]);
2673 emit_move_insn (gen_lowpart (SImode, operands[0]),
2674 gen_lowpart (SImode, operands[1]));
2677 ;; movabsq $0x0012345678000000, %rax is longer
2678 ;; than movl $0x12345678, %eax; shlq $24, %rax.
2680 [(set (match_operand:DI 0 "register_operand")
2681 (match_operand:DI 1 "const_int_operand"))]
2683 && optimize_insn_for_size_p ()
2684 && LEGACY_INT_REG_P (operands[0])
2685 && !x86_64_immediate_operand (operands[1], DImode)
2686 && !x86_64_zext_immediate_operand (operands[1], DImode)
2687 && !((UINTVAL (operands[1]) >> ctz_hwi (UINTVAL (operands[1])))
2688 & ~(HOST_WIDE_INT) 0xffffffff)
2689 && peep2_regno_dead_p (0, FLAGS_REG)"
2690 [(set (match_dup 0) (match_dup 1))
2691 (parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
2692 (clobber (reg:CC FLAGS_REG))])]
2694 int shift = ctz_hwi (UINTVAL (operands[1]));
2695 operands[1] = gen_int_mode (UINTVAL (operands[1]) >> shift, DImode);
2696 operands[2] = gen_int_mode (shift, QImode);
2699 (define_insn "*movsi_internal"
2700 [(set (match_operand:SI 0 "nonimmediate_operand"
2701 "=r,m ,*y,*y,?*y,?m,?r,?*y,?v,?v,?v,m ,?r,?v,*k,*k ,*rm,*k")
2702 (match_operand:SI 1 "general_operand"
2703 "g ,re,C ,*y,Bk ,*y,*y,r ,C ,?v,Bk,?v,?v,r ,*r,*kBk,*k ,CBC"))]
2704 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2705 && ix86_hardreg_mov_ok (operands[0], operands[1])"
2707 switch (get_attr_type (insn))
2710 return standard_sse_constant_opcode (insn, operands);
2713 return "kmovd\t{%1, %0|%0, %1}";
2716 if (operands[1] == const0_rtx)
2717 return "kxord\t%0, %0, %0";
2718 else if (operands[1] == constm1_rtx)
2719 return "kxnord\t%0, %0, %0";
2723 return ix86_output_ssemov (insn, operands);
2726 return "pxor\t%0, %0";
2729 switch (get_attr_mode (insn))
2732 return "movq\t{%1, %0|%0, %1}";
2734 return "movd\t{%1, %0|%0, %1}";
2741 return "lea{l}\t{%E1, %0|%0, %E1}";
2744 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2745 if (ix86_use_lea_for_mov (insn, operands))
2746 return "lea{l}\t{%E1, %0|%0, %E1}";
2748 return "mov{l}\t{%1, %0|%0, %1}";
2755 (cond [(eq_attr "alternative" "12,13")
2756 (const_string "sse2")
2758 (const_string "*")))
2760 (cond [(eq_attr "alternative" "2")
2761 (const_string "mmx")
2762 (eq_attr "alternative" "3,4,5,6,7")
2763 (const_string "mmxmov")
2764 (eq_attr "alternative" "8")
2765 (const_string "sselog1")
2766 (eq_attr "alternative" "9,10,11,12,13")
2767 (const_string "ssemov")
2768 (eq_attr "alternative" "14,15,16")
2769 (const_string "mskmov")
2770 (eq_attr "alternative" "17")
2771 (const_string "msklog")
2772 (and (match_operand 0 "register_operand")
2773 (match_operand 1 "pic_32bit_operand"))
2774 (const_string "lea")
2776 (const_string "imov")))
2777 (set (attr "prefix")
2778 (if_then_else (eq_attr "type" "sselog1,ssemov")
2779 (const_string "maybe_vex")
2780 (const_string "orig")))
2781 (set (attr "prefix_data16")
2782 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2784 (const_string "*")))
2786 (cond [(eq_attr "alternative" "2,3")
2788 (eq_attr "alternative" "8,9")
2789 (cond [(match_test "TARGET_AVX")
2791 (ior (not (match_test "TARGET_SSE2"))
2792 (match_test "optimize_function_for_size_p (cfun)"))
2793 (const_string "V4SF")
2795 (const_string "TI"))
2797 (and (eq_attr "alternative" "10,11")
2798 (not (match_test "TARGET_SSE2")))
2801 (const_string "SI")))
2802 (set (attr "preferred_for_speed")
2803 (cond [(eq_attr "alternative" "6,12")
2804 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2805 (eq_attr "alternative" "7,13")
2806 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2808 (symbol_ref "true")))])
2810 ;; With -Oz, transform mov $imm,reg to the shorter push $imm; pop reg.
2812 [(set (match_operand:SWI248 0 "general_reg_operand")
2813 (match_operand:SWI248 1 "const_int_operand"))]
2814 "optimize_insn_for_size_p () && optimize_size > 1
2815 && operands[1] != const0_rtx
2816 && IN_RANGE (INTVAL (operands[1]), -128, 127)
2817 && !ix86_red_zone_used
2818 && REGNO (operands[0]) != SP_REG"
2819 [(set (match_dup 2) (match_dup 1))
2820 (set (match_dup 0) (match_dup 3))]
2822 if (GET_MODE (operands[0]) != word_mode)
2823 operands[0] = gen_rtx_REG (word_mode, REGNO (operands[0]));
2825 operands[2] = gen_rtx_MEM (word_mode,
2826 gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
2827 operands[3] = gen_rtx_MEM (word_mode,
2828 gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
2831 ;; With -Oz, transform mov $0,mem to the shorter and $0,mem.
2832 ;; Likewise, transform mov $-1,mem to the shorter or $-1,mem.
2834 [(set (match_operand:SWI248 0 "memory_operand")
2835 (match_operand:SWI248 1 "const_int_operand"))]
2836 "(operands[1] == const0_rtx || operands[1] == constm1_rtx)
2837 && optimize_insn_for_size_p () && optimize_size > 1
2838 && peep2_regno_dead_p (0, FLAGS_REG)"
2839 [(parallel [(set (match_dup 0) (match_dup 1))
2840 (clobber (reg:CC FLAGS_REG))])])
2842 (define_insn "*movhi_internal"
2843 [(set (match_operand:HI 0 "nonimmediate_operand"
2844 "=r,r,r,m ,*k,*k ,r ,m ,*k ,?r,?*v,*v,*v,*v,m")
2845 (match_operand:HI 1 "general_operand"
2846 "r ,n,m,rn,r ,*km,*k,*k,CBC,*v,r ,C ,*v,m ,*v"))]
2847 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2848 && ix86_hardreg_mov_ok (operands[0], operands[1])"
2850 switch (get_attr_type (insn))
2853 /* movzwl is faster than movw on p2 due to partial word stalls,
2854 though not as fast as an aligned movl. */
2855 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2858 switch (which_alternative)
2861 return "kmovw\t{%k1, %0|%0, %k1}";
2863 return "kmovw\t{%1, %k0|%k0, %1}";
2866 return "kmovw\t{%1, %0|%0, %1}";
2872 return ix86_output_ssemov (insn, operands);
2875 if (satisfies_constraint_C (operands[1]))
2876 return standard_sse_constant_opcode (insn, operands);
2878 if (SSE_REG_P (operands[0]))
2879 return "%vpinsrw\t{$0, %1, %d0|%d0, %1, 0}";
2881 return "%vpextrw\t{$0, %1, %0|%0, %1, 0}";
2884 if (operands[1] == const0_rtx)
2885 return "kxorw\t%0, %0, %0";
2886 else if (operands[1] == constm1_rtx)
2887 return "kxnorw\t%0, %0, %0";
2891 if (get_attr_mode (insn) == MODE_SI)
2892 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2894 return "mov{w}\t{%1, %0|%0, %1}";
2898 (cond [(eq_attr "alternative" "9,10,11,12,13")
2899 (const_string "sse2")
2900 (eq_attr "alternative" "14")
2901 (const_string "sse4")
2903 (const_string "*")))
2905 (cond [(eq_attr "alternative" "4,5,6,7")
2906 (const_string "mskmov")
2907 (eq_attr "alternative" "8")
2908 (const_string "msklog")
2909 (eq_attr "alternative" "13,14")
2910 (if_then_else (match_test "TARGET_AVX512FP16")
2911 (const_string "ssemov")
2912 (const_string "sselog1"))
2913 (eq_attr "alternative" "11")
2914 (const_string "sselog1")
2915 (eq_attr "alternative" "9,10,12")
2916 (const_string "ssemov")
2917 (match_test "optimize_function_for_size_p (cfun)")
2918 (const_string "imov")
2919 (and (eq_attr "alternative" "0")
2920 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2921 (not (match_test "TARGET_HIMODE_MATH"))))
2922 (const_string "imov")
2923 (and (eq_attr "alternative" "1,2")
2924 (match_operand:HI 1 "aligned_operand"))
2925 (const_string "imov")
2926 (and (match_test "TARGET_MOVX")
2927 (eq_attr "alternative" "0,2"))
2928 (const_string "imovx")
2930 (const_string "imov")))
2931 (set (attr "prefix")
2932 (cond [(eq_attr "alternative" "4,5,6,7,8")
2933 (const_string "vex")
2934 (eq_attr "alternative" "9,10,11,12,13,14")
2935 (const_string "maybe_evex")
2937 (const_string "orig")))
2939 (cond [(eq_attr "alternative" "9,10")
2940 (if_then_else (match_test "TARGET_AVX512FP16")
2942 (const_string "SI"))
2943 (eq_attr "alternative" "13,14")
2944 (if_then_else (match_test "TARGET_AVX512FP16")
2946 (const_string "TI"))
2947 (eq_attr "alternative" "11")
2948 (cond [(match_test "TARGET_AVX")
2950 (ior (not (match_test "TARGET_SSE2"))
2951 (match_test "optimize_function_for_size_p (cfun)"))
2952 (const_string "V4SF")
2954 (const_string "TI"))
2955 (eq_attr "alternative" "12")
2956 (cond [(match_test "TARGET_AVX512FP16")
2958 (match_test "TARGET_AVX")
2960 (ior (not (match_test "TARGET_SSE2"))
2961 (match_test "optimize_function_for_size_p (cfun)"))
2962 (const_string "V4SF")
2964 (const_string "TI"))
2965 (eq_attr "type" "imovx")
2967 (and (eq_attr "alternative" "1,2")
2968 (match_operand:HI 1 "aligned_operand"))
2970 (and (eq_attr "alternative" "0")
2971 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2972 (not (match_test "TARGET_HIMODE_MATH"))))
2975 (const_string "HI")))
2976 (set (attr "preferred_for_speed")
2977 (cond [(eq_attr "alternative" "9")
2978 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2979 (eq_attr "alternative" "10")
2980 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2982 (symbol_ref "true")))])
2984 ;; Situation is quite tricky about when to choose full sized (SImode) move
2985 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2986 ;; partial register dependency machines (such as AMD Athlon), where QImode
2987 ;; moves issue extra dependency and for partial register stalls machines
2988 ;; that don't use QImode patterns (and QImode move cause stall on the next
2991 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2992 ;; register stall machines with, where we use QImode instructions, since
2993 ;; partial register stall can be caused there. Then we use movzx.
2995 (define_insn "*movqi_internal"
2996 [(set (match_operand:QI 0 "nonimmediate_operand"
2997 "=Q,R,r,q,q,r,r ,?r,m ,*k,*k,*r,*m,*k,*k,*k")
2998 (match_operand:QI 1 "general_operand"
2999 "Q ,R,r,n,m,q,rn, m,qn,*r,*k,*k,*k,*m,C,BC"))]
3000 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3001 && ix86_hardreg_mov_ok (operands[0], operands[1])"
3008 switch (get_attr_type (insn))
3011 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
3012 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
3015 switch (which_alternative)
3018 ops = "kmov%s\t{%%k1, %%0|%%0, %%k1}";
3021 ops = "kmov%s\t{%%1, %%k0|%%k0, %%1}";
3025 gcc_assert (TARGET_AVX512DQ);
3028 ops = "kmov%s\t{%%1, %%0|%%0, %%1}";
3034 suffix = (get_attr_mode (insn) == MODE_HI) ? "w" : "b";
3036 snprintf (buf, sizeof (buf), ops, suffix);
3037 output_asm_insn (buf, operands);
3041 if (operands[1] == const0_rtx)
3043 if (get_attr_mode (insn) == MODE_HI)
3044 return "kxorw\t%0, %0, %0";
3046 return "kxorb\t%0, %0, %0";
3048 else if (operands[1] == constm1_rtx)
3050 gcc_assert (TARGET_AVX512DQ);
3051 return "kxnorb\t%0, %0, %0";
3056 if (get_attr_mode (insn) == MODE_SI)
3057 return "mov{l}\t{%k1, %k0|%k0, %k1}";
3059 return "mov{b}\t{%1, %0|%0, %1}";
3063 (cond [(eq_attr "alternative" "1,2")
3064 (const_string "x64")
3065 (eq_attr "alternative" "12,13,15")
3066 (const_string "avx512dq")
3068 (const_string "*")))
3070 (cond [(eq_attr "alternative" "9,10,11,12,13")
3071 (const_string "mskmov")
3072 (eq_attr "alternative" "14,15")
3073 (const_string "msklog")
3074 (and (eq_attr "alternative" "7")
3075 (not (match_operand:QI 1 "aligned_operand")))
3076 (const_string "imovx")
3077 (match_test "optimize_function_for_size_p (cfun)")
3078 (const_string "imov")
3079 (and (eq_attr "alternative" "5")
3080 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
3081 (not (match_test "TARGET_QIMODE_MATH"))))
3082 (const_string "imov")
3083 (eq_attr "alternative" "5,7")
3084 (const_string "imovx")
3085 (and (match_test "TARGET_MOVX")
3086 (eq_attr "alternative" "4"))
3087 (const_string "imovx")
3089 (const_string "imov")))
3090 (set (attr "prefix")
3091 (if_then_else (eq_attr "alternative" "9,10,11,12,13,14,15")
3092 (const_string "vex")
3093 (const_string "orig")))
3095 (cond [(eq_attr "alternative" "5,6,7")
3097 (eq_attr "alternative" "8")
3099 (and (eq_attr "alternative" "9,10,11,14")
3100 (not (match_test "TARGET_AVX512DQ")))
3102 (eq_attr "type" "imovx")
3104 ;; For -Os, 8-bit immediates are always shorter than 32-bit
3106 (and (eq_attr "type" "imov")
3107 (and (eq_attr "alternative" "3")
3108 (match_test "optimize_function_for_size_p (cfun)")))
3110 ;; For -Os, movl where one or both operands are NON_Q_REGS
3111 ;; and both are LEGACY_REGS is shorter than movb.
3112 ;; Otherwise movb and movl sizes are the same, so decide purely
3113 ;; based on speed factors.
3114 (and (eq_attr "type" "imov")
3115 (and (eq_attr "alternative" "1")
3116 (match_test "optimize_function_for_size_p (cfun)")))
3118 (and (eq_attr "type" "imov")
3119 (and (eq_attr "alternative" "0,1,2,3")
3120 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
3121 (not (match_test "TARGET_PARTIAL_REG_STALL")))))
3123 ;; Avoid partial register stalls when not using QImode arithmetic
3124 (and (eq_attr "type" "imov")
3125 (and (eq_attr "alternative" "0,1,2,3")
3126 (and (match_test "TARGET_PARTIAL_REG_STALL")
3127 (not (match_test "TARGET_QIMODE_MATH")))))
3130 (const_string "QI")))])
3132 /* Reload dislikes loading 0/-1 directly into mask registers.
3133 Try to tidy things up here. */
3135 [(set (match_operand:SWI 0 "general_reg_operand")
3136 (match_operand:SWI 1 "immediate_operand"))
3137 (set (match_operand:SWI 2 "mask_reg_operand")
3139 "peep2_reg_dead_p (2, operands[0])
3140 && (const0_operand (operands[1], <MODE>mode)
3141 || (constm1_operand (operands[1], <MODE>mode)
3142 && (<MODE_SIZE> > 1 || TARGET_AVX512DQ)))"
3143 [(set (match_dup 2) (match_dup 1))])
3145 ;; Stores and loads of ax to arbitrary constant address.
3146 ;; We fake an second form of instruction to force reload to load address
3147 ;; into register when rax is not available
3148 (define_insn "*movabs<mode>_1"
3149 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
3150 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
3151 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
3153 /* Recover the full memory rtx. */
3154 operands[0] = SET_DEST (PATTERN (insn));
3155 switch (which_alternative)
3158 return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}";
3160 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
3165 [(set_attr "type" "imov")
3166 (set_attr "modrm" "0,*")
3167 (set_attr "length_address" "8,0")
3168 (set_attr "length_immediate" "0,*")
3169 (set_attr "memory" "store")
3170 (set_attr "mode" "<MODE>")])
3172 (define_insn "*movabs<mode>_2"
3173 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
3174 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
3175 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
3177 /* Recover the full memory rtx. */
3178 operands[1] = SET_SRC (PATTERN (insn));
3179 switch (which_alternative)
3182 return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}";
3184 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
3189 [(set_attr "type" "imov")
3190 (set_attr "modrm" "0,*")
3191 (set_attr "length_address" "8,0")
3192 (set_attr "length_immediate" "0")
3193 (set_attr "memory" "load")
3194 (set_attr "mode" "<MODE>")])
3196 (define_insn "swap<mode>"
3197 [(set (match_operand:SWI48 0 "register_operand" "+r")
3198 (match_operand:SWI48 1 "register_operand" "+r"))
3202 "xchg{<imodesuffix>}\t%1, %0"
3203 [(set_attr "type" "imov")
3204 (set_attr "mode" "<MODE>")
3205 (set_attr "pent_pair" "np")
3206 (set_attr "athlon_decode" "vector")
3207 (set_attr "amdfam10_decode" "double")
3208 (set_attr "bdver1_decode" "double")])
3210 (define_insn "*swap<mode>"
3211 [(set (match_operand:SWI12 0 "register_operand" "+<r>,r")
3212 (match_operand:SWI12 1 "register_operand" "+<r>,r"))
3217 xchg{<imodesuffix>}\t%1, %0
3219 [(set_attr "type" "imov")
3220 (set_attr "mode" "<MODE>,SI")
3221 (set (attr "preferred_for_size")
3222 (cond [(eq_attr "alternative" "0")
3223 (symbol_ref "false")]
3224 (symbol_ref "true")))
3225 ;; Potential partial reg stall on alternative 1.
3226 (set (attr "preferred_for_speed")
3227 (cond [(eq_attr "alternative" "1")
3228 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
3229 (symbol_ref "true")))
3230 (set_attr "pent_pair" "np")
3231 (set_attr "athlon_decode" "vector")
3232 (set_attr "amdfam10_decode" "double")
3233 (set_attr "bdver1_decode" "double")])
3236 [(set (match_operand:SWI 0 "general_reg_operand")
3237 (match_operand:SWI 1 "general_reg_operand"))
3239 (match_operand:SWI 2 "general_reg_operand"))
3240 (set (match_dup 2) (match_dup 0))]
3241 "peep2_reg_dead_p (3, operands[0])
3242 && optimize_insn_for_size_p ()"
3243 [(parallel [(set (match_dup 1) (match_dup 2))
3244 (set (match_dup 2) (match_dup 1))])])
3246 ;; Convert xchg with a REG_UNUSED note to a mov (variant #1).
3248 [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
3249 (match_operand:SWI 1 "general_reg_operand"))
3250 (set (match_dup 1) (match_dup 0))])]
3251 "((REGNO (operands[0]) != AX_REG
3252 && REGNO (operands[1]) != AX_REG)
3253 || optimize_size < 2
3254 || !optimize_insn_for_size_p ())
3255 && peep2_reg_dead_p (1, operands[0])"
3256 [(set (match_dup 1) (match_dup 0))])
3258 ;; Convert xchg with a REG_UNUSED note to a mov (variant #2).
3260 [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
3261 (match_operand:SWI 1 "general_reg_operand"))
3262 (set (match_dup 1) (match_dup 0))])]
3263 "((REGNO (operands[0]) != AX_REG
3264 && REGNO (operands[1]) != AX_REG)
3265 || optimize_size < 2
3266 || !optimize_insn_for_size_p ())
3267 && peep2_reg_dead_p (1, operands[1])"
3268 [(set (match_dup 0) (match_dup 1))])
3270 ;; Convert moves to/from AX_REG into xchg with -Oz.
3272 [(set (match_operand:SWI48 0 "general_reg_operand")
3273 (match_operand:SWI48 1 "general_reg_operand"))]
3275 && ((REGNO (operands[0]) == AX_REG)
3276 != (REGNO (operands[1]) == AX_REG))
3277 && optimize_insn_for_size_p ()
3278 && peep2_reg_dead_p (1, operands[1])"
3279 [(parallel [(set (match_dup 0) (match_dup 1))
3280 (set (match_dup 1) (match_dup 0))])])
3282 (define_expand "movstrict<mode>"
3283 [(set (strict_low_part (match_operand:SWI12 0 "register_operand"))
3284 (match_operand:SWI12 1 "general_operand"))]
3287 gcc_assert (SUBREG_P (operands[0]));
3288 if ((TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
3289 || !VALID_INT_MODE_P (GET_MODE (SUBREG_REG (operands[0]))))
3293 (define_insn "*movstrict<mode>_1"
3294 [(set (strict_low_part
3295 (match_operand:SWI12 0 "register_operand" "+<r>"))
3296 (match_operand:SWI12 1 "general_operand" "<r>mn"))]
3297 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
3298 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
3299 [(set_attr "type" "imov")
3300 (set_attr "mode" "<MODE>")])
3302 (define_insn "*movstrict<mode>_xor"
3303 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
3304 (match_operand:SWI12 1 "const0_operand"))
3305 (clobber (reg:CC FLAGS_REG))]
3307 "xor{<imodesuffix>}\t%0, %0"
3308 [(set_attr "type" "alu1")
3309 (set_attr "mode" "<MODE>")
3310 (set_attr "length_immediate" "0")])
3312 (define_expand "extv<mode>"
3313 [(set (match_operand:SWI24 0 "register_operand")
3314 (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
3315 (match_operand:SI 2 "const_int_operand")
3316 (match_operand:SI 3 "const_int_operand")))]
3319 /* Handle extractions from %ah et al. */
3320 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
3323 unsigned int regno = reg_or_subregno (operands[1]);
3325 /* Be careful to expand only with registers having upper parts. */
3326 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3327 operands[1] = copy_to_reg (operands[1]);
3330 (define_insn "*extv<mode>"
3331 [(set (match_operand:SWI24 0 "register_operand" "=R")
3332 (sign_extract:SWI24 (match_operand 1 "int248_register_operand" "Q")
3336 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
3337 [(set_attr "type" "imovx")
3338 (set_attr "mode" "SI")])
3340 (define_expand "extzv<mode>"
3341 [(set (match_operand:SWI248 0 "register_operand")
3342 (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
3343 (match_operand:SI 2 "const_int_operand")
3344 (match_operand:SI 3 "const_int_operand")))]
3347 if (ix86_expand_pextr (operands))
3350 /* Handle extractions from %ah et al. */
3351 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
3354 unsigned int regno = reg_or_subregno (operands[1]);
3356 /* Be careful to expand only with registers having upper parts. */
3357 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3358 operands[1] = copy_to_reg (operands[1]);
3361 (define_insn "*extzv<mode>"
3362 [(set (match_operand:SWI248 0 "register_operand" "=R")
3363 (zero_extract:SWI248 (match_operand 1 "int248_register_operand" "Q")
3367 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
3368 [(set_attr "type" "imovx")
3369 (set_attr "mode" "SI")])
3371 (define_insn "*extzvqi_mem_rex64"
3372 [(set (match_operand:QI 0 "norex_memory_operand" "=Bn")
3374 (match_operator:SWI248 2 "extract_operator"
3375 [(match_operand 1 "int248_register_operand" "Q")
3377 (const_int 8)]) 0))]
3378 "TARGET_64BIT && reload_completed"
3379 "mov{b}\t{%h1, %0|%0, %h1}"
3380 [(set_attr "type" "imov")
3381 (set_attr "mode" "QI")])
3383 (define_insn "*extzvqi"
3384 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBc,?R,m")
3386 (match_operator:SWI248 2 "extract_operator"
3387 [(match_operand 1 "int248_register_operand" "Q,Q,Q")
3389 (const_int 8)]) 0))]
3392 switch (get_attr_type (insn))
3395 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
3397 return "mov{b}\t{%h1, %0|%0, %h1}";
3400 [(set_attr "isa" "*,*,nox64")
3402 (if_then_else (and (match_operand:QI 0 "register_operand")
3403 (ior (not (match_operand:QI 0 "QIreg_operand"))
3404 (match_test "TARGET_MOVX")))
3405 (const_string "imovx")
3406 (const_string "imov")))
3408 (if_then_else (eq_attr "type" "imovx")
3410 (const_string "QI")))])
3413 [(set (match_operand:QI 0 "register_operand")
3415 (match_operator:SWI248 3 "extract_operator"
3416 [(match_operand 1 "int248_register_operand")
3419 (set (match_operand:QI 2 "norex_memory_operand") (match_dup 0))]
3421 && peep2_reg_dead_p (2, operands[0])"
3427 (const_int 8)]) 0))])
3429 (define_expand "insv<mode>"
3430 [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
3431 (match_operand:SI 1 "const_int_operand")
3432 (match_operand:SI 2 "const_int_operand"))
3433 (match_operand:SWI248 3 "register_operand"))]
3438 if (ix86_expand_pinsr (operands))
3441 /* Handle insertions to %ah et al. */
3442 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
3445 unsigned int regno = reg_or_subregno (operands[0]);
3447 /* Be careful to expand only with registers having upper parts. */
3448 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3449 dst = copy_to_reg (operands[0]);
3453 emit_insn (gen_insv_1 (<MODE>mode, dst, operands[3]));
3455 /* Fix up the destination if needed. */
3456 if (dst != operands[0])
3457 emit_move_insn (operands[0], dst);
3462 (define_insn "*insvqi_1_mem_rex64"
3463 [(set (zero_extract:SWI248
3464 (match_operand 0 "int248_register_operand" "+Q")
3468 (match_operand:QI 1 "norex_memory_operand" "Bn") 0))]
3469 "TARGET_64BIT && reload_completed"
3470 "mov{b}\t{%1, %h0|%h0, %1}"
3471 [(set_attr "type" "imov")
3472 (set_attr "mode" "QI")])
3474 (define_insn "@insv<mode>_1"
3475 [(set (zero_extract:SWI248
3476 (match_operand 0 "int248_register_operand" "+Q,Q")
3479 (match_operand:SWI248 1 "general_operand" "QnBc,m"))]
3482 if (CONST_INT_P (operands[1]))
3483 operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
3484 return "mov{b}\t{%b1, %h0|%h0, %b1}";
3486 [(set_attr "isa" "*,nox64")
3487 (set_attr "type" "imov")
3488 (set_attr "mode" "QI")])
3490 (define_insn "*insvqi_1"
3491 [(set (zero_extract:SWI248
3492 (match_operand 0 "int248_register_operand" "+Q,Q")
3496 (match_operand:QI 1 "general_operand" "QnBc,m") 0))]
3498 "mov{b}\t{%1, %h0|%h0, %1}"
3499 [(set_attr "isa" "*,nox64")
3500 (set_attr "type" "imov")
3501 (set_attr "mode" "QI")])
3504 [(set (match_operand:QI 0 "register_operand")
3505 (match_operand:QI 1 "norex_memory_operand"))
3506 (set (zero_extract:SWI248 (match_operand 2 "int248_register_operand")
3509 (subreg:SWI248 (match_dup 0) 0))]
3511 && peep2_reg_dead_p (2, operands[0])"
3512 [(set (zero_extract:SWI248 (match_dup 2)
3515 (subreg:SWI248 (match_dup 1) 0))])
3517 ;; Eliminate redundant insv, e.g. xorl %eax,%eax; movb $0, %ah
3519 [(parallel [(set (match_operand:SWI48 0 "general_reg_operand")
3521 (clobber (reg:CC FLAGS_REG))])
3522 (set (zero_extract:SWI248 (match_operand 1 "int248_register_operand")
3526 "REGNO (operands[0]) == REGNO (operands[1])"
3527 [(parallel [(set (match_operand:SWI48 0 "general_reg_operand")
3529 (clobber (reg:CC FLAGS_REG))])])
3531 ;; Combine movl followed by movb.
3533 [(set (match_operand:SWI48 0 "general_reg_operand")
3534 (match_operand:SWI48 1 "const_int_operand"))
3535 (set (zero_extract:SWI248 (match_operand 2 "int248_register_operand")
3538 (match_operand:SWI248 3 "const_int_operand"))]
3539 "REGNO (operands[0]) == REGNO (operands[2])"
3540 [(set (match_operand:SWI48 0 "general_reg_operand")
3543 HOST_WIDE_INT tmp = INTVAL (operands[1]) & ~(HOST_WIDE_INT)0xff00;
3544 tmp |= (INTVAL (operands[3]) & 0xff) << 8;
3545 operands[4] = gen_int_mode (tmp, <SWI48:MODE>mode);
3548 (define_insn "*insvqi_2"
3549 [(set (zero_extract:SWI248
3550 (match_operand 0 "int248_register_operand" "+Q")
3553 (match_operator:SWI248 2 "extract_operator"
3554 [(match_operand 1 "int248_register_operand" "Q")
3558 "mov{b}\t{%h1, %h0|%h0, %h1}"
3559 [(set_attr "type" "imov")
3560 (set_attr "mode" "QI")])
3562 (define_insn "*insvqi_3"
3563 [(set (zero_extract:SWI248
3564 (match_operand 0 "int248_register_operand" "+Q")
3568 (match_operand:SWI248 1 "register_operand" "Q")
3571 "mov{b}\t{%h1, %h0|%h0, %h1}"
3572 [(set_attr "type" "imov")
3573 (set_attr "mode" "QI")])
3575 (define_code_iterator any_or_plus [plus ior xor])
3577 (define_insn_and_split "*insvti_highpart_1"
3578 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro,r,r,&r")
3581 (match_operand:TI 1 "nonimmediate_operand" "r,m,r,m")
3582 (match_operand:TI 3 "const_scalar_int_operand" "n,n,n,n"))
3585 (match_operand:DI 2 "nonimmediate_operand" "r,r,m,m"))
3588 && CONST_WIDE_INT_P (operands[3])
3589 && CONST_WIDE_INT_NUNITS (operands[3]) == 2
3590 && CONST_WIDE_INT_ELT (operands[3], 0) == -1
3591 && CONST_WIDE_INT_ELT (operands[3], 1) == 0"
3593 "&& reload_completed"
3596 operands[4] = gen_lowpart (DImode, operands[1]);
3597 split_double_concat (TImode, operands[0], operands[4], operands[2]);
3601 (define_insn_and_split "*insvti_lowpart_1"
3602 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro,r,r,&r")
3605 (match_operand:TI 1 "nonimmediate_operand" "r,m,r,m")
3606 (match_operand:TI 3 "const_scalar_int_operand" "n,n,n,n"))
3608 (match_operand:DI 2 "nonimmediate_operand" "r,r,m,m"))))]
3610 && CONST_WIDE_INT_P (operands[3])
3611 && CONST_WIDE_INT_NUNITS (operands[3]) == 2
3612 && CONST_WIDE_INT_ELT (operands[3], 0) == 0
3613 && CONST_WIDE_INT_ELT (operands[3], 1) == -1"
3615 "&& reload_completed"
3618 operands[4] = gen_highpart (DImode, operands[1]);
3619 split_double_concat (TImode, operands[0], operands[2], operands[4]);
3623 (define_insn_and_split "*insvdi_lowpart_1"
3624 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro,r,r,&r")
3627 (match_operand:DI 1 "nonimmediate_operand" "r,m,r,m")
3628 (match_operand:DI 3 "const_int_operand" "n,n,n,n"))
3630 (match_operand:SI 2 "nonimmediate_operand" "r,r,m,m"))))]
3632 && CONST_INT_P (operands[3])
3633 && UINTVAL (operands[3]) == 0xffffffff00000000ll"
3635 "&& reload_completed"
3638 operands[4] = gen_highpart (SImode, operands[1]);
3639 split_double_concat (DImode, operands[0], operands[2], operands[4]);
3643 ;; Floating point push instructions.
3645 (define_insn "*pushtf"
3646 [(set (match_operand:TF 0 "push_operand" "=<,<")
3647 (match_operand:TF 1 "general_no_elim_operand" "v,*roC"))]
3648 "TARGET_64BIT || TARGET_SSE"
3650 /* This insn should be already split before reg-stack. */
3653 [(set_attr "isa" "*,x64")
3654 (set_attr "type" "multi")
3655 (set_attr "unit" "sse,*")
3656 (set_attr "mode" "TF,DI")])
3658 ;; %%% Kill this when call knows how to work this out.
3660 [(set (match_operand:TF 0 "push_operand")
3661 (match_operand:TF 1 "sse_reg_operand"))]
3662 "TARGET_SSE && reload_completed"
3663 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3664 (set (match_dup 0) (match_dup 1))]
3666 /* Preserve memory attributes. */
3667 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3670 (define_insn "*pushxf"
3671 [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<")
3672 (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF,oC"))]
3675 /* This insn should be already split before reg-stack. */
3678 [(set_attr "isa" "*,*,*,nox64,x64")
3679 (set_attr "type" "multi")
3680 (set_attr "unit" "i387,*,*,*,*")
3682 (cond [(eq_attr "alternative" "1,2,3,4")
3683 (if_then_else (match_test "TARGET_64BIT")
3685 (const_string "SI"))
3687 (const_string "XF")))
3688 (set (attr "preferred_for_size")
3689 (cond [(eq_attr "alternative" "1")
3690 (symbol_ref "false")]
3691 (symbol_ref "true")))])
3693 ;; %%% Kill this when call knows how to work this out.
3695 [(set (match_operand:XF 0 "push_operand")
3696 (match_operand:XF 1 "fp_register_operand"))]
3698 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3699 (set (match_dup 0) (match_dup 1))]
3701 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (XFmode)));
3702 /* Preserve memory attributes. */
3703 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3706 (define_insn "*pushdf"
3707 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
3708 (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmC,v"))]
3711 /* This insn should be already split before reg-stack. */
3714 [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
3715 (set_attr "type" "multi")
3716 (set_attr "unit" "i387,*,*,*,*,sse")
3717 (set_attr "mode" "DF,SI,SI,SI,DI,DF")
3718 (set (attr "preferred_for_size")
3719 (cond [(eq_attr "alternative" "1")
3720 (symbol_ref "false")]
3721 (symbol_ref "true")))
3722 (set (attr "preferred_for_speed")
3723 (cond [(eq_attr "alternative" "1")
3724 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3725 (symbol_ref "true")))])
3727 ;; %%% Kill this when call knows how to work this out.
3729 [(set (match_operand:DF 0 "push_operand")
3730 (match_operand:DF 1 "any_fp_register_operand"))]
3732 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3733 (set (match_dup 0) (match_dup 1))]
3735 /* Preserve memory attributes. */
3736 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3739 (define_mode_iterator HFBF [HF BF])
3741 (define_insn "*push<mode>_rex64"
3742 [(set (match_operand:HFBF 0 "push_operand" "=X,X")
3743 (match_operand:HFBF 1 "nonmemory_no_elim_operand" "r,x"))]
3746 /* Anything else should be already split before reg-stack. */
3747 gcc_assert (which_alternative == 0);
3748 return "push{q}\t%q1";
3750 [(set_attr "isa" "*,sse4")
3751 (set_attr "type" "push,multi")
3752 (set_attr "mode" "DI,TI")])
3754 (define_insn "*push<mode>"
3755 [(set (match_operand:HFBF 0 "push_operand" "=X,X")
3756 (match_operand:HFBF 1 "general_no_elim_operand" "rmF,x"))]
3759 /* Anything else should be already split before reg-stack. */
3760 gcc_assert (which_alternative == 0);
3761 return "push{l}\t%k1";
3763 [(set_attr "isa" "*,sse4")
3764 (set_attr "type" "push,multi")
3765 (set_attr "mode" "SI,TI")])
3767 (define_insn "*pushsf_rex64"
3768 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3769 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,v"))]
3772 /* Anything else should be already split before reg-stack. */
3773 if (which_alternative != 1)
3775 return "push{q}\t%q1";
3777 [(set_attr "type" "multi,push,multi")
3778 (set_attr "unit" "i387,*,*")
3779 (set_attr "mode" "SF,DI,SF")])
3781 (define_insn "*pushsf"
3782 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3783 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,v"))]
3786 /* Anything else should be already split before reg-stack. */
3787 if (which_alternative != 1)
3789 return "push{l}\t%1";
3791 [(set_attr "type" "multi,push,multi")
3792 (set_attr "unit" "i387,*,*")
3793 (set_attr "mode" "SF,SI,SF")])
3795 (define_mode_iterator MODESH [SF HF BF])
3796 ;; %%% Kill this when call knows how to work this out.
3798 [(set (match_operand:MODESH 0 "push_operand")
3799 (match_operand:MODESH 1 "any_fp_register_operand"))]
3801 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3802 (set (match_dup 0) (match_dup 1))]
3804 rtx op = XEXP (operands[0], 0);
3805 if (GET_CODE (op) == PRE_DEC)
3807 gcc_assert (!TARGET_64BIT);
3812 op = XEXP (XEXP (op, 1), 1);
3813 gcc_assert (CONST_INT_P (op));
3816 /* Preserve memory attributes. */
3817 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3821 [(set (match_operand:SF 0 "push_operand")
3822 (match_operand:SF 1 "memory_operand"))]
3824 && find_constant_src (insn)"
3825 [(set (match_dup 0) (match_dup 2))]
3826 "operands[2] = find_constant_src (curr_insn);")
3829 [(set (match_operand 0 "push_operand")
3830 (match_operand 1 "general_gr_operand"))]
3832 && (GET_MODE (operands[0]) == TFmode
3833 || GET_MODE (operands[0]) == XFmode
3834 || GET_MODE (operands[0]) == DFmode)"
3836 "ix86_split_long_move (operands); DONE;")
3838 ;; Floating point move instructions.
3840 (define_expand "movtf"
3841 [(set (match_operand:TF 0 "nonimmediate_operand")
3842 (match_operand:TF 1 "nonimmediate_operand"))]
3843 "TARGET_64BIT || TARGET_SSE"
3844 "ix86_expand_move (TFmode, operands); DONE;")
3846 (define_expand "mov<mode>"
3847 [(set (match_operand:X87MODEFH 0 "nonimmediate_operand")
3848 (match_operand:X87MODEFH 1 "general_operand"))]
3850 "ix86_expand_move (<MODE>mode, operands); DONE;")
3852 (define_insn "*movtf_internal"
3853 [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o")
3854 (match_operand:TF 1 "general_operand" "C ,vm,v,*roF,*rC"))]
3855 "(TARGET_64BIT || TARGET_SSE)
3856 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3857 && (lra_in_progress || reload_completed
3858 || !CONST_DOUBLE_P (operands[1])
3859 || (standard_sse_constant_p (operands[1], TFmode) == 1
3860 && !memory_operand (operands[0], TFmode))
3861 || (!TARGET_MEMORY_MISMATCH_STALL
3862 && memory_operand (operands[0], TFmode)))"
3864 switch (get_attr_type (insn))
3867 return standard_sse_constant_opcode (insn, operands);
3870 return ix86_output_ssemov (insn, operands);
3879 [(set_attr "isa" "*,*,*,x64,x64")
3880 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3881 (set (attr "prefix")
3882 (if_then_else (eq_attr "type" "sselog1,ssemov")
3883 (const_string "maybe_vex")
3884 (const_string "orig")))
3886 (cond [(eq_attr "alternative" "3,4")
3888 (match_test "TARGET_AVX")
3890 (ior (not (match_test "TARGET_SSE2"))
3891 (match_test "optimize_function_for_size_p (cfun)"))
3892 (const_string "V4SF")
3893 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3894 (const_string "V4SF")
3895 (and (eq_attr "alternative" "2")
3896 (match_test "TARGET_SSE_TYPELESS_STORES"))
3897 (const_string "V4SF")
3899 (const_string "TI")))])
3902 [(set (match_operand:TF 0 "nonimmediate_gr_operand")
3903 (match_operand:TF 1 "general_gr_operand"))]
3906 "ix86_split_long_move (operands); DONE;")
3908 ;; Possible store forwarding (partial memory) stall
3909 ;; in alternatives 4, 6, 7 and 8.
3910 (define_insn "*movxf_internal"
3911 [(set (match_operand:XF 0 "nonimmediate_operand"
3912 "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r ,o ,o")
3913 (match_operand:XF 1 "general_operand"
3914 "fm,f,G,roF,r ,*roF,*r,F ,C ,roF,rF,rC"))]
3915 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3916 && (lra_in_progress || reload_completed
3917 || !CONST_DOUBLE_P (operands[1])
3918 || ((optimize_function_for_size_p (cfun)
3919 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3920 && standard_80387_constant_p (operands[1]) > 0
3921 && !memory_operand (operands[0], XFmode))
3922 || (!TARGET_MEMORY_MISMATCH_STALL
3923 && memory_operand (operands[0], XFmode))
3924 || !TARGET_HARD_XF_REGS)"
3926 switch (get_attr_type (insn))
3929 if (which_alternative == 2)
3930 return standard_80387_constant_opcode (operands[1]);
3931 return output_387_reg_move (insn, operands);
3941 (cond [(eq_attr "alternative" "7,10")
3942 (const_string "nox64")
3943 (eq_attr "alternative" "8,11")
3944 (const_string "x64")
3946 (const_string "*")))
3948 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3949 (const_string "multi")
3951 (const_string "fmov")))
3953 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3954 (if_then_else (match_test "TARGET_64BIT")
3956 (const_string "SI"))
3958 (const_string "XF")))
3959 (set (attr "preferred_for_size")
3960 (cond [(eq_attr "alternative" "3,4")
3961 (symbol_ref "false")]
3962 (symbol_ref "true")))
3963 (set (attr "enabled")
3964 (cond [(eq_attr "alternative" "9,10,11")
3966 (match_test "TARGET_HARD_XF_REGS")
3967 (symbol_ref "false")
3969 (not (match_test "TARGET_HARD_XF_REGS"))
3970 (symbol_ref "false")
3972 (const_string "*")))])
3975 [(set (match_operand:XF 0 "nonimmediate_gr_operand")
3976 (match_operand:XF 1 "general_gr_operand"))]
3979 "ix86_split_long_move (operands); DONE;")
3981 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3982 (define_insn "*movdf_internal"
3983 [(set (match_operand:DF 0 "nonimmediate_operand"
3984 "=Yf*f,m ,Yf*f,?r ,!o,?*r ,!o,!o,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,?r,?v,r ,o ,r ,m")
3985 (match_operand:DF 1 "general_operand"
3986 "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"))]
3987 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3988 && (lra_in_progress || reload_completed
3989 || !CONST_DOUBLE_P (operands[1])
3990 || ((optimize_function_for_size_p (cfun)
3991 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3992 && IS_STACK_MODE (DFmode)
3993 && standard_80387_constant_p (operands[1]) > 0
3994 && !memory_operand (operands[0], DFmode))
3995 || (TARGET_SSE2 && TARGET_SSE_MATH
3996 && standard_sse_constant_p (operands[1], DFmode) == 1
3997 && !memory_operand (operands[0], DFmode))
3998 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3999 && memory_operand (operands[0], DFmode))
4000 || !TARGET_HARD_DF_REGS)"
4002 switch (get_attr_type (insn))
4005 if (which_alternative == 2)
4006 return standard_80387_constant_opcode (operands[1]);
4007 return output_387_reg_move (insn, operands);
4013 if (get_attr_mode (insn) == MODE_SI)
4014 return "mov{l}\t{%1, %k0|%k0, %1}";
4015 else if (which_alternative == 11)
4016 return "movabs{q}\t{%1, %0|%0, %1}";
4018 return "mov{q}\t{%1, %0|%0, %1}";
4021 return standard_sse_constant_opcode (insn, operands);
4024 return ix86_output_ssemov (insn, operands);
4031 (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
4032 (const_string "nox64")
4033 (eq_attr "alternative" "8,9,10,11,24,25")
4034 (const_string "x64")
4035 (eq_attr "alternative" "12,13,14,15")
4036 (const_string "sse2")
4037 (eq_attr "alternative" "20,21")
4038 (const_string "x64_sse2")
4040 (const_string "*")))
4042 (cond [(eq_attr "alternative" "0,1,2")
4043 (const_string "fmov")
4044 (eq_attr "alternative" "3,4,5,6,7,22,23")
4045 (const_string "multi")
4046 (eq_attr "alternative" "8,9,10,11,24,25")
4047 (const_string "imov")
4048 (eq_attr "alternative" "12,16")
4049 (const_string "sselog1")
4051 (const_string "ssemov")))
4053 (if_then_else (eq_attr "alternative" "11")
4055 (const_string "*")))
4056 (set (attr "length_immediate")
4057 (if_then_else (eq_attr "alternative" "11")
4059 (const_string "*")))
4060 (set (attr "prefix")
4061 (if_then_else (eq_attr "type" "sselog1,ssemov")
4062 (const_string "maybe_vex")
4063 (const_string "orig")))
4064 (set (attr "prefix_data16")
4066 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
4067 (eq_attr "mode" "V1DF"))
4069 (const_string "*")))
4071 (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
4073 (eq_attr "alternative" "8,9,11,20,21,24,25")
4076 /* xorps is one byte shorter for non-AVX targets. */
4077 (eq_attr "alternative" "12,16")
4078 (cond [(match_test "TARGET_AVX")
4079 (const_string "V2DF")
4080 (ior (not (match_test "TARGET_SSE2"))
4081 (match_test "optimize_function_for_size_p (cfun)"))
4082 (const_string "V4SF")
4083 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
4086 (const_string "V2DF"))
4088 /* For architectures resolving dependencies on
4089 whole SSE registers use movapd to break dependency
4090 chains, otherwise use short move to avoid extra work. */
4092 /* movaps is one byte shorter for non-AVX targets. */
4093 (eq_attr "alternative" "13,17")
4094 (cond [(match_test "TARGET_AVX")
4096 (ior (not (match_test "TARGET_SSE2"))
4097 (match_test "optimize_function_for_size_p (cfun)"))
4098 (const_string "V4SF")
4099 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
4100 (const_string "V4SF")
4101 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
4102 (const_string "V2DF")
4104 (const_string "DF"))
4106 /* For architectures resolving dependencies on register
4107 parts we may avoid extra work to zero out upper part
4109 (eq_attr "alternative" "14,18")
4110 (cond [(not (match_test "TARGET_SSE2"))
4111 (const_string "V2SF")
4112 (match_test "TARGET_AVX")
4114 (match_test "TARGET_SSE_SPLIT_REGS")
4115 (const_string "V1DF")
4117 (const_string "DF"))
4119 (and (eq_attr "alternative" "15,19")
4120 (not (match_test "TARGET_SSE2")))
4121 (const_string "V2SF")
4123 (const_string "DF")))
4124 (set (attr "preferred_for_size")
4125 (cond [(eq_attr "alternative" "3,4")
4126 (symbol_ref "false")]
4127 (symbol_ref "true")))
4128 (set (attr "preferred_for_speed")
4129 (cond [(eq_attr "alternative" "3,4")
4130 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")
4131 (eq_attr "alternative" "20")
4132 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4133 (eq_attr "alternative" "21")
4134 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4136 (symbol_ref "true")))
4137 (set (attr "enabled")
4138 (cond [(eq_attr "alternative" "22,23,24,25")
4140 (match_test "TARGET_HARD_DF_REGS")
4141 (symbol_ref "false")
4143 (not (match_test "TARGET_HARD_DF_REGS"))
4144 (symbol_ref "false")
4146 (const_string "*")))])
4149 [(set (match_operand:DF 0 "nonimmediate_gr_operand")
4150 (match_operand:DF 1 "general_gr_operand"))]
4151 "!TARGET_64BIT && reload_completed"
4153 "ix86_split_long_move (operands); DONE;")
4155 (define_insn "*movsf_internal"
4156 [(set (match_operand:SF 0 "nonimmediate_operand"
4157 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?v,!*y,!*y,!m,!r,!*y,r ,m")
4158 (match_operand:SF 1 "general_operand"
4159 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,v ,r ,*y ,m ,*y,*y,r ,rmF,rF"))]
4160 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
4161 && (lra_in_progress || reload_completed
4162 || !CONST_DOUBLE_P (operands[1])
4163 || ((optimize_function_for_size_p (cfun)
4164 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
4165 && IS_STACK_MODE (SFmode)
4166 && standard_80387_constant_p (operands[1]) > 0)
4167 || (TARGET_SSE && TARGET_SSE_MATH
4168 && standard_sse_constant_p (operands[1], SFmode) == 1)
4169 || memory_operand (operands[0], SFmode)
4170 || !TARGET_HARD_SF_REGS)"
4172 switch (get_attr_type (insn))
4175 if (which_alternative == 2)
4176 return standard_80387_constant_opcode (operands[1]);
4177 return output_387_reg_move (insn, operands);
4180 return "mov{l}\t{%1, %0|%0, %1}";
4183 return standard_sse_constant_opcode (insn, operands);
4186 return ix86_output_ssemov (insn, operands);
4189 switch (get_attr_mode (insn))
4192 return "movq\t{%1, %0|%0, %1}";
4194 return "movd\t{%1, %0|%0, %1}";
4205 (cond [(eq_attr "alternative" "9,10")
4206 (const_string "sse2")
4208 (const_string "*")))
4210 (cond [(eq_attr "alternative" "0,1,2")
4211 (const_string "fmov")
4212 (eq_attr "alternative" "3,4,16,17")
4213 (const_string "imov")
4214 (eq_attr "alternative" "5")
4215 (const_string "sselog1")
4216 (eq_attr "alternative" "11,12,13,14,15")
4217 (const_string "mmxmov")
4219 (const_string "ssemov")))
4220 (set (attr "prefix")
4221 (if_then_else (eq_attr "type" "sselog1,ssemov")
4222 (const_string "maybe_vex")
4223 (const_string "orig")))
4224 (set (attr "prefix_data16")
4225 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
4227 (const_string "*")))
4229 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
4231 (eq_attr "alternative" "11")
4233 (eq_attr "alternative" "5")
4234 (cond [(and (match_test "TARGET_AVX512F")
4235 (not (match_test "TARGET_PREFER_AVX256")))
4236 (const_string "V16SF")
4237 (match_test "TARGET_AVX")
4238 (const_string "V4SF")
4239 (ior (not (match_test "TARGET_SSE2"))
4240 (match_test "optimize_function_for_size_p (cfun)"))
4241 (const_string "V4SF")
4242 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
4245 (const_string "V4SF"))
4247 /* For architectures resolving dependencies on
4248 whole SSE registers use APS move to break dependency
4249 chains, otherwise use short move to avoid extra work.
4251 Do the same for architectures resolving dependencies on
4252 the parts. While in DF mode it is better to always handle
4253 just register parts, the SF mode is different due to lack
4254 of instructions to load just part of the register. It is
4255 better to maintain the whole registers in single format
4256 to avoid problems on using packed logical operations. */
4257 (eq_attr "alternative" "6")
4258 (cond [(ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
4259 (match_test "TARGET_SSE_SPLIT_REGS"))
4260 (const_string "V4SF")
4262 (const_string "SF"))
4264 (const_string "SF")))
4265 (set (attr "preferred_for_speed")
4266 (cond [(eq_attr "alternative" "9,14")
4267 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4268 (eq_attr "alternative" "10,15")
4269 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4271 (symbol_ref "true")))
4272 (set (attr "enabled")
4273 (cond [(eq_attr "alternative" "16,17")
4275 (match_test "TARGET_HARD_SF_REGS")
4276 (symbol_ref "false")
4278 (not (match_test "TARGET_HARD_SF_REGS"))
4279 (symbol_ref "false")
4281 (const_string "*")))])
4283 (define_mode_attr hfbfconstf
4286 (define_insn "*mov<mode>_internal"
4287 [(set (match_operand:HFBF 0 "nonimmediate_operand"
4288 "=?r,?r,?r,?m,v,v,?r,m,?v,v")
4289 (match_operand:HFBF 1 "general_operand"
4290 "r ,F ,m ,r<hfbfconstf>,C,v, v,v,r ,m"))]
4291 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
4294 || !CONST_DOUBLE_P (operands[1])
4296 && standard_sse_constant_p (operands[1], <MODE>mode) == 1)
4297 || memory_operand (operands[0], <MODE>mode))"
4299 switch (get_attr_type (insn))
4302 /* movzwl is faster than movw on p2 due to partial word stalls,
4303 though not as fast as an aligned movl. */
4304 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
4307 return ix86_output_ssemov (insn, operands);
4310 if (satisfies_constraint_C (operands[1]))
4311 return standard_sse_constant_opcode (insn, operands);
4313 if (SSE_REG_P (operands[0]))
4314 return "%vpinsrw\t{$0, %1, %d0|%d0, %1, 0}";
4316 return "%vpextrw\t{$0, %1, %0|%0, %1, 0}";
4319 if (get_attr_mode (insn) == MODE_SI)
4320 return "mov{l}\t{%k1, %k0|%k0, %k1}";
4322 return "mov{w}\t{%1, %0|%0, %1}";
4326 (cond [(eq_attr "alternative" "4,5,6,8,9")
4327 (const_string "sse2")
4328 (eq_attr "alternative" "7")
4329 (const_string "sse4")
4331 (const_string "*")))
4333 (cond [(eq_attr "alternative" "4")
4334 (const_string "sselog1")
4335 (eq_attr "alternative" "5,6,8")
4336 (const_string "ssemov")
4337 (eq_attr "alternative" "7,9")
4339 (match_test ("TARGET_AVX512FP16"))
4340 (const_string "ssemov")
4341 (const_string "sselog1"))
4342 (match_test "optimize_function_for_size_p (cfun)")
4343 (const_string "imov")
4344 (and (eq_attr "alternative" "0")
4345 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
4346 (not (match_test "TARGET_HIMODE_MATH"))))
4347 (const_string "imov")
4348 (and (eq_attr "alternative" "1,2")
4349 (match_operand:HI 1 "aligned_operand"))
4350 (const_string "imov")
4351 (and (match_test "TARGET_MOVX")
4352 (eq_attr "alternative" "0,2"))
4353 (const_string "imovx")
4355 (const_string "imov")))
4356 (set (attr "prefix")
4357 (cond [(eq_attr "alternative" "4,5,6,7,8,9")
4358 (const_string "maybe_vex")
4360 (const_string "orig")))
4362 (cond [(eq_attr "alternative" "4")
4363 (const_string "V4SF")
4364 (eq_attr "alternative" "6,8")
4366 (match_test "TARGET_AVX512FP16")
4368 (const_string "SI"))
4369 (eq_attr "alternative" "7,9")
4371 (match_test "TARGET_AVX512FP16")
4373 (const_string "TI"))
4374 (eq_attr "alternative" "5")
4375 (cond [(match_test "TARGET_AVX512FP16")
4377 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
4378 (match_test "TARGET_SSE_SPLIT_REGS"))
4379 (const_string "V4SF")
4381 (const_string "SF"))
4382 (eq_attr "type" "imovx")
4384 (and (eq_attr "alternative" "1,2")
4385 (match_operand:HI 1 "aligned_operand"))
4387 (and (eq_attr "alternative" "0")
4388 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
4389 (not (match_test "TARGET_HIMODE_MATH"))))
4392 (const_string "HI")))
4393 (set (attr "enabled")
4394 (cond [(and (match_test "<MODE>mode == BFmode")
4395 (eq_attr "alternative" "1"))
4396 (symbol_ref "false")
4398 (const_string "*")))])
4401 [(set (match_operand 0 "any_fp_register_operand")
4402 (match_operand 1 "memory_operand"))]
4404 && (GET_MODE (operands[0]) == TFmode
4405 || GET_MODE (operands[0]) == XFmode
4406 || GET_MODE (operands[0]) == DFmode
4407 || GET_MODE (operands[0]) == SFmode)
4408 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
4409 [(set (match_dup 0) (match_dup 2))]
4410 "operands[2] = find_constant_src (curr_insn);")
4413 [(set (match_operand 0 "any_fp_register_operand")
4414 (float_extend (match_operand 1 "memory_operand")))]
4416 && (GET_MODE (operands[0]) == TFmode
4417 || GET_MODE (operands[0]) == XFmode
4418 || GET_MODE (operands[0]) == DFmode)
4419 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
4420 [(set (match_dup 0) (match_dup 2))]
4421 "operands[2] = find_constant_src (curr_insn);")
4423 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
4425 [(set (match_operand:X87MODEF 0 "fp_register_operand")
4426 (match_operand:X87MODEF 1 "immediate_operand"))]
4428 && (standard_80387_constant_p (operands[1]) == 8
4429 || standard_80387_constant_p (operands[1]) == 9)"
4430 [(set (match_dup 0)(match_dup 1))
4432 (neg:X87MODEF (match_dup 0)))]
4434 if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
4435 operands[1] = CONST0_RTX (<MODE>mode);
4437 operands[1] = CONST1_RTX (<MODE>mode);
4440 (define_insn "*swapxf"
4441 [(set (match_operand:XF 0 "register_operand" "+f")
4442 (match_operand:XF 1 "register_operand" "+f"))
4447 if (STACK_TOP_P (operands[0]))
4452 [(set_attr "type" "fxch")
4453 (set_attr "mode" "XF")])
4456 ;; Zero extension instructions
4458 (define_insn_and_split "zero_extendditi2"
4459 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4460 (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "rm,r")))]
4463 "&& reload_completed"
4464 [(set (match_dup 3) (match_dup 1))
4465 (set (match_dup 4) (const_int 0))]
4466 "split_double_mode (TImode, &operands[0], 1, &operands[3], &operands[4]);")
4468 (define_expand "zero_extendsidi2"
4469 [(set (match_operand:DI 0 "nonimmediate_operand")
4470 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
4472 (define_insn "*zero_extendsidi2"
4473 [(set (match_operand:DI 0 "nonimmediate_operand"
4474 "=r,?r,?o,r ,o,?*y,?!*y,$r,$v,$x,*x,*v,*r,*k")
4476 (match_operand:SI 1 "x86_64_zext_operand"
4477 "0 ,rm,r ,rmWz,0,r ,m ,v ,r ,m ,*x,*v,*k,*km")))]
4480 switch (get_attr_type (insn))
4483 if (ix86_use_lea_for_mov (insn, operands))
4484 return "lea{l}\t{%E1, %k0|%k0, %E1}";
4486 return "mov{l}\t{%1, %k0|%k0, %1}";
4492 return "movd\t{%1, %0|%0, %1}";
4495 if (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1]))
4497 if (EXT_REX_SSE_REG_P (operands[0])
4498 || EXT_REX_SSE_REG_P (operands[1]))
4499 return "vpmovzxdq\t{%t1, %g0|%g0, %t1}";
4501 return "%vpmovzxdq\t{%1, %0|%0, %1}";
4504 if (GENERAL_REG_P (operands[0]))
4505 return "%vmovd\t{%1, %k0|%k0, %1}";
4507 return "%vmovd\t{%1, %0|%0, %1}";
4510 return "kmovd\t{%1, %k0|%k0, %1}";
4517 (cond [(eq_attr "alternative" "0,1,2")
4518 (const_string "nox64")
4519 (eq_attr "alternative" "3")
4520 (const_string "x64")
4521 (eq_attr "alternative" "7,8,9")
4522 (const_string "sse2")
4523 (eq_attr "alternative" "10")
4524 (const_string "sse4")
4525 (eq_attr "alternative" "11")
4526 (const_string "avx512f")
4527 (eq_attr "alternative" "12")
4528 (const_string "x64_avx512bw")
4529 (eq_attr "alternative" "13")
4530 (const_string "avx512bw")
4532 (const_string "*")))
4533 (set (attr "mmx_isa")
4534 (if_then_else (eq_attr "alternative" "5,6")
4535 (const_string "native")
4536 (const_string "*")))
4538 (cond [(eq_attr "alternative" "0,1,2,4")
4539 (const_string "multi")
4540 (eq_attr "alternative" "5,6")
4541 (const_string "mmxmov")
4542 (eq_attr "alternative" "7")
4543 (if_then_else (match_test "TARGET_64BIT")
4544 (const_string "ssemov")
4545 (const_string "multi"))
4546 (eq_attr "alternative" "8,9,10,11")
4547 (const_string "ssemov")
4548 (eq_attr "alternative" "12,13")
4549 (const_string "mskmov")
4551 (const_string "imovx")))
4552 (set (attr "prefix_extra")
4553 (if_then_else (eq_attr "alternative" "10,11")
4555 (const_string "*")))
4556 (set (attr "prefix")
4557 (if_then_else (eq_attr "type" "ssemov")
4558 (const_string "maybe_vex")
4559 (const_string "orig")))
4560 (set (attr "prefix_0f")
4561 (if_then_else (eq_attr "type" "imovx")
4563 (const_string "*")))
4565 (cond [(eq_attr "alternative" "5,6")
4567 (and (eq_attr "alternative" "7")
4568 (match_test "TARGET_64BIT"))
4570 (eq_attr "alternative" "8,10,11")
4573 (const_string "SI")))
4574 (set (attr "preferred_for_speed")
4575 (cond [(eq_attr "alternative" "7")
4576 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4577 (eq_attr "alternative" "5,8")
4578 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4580 (symbol_ref "true")))])
4583 [(set (match_operand:DI 0 "memory_operand")
4584 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
4586 [(set (match_dup 4) (const_int 0))]
4587 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4590 [(set (match_operand:DI 0 "general_reg_operand")
4591 (zero_extend:DI (match_operand:SI 1 "general_reg_operand")))]
4592 "!TARGET_64BIT && reload_completed
4593 && REGNO (operands[0]) == REGNO (operands[1])"
4594 [(set (match_dup 4) (const_int 0))]
4595 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4598 [(set (match_operand:DI 0 "nonimmediate_gr_operand")
4599 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
4600 "!TARGET_64BIT && reload_completed
4601 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
4602 [(set (match_dup 3) (match_dup 1))
4603 (set (match_dup 4) (const_int 0))]
4604 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4606 (define_mode_attr kmov_isa
4607 [(QI "avx512dq") (HI "avx512f") (SI "avx512bw") (DI "avx512bw")])
4609 (define_insn "zero_extend<mode>di2"
4610 [(set (match_operand:DI 0 "register_operand" "=r,*r,*k")
4612 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k,*km")))]
4615 movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}
4616 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}
4617 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}"
4618 [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
4619 (set_attr "type" "imovx,mskmov,mskmov")
4620 (set_attr "mode" "SI,<MODE>,<MODE>")])
4622 (define_expand "zero_extend<mode>si2"
4623 [(set (match_operand:SI 0 "register_operand")
4624 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
4627 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4629 operands[1] = force_reg (<MODE>mode, operands[1]);
4630 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
4635 (define_insn_and_split "zero_extend<mode>si2_and"
4636 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
4638 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
4639 (clobber (reg:CC FLAGS_REG))]
4640 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4642 "&& reload_completed"
4643 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
4644 (clobber (reg:CC FLAGS_REG))])]
4646 if (!REG_P (operands[1])
4647 || REGNO (operands[0]) != REGNO (operands[1]))
4649 ix86_expand_clear (operands[0]);
4651 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4652 emit_insn (gen_rtx_SET
4653 (gen_rtx_STRICT_LOW_PART
4654 (VOIDmode, gen_lowpart (<MODE>mode, operands[0])),
4659 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
4661 [(set_attr "type" "alu1")
4662 (set_attr "mode" "SI")])
4664 (define_insn "*zero_extend<mode>si2"
4665 [(set (match_operand:SI 0 "register_operand" "=r,*r,*k")
4667 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k,*km")))]
4668 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4670 movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}
4671 kmov<mskmodesuffix>\t{%1, %0|%0, %1}
4672 kmov<mskmodesuffix>\t{%1, %0|%0, %1}"
4673 [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
4674 (set_attr "type" "imovx,mskmov,mskmov")
4675 (set_attr "mode" "SI,<MODE>,<MODE>")])
4677 (define_expand "zero_extendqihi2"
4678 [(set (match_operand:HI 0 "register_operand")
4679 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
4682 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4684 operands[1] = force_reg (QImode, operands[1]);
4685 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
4690 (define_insn_and_split "zero_extendqihi2_and"
4691 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
4692 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4693 (clobber (reg:CC FLAGS_REG))]
4694 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4696 "&& reload_completed"
4697 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4698 (clobber (reg:CC FLAGS_REG))])]
4700 if (!REG_P (operands[1])
4701 || REGNO (operands[0]) != REGNO (operands[1]))
4703 ix86_expand_clear (operands[0]);
4705 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4706 emit_insn (gen_rtx_SET
4707 (gen_rtx_STRICT_LOW_PART
4708 (VOIDmode, gen_lowpart (QImode, operands[0])),
4713 operands[0] = gen_lowpart (SImode, operands[0]);
4715 [(set_attr "type" "alu1")
4716 (set_attr "mode" "SI")])
4718 ; zero extend to SImode to avoid partial register stalls
4719 (define_insn "*zero_extendqihi2"
4720 [(set (match_operand:HI 0 "register_operand" "=r,*r,*k")
4721 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,*k,*km")))]
4722 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4724 movz{bl|x}\t{%1, %k0|%k0, %1}
4725 kmovb\t{%1, %k0|%k0, %1}
4726 kmovb\t{%1, %0|%0, %1}"
4727 [(set_attr "isa" "*,avx512dq,avx512dq")
4728 (set_attr "type" "imovx,mskmov,mskmov")
4729 (set_attr "mode" "SI,QI,QI")])
4731 ;; Transform xorl; mov[bw] (set strict_low_part) into movz[bw]l.
4733 [(parallel [(set (match_operand:SWI48 0 "general_reg_operand")
4735 (clobber (reg:CC FLAGS_REG))])
4736 (set (strict_low_part (match_operand:SWI12 1 "general_reg_operand"))
4737 (match_operand:SWI12 2 "nonimmediate_operand"))]
4738 "REGNO (operands[0]) == REGNO (operands[1])
4739 && (<SWI48:MODE>mode != SImode
4740 || !TARGET_ZERO_EXTEND_WITH_AND
4741 || !optimize_function_for_speed_p (cfun))"
4742 [(set (match_dup 0) (zero_extend:SWI48 (match_dup 2)))])
4744 ;; Likewise, but preserving FLAGS_REG.
4746 [(set (match_operand:SWI48 0 "general_reg_operand") (const_int 0))
4747 (set (strict_low_part (match_operand:SWI12 1 "general_reg_operand"))
4748 (match_operand:SWI12 2 "nonimmediate_operand"))]
4749 "REGNO (operands[0]) == REGNO (operands[1])
4750 && (<SWI48:MODE>mode != SImode
4751 || !TARGET_ZERO_EXTEND_WITH_AND
4752 || !optimize_function_for_speed_p (cfun))"
4753 [(set (match_dup 0) (zero_extend:SWI48 (match_dup 2)))])
4755 ;; Sign extension instructions
4757 (define_expand "extendsidi2"
4758 [(set (match_operand:DI 0 "register_operand")
4759 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
4764 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
4769 (define_insn "*extendsidi2_rex64"
4770 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4771 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4775 movs{lq|x}\t{%1, %0|%0, %1}"
4776 [(set_attr "type" "imovx")
4777 (set_attr "mode" "DI")
4778 (set_attr "prefix_0f" "0")
4779 (set_attr "modrm" "0,1")])
4781 (define_insn "extendsidi2_1"
4782 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4783 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4784 (clobber (reg:CC FLAGS_REG))
4785 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4789 (define_insn "extendditi2"
4790 [(set (match_operand:TI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4791 (sign_extend:TI (match_operand:DI 1 "register_operand" "0,0,r,r")))
4792 (clobber (reg:CC FLAGS_REG))
4793 (clobber (match_scratch:DI 2 "=X,X,X,&r"))]
4797 ;; Split the memory case. If the source register doesn't die, it will stay
4798 ;; this way, if it does die, following peephole2s take care of it.
4800 [(set (match_operand:<DWI> 0 "memory_operand")
4801 (sign_extend:<DWI> (match_operand:DWIH 1 "register_operand")))
4802 (clobber (reg:CC FLAGS_REG))
4803 (clobber (match_operand:DWIH 2 "register_operand"))]
4807 rtx bits = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
4809 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
4811 emit_move_insn (operands[3], operands[1]);
4813 /* Generate a cltd if possible and doing so it profitable. */
4814 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4815 && REGNO (operands[1]) == AX_REG
4816 && REGNO (operands[2]) == DX_REG)
4818 emit_insn (gen_ashr<mode>3_cvt (operands[2], operands[1], bits));
4822 emit_move_insn (operands[2], operands[1]);
4823 emit_insn (gen_ashr<mode>3_cvt (operands[2], operands[2], bits));
4825 emit_move_insn (operands[4], operands[2]);
4829 ;; Peepholes for the case where the source register does die, after
4830 ;; being split with the above splitter.
4832 [(set (match_operand:DWIH 0 "memory_operand")
4833 (match_operand:DWIH 1 "general_reg_operand"))
4834 (set (match_operand:DWIH 2 "general_reg_operand") (match_dup 1))
4835 (parallel [(set (match_dup 2)
4836 (ashiftrt:DWIH (match_dup 2)
4837 (match_operand 4 "const_int_operand")))
4838 (clobber (reg:CC FLAGS_REG))])
4839 (set (match_operand:DWIH 3 "memory_operand") (match_dup 2))]
4840 "REGNO (operands[1]) != REGNO (operands[2])
4841 && INTVAL (operands[4]) == (<MODE_SIZE> * BITS_PER_UNIT - 1)
4842 && peep2_reg_dead_p (2, operands[1])
4843 && peep2_reg_dead_p (4, operands[2])
4844 && !reg_mentioned_p (operands[2], operands[3])"
4845 [(set (match_dup 0) (match_dup 1))
4846 (parallel [(set (match_dup 1) (ashiftrt:DWIH (match_dup 1) (match_dup 4)))
4847 (clobber (reg:CC FLAGS_REG))])
4848 (set (match_dup 3) (match_dup 1))])
4851 [(set (match_operand:DWIH 0 "memory_operand")
4852 (match_operand:DWIH 1 "general_reg_operand"))
4853 (parallel [(set (match_operand:DWIH 2 "general_reg_operand")
4854 (ashiftrt:DWIH (match_dup 1)
4855 (match_operand 4 "const_int_operand")))
4856 (clobber (reg:CC FLAGS_REG))])
4857 (set (match_operand:DWIH 3 "memory_operand") (match_dup 2))]
4858 "/* cltd is shorter than sarl $31, %eax */
4859 !optimize_function_for_size_p (cfun)
4860 && REGNO (operands[1]) == AX_REG
4861 && REGNO (operands[2]) == DX_REG
4862 && INTVAL (operands[4]) == (<MODE_SIZE> * BITS_PER_UNIT - 1)
4863 && peep2_reg_dead_p (2, operands[1])
4864 && peep2_reg_dead_p (3, operands[2])
4865 && !reg_mentioned_p (operands[2], operands[3])"
4866 [(set (match_dup 0) (match_dup 1))
4867 (parallel [(set (match_dup 1) (ashiftrt:DWIH (match_dup 1) (match_dup 4)))
4868 (clobber (reg:CC FLAGS_REG))])
4869 (set (match_dup 3) (match_dup 1))])
4871 ;; Extend to register case. Optimize case where source and destination
4872 ;; registers match and cases where we can use cltd.
4874 [(set (match_operand:<DWI> 0 "register_operand")
4875 (sign_extend:<DWI> (match_operand:DWIH 1 "register_operand")))
4876 (clobber (reg:CC FLAGS_REG))
4877 (clobber (match_scratch:DWIH 2))]
4881 rtx bits = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
4883 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
4885 if (REGNO (operands[3]) != REGNO (operands[1]))
4886 emit_move_insn (operands[3], operands[1]);
4888 rtx src = operands[1];
4889 if (REGNO (operands[3]) == AX_REG)
4892 /* Generate a cltd if possible and doing so it profitable. */
4893 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4894 && REGNO (src) == AX_REG
4895 && REGNO (operands[4]) == DX_REG)
4897 emit_insn (gen_ashr<mode>3_cvt (operands[4], src, bits));
4901 if (REGNO (operands[4]) != REGNO (operands[1]))
4902 emit_move_insn (operands[4], operands[1]);
4904 emit_insn (gen_ashr<mode>3_cvt (operands[4], operands[4], bits));
4908 (define_insn "extend<mode>di2"
4909 [(set (match_operand:DI 0 "register_operand" "=r")
4911 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4913 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
4914 [(set_attr "type" "imovx")
4915 (set_attr "mode" "DI")])
4917 (define_insn "extendhisi2"
4918 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4919 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4922 switch (get_attr_prefix_0f (insn))
4925 return "{cwtl|cwde}";
4927 return "movs{wl|x}\t{%1, %0|%0, %1}";
4930 [(set_attr "type" "imovx")
4931 (set_attr "mode" "SI")
4932 (set (attr "prefix_0f")
4933 ;; movsx is short decodable while cwtl is vector decoded.
4934 (if_then_else (and (eq_attr "cpu" "!k6")
4935 (eq_attr "alternative" "0"))
4937 (const_string "1")))
4938 (set (attr "znver1_decode")
4939 (if_then_else (eq_attr "prefix_0f" "0")
4940 (const_string "double")
4941 (const_string "direct")))
4943 (if_then_else (eq_attr "prefix_0f" "0")
4945 (const_string "1")))])
4947 (define_insn "*extendhisi2_zext"
4948 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4951 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4954 switch (get_attr_prefix_0f (insn))
4957 return "{cwtl|cwde}";
4959 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4962 [(set_attr "type" "imovx")
4963 (set_attr "mode" "SI")
4964 (set (attr "prefix_0f")
4965 ;; movsx is short decodable while cwtl is vector decoded.
4966 (if_then_else (and (eq_attr "cpu" "!k6")
4967 (eq_attr "alternative" "0"))
4969 (const_string "1")))
4971 (if_then_else (eq_attr "prefix_0f" "0")
4973 (const_string "1")))])
4975 (define_insn "extendqisi2"
4976 [(set (match_operand:SI 0 "register_operand" "=r")
4977 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4979 "movs{bl|x}\t{%1, %0|%0, %1}"
4980 [(set_attr "type" "imovx")
4981 (set_attr "mode" "SI")])
4983 (define_insn "*extendqisi2_zext"
4984 [(set (match_operand:DI 0 "register_operand" "=r")
4986 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4988 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4989 [(set_attr "type" "imovx")
4990 (set_attr "mode" "SI")])
4992 (define_insn "extendqihi2"
4993 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4994 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4997 switch (get_attr_prefix_0f (insn))
5000 return "{cbtw|cbw}";
5002 return "movs{bw|x}\t{%1, %0|%0, %1}";
5005 [(set_attr "type" "imovx")
5006 (set_attr "mode" "HI")
5007 (set (attr "prefix_0f")
5008 ;; movsx is short decodable while cwtl is vector decoded.
5009 (if_then_else (and (eq_attr "cpu" "!k6")
5010 (eq_attr "alternative" "0"))
5012 (const_string "1")))
5014 (if_then_else (eq_attr "prefix_0f" "0")
5016 (const_string "1")))])
5018 (define_insn "*extendqi<SWI24:mode>_ext_1"
5019 [(set (match_operand:SWI24 0 "register_operand" "=R")
5022 (match_operator:SWI248 2 "extract_operator"
5023 [(match_operand 1 "int248_register_operand" "Q")
5025 (const_int 8)]) 0)))]
5027 "movs{b<SWI24:imodesuffix>|x}\t{%h1, %0|%0, %h1}"
5028 [(set_attr "type" "imovx")
5029 (set_attr "mode" "<SWI24:MODE>")])
5031 ;; Conversions between float and double.
5033 ;; These are all no-ops in the model used for the 80387.
5034 ;; So just emit moves.
5036 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
5038 [(set (match_operand:DF 0 "push_operand")
5039 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
5041 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
5042 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
5045 [(set (match_operand:XF 0 "push_operand")
5046 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
5048 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
5049 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
5050 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
5052 (define_expand "extendsfdf2"
5053 [(set (match_operand:DF 0 "nonimm_ssenomem_operand")
5054 (float_extend:DF (match_operand:SF 1 "general_operand")))]
5055 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5057 /* ??? Needed for compress_float_constant since all fp constants
5058 are TARGET_LEGITIMATE_CONSTANT_P. */
5059 if (CONST_DOUBLE_P (operands[1]))
5061 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
5062 && standard_80387_constant_p (operands[1]) > 0)
5064 operands[1] = simplify_const_unary_operation
5065 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
5066 emit_move_insn_1 (operands[0], operands[1]);
5069 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
5073 (define_insn "*extendsfdf2"
5074 [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v,v")
5076 (match_operand:SF 1 "nonimmediate_operand" "fm,f,v,m")))]
5077 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5079 switch (which_alternative)
5083 return output_387_reg_move (insn, operands);
5086 return "%vcvtss2sd\t{%d1, %0|%0, %d1}";
5088 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
5094 [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
5095 (set_attr "avx_partial_xmm_update" "false,false,false,true")
5096 (set_attr "prefix" "orig,orig,maybe_vex,maybe_vex")
5097 (set_attr "mode" "SF,XF,DF,DF")
5098 (set (attr "enabled")
5100 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
5102 (eq_attr "alternative" "0,1")
5103 (symbol_ref "TARGET_MIX_SSE_I387")
5104 (symbol_ref "true"))
5106 (eq_attr "alternative" "0,1")
5108 (symbol_ref "false"))))])
5110 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
5112 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
5114 We do the conversion post reload to avoid producing of 128bit spills
5115 that might lead to ICE on 32bit target. The sequence unlikely combine
5118 [(set (match_operand:DF 0 "sse_reg_operand")
5120 (match_operand:SF 1 "nonimmediate_operand")))]
5121 "TARGET_USE_VECTOR_FP_CONVERTS
5122 && optimize_insn_for_speed_p ()
5124 && (!EXT_REX_SSE_REG_P (operands[0])
5125 || TARGET_AVX512VL)"
5130 (parallel [(const_int 0) (const_int 1)]))))]
5132 operands[2] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5133 operands[3] = lowpart_subreg (V4SFmode, operands[0], DFmode);
5134 /* Use movss for loading from memory, unpcklps reg, reg for registers.
5135 Try to avoid move when unpacking can be done in source. */
5136 if (REG_P (operands[1]))
5138 /* If it is unsafe to overwrite upper half of source, we need
5139 to move to destination and unpack there. */
5140 if (REGNO (operands[0]) != REGNO (operands[1])
5141 || (EXT_REX_SSE_REG_P (operands[1])
5142 && !TARGET_AVX512VL))
5144 rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode);
5145 emit_move_insn (tmp, operands[1]);
5148 operands[3] = lowpart_subreg (V4SFmode, operands[1], SFmode);
5149 /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
5150 =v, v, then vbroadcastss will be only needed for AVX512F without
5152 if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3])))
5153 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
5157 rtx tmp = lowpart_subreg (V16SFmode, operands[3], V4SFmode);
5158 emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
5162 emit_insn (gen_vec_setv4sf_0 (operands[3],
5163 CONST0_RTX (V4SFmode), operands[1]));
5166 ;; It's more profitable to split and then extend in the same register.
5168 [(set (match_operand:DF 0 "sse_reg_operand")
5170 (match_operand:SF 1 "memory_operand")))]
5171 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
5172 && optimize_insn_for_speed_p ()"
5173 [(set (match_dup 2) (match_dup 1))
5174 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
5175 "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);")
5177 ;; Break partial SSE register dependency stall. This splitter should split
5178 ;; late in the pass sequence (after register rename pass), so allocated
5179 ;; registers won't change anymore
5182 [(set (match_operand:DF 0 "sse_reg_operand")
5184 (match_operand:SF 1 "nonimmediate_operand")))]
5186 && TARGET_SSE_PARTIAL_REG_FP_CONVERTS_DEPENDENCY
5187 && epilogue_completed
5188 && optimize_function_for_speed_p (cfun)
5189 && (!REG_P (operands[1])
5190 || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
5191 && (!EXT_REX_SSE_REG_P (operands[0])
5192 || TARGET_AVX512VL)"
5201 operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5202 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5205 (define_expand "extendhfsf2"
5206 [(set (match_operand:SF 0 "register_operand")
5208 (match_operand:HF 1 "nonimmediate_operand")))]
5209 "TARGET_AVX512FP16 || TARGET_F16C || TARGET_AVX512VL"
5211 if (!TARGET_AVX512FP16)
5213 rtx res = gen_reg_rtx (V4SFmode);
5214 rtx tmp = gen_reg_rtx (V8HFmode);
5215 rtx zero = force_reg (V8HFmode, CONST0_RTX (V8HFmode));
5217 emit_insn (gen_vec_setv8hf_0 (tmp, zero, operands[1]));
5218 emit_insn (gen_vcvtph2ps (res, gen_lowpart (V8HImode, tmp)));
5219 emit_move_insn (operands[0], gen_lowpart (SFmode, res));
5224 (define_expand "extendhfdf2"
5225 [(set (match_operand:DF 0 "register_operand")
5227 (match_operand:HF 1 "nonimmediate_operand")))]
5228 "TARGET_AVX512FP16")
5230 (define_insn "*extendhf<mode>2"
5231 [(set (match_operand:MODEF 0 "register_operand" "=v")
5233 (match_operand:HF 1 "nonimmediate_operand" "vm")))]
5235 "vcvtsh2<ssemodesuffix>\t{%1, %0, %0|%0, %0, %1}"
5236 [(set_attr "type" "ssecvt")
5237 (set_attr "prefix" "evex")
5238 (set_attr "mode" "<MODE>")])
5240 (define_expand "extendbfsf2"
5241 [(set (match_operand:SF 0 "register_operand")
5243 [(match_operand:BF 1 "register_operand")]
5245 "TARGET_SSE2 && !HONOR_NANS (BFmode)")
5247 ;; Don't use float_extend since psrlld doesn't raise
5248 ;; exceptions and turn a sNaN into a qNaN.
5249 (define_insn "extendbfsf2_1"
5250 [(set (match_operand:SF 0 "register_operand" "=x,Yv,v")
5252 [(match_operand:BF 1 "register_operand" " 0,Yv,v")]
5256 pslld\t{$16, %0|%0, 16}
5257 vpslld\t{$16, %1, %0|%0, %1, 16}
5258 vpslld\t{$16, %g1, %g0|%g0, %g1, 16}"
5259 [(set_attr "isa" "noavx,avx,*")
5260 (set_attr "type" "sseishft1")
5261 (set_attr "length_immediate" "1")
5262 (set_attr "prefix_data16" "1,*,*")
5263 (set_attr "prefix" "orig,maybe_evex,evex")
5264 (set_attr "mode" "TI,TI,XI")
5265 (set_attr "memory" "none")
5266 (set (attr "enabled")
5267 (if_then_else (eq_attr "alternative" "2")
5268 (symbol_ref "TARGET_AVX512F && !TARGET_AVX512VL
5269 && !TARGET_PREFER_AVX256")
5270 (const_string "*")))])
5272 (define_expand "extend<mode>xf2"
5273 [(set (match_operand:XF 0 "nonimmediate_operand")
5274 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
5277 /* ??? Needed for compress_float_constant since all fp constants
5278 are TARGET_LEGITIMATE_CONSTANT_P. */
5279 if (CONST_DOUBLE_P (operands[1]))
5281 if (standard_80387_constant_p (operands[1]) > 0)
5283 operands[1] = simplify_const_unary_operation
5284 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
5285 emit_move_insn_1 (operands[0], operands[1]);
5288 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
5292 (define_insn "*extend<mode>xf2_i387"
5293 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
5295 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
5297 "* return output_387_reg_move (insn, operands);"
5298 [(set_attr "type" "fmov")
5299 (set_attr "mode" "<MODE>,XF")])
5301 ;; %%% This seems like bad news.
5302 ;; This cannot output into an f-reg because there is no way to be sure
5303 ;; of truncating in that case. Otherwise this is just like a simple move
5304 ;; insn. So we pretend we can output to a reg in order to get better
5305 ;; register preferencing, but we really use a stack slot.
5307 ;; Conversion from DFmode to SFmode.
5309 (define_insn "truncdfsf2"
5310 [(set (match_operand:SF 0 "nonimm_ssenomem_operand" "=m,f,v,v")
5312 (match_operand:DF 1 "register_ssemem_operand" "f,f,v,m")))]
5313 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5315 switch (which_alternative)
5319 return output_387_reg_move (insn, operands);
5322 return "%vcvtsd2ss\t{%d1, %0|%0, %d1}";
5324 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
5330 [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
5331 (set_attr "avx_partial_xmm_update" "false,false,false,true")
5332 (set_attr "mode" "SF")
5333 (set (attr "enabled")
5335 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
5336 (cond [(eq_attr "alternative" "0")
5337 (symbol_ref "TARGET_MIX_SSE_I387")
5338 (eq_attr "alternative" "1")
5339 (symbol_ref "TARGET_MIX_SSE_I387
5340 && flag_unsafe_math_optimizations")
5342 (symbol_ref "true"))
5343 (cond [(eq_attr "alternative" "0")
5345 (eq_attr "alternative" "1")
5346 (symbol_ref "flag_unsafe_math_optimizations")
5348 (symbol_ref "false"))))])
5350 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
5352 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
5354 We do the conversion post reload to avoid producing of 128bit spills
5355 that might lead to ICE on 32bit target. The sequence unlikely combine
5358 [(set (match_operand:SF 0 "sse_reg_operand")
5360 (match_operand:DF 1 "nonimmediate_operand")))]
5361 "TARGET_USE_VECTOR_FP_CONVERTS
5362 && optimize_insn_for_speed_p ()
5364 && (!EXT_REX_SSE_REG_P (operands[0])
5365 || TARGET_AVX512VL)"
5368 (float_truncate:V2SF
5372 operands[2] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5373 operands[3] = CONST0_RTX (V2SFmode);
5374 operands[4] = lowpart_subreg (V2DFmode, operands[0], SFmode);
5375 /* Use movsd for loading from memory, unpcklpd for registers.
5376 Try to avoid move when unpacking can be done in source, or SSE3
5377 movddup is available. */
5378 if (REG_P (operands[1]))
5380 if ((!TARGET_SSE3 && REGNO (operands[0]) != REGNO (operands[1]))
5381 || (EXT_REX_SSE_REG_P (operands[1]) && !TARGET_AVX512VL))
5383 rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode);
5384 emit_move_insn (tmp, operands[1]);
5387 else if (!TARGET_SSE3)
5388 operands[4] = lowpart_subreg (V2DFmode, operands[1], DFmode);
5389 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
5392 emit_insn (gen_vec_concatv2df (operands[4], operands[1],
5393 CONST0_RTX (DFmode)));
5396 ;; It's more profitable to split and then truncate in the same register.
5398 [(set (match_operand:SF 0 "sse_reg_operand")
5400 (match_operand:DF 1 "memory_operand")))]
5401 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
5402 && optimize_insn_for_speed_p ()"
5403 [(set (match_dup 2) (match_dup 1))
5404 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
5405 "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
5407 ;; Break partial SSE register dependency stall. This splitter should split
5408 ;; late in the pass sequence (after register rename pass), so allocated
5409 ;; registers won't change anymore
5412 [(set (match_operand:SF 0 "sse_reg_operand")
5414 (match_operand:DF 1 "nonimmediate_operand")))]
5416 && TARGET_SSE_PARTIAL_REG_FP_CONVERTS_DEPENDENCY
5417 && epilogue_completed
5418 && optimize_function_for_speed_p (cfun)
5419 && (!REG_P (operands[1])
5420 || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
5421 && (!EXT_REX_SSE_REG_P (operands[0])
5422 || TARGET_AVX512VL)"
5431 operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5432 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5435 ;; Conversion from XFmode to {SF,DF}mode
5437 (define_insn "truncxf<mode>2"
5438 [(set (match_operand:MODEF 0 "nonimmediate_operand" "=m,f")
5439 (float_truncate:MODEF
5440 (match_operand:XF 1 "register_operand" "f,f")))]
5442 "* return output_387_reg_move (insn, operands);"
5443 [(set_attr "type" "fmov")
5444 (set_attr "mode" "<MODE>")
5445 (set (attr "enabled")
5446 (cond [(eq_attr "alternative" "1")
5447 (symbol_ref "flag_unsafe_math_optimizations")
5449 (symbol_ref "true")))])
5451 ;; Conversion from {SF,DF}mode to HFmode.
5453 (define_expand "truncsfhf2"
5454 [(set (match_operand:HF 0 "register_operand")
5456 (match_operand:SF 1 "nonimmediate_operand")))]
5457 "TARGET_AVX512FP16 || TARGET_F16C || TARGET_AVX512VL"
5459 if (!TARGET_AVX512FP16)
5461 rtx res = gen_reg_rtx (V8HFmode);
5462 rtx tmp = gen_reg_rtx (V4SFmode);
5463 rtx zero = force_reg (V4SFmode, CONST0_RTX (V4SFmode));
5465 emit_insn (gen_vec_setv4sf_0 (tmp, zero, operands[1]));
5466 emit_insn (gen_vcvtps2ph (gen_lowpart (V8HImode, res), tmp, GEN_INT (4)));
5467 emit_move_insn (operands[0], gen_lowpart (HFmode, res));
5472 (define_expand "truncdfhf2"
5473 [(set (match_operand:HF 0 "register_operand")
5475 (match_operand:DF 1 "nonimmediate_operand")))]
5476 "TARGET_AVX512FP16")
5478 (define_insn "*trunc<mode>hf2"
5479 [(set (match_operand:HF 0 "register_operand" "=v")
5481 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5483 "vcvt<ssemodesuffix>2sh\t{%1, %d0|%d0, %1}"
5484 [(set_attr "type" "ssecvt")
5485 (set_attr "prefix" "evex")
5486 (set_attr "mode" "HF")])
5488 (define_insn "truncsfbf2"
5489 [(set (match_operand:BF 0 "register_operand" "=x, v")
5491 (match_operand:SF 1 "register_operand" "x,v")))]
5492 "((TARGET_AVX512BF16 && TARGET_AVX512VL) || TARGET_AVXNECONVERT)
5493 && !HONOR_NANS (BFmode) && flag_unsafe_math_optimizations"
5495 %{vex%} vcvtneps2bf16\t{%1, %0|%0, %1}
5496 vcvtneps2bf16\t{%1, %0|%0, %1}"
5497 [(set_attr "isa" "avxneconvert,avx512bf16vl")
5498 (set_attr "prefix" "vex,evex")])
5500 ;; Signed conversion to DImode.
5502 (define_expand "fix_truncxfdi2"
5503 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
5504 (fix:DI (match_operand:XF 1 "register_operand")))
5505 (clobber (reg:CC FLAGS_REG))])]
5510 emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
5515 (define_expand "fix_trunc<mode>di2"
5516 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
5517 (fix:DI (match_operand:MODEF 1 "register_operand")))
5518 (clobber (reg:CC FLAGS_REG))])]
5519 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
5522 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
5524 emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
5527 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
5529 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
5530 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
5531 if (out != operands[0])
5532 emit_move_insn (operands[0], out);
5537 (define_insn "fix<fixunssuffix>_trunchf<mode>2"
5538 [(set (match_operand:SWI48 0 "register_operand" "=r")
5540 (match_operand:HF 1 "nonimmediate_operand" "vm")))]
5542 "vcvttsh2<fixsuffix>si\t{%1, %0|%0, %1}"
5543 [(set_attr "type" "sseicvt")
5544 (set_attr "prefix" "evex")
5545 (set_attr "mode" "<MODE>")])
5547 ;; Signed conversion to SImode.
5549 (define_expand "fix_truncxfsi2"
5550 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
5551 (fix:SI (match_operand:XF 1 "register_operand")))
5552 (clobber (reg:CC FLAGS_REG))])]
5557 emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
5562 (define_expand "fix_trunc<mode>si2"
5563 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
5564 (fix:SI (match_operand:MODEF 1 "register_operand")))
5565 (clobber (reg:CC FLAGS_REG))])]
5566 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
5569 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
5571 emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
5574 if (SSE_FLOAT_MODE_P (<MODE>mode))
5576 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
5577 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
5578 if (out != operands[0])
5579 emit_move_insn (operands[0], out);
5584 ;; Signed conversion to HImode.
5586 (define_expand "fix_trunc<mode>hi2"
5587 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
5588 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
5589 (clobber (reg:CC FLAGS_REG))])]
5591 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
5595 emit_insn (gen_fix_trunchi_i387_fisttp (operands[0], operands[1]));
5600 ;; Unsigned conversion to DImode
5602 (define_insn "fixuns_trunc<mode>di2"
5603 [(set (match_operand:DI 0 "register_operand" "=r")
5605 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5606 "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
5607 "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
5608 [(set_attr "type" "sseicvt")
5609 (set_attr "prefix" "evex")
5610 (set_attr "mode" "DI")])
5612 ;; Unsigned conversion to SImode.
5614 (define_expand "fixuns_trunc<mode>si2"
5616 [(set (match_operand:SI 0 "register_operand")
5618 (match_operand:MODEF 1 "nonimmediate_operand")))
5620 (clobber (scratch:<ssevecmode>))
5621 (clobber (scratch:<ssevecmode>))])]
5622 "(!TARGET_64BIT || TARGET_AVX512F) && TARGET_SSE2 && TARGET_SSE_MATH"
5624 machine_mode mode = <MODE>mode;
5625 machine_mode vecmode = <ssevecmode>mode;
5626 REAL_VALUE_TYPE TWO31r;
5631 emit_insn (gen_fixuns_trunc<mode>si2_avx512f (operands[0], operands[1]));
5635 if (optimize_insn_for_size_p ())
5638 real_ldexp (&TWO31r, &dconst1, 31);
5639 two31 = const_double_from_real_value (TWO31r, mode);
5640 two31 = ix86_build_const_vector (vecmode, true, two31);
5641 operands[2] = force_reg (vecmode, two31);
5644 (define_insn "fixuns_trunc<mode>si2_avx512f"
5645 [(set (match_operand:SI 0 "register_operand" "=r")
5647 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5648 "TARGET_AVX512F && TARGET_SSE_MATH"
5649 "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
5650 [(set_attr "type" "sseicvt")
5651 (set_attr "prefix" "evex")
5652 (set_attr "mode" "SI")])
5654 (define_insn "*fixuns_trunchfsi2zext"
5655 [(set (match_operand:DI 0 "register_operand" "=r")
5658 (match_operand:HF 1 "nonimmediate_operand" "vm"))))]
5659 "TARGET_64BIT && TARGET_AVX512FP16"
5660 "vcvttsh2usi\t{%1, %k0|%k0, %1}"
5661 [(set_attr "type" "sseicvt")
5662 (set_attr "prefix" "evex")
5663 (set_attr "mode" "SI")])
5665 (define_insn "*fixuns_trunc<mode>si2_avx512f_zext"
5666 [(set (match_operand:DI 0 "register_operand" "=r")
5669 (match_operand:MODEF 1 "nonimmediate_operand" "vm"))))]
5670 "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
5671 "vcvtt<ssemodesuffix>2usi\t{%1, %k0|%k0, %1}"
5672 [(set_attr "type" "sseicvt")
5673 (set_attr "prefix" "evex")
5674 (set_attr "mode" "SI")])
5676 (define_insn_and_split "*fixuns_trunc<mode>_1"
5677 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
5679 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
5680 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
5681 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
5682 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
5683 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5684 && optimize_function_for_speed_p (cfun)"
5686 "&& reload_completed"
5689 ix86_split_convert_uns_si_sse (operands);
5693 ;; Unsigned conversion to HImode.
5694 ;; Without these patterns, we'll try the unsigned SI conversion which
5695 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
5697 (define_expand "fixuns_trunchfhi2"
5699 (fix:SI (match_operand:HF 1 "nonimmediate_operand")))
5700 (set (match_operand:HI 0 "nonimmediate_operand")
5701 (subreg:HI (match_dup 2) 0))]
5703 "operands[2] = gen_reg_rtx (SImode);")
5705 (define_expand "fixuns_trunc<mode>hi2"
5707 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
5708 (set (match_operand:HI 0 "nonimmediate_operand")
5709 (subreg:HI (match_dup 2) 0))]
5710 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
5711 "operands[2] = gen_reg_rtx (SImode);")
5713 ;; When SSE is available, it is always faster to use it!
5714 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
5715 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
5716 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
5717 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5718 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
5719 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
5720 [(set_attr "type" "sseicvt")
5721 (set_attr "prefix" "maybe_vex")
5722 (set (attr "prefix_rex")
5724 (match_test "<SWI48:MODE>mode == DImode")
5726 (const_string "*")))
5727 (set_attr "mode" "<MODEF:MODE>")
5728 (set_attr "athlon_decode" "double,vector")
5729 (set_attr "amdfam10_decode" "double,double")
5730 (set_attr "bdver1_decode" "double,double")])
5732 ;; Avoid vector decoded forms of the instruction.
5734 [(match_scratch:MODEF 2 "x")
5735 (set (match_operand:SWI48 0 "register_operand")
5736 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
5737 "TARGET_AVOID_VECTOR_DECODE
5738 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5739 && optimize_insn_for_speed_p ()"
5740 [(set (match_dup 2) (match_dup 1))
5741 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
5743 (define_insn "fix_trunc<mode>_i387_fisttp"
5744 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m")
5745 (fix:SWI248x (match_operand 1 "register_operand" "f")))
5746 (clobber (match_scratch:XF 2 "=&f"))]
5747 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5749 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5750 && (TARGET_64BIT || <MODE>mode != DImode))
5751 && TARGET_SSE_MATH)"
5752 "* return output_fix_trunc (insn, operands, true);"
5753 [(set_attr "type" "fisttp")
5754 (set_attr "mode" "<MODE>")])
5756 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5757 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5758 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5759 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5760 ;; function in i386.cc.
5761 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5762 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
5763 (fix:SWI248x (match_operand 1 "register_operand")))
5764 (clobber (reg:CC FLAGS_REG))]
5765 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5767 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5768 && (TARGET_64BIT || <MODE>mode != DImode))
5769 && ix86_pre_reload_split ()"
5774 ix86_optimize_mode_switching[I387_TRUNC] = 1;
5776 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5777 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5779 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5780 operands[2], operands[3]));
5783 [(set_attr "type" "fistp")
5784 (set_attr "i387_cw" "trunc")
5785 (set_attr "mode" "<MODE>")])
5787 (define_insn "fix_truncdi_i387"
5788 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
5789 (fix:DI (match_operand 1 "register_operand" "f")))
5790 (use (match_operand:HI 2 "memory_operand" "m"))
5791 (use (match_operand:HI 3 "memory_operand" "m"))
5792 (clobber (match_scratch:XF 4 "=&f"))]
5793 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5795 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5796 "* return output_fix_trunc (insn, operands, false);"
5797 [(set_attr "type" "fistp")
5798 (set_attr "i387_cw" "trunc")
5799 (set_attr "mode" "DI")])
5801 (define_insn "fix_trunc<mode>_i387"
5802 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
5803 (fix:SWI24 (match_operand 1 "register_operand" "f")))
5804 (use (match_operand:HI 2 "memory_operand" "m"))
5805 (use (match_operand:HI 3 "memory_operand" "m"))]
5806 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5808 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5809 "* return output_fix_trunc (insn, operands, false);"
5810 [(set_attr "type" "fistp")
5811 (set_attr "i387_cw" "trunc")
5812 (set_attr "mode" "<MODE>")])
5814 (define_insn "x86_fnstcw_1"
5815 [(set (match_operand:HI 0 "memory_operand" "=m")
5816 (unspec:HI [(const_int 0)] UNSPEC_FSTCW))]
5819 [(set (attr "length")
5820 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5821 (set_attr "mode" "HI")
5822 (set_attr "unit" "i387")
5823 (set_attr "bdver1_decode" "vector")])
5825 ;; Conversion between fixed point and floating point.
5827 ;; Even though we only accept memory inputs, the backend _really_
5828 ;; wants to be able to do this between registers. Thankfully, LRA
5829 ;; will fix this up for us during register allocation.
5831 (define_insn "floathi<mode>2"
5832 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5833 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
5835 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5836 || TARGET_MIX_SSE_I387)"
5838 [(set_attr "type" "fmov")
5839 (set_attr "mode" "<MODE>")
5840 (set_attr "znver1_decode" "double")
5841 (set_attr "fp_int_src" "true")])
5843 (define_insn "float<SWI48x:mode>xf2"
5844 [(set (match_operand:XF 0 "register_operand" "=f")
5845 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5848 [(set_attr "type" "fmov")
5849 (set_attr "mode" "XF")
5850 (set_attr "znver1_decode" "double")
5851 (set_attr "fp_int_src" "true")])
5853 (define_expand "float<SWI48x:mode><MODEF:mode>2"
5854 [(set (match_operand:MODEF 0 "register_operand")
5855 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand")))]
5856 "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode))
5857 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5858 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT))")
5860 (define_insn "*float<SWI48:mode><MODEF:mode>2"
5861 [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
5863 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
5864 "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
5865 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
5868 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
5869 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5870 [(set_attr "type" "fmov,sseicvt,sseicvt")
5871 (set_attr "avx_partial_xmm_update" "false,true,true")
5872 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5873 (set_attr "mode" "<MODEF:MODE>")
5874 (set (attr "prefix_rex")
5876 (and (eq_attr "prefix" "maybe_vex")
5877 (match_test "<SWI48:MODE>mode == DImode"))
5879 (const_string "*")))
5880 (set_attr "unit" "i387,*,*")
5881 (set_attr "athlon_decode" "*,double,direct")
5882 (set_attr "amdfam10_decode" "*,vector,double")
5883 (set_attr "bdver1_decode" "*,double,direct")
5884 (set_attr "znver1_decode" "double,*,*")
5885 (set_attr "fp_int_src" "true")
5886 (set (attr "enabled")
5888 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
5890 (eq_attr "alternative" "0")
5891 (symbol_ref "TARGET_MIX_SSE_I387
5892 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
5894 (symbol_ref "true"))
5896 (eq_attr "alternative" "0")
5898 (symbol_ref "false"))))
5899 (set (attr "preferred_for_speed")
5900 (cond [(eq_attr "alternative" "1")
5901 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
5902 (symbol_ref "true")))])
5904 (define_insn "float<floatunssuffix><mode>hf2"
5905 [(set (match_operand:HF 0 "register_operand" "=v")
5907 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
5909 "vcvt<floatsuffix>si2sh<rex64suffix>\t{%1, %d0|%d0, %1}"
5910 [(set_attr "type" "sseicvt")
5911 (set_attr "prefix" "evex")
5912 (set_attr "mode" "HF")])
5914 (define_insn "*floatdi<MODEF:mode>2_i387"
5915 [(set (match_operand:MODEF 0 "register_operand" "=f")
5916 (float:MODEF (match_operand:DI 1 "nonimmediate_operand" "m")))]
5918 && TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, DImode)"
5920 [(set_attr "type" "fmov")
5921 (set_attr "mode" "<MODEF:MODE>")
5922 (set_attr "znver1_decode" "double")
5923 (set_attr "fp_int_src" "true")])
5925 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
5926 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
5927 ;; alternative in sse2_loadld.
5929 [(set (match_operand:MODEF 0 "sse_reg_operand")
5930 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5932 && TARGET_USE_VECTOR_CONVERTS
5933 && optimize_function_for_speed_p (cfun)
5935 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
5936 && (!EXT_REX_SSE_REG_P (operands[0])
5937 || TARGET_AVX512VL)"
5940 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode);
5941 operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode);
5943 emit_insn (gen_sse2_loadld (operands[4],
5944 CONST0_RTX (V4SImode), operands[1]));
5946 if (<ssevecmode>mode == V4SFmode)
5947 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5949 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5953 ;; Avoid store forwarding (partial memory) stall penalty
5954 ;; by passing DImode value through XMM registers. */
5957 [(set (match_operand:X87MODEF 0 "register_operand")
5959 (match_operand:DI 1 "register_operand")))]
5960 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
5961 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5962 && TARGET_SSE2 && optimize_function_for_speed_p (cfun)
5963 && can_create_pseudo_p ()"
5966 rtx s = assign_386_stack_local (DImode, SLOT_FLOATxFDI_387);
5967 emit_insn (gen_floatdi<mode>2_i387_with_xmm (operands[0], operands[1], s));
5971 (define_insn_and_split "floatdi<X87MODEF:mode>2_i387_with_xmm"
5972 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5974 (match_operand:DI 1 "register_operand" "r,r")))
5975 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5976 (clobber (match_scratch:V4SI 3 "=x,x"))
5977 (clobber (match_scratch:V4SI 4 "=X,x"))]
5978 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
5979 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5980 && TARGET_SSE2 && optimize_function_for_speed_p (cfun)"
5982 "&& reload_completed"
5983 [(set (match_dup 2) (match_dup 3))
5984 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5986 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5987 Assemble the 64-bit DImode value in an xmm register. */
5988 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5989 gen_lowpart (SImode, operands[1])));
5991 emit_insn (gen_sse4_1_pinsrd (operands[3], operands[3],
5992 gen_highpart (SImode, operands[1]),
5996 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5997 gen_highpart (SImode, operands[1])));
5998 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
6001 operands[3] = gen_lowpart (DImode, operands[3]);
6003 [(set_attr "isa" "sse4,*")
6004 (set_attr "type" "multi")
6005 (set_attr "mode" "<X87MODEF:MODE>")
6006 (set_attr "unit" "i387")
6007 (set_attr "fp_int_src" "true")])
6009 ;; Break partial SSE register dependency stall. This splitter should split
6010 ;; late in the pass sequence (after register rename pass), so allocated
6011 ;; registers won't change anymore
6014 [(set (match_operand:MODEF 0 "sse_reg_operand")
6015 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
6017 && TARGET_SSE_PARTIAL_REG_CONVERTS_DEPENDENCY
6018 && epilogue_completed
6019 && optimize_function_for_speed_p (cfun)
6020 && (!EXT_REX_SSE_REG_P (operands[0])
6021 || TARGET_AVX512VL)"
6023 (vec_merge:<MODEF:ssevecmode>
6024 (vec_duplicate:<MODEF:ssevecmode>
6030 const machine_mode vmode = <MODEF:ssevecmode>mode;
6032 operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode);
6033 emit_move_insn (operands[0], CONST0_RTX (vmode));
6036 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
6037 [(set (match_operand:MODEF 0 "register_operand")
6038 (unsigned_float:MODEF
6039 (match_operand:SWI12 1 "nonimmediate_operand")))]
6041 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
6043 operands[1] = convert_to_mode (SImode, operands[1], 1);
6044 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
6048 (define_insn "*floatuns<SWI48:mode><MODEF:mode>2_avx512"
6049 [(set (match_operand:MODEF 0 "register_operand" "=v")
6050 (unsigned_float:MODEF
6051 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
6052 "TARGET_AVX512F && TARGET_SSE_MATH"
6053 "vcvtusi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %0, %0|%0, %0, %1}"
6054 [(set_attr "type" "sseicvt")
6055 (set_attr "avx_partial_xmm_update" "true")
6056 (set_attr "prefix" "evex")
6057 (set_attr "mode" "<MODEF:MODE>")])
6059 ;; Avoid store forwarding (partial memory) stall penalty by extending
6060 ;; SImode value to DImode through XMM register instead of pushing two
6061 ;; SImode values to stack. Also note that fild loads from memory only.
6063 (define_insn_and_split "floatunssi<mode>2_i387_with_xmm"
6064 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
6065 (unsigned_float:X87MODEF
6066 (match_operand:SI 1 "nonimmediate_operand" "rm")))
6067 (clobber (match_operand:DI 2 "memory_operand" "=m"))
6068 (clobber (match_scratch:DI 3 "=x"))]
6070 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6071 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
6073 "&& reload_completed"
6074 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
6075 (set (match_dup 2) (match_dup 3))
6077 (float:X87MODEF (match_dup 2)))]
6079 [(set_attr "type" "multi")
6080 (set_attr "mode" "<MODE>")])
6082 (define_expand "floatunssi<mode>2"
6083 [(set (match_operand:X87MODEF 0 "register_operand")
6084 (unsigned_float:X87MODEF
6085 (match_operand:SI 1 "nonimmediate_operand")))]
6087 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6088 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
6089 || ((!TARGET_64BIT || TARGET_AVX512F)
6090 && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
6092 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
6094 emit_insn (gen_floatunssi<mode>2_i387_with_xmm
6095 (operands[0], operands[1],
6096 assign_386_stack_local (DImode, SLOT_TEMP)));
6099 if (!TARGET_AVX512F)
6101 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
6106 (define_expand "floatunsdisf2"
6107 [(set (match_operand:SF 0 "register_operand")
6109 (match_operand:DI 1 "nonimmediate_operand")))]
6110 "TARGET_64BIT && TARGET_SSE && TARGET_SSE_MATH"
6112 if (!TARGET_AVX512F)
6114 x86_emit_floatuns (operands);
6119 (define_expand "floatunsdidf2"
6120 [(set (match_operand:DF 0 "register_operand")
6122 (match_operand:DI 1 "nonimmediate_operand")))]
6123 "((TARGET_64BIT && TARGET_AVX512F)
6124 || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
6125 && TARGET_SSE2 && TARGET_SSE_MATH"
6129 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
6132 if (!TARGET_AVX512F)
6134 x86_emit_floatuns (operands);
6139 ;; Load effective address instructions
6141 (define_insn "*lea<mode>"
6142 [(set (match_operand:SWI48 0 "register_operand" "=r")
6143 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
6144 "ix86_hardreg_mov_ok (operands[0], operands[1])"
6146 if (SImode_address_operand (operands[1], VOIDmode))
6148 gcc_assert (TARGET_64BIT);
6149 return "lea{l}\t{%E1, %k0|%k0, %E1}";
6152 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
6154 [(set_attr "type" "lea")
6157 (match_operand 1 "SImode_address_operand")
6159 (const_string "<MODE>")))])
6162 [(set (match_operand:SWI48 0 "register_operand")
6163 (match_operand:SWI48 1 "address_no_seg_operand"))]
6164 "ix86_hardreg_mov_ok (operands[0], operands[1])
6165 && peep2_regno_dead_p (0, FLAGS_REG)
6166 && ix86_avoid_lea_for_addr (peep2_next_insn (0), operands)"
6169 machine_mode mode = <MODE>mode;
6171 /* Emit all operations in SImode for zero-extended addresses. */
6172 if (SImode_address_operand (operands[1], VOIDmode))
6175 ix86_split_lea_for_addr (peep2_next_insn (0), operands, mode);
6177 /* Zero-extend return register to DImode for zero-extended addresses. */
6178 if (mode != <MODE>mode)
6179 emit_insn (gen_zero_extendsidi2 (operands[0],
6180 gen_lowpart (mode, operands[0])));
6185 ;; ix86_split_lea_for_addr emits the shifts as MULT to avoid it from being
6186 ;; peephole2 optimized back into a lea. Split that into the shift during
6187 ;; the following split pass.
6189 [(set (match_operand:SWI48 0 "general_reg_operand")
6190 (mult:SWI48 (match_dup 0) (match_operand:SWI48 1 "const1248_operand")))
6191 (clobber (reg:CC FLAGS_REG))]
6193 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
6194 (clobber (reg:CC FLAGS_REG))])]
6195 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
6199 (define_expand "add<mode>3"
6200 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6201 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6202 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
6204 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
6206 (define_insn_and_split "*add<dwi>3_doubleword"
6207 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
6209 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
6210 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
6211 (clobber (reg:CC FLAGS_REG))]
6212 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
6214 "&& reload_completed"
6215 [(parallel [(set (reg:CCC FLAGS_REG)
6217 (plus:DWIH (match_dup 1) (match_dup 2))
6220 (plus:DWIH (match_dup 1) (match_dup 2)))])
6221 (parallel [(set (match_dup 3)
6224 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6227 (clobber (reg:CC FLAGS_REG))])]
6229 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6230 if (operands[2] == const0_rtx)
6232 if (operands[5] != const0_rtx)
6233 ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]);
6234 else if (!rtx_equal_p (operands[3], operands[4]))
6235 emit_move_insn (operands[3], operands[4]);
6237 emit_note (NOTE_INSN_DELETED);
6242 (define_insn_and_split "*add<dwi>3_doubleword_zext"
6243 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6246 (match_operand:DWIH 2 "nonimmediate_operand" "rm,r"))
6247 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")))
6248 (clobber (reg:CC FLAGS_REG))]
6249 "ix86_binary_operator_ok (UNKNOWN, <DWI>mode, operands)"
6251 "&& reload_completed"
6252 [(parallel [(set (reg:CCC FLAGS_REG)
6254 (plus:DWIH (match_dup 1) (match_dup 2))
6257 (plus:DWIH (match_dup 1) (match_dup 2)))])
6258 (parallel [(set (match_dup 3)
6261 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6264 (clobber (reg:CC FLAGS_REG))])]
6265 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[3]);")
6267 (define_insn_and_split "*add<dwi>3_doubleword_concat"
6268 [(set (match_operand:<DWI> 0 "register_operand" "=&r")
6273 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))
6274 (match_operand:QI 3 "const_int_operand"))
6276 (match_operand:DWIH 4 "nonimmediate_operand" "rm")))
6277 (match_operand:<DWI> 1 "register_operand" "0")))
6278 (clobber (reg:CC FLAGS_REG))]
6279 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
6281 "&& reload_completed"
6282 [(parallel [(set (reg:CCC FLAGS_REG)
6284 (plus:DWIH (match_dup 1) (match_dup 4))
6287 (plus:DWIH (match_dup 1) (match_dup 4)))])
6288 (parallel [(set (match_dup 5)
6291 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6294 (clobber (reg:CC FLAGS_REG))])]
6295 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[5]);")
6297 (define_insn "*add<mode>_1"
6298 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,r")
6300 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
6301 (match_operand:SWI48 2 "x86_64_general_operand" "re,BM,0,le")))
6302 (clobber (reg:CC FLAGS_REG))]
6303 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6305 switch (get_attr_type (insn))
6311 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6312 if (operands[2] == const1_rtx)
6313 return "inc{<imodesuffix>}\t%0";
6316 gcc_assert (operands[2] == constm1_rtx);
6317 return "dec{<imodesuffix>}\t%0";
6321 /* For most processors, ADD is faster than LEA. This alternative
6322 was added to use ADD as much as possible. */
6323 if (which_alternative == 2)
6324 std::swap (operands[1], operands[2]);
6326 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6327 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6328 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6330 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6334 (cond [(eq_attr "alternative" "3")
6335 (const_string "lea")
6336 (match_operand:SWI48 2 "incdec_operand")
6337 (const_string "incdec")
6339 (const_string "alu")))
6340 (set (attr "length_immediate")
6342 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6344 (const_string "*")))
6345 (set_attr "mode" "<MODE>")])
6347 ;; It may seem that nonimmediate operand is proper one for operand 1.
6348 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6349 ;; we take care in ix86_binary_operator_ok to not allow two memory
6350 ;; operands so proper swapping will be done in reload. This allow
6351 ;; patterns constructed from addsi_1 to match.
6353 (define_insn "addsi_1_zext"
6354 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6356 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
6357 (match_operand:SI 2 "x86_64_general_operand" "rBMe,0,le"))))
6358 (clobber (reg:CC FLAGS_REG))]
6359 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6361 switch (get_attr_type (insn))
6367 if (operands[2] == const1_rtx)
6368 return "inc{l}\t%k0";
6371 gcc_assert (operands[2] == constm1_rtx);
6372 return "dec{l}\t%k0";
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 == 1)
6379 std::swap (operands[1], operands[2]);
6381 if (x86_maybe_negate_const_int (&operands[2], SImode))
6382 return "sub{l}\t{%2, %k0|%k0, %2}";
6384 return "add{l}\t{%2, %k0|%k0, %2}";
6388 (cond [(eq_attr "alternative" "2")
6389 (const_string "lea")
6390 (match_operand:SI 2 "incdec_operand")
6391 (const_string "incdec")
6393 (const_string "alu")))
6394 (set (attr "length_immediate")
6396 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6398 (const_string "*")))
6399 (set_attr "mode" "SI")])
6401 (define_insn "*addhi_1"
6402 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
6403 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
6404 (match_operand:HI 2 "general_operand" "rn,m,0,ln")))
6405 (clobber (reg:CC FLAGS_REG))]
6406 "ix86_binary_operator_ok (PLUS, HImode, operands)"
6408 switch (get_attr_type (insn))
6414 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6415 if (operands[2] == const1_rtx)
6416 return "inc{w}\t%0";
6419 gcc_assert (operands[2] == constm1_rtx);
6420 return "dec{w}\t%0";
6424 /* For most processors, ADD is faster than LEA. This alternative
6425 was added to use ADD as much as possible. */
6426 if (which_alternative == 2)
6427 std::swap (operands[1], operands[2]);
6429 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6430 if (x86_maybe_negate_const_int (&operands[2], HImode))
6431 return "sub{w}\t{%2, %0|%0, %2}";
6433 return "add{w}\t{%2, %0|%0, %2}";
6437 (cond [(eq_attr "alternative" "3")
6438 (const_string "lea")
6439 (match_operand:HI 2 "incdec_operand")
6440 (const_string "incdec")
6442 (const_string "alu")))
6443 (set (attr "length_immediate")
6445 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6447 (const_string "*")))
6448 (set_attr "mode" "HI,HI,HI,SI")])
6450 (define_insn "*addqi_1"
6451 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
6452 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
6453 (match_operand:QI 2 "general_operand" "qn,m,0,rn,0,ln")))
6454 (clobber (reg:CC FLAGS_REG))]
6455 "ix86_binary_operator_ok (PLUS, QImode, operands)"
6457 bool widen = (get_attr_mode (insn) != MODE_QI);
6459 switch (get_attr_type (insn))
6465 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6466 if (operands[2] == const1_rtx)
6467 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6470 gcc_assert (operands[2] == constm1_rtx);
6471 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6475 /* For most processors, ADD is faster than LEA. These alternatives
6476 were added to use ADD as much as possible. */
6477 if (which_alternative == 2 || which_alternative == 4)
6478 std::swap (operands[1], operands[2]);
6480 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6481 if (x86_maybe_negate_const_int (&operands[2], QImode))
6484 return "sub{l}\t{%2, %k0|%k0, %2}";
6486 return "sub{b}\t{%2, %0|%0, %2}";
6489 return "add{l}\t{%k2, %k0|%k0, %k2}";
6491 return "add{b}\t{%2, %0|%0, %2}";
6495 (cond [(eq_attr "alternative" "5")
6496 (const_string "lea")
6497 (match_operand:QI 2 "incdec_operand")
6498 (const_string "incdec")
6500 (const_string "alu")))
6501 (set (attr "length_immediate")
6503 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6505 (const_string "*")))
6506 (set_attr "mode" "QI,QI,QI,SI,SI,SI")
6507 ;; Potential partial reg stall on alternatives 3 and 4.
6508 (set (attr "preferred_for_speed")
6509 (cond [(eq_attr "alternative" "3,4")
6510 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
6511 (symbol_ref "true")))])
6513 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
6514 (define_insn_and_split "*add<mode>_1_slp"
6515 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
6516 (plus:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0,!<r>")
6517 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
6518 (clobber (reg:CC FLAGS_REG))]
6519 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6521 if (which_alternative)
6524 switch (get_attr_type (insn))
6527 if (operands[2] == const1_rtx)
6528 return "inc{<imodesuffix>}\t%0";
6531 gcc_assert (operands[2] == constm1_rtx);
6532 return "dec{<imodesuffix>}\t%0";
6536 if (x86_maybe_negate_const_int (&operands[2], QImode))
6537 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6539 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6542 "&& reload_completed"
6543 [(set (strict_low_part (match_dup 0)) (match_dup 1))
6545 [(set (strict_low_part (match_dup 0))
6546 (plus:SWI12 (match_dup 0) (match_dup 2)))
6547 (clobber (reg:CC FLAGS_REG))])]
6550 (if_then_else (match_operand:QI 2 "incdec_operand")
6551 (const_string "incdec")
6552 (const_string "alu")))
6553 (set_attr "mode" "<MODE>")])
6555 ;; Split non destructive adds if we cannot use lea.
6557 [(set (match_operand:SWI48 0 "register_operand")
6558 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
6559 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
6560 (clobber (reg:CC FLAGS_REG))]
6561 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
6562 [(set (match_dup 0) (match_dup 1))
6563 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
6564 (clobber (reg:CC FLAGS_REG))])])
6566 ;; Split non destructive adds if we cannot use lea.
6568 [(set (match_operand:DI 0 "register_operand")
6570 (plus:SI (match_operand:SI 1 "register_operand")
6571 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
6572 (clobber (reg:CC FLAGS_REG))]
6574 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
6575 [(set (match_dup 3) (match_dup 1))
6576 (parallel [(set (match_dup 0)
6577 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
6578 (clobber (reg:CC FLAGS_REG))])]
6579 "operands[3] = gen_lowpart (SImode, operands[0]);")
6581 ;; Convert add to the lea pattern to avoid flags dependency.
6583 [(set (match_operand:SWI 0 "register_operand")
6584 (plus:SWI (match_operand:SWI 1 "register_operand")
6585 (match_operand:SWI 2 "<nonmemory_operand>")))
6586 (clobber (reg:CC FLAGS_REG))]
6587 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
6589 (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
6591 if (<MODE>mode != <LEAMODE>mode)
6593 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
6594 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
6595 operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
6599 ;; Convert add to the lea pattern to avoid flags dependency.
6601 [(set (match_operand:DI 0 "register_operand")
6603 (plus:SI (match_operand:SI 1 "register_operand")
6604 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
6605 (clobber (reg:CC FLAGS_REG))]
6606 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
6608 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
6610 (define_insn "*add<mode>_2"
6611 [(set (reg FLAGS_REG)
6614 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
6615 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,0"))
6617 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,<r>")
6618 (plus:SWI (match_dup 1) (match_dup 2)))]
6619 "ix86_match_ccmode (insn, CCGOCmode)
6620 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6622 switch (get_attr_type (insn))
6625 if (operands[2] == const1_rtx)
6626 return "inc{<imodesuffix>}\t%0";
6629 gcc_assert (operands[2] == constm1_rtx);
6630 return "dec{<imodesuffix>}\t%0";
6634 if (which_alternative == 2)
6635 std::swap (operands[1], operands[2]);
6637 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6638 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6639 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6641 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6645 (if_then_else (match_operand:SWI 2 "incdec_operand")
6646 (const_string "incdec")
6647 (const_string "alu")))
6648 (set (attr "length_immediate")
6650 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6652 (const_string "*")))
6653 (set_attr "mode" "<MODE>")])
6655 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6656 (define_insn "*addsi_2_zext"
6657 [(set (reg FLAGS_REG)
6659 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6660 (match_operand:SI 2 "x86_64_general_operand" "rBMe,0"))
6662 (set (match_operand:DI 0 "register_operand" "=r,r")
6663 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6664 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6665 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6667 switch (get_attr_type (insn))
6670 if (operands[2] == const1_rtx)
6671 return "inc{l}\t%k0";
6674 gcc_assert (operands[2] == constm1_rtx);
6675 return "dec{l}\t%k0";
6679 if (which_alternative == 1)
6680 std::swap (operands[1], operands[2]);
6682 if (x86_maybe_negate_const_int (&operands[2], SImode))
6683 return "sub{l}\t{%2, %k0|%k0, %2}";
6685 return "add{l}\t{%2, %k0|%k0, %2}";
6689 (if_then_else (match_operand:SI 2 "incdec_operand")
6690 (const_string "incdec")
6691 (const_string "alu")))
6692 (set (attr "length_immediate")
6694 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6696 (const_string "*")))
6697 (set_attr "mode" "SI")])
6699 (define_insn "*add<mode>_3"
6700 [(set (reg FLAGS_REG)
6702 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6703 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
6704 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6705 "ix86_match_ccmode (insn, CCZmode)
6706 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6708 switch (get_attr_type (insn))
6711 if (operands[2] == const1_rtx)
6712 return "inc{<imodesuffix>}\t%0";
6715 gcc_assert (operands[2] == constm1_rtx);
6716 return "dec{<imodesuffix>}\t%0";
6720 if (which_alternative == 1)
6721 std::swap (operands[1], operands[2]);
6723 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6724 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6725 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6727 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6731 (if_then_else (match_operand:SWI 2 "incdec_operand")
6732 (const_string "incdec")
6733 (const_string "alu")))
6734 (set (attr "length_immediate")
6736 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6738 (const_string "*")))
6739 (set_attr "mode" "<MODE>")])
6741 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6742 (define_insn "*addsi_3_zext"
6743 [(set (reg FLAGS_REG)
6745 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rBMe,0"))
6746 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
6747 (set (match_operand:DI 0 "register_operand" "=r,r")
6748 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6749 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6750 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6752 switch (get_attr_type (insn))
6755 if (operands[2] == const1_rtx)
6756 return "inc{l}\t%k0";
6759 gcc_assert (operands[2] == constm1_rtx);
6760 return "dec{l}\t%k0";
6764 if (which_alternative == 1)
6765 std::swap (operands[1], operands[2]);
6767 if (x86_maybe_negate_const_int (&operands[2], SImode))
6768 return "sub{l}\t{%2, %k0|%k0, %2}";
6770 return "add{l}\t{%2, %k0|%k0, %2}";
6774 (if_then_else (match_operand:SI 2 "incdec_operand")
6775 (const_string "incdec")
6776 (const_string "alu")))
6777 (set (attr "length_immediate")
6779 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6781 (const_string "*")))
6782 (set_attr "mode" "SI")])
6784 ; For comparisons against 1, -1 and 128, we may generate better code
6785 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6786 ; is matched then. We can't accept general immediate, because for
6787 ; case of overflows, the result is messed up.
6788 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6789 ; only for comparisons not depending on it.
6791 (define_insn "*adddi_4"
6792 [(set (reg FLAGS_REG)
6794 (match_operand:DI 1 "nonimmediate_operand" "0")
6795 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6796 (clobber (match_scratch:DI 0 "=r"))]
6798 && ix86_match_ccmode (insn, CCGCmode)"
6800 switch (get_attr_type (insn))
6803 if (operands[2] == constm1_rtx)
6804 return "inc{q}\t%0";
6807 gcc_assert (operands[2] == const1_rtx);
6808 return "dec{q}\t%0";
6812 if (x86_maybe_negate_const_int (&operands[2], DImode))
6813 return "add{q}\t{%2, %0|%0, %2}";
6815 return "sub{q}\t{%2, %0|%0, %2}";
6819 (if_then_else (match_operand:DI 2 "incdec_operand")
6820 (const_string "incdec")
6821 (const_string "alu")))
6822 (set (attr "length_immediate")
6824 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6826 (const_string "*")))
6827 (set_attr "mode" "DI")])
6829 ; For comparisons against 1, -1 and 128, we may generate better code
6830 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6831 ; is matched then. We can't accept general immediate, because for
6832 ; case of overflows, the result is messed up.
6833 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6834 ; only for comparisons not depending on it.
6836 (define_insn "*add<mode>_4"
6837 [(set (reg FLAGS_REG)
6839 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6840 (match_operand:SWI124 2 "const_int_operand")))
6841 (clobber (match_scratch:SWI124 0 "=<r>"))]
6842 "ix86_match_ccmode (insn, CCGCmode)"
6844 switch (get_attr_type (insn))
6847 if (operands[2] == constm1_rtx)
6848 return "inc{<imodesuffix>}\t%0";
6851 gcc_assert (operands[2] == const1_rtx);
6852 return "dec{<imodesuffix>}\t%0";
6856 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6857 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6859 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6863 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6864 (const_string "incdec")
6865 (const_string "alu")))
6866 (set (attr "length_immediate")
6868 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6870 (const_string "*")))
6871 (set_attr "mode" "<MODE>")])
6873 (define_insn "*add<mode>_5"
6874 [(set (reg FLAGS_REG)
6877 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6878 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6880 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6881 "ix86_match_ccmode (insn, CCGOCmode)
6882 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6884 switch (get_attr_type (insn))
6887 if (operands[2] == const1_rtx)
6888 return "inc{<imodesuffix>}\t%0";
6891 gcc_assert (operands[2] == constm1_rtx);
6892 return "dec{<imodesuffix>}\t%0";
6896 if (which_alternative == 1)
6897 std::swap (operands[1], operands[2]);
6899 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6900 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6901 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6903 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6907 (if_then_else (match_operand:SWI 2 "incdec_operand")
6908 (const_string "incdec")
6909 (const_string "alu")))
6910 (set (attr "length_immediate")
6912 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6914 (const_string "*")))
6915 (set_attr "mode" "<MODE>")])
6917 (define_insn "*addqi_ext<mode>_0"
6918 [(set (match_operand:QI 0 "nonimm_x64constmem_operand" "=QBc,m")
6921 (match_operator:SWI248 3 "extract_operator"
6922 [(match_operand 2 "int248_register_operand" "Q,Q")
6925 (match_operand:QI 1 "nonimm_x64constmem_operand" "0,0")))
6926 (clobber (reg:CC FLAGS_REG))]
6928 "add{b}\t{%h2, %0|%0, %h2}"
6929 [(set_attr "isa" "*,nox64")
6930 (set_attr "type" "alu")
6931 (set_attr "mode" "QI")])
6933 (define_expand "addqi_ext_1"
6935 [(set (zero_extract:HI (match_operand:HI 0 "register_operand")
6941 (zero_extract:HI (match_operand:HI 1 "register_operand")
6944 (match_operand:QI 2 "const_int_operand")) 0))
6945 (clobber (reg:CC FLAGS_REG))])])
6947 (define_insn "*addqi_ext<mode>_1"
6948 [(set (zero_extract:SWI248
6949 (match_operand 0 "int248_register_operand" "+Q,Q")
6955 (match_operator:SWI248 3 "extract_operator"
6956 [(match_operand 1 "int248_register_operand" "0,0")
6959 (match_operand:QI 2 "general_x64constmem_operand" "QnBc,m")) 0))
6960 (clobber (reg:CC FLAGS_REG))]
6961 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
6962 rtx_equal_p (operands[0], operands[1])"
6964 switch (get_attr_type (insn))
6967 if (operands[2] == const1_rtx)
6968 return "inc{b}\t%h0";
6971 gcc_assert (operands[2] == constm1_rtx);
6972 return "dec{b}\t%h0";
6976 return "add{b}\t{%2, %h0|%h0, %2}";
6979 [(set_attr "isa" "*,nox64")
6981 (if_then_else (match_operand:QI 2 "incdec_operand")
6982 (const_string "incdec")
6983 (const_string "alu")))
6984 (set_attr "mode" "QI")])
6986 (define_insn "*addqi_ext<mode>_2"
6987 [(set (zero_extract:SWI248
6988 (match_operand 0 "int248_register_operand" "+Q")
6994 (match_operator:SWI248 3 "extract_operator"
6995 [(match_operand 1 "int248_register_operand" "%0")
6999 (match_operator:SWI248 4 "extract_operator"
7000 [(match_operand 2 "int248_register_operand" "Q")
7002 (const_int 8)]) 0)) 0))
7003 (clobber (reg:CC FLAGS_REG))]
7004 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
7005 rtx_equal_p (operands[0], operands[1])
7006 || rtx_equal_p (operands[0], operands[2])"
7007 "add{b}\t{%h2, %h0|%h0, %h2}"
7008 [(set_attr "type" "alu")
7009 (set_attr "mode" "QI")])
7011 ;; Like DWI, but use POImode instead of OImode.
7012 (define_mode_attr DPWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI") (TI "POI")])
7014 ;; Add with jump on overflow.
7015 (define_expand "addv<mode>4"
7016 [(parallel [(set (reg:CCO FLAGS_REG)
7020 (match_operand:SWIDWI 1 "nonimmediate_operand"))
7023 (plus:SWIDWI (match_dup 1)
7024 (match_operand:SWIDWI 2
7025 "<general_hilo_operand>")))))
7026 (set (match_operand:SWIDWI 0 "register_operand")
7027 (plus:SWIDWI (match_dup 1) (match_dup 2)))])
7028 (set (pc) (if_then_else
7029 (eq (reg:CCO FLAGS_REG) (const_int 0))
7030 (label_ref (match_operand 3))
7034 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
7035 if (CONST_SCALAR_INT_P (operands[2]))
7036 operands[4] = operands[2];
7038 operands[4] = gen_rtx_SIGN_EXTEND (<DPWI>mode, operands[2]);
7041 (define_insn "*addv<mode>4"
7042 [(set (reg:CCO FLAGS_REG)
7045 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
7047 (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m")))
7049 (plus:SWI (match_dup 1) (match_dup 2)))))
7050 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7051 (plus:SWI (match_dup 1) (match_dup 2)))]
7052 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7053 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7054 [(set_attr "type" "alu")
7055 (set_attr "mode" "<MODE>")])
7057 (define_insn "addv<mode>4_1"
7058 [(set (reg:CCO FLAGS_REG)
7061 (match_operand:SWI 1 "nonimmediate_operand" "0"))
7062 (match_operand:<DWI> 3 "const_int_operand"))
7066 (match_operand:SWI 2 "x86_64_immediate_operand" "<i>")))))
7067 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
7068 (plus:SWI (match_dup 1) (match_dup 2)))]
7069 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
7070 && CONST_INT_P (operands[2])
7071 && INTVAL (operands[2]) == INTVAL (operands[3])"
7072 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7073 [(set_attr "type" "alu")
7074 (set_attr "mode" "<MODE>")
7075 (set (attr "length_immediate")
7076 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7078 (match_test "<MODE_SIZE> == 8")
7080 (const_string "<MODE_SIZE>")))])
7082 ;; Quad word integer modes as mode attribute.
7083 (define_mode_attr QPWI [(SI "TI") (DI "POI")])
7085 (define_insn_and_split "*addv<dwi>4_doubleword"
7086 [(set (reg:CCO FLAGS_REG)
7090 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0"))
7092 (match_operand:<DWI> 2 "nonimmediate_operand" "r,o")))
7094 (plus:<DWI> (match_dup 1) (match_dup 2)))))
7095 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
7096 (plus:<DWI> (match_dup 1) (match_dup 2)))]
7097 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
7099 "&& reload_completed"
7100 [(parallel [(set (reg:CCC FLAGS_REG)
7102 (plus:DWIH (match_dup 1) (match_dup 2))
7105 (plus:DWIH (match_dup 1) (match_dup 2)))])
7106 (parallel [(set (reg:CCO FLAGS_REG)
7110 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7111 (sign_extend:<DWI> (match_dup 4)))
7112 (sign_extend:<DWI> (match_dup 5)))
7116 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7122 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7126 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7129 (define_insn_and_split "*addv<dwi>4_doubleword_1"
7130 [(set (reg:CCO FLAGS_REG)
7134 (match_operand:<DWI> 1 "nonimmediate_operand" "%0"))
7135 (match_operand:<QPWI> 3 "const_scalar_int_operand" "n"))
7139 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>")))))
7140 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
7141 (plus:<DWI> (match_dup 1) (match_dup 2)))]
7142 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)
7143 && CONST_SCALAR_INT_P (operands[2])
7144 && rtx_equal_p (operands[2], operands[3])"
7146 "&& reload_completed"
7147 [(parallel [(set (reg:CCC FLAGS_REG)
7149 (plus:DWIH (match_dup 1) (match_dup 2))
7152 (plus:DWIH (match_dup 1) (match_dup 2)))])
7153 (parallel [(set (reg:CCO FLAGS_REG)
7157 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7158 (sign_extend:<DWI> (match_dup 4)))
7163 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7169 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7173 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7174 if (operands[2] == const0_rtx)
7176 emit_insn (gen_addv<mode>4_1 (operands[3], operands[4], operands[5],
7182 (define_insn "*addv<mode>4_overflow_1"
7183 [(set (reg:CCO FLAGS_REG)
7187 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7188 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7190 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")))
7192 (match_operand:SWI 2 "<general_sext_operand>" "rWe,m")))
7196 (match_operator:SWI 5 "ix86_carry_flag_operator"
7197 [(match_dup 3) (const_int 0)])
7200 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r")
7203 (match_op_dup 5 [(match_dup 3) (const_int 0)])
7206 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7207 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
7208 [(set_attr "type" "alu")
7209 (set_attr "mode" "<MODE>")])
7211 (define_insn "*addv<mode>4_overflow_2"
7212 [(set (reg:CCO FLAGS_REG)
7216 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7217 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7219 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
7220 (match_operand:<DWI> 6 "const_int_operand" "n"))
7224 (match_operator:SWI 5 "ix86_carry_flag_operator"
7225 [(match_dup 3) (const_int 0)])
7227 (match_operand:SWI 2 "x86_64_immediate_operand" "e")))))
7228 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm")
7231 (match_op_dup 5 [(match_dup 3) (const_int 0)])
7234 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
7235 && CONST_INT_P (operands[2])
7236 && INTVAL (operands[2]) == INTVAL (operands[6])"
7237 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
7238 [(set_attr "type" "alu")
7239 (set_attr "mode" "<MODE>")
7240 (set (attr "length_immediate")
7241 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7243 (const_string "4")))])
7245 (define_expand "uaddv<mode>4"
7246 [(parallel [(set (reg:CCC FLAGS_REG)
7249 (match_operand:SWIDWI 1 "nonimmediate_operand")
7250 (match_operand:SWIDWI 2 "<general_hilo_operand>"))
7252 (set (match_operand:SWIDWI 0 "register_operand")
7253 (plus:SWIDWI (match_dup 1) (match_dup 2)))])
7254 (set (pc) (if_then_else
7255 (ltu (reg:CCC FLAGS_REG) (const_int 0))
7256 (label_ref (match_operand 3))
7259 "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
7261 ;; The lea patterns for modes less than 32 bits need to be matched by
7262 ;; several insns converted to real lea by splitters.
7264 (define_insn_and_split "*lea<mode>_general_1"
7265 [(set (match_operand:SWI12 0 "register_operand" "=r")
7267 (plus:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7268 (match_operand:SWI12 2 "register_operand" "r"))
7269 (match_operand:SWI12 3 "immediate_operand" "i")))]
7270 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7272 "&& reload_completed"
7275 (plus:SI (match_dup 1) (match_dup 2))
7278 operands[0] = gen_lowpart (SImode, operands[0]);
7279 operands[1] = gen_lowpart (SImode, operands[1]);
7280 operands[2] = gen_lowpart (SImode, operands[2]);
7281 operands[3] = gen_lowpart (SImode, operands[3]);
7283 [(set_attr "type" "lea")
7284 (set_attr "mode" "SI")])
7286 (define_insn_and_split "*lea<mode>_general_2"
7287 [(set (match_operand:SWI12 0 "register_operand" "=r")
7289 (mult:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7290 (match_operand 2 "const248_operand" "n"))
7291 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
7292 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7294 "&& reload_completed"
7297 (mult:SI (match_dup 1) (match_dup 2))
7300 operands[0] = gen_lowpart (SImode, operands[0]);
7301 operands[1] = gen_lowpart (SImode, operands[1]);
7302 operands[3] = gen_lowpart (SImode, operands[3]);
7304 [(set_attr "type" "lea")
7305 (set_attr "mode" "SI")])
7307 (define_insn_and_split "*lea<mode>_general_2b"
7308 [(set (match_operand:SWI12 0 "register_operand" "=r")
7310 (ashift:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7311 (match_operand 2 "const123_operand" "n"))
7312 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
7313 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7315 "&& reload_completed"
7318 (ashift:SI (match_dup 1) (match_dup 2))
7321 operands[0] = gen_lowpart (SImode, operands[0]);
7322 operands[1] = gen_lowpart (SImode, operands[1]);
7323 operands[3] = gen_lowpart (SImode, operands[3]);
7325 [(set_attr "type" "lea")
7326 (set_attr "mode" "SI")])
7328 (define_insn_and_split "*lea<mode>_general_3"
7329 [(set (match_operand:SWI12 0 "register_operand" "=r")
7332 (mult:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7333 (match_operand 2 "const248_operand" "n"))
7334 (match_operand:SWI12 3 "register_operand" "r"))
7335 (match_operand:SWI12 4 "immediate_operand" "i")))]
7336 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7338 "&& reload_completed"
7342 (mult:SI (match_dup 1) (match_dup 2))
7346 operands[0] = gen_lowpart (SImode, operands[0]);
7347 operands[1] = gen_lowpart (SImode, operands[1]);
7348 operands[3] = gen_lowpart (SImode, operands[3]);
7349 operands[4] = gen_lowpart (SImode, operands[4]);
7351 [(set_attr "type" "lea")
7352 (set_attr "mode" "SI")])
7354 (define_insn_and_split "*lea<mode>_general_3b"
7355 [(set (match_operand:SWI12 0 "register_operand" "=r")
7358 (ashift:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7359 (match_operand 2 "const123_operand" "n"))
7360 (match_operand:SWI12 3 "register_operand" "r"))
7361 (match_operand:SWI12 4 "immediate_operand" "i")))]
7362 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7364 "&& reload_completed"
7368 (ashift:SI (match_dup 1) (match_dup 2))
7372 operands[0] = gen_lowpart (SImode, operands[0]);
7373 operands[1] = gen_lowpart (SImode, operands[1]);
7374 operands[3] = gen_lowpart (SImode, operands[3]);
7375 operands[4] = gen_lowpart (SImode, operands[4]);
7377 [(set_attr "type" "lea")
7378 (set_attr "mode" "SI")])
7380 (define_insn_and_split "*lea<mode>_general_4"
7381 [(set (match_operand:SWI12 0 "register_operand" "=r")
7384 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7385 (match_operand 2 "const_0_to_3_operand"))
7386 (match_operand 3 "const_int_operand")))]
7387 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7388 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
7389 < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
7391 "&& reload_completed"
7394 (mult:SI (match_dup 1) (match_dup 2))
7397 operands[0] = gen_lowpart (SImode, operands[0]);
7398 operands[1] = gen_lowpart (SImode, operands[1]);
7399 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
7401 [(set_attr "type" "lea")
7402 (set_attr "mode" "SI")])
7404 (define_insn_and_split "*lea<mode>_general_4"
7405 [(set (match_operand:SWI48 0 "register_operand" "=r")
7408 (match_operand:SWI48 1 "register_no_SP_operand" "l")
7409 (match_operand 2 "const_0_to_3_operand"))
7410 (match_operand 3 "const_int_operand")))]
7411 "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
7412 < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
7414 "&& reload_completed"
7417 (mult:SWI48 (match_dup 1) (match_dup 2))
7419 "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
7420 [(set_attr "type" "lea")
7421 (set_attr "mode" "<MODE>")])
7423 ;; Subtract instructions
7425 (define_expand "sub<mode>3"
7426 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
7427 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
7428 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
7430 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
7432 (define_insn_and_split "*sub<dwi>3_doubleword"
7433 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
7435 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7436 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
7437 (clobber (reg:CC FLAGS_REG))]
7438 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7440 "&& reload_completed"
7441 [(parallel [(set (reg:CC FLAGS_REG)
7442 (compare:CC (match_dup 1) (match_dup 2)))
7444 (minus:DWIH (match_dup 1) (match_dup 2)))])
7445 (parallel [(set (match_dup 3)
7449 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7451 (clobber (reg:CC FLAGS_REG))])]
7453 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7454 if (operands[2] == const0_rtx)
7456 ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
7461 (define_insn_and_split "*sub<dwi>3_doubleword_zext"
7462 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
7464 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7466 (match_operand:DWIH 2 "nonimmediate_operand" "rm,r"))))
7467 (clobber (reg:CC FLAGS_REG))]
7468 "ix86_binary_operator_ok (UNKNOWN, <DWI>mode, operands)"
7470 "&& reload_completed"
7471 [(parallel [(set (reg:CC FLAGS_REG)
7472 (compare:CC (match_dup 1) (match_dup 2)))
7474 (minus:DWIH (match_dup 1) (match_dup 2)))])
7475 (parallel [(set (match_dup 3)
7479 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7481 (clobber (reg:CC FLAGS_REG))])]
7482 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[3]);")
7484 (define_insn "*sub<mode>_1"
7485 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7487 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7488 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
7489 (clobber (reg:CC FLAGS_REG))]
7490 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7491 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7492 [(set_attr "type" "alu")
7493 (set_attr "mode" "<MODE>")])
7495 (define_insn "*subsi_1_zext"
7496 [(set (match_operand:DI 0 "register_operand" "=r")
7498 (minus:SI (match_operand:SI 1 "register_operand" "0")
7499 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
7500 (clobber (reg:CC FLAGS_REG))]
7501 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7502 "sub{l}\t{%2, %k0|%k0, %2}"
7503 [(set_attr "type" "alu")
7504 (set_attr "mode" "SI")])
7506 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
7507 (define_insn_and_split "*sub<mode>_1_slp"
7508 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
7509 (minus:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
7510 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
7511 (clobber (reg:CC FLAGS_REG))]
7512 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7514 sub{<imodesuffix>}\t{%2, %0|%0, %2}
7516 "&& reload_completed"
7517 [(set (strict_low_part (match_dup 0)) (match_dup 1))
7519 [(set (strict_low_part (match_dup 0))
7520 (minus:SWI12 (match_dup 0) (match_dup 2)))
7521 (clobber (reg:CC FLAGS_REG))])]
7523 [(set_attr "type" "alu")
7524 (set_attr "mode" "<MODE>")])
7526 (define_insn "*sub<mode>_2"
7527 [(set (reg FLAGS_REG)
7530 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7531 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
7533 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7534 (minus:SWI (match_dup 1) (match_dup 2)))]
7535 "ix86_match_ccmode (insn, CCGOCmode)
7536 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7537 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7538 [(set_attr "type" "alu")
7539 (set_attr "mode" "<MODE>")])
7541 (define_insn "*subsi_2_zext"
7542 [(set (reg FLAGS_REG)
7544 (minus:SI (match_operand:SI 1 "register_operand" "0")
7545 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
7547 (set (match_operand:DI 0 "register_operand" "=r")
7549 (minus:SI (match_dup 1)
7551 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7552 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7553 "sub{l}\t{%2, %k0|%k0, %2}"
7554 [(set_attr "type" "alu")
7555 (set_attr "mode" "SI")])
7557 (define_insn "*subqi_ext<mode>_0"
7558 [(set (match_operand:QI 0 "nonimm_x64constmem_operand" "=QBc,m")
7560 (match_operand:QI 1 "nonimm_x64constmem_operand" "0,0")
7562 (match_operator:SWI248 3 "extract_operator"
7563 [(match_operand 2 "int248_register_operand" "Q,Q")
7565 (const_int 8)]) 0)))
7566 (clobber (reg:CC FLAGS_REG))]
7568 "sub{b}\t{%h2, %0|%0, %h2}"
7569 [(set_attr "isa" "*,nox64")
7570 (set_attr "type" "alu")
7571 (set_attr "mode" "QI")])
7573 (define_insn "*subqi_ext<mode>_2"
7574 [(set (zero_extract:SWI248
7575 (match_operand 0 "int248_register_operand" "+Q")
7581 (match_operator:SWI248 3 "extract_operator"
7582 [(match_operand 1 "int248_register_operand" "0")
7586 (match_operator:SWI248 4 "extract_operator"
7587 [(match_operand 2 "int248_register_operand" "Q")
7589 (const_int 8)]) 0)) 0))
7590 (clobber (reg:CC FLAGS_REG))]
7591 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
7592 rtx_equal_p (operands[0], operands[1])"
7593 "sub{b}\t{%h2, %h0|%h0, %h2}"
7594 [(set_attr "type" "alu")
7595 (set_attr "mode" "QI")])
7597 ;; Subtract with jump on overflow.
7598 (define_expand "subv<mode>4"
7599 [(parallel [(set (reg:CCO FLAGS_REG)
7603 (match_operand:SWIDWI 1 "nonimmediate_operand"))
7606 (minus:SWIDWI (match_dup 1)
7607 (match_operand:SWIDWI 2
7608 "<general_hilo_operand>")))))
7609 (set (match_operand:SWIDWI 0 "register_operand")
7610 (minus:SWIDWI (match_dup 1) (match_dup 2)))])
7611 (set (pc) (if_then_else
7612 (eq (reg:CCO FLAGS_REG) (const_int 0))
7613 (label_ref (match_operand 3))
7617 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
7618 if (CONST_SCALAR_INT_P (operands[2]))
7619 operands[4] = operands[2];
7621 operands[4] = gen_rtx_SIGN_EXTEND (<DPWI>mode, operands[2]);
7624 (define_insn "*subv<mode>4"
7625 [(set (reg:CCO FLAGS_REG)
7626 (eq:CCO (minus:<DWI>
7628 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
7630 (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m")))
7632 (minus:SWI (match_dup 1) (match_dup 2)))))
7633 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7634 (minus:SWI (match_dup 1) (match_dup 2)))]
7635 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7636 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7637 [(set_attr "type" "alu")
7638 (set_attr "mode" "<MODE>")])
7640 (define_insn "subv<mode>4_1"
7641 [(set (reg:CCO FLAGS_REG)
7642 (eq:CCO (minus:<DWI>
7644 (match_operand:SWI 1 "nonimmediate_operand" "0"))
7645 (match_operand:<DWI> 3 "const_int_operand"))
7649 (match_operand:SWI 2 "x86_64_immediate_operand" "<i>")))))
7650 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
7651 (minus:SWI (match_dup 1) (match_dup 2)))]
7652 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7653 && CONST_INT_P (operands[2])
7654 && INTVAL (operands[2]) == INTVAL (operands[3])"
7655 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7656 [(set_attr "type" "alu")
7657 (set_attr "mode" "<MODE>")
7658 (set (attr "length_immediate")
7659 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7661 (match_test "<MODE_SIZE> == 8")
7663 (const_string "<MODE_SIZE>")))])
7665 (define_insn_and_split "*subv<dwi>4_doubleword"
7666 [(set (reg:CCO FLAGS_REG)
7670 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0"))
7672 (match_operand:<DWI> 2 "nonimmediate_operand" "r,o")))
7674 (minus:<DWI> (match_dup 1) (match_dup 2)))))
7675 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
7676 (minus:<DWI> (match_dup 1) (match_dup 2)))]
7677 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7679 "&& reload_completed"
7680 [(parallel [(set (reg:CC FLAGS_REG)
7681 (compare:CC (match_dup 1) (match_dup 2)))
7683 (minus:DWIH (match_dup 1) (match_dup 2)))])
7684 (parallel [(set (reg:CCO FLAGS_REG)
7688 (sign_extend:<DWI> (match_dup 4))
7689 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))
7690 (sign_extend:<DWI> (match_dup 5)))
7695 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7701 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7704 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7707 (define_insn_and_split "*subv<dwi>4_doubleword_1"
7708 [(set (reg:CCO FLAGS_REG)
7712 (match_operand:<DWI> 1 "nonimmediate_operand" "0"))
7713 (match_operand:<QPWI> 3 "const_scalar_int_operand"))
7717 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>")))))
7718 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
7719 (minus:<DWI> (match_dup 1) (match_dup 2)))]
7720 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7721 && CONST_SCALAR_INT_P (operands[2])
7722 && rtx_equal_p (operands[2], operands[3])"
7724 "&& reload_completed"
7725 [(parallel [(set (reg:CC FLAGS_REG)
7726 (compare:CC (match_dup 1) (match_dup 2)))
7728 (minus:DWIH (match_dup 1) (match_dup 2)))])
7729 (parallel [(set (reg:CCO FLAGS_REG)
7733 (sign_extend:<DWI> (match_dup 4))
7734 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))
7740 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7746 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7749 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7750 if (operands[2] == const0_rtx)
7752 emit_insn (gen_subv<mode>4_1 (operands[3], operands[4], operands[5],
7758 (define_insn "*subv<mode>4_overflow_1"
7759 [(set (reg:CCO FLAGS_REG)
7764 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
7765 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7766 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
7768 (match_operand:SWI 2 "<general_sext_operand>" "rWe,m")))
7773 (match_operator:SWI 5 "ix86_carry_flag_operator"
7774 [(match_dup 3) (const_int 0)]))
7776 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r")
7780 (match_op_dup 5 [(match_dup 3) (const_int 0)]))
7782 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7783 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7784 [(set_attr "type" "alu")
7785 (set_attr "mode" "<MODE>")])
7787 (define_insn "*subv<mode>4_overflow_2"
7788 [(set (reg:CCO FLAGS_REG)
7793 (match_operand:SWI 1 "nonimmediate_operand" "%0"))
7794 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7795 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
7796 (match_operand:<DWI> 6 "const_int_operand" "n"))
7801 (match_operator:SWI 5 "ix86_carry_flag_operator"
7802 [(match_dup 3) (const_int 0)]))
7803 (match_operand:SWI 2 "x86_64_immediate_operand" "e")))))
7804 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm")
7808 (match_op_dup 5 [(match_dup 3) (const_int 0)]))
7810 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7811 && CONST_INT_P (operands[2])
7812 && INTVAL (operands[2]) == INTVAL (operands[6])"
7813 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7814 [(set_attr "type" "alu")
7815 (set_attr "mode" "<MODE>")
7816 (set (attr "length_immediate")
7817 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7819 (const_string "4")))])
7821 (define_expand "usubv<mode>4"
7822 [(parallel [(set (reg:CC FLAGS_REG)
7824 (match_operand:SWI 1 "nonimmediate_operand")
7825 (match_operand:SWI 2 "<general_operand>")))
7826 (set (match_operand:SWI 0 "register_operand")
7827 (minus:SWI (match_dup 1) (match_dup 2)))])
7828 (set (pc) (if_then_else
7829 (ltu (reg:CC FLAGS_REG) (const_int 0))
7830 (label_ref (match_operand 3))
7833 "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
7835 (define_insn "*sub<mode>_3"
7836 [(set (reg FLAGS_REG)
7837 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7838 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
7839 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7840 (minus:SWI (match_dup 1) (match_dup 2)))]
7841 "ix86_match_ccmode (insn, CCmode)
7842 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7843 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7844 [(set_attr "type" "alu")
7845 (set_attr "mode" "<MODE>")])
7849 [(set (reg:CC FLAGS_REG)
7850 (compare:CC (match_operand:SWI 0 "general_reg_operand")
7851 (match_operand:SWI 1 "general_gr_operand")))
7853 (minus:SWI (match_dup 0) (match_dup 1)))])]
7854 "find_regno_note (peep2_next_insn (0), REG_UNUSED, REGNO (operands[0])) != 0"
7855 [(set (reg:CC FLAGS_REG)
7856 (compare:CC (match_dup 0) (match_dup 1)))])
7859 [(set (match_operand:SWI 0 "general_reg_operand")
7860 (match_operand:SWI 1 "memory_operand"))
7861 (parallel [(set (reg:CC FLAGS_REG)
7862 (compare:CC (match_dup 0)
7863 (match_operand:SWI 2 "memory_operand")))
7865 (minus:SWI (match_dup 0) (match_dup 2)))])
7866 (set (match_dup 1) (match_dup 0))]
7867 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
7868 && peep2_reg_dead_p (3, operands[0])
7869 && !reg_overlap_mentioned_p (operands[0], operands[1])
7870 && !reg_overlap_mentioned_p (operands[0], operands[2])"
7871 [(set (match_dup 0) (match_dup 2))
7872 (parallel [(set (reg:CC FLAGS_REG)
7873 (compare:CC (match_dup 1) (match_dup 0)))
7875 (minus:SWI (match_dup 1) (match_dup 0)))])])
7877 ;; decl %eax; cmpl $-1, %eax; jne .Lxx; can be optimized into
7878 ;; subl $1, %eax; jnc .Lxx;
7881 [(set (match_operand:SWI 0 "general_reg_operand")
7882 (plus:SWI (match_dup 0) (const_int -1)))
7883 (clobber (reg FLAGS_REG))])
7884 (set (reg:CCZ FLAGS_REG)
7885 (compare:CCZ (match_dup 0) (const_int -1)))
7887 (if_then_else (match_operator 1 "bt_comparison_operator"
7888 [(reg:CCZ FLAGS_REG) (const_int 0)])
7891 "peep2_regno_dead_p (3, FLAGS_REG)"
7893 [(set (reg:CC FLAGS_REG)
7894 (compare:CC (match_dup 0) (const_int 1)))
7896 (minus:SWI (match_dup 0) (const_int 1)))])
7898 (if_then_else (match_dup 3)
7902 rtx cc = gen_rtx_REG (CCmode, FLAGS_REG);
7903 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE
7904 ? GEU : LTU, VOIDmode, cc, const0_rtx);
7907 ;; Help combine use borrow flag to test for -1 after dec (add $-1).
7908 (define_insn_and_split "*dec_cmov<mode>"
7909 [(set (match_operand:SWI248 0 "register_operand" "=r")
7910 (if_then_else:SWI248
7911 (match_operator 1 "bt_comparison_operator"
7912 [(match_operand:SWI248 2 "register_operand" "0") (const_int 0)])
7913 (plus:SWI248 (match_dup 2) (const_int -1))
7914 (match_operand:SWI248 3 "nonimmediate_operand" "rm")))
7915 (clobber (reg:CC FLAGS_REG))]
7918 "&& reload_completed"
7919 [(parallel [(set (reg:CC FLAGS_REG)
7920 (compare:CC (match_dup 2) (const_int 1)))
7921 (set (match_dup 0) (minus:SWI248 (match_dup 2) (const_int 1)))])
7923 (if_then_else:SWI248 (match_dup 4) (match_dup 0) (match_dup 3)))]
7925 rtx cc = gen_rtx_REG (CCCmode, FLAGS_REG);
7926 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE
7927 ? GEU : LTU, VOIDmode, cc, const0_rtx);
7930 (define_insn "*subsi_3_zext"
7931 [(set (reg FLAGS_REG)
7932 (compare (match_operand:SI 1 "register_operand" "0")
7933 (match_operand:SI 2 "x86_64_general_operand" "rBMe")))
7934 (set (match_operand:DI 0 "register_operand" "=r")
7936 (minus:SI (match_dup 1)
7938 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7939 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7940 "sub{l}\t{%2, %1|%1, %2}"
7941 [(set_attr "type" "alu")
7942 (set_attr "mode" "SI")])
7944 ;; Add with carry and subtract with borrow
7946 (define_insn "@add<mode>3_carry"
7947 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7950 (match_operator:SWI 4 "ix86_carry_flag_operator"
7951 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7952 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
7953 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
7954 (clobber (reg:CC FLAGS_REG))]
7955 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7956 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
7957 [(set_attr "type" "alu")
7958 (set_attr "use_carry" "1")
7959 (set_attr "pent_pair" "pu")
7960 (set_attr "mode" "<MODE>")])
7963 [(set (match_operand:SWI 0 "general_reg_operand")
7964 (match_operand:SWI 1 "memory_operand"))
7965 (parallel [(set (match_dup 0)
7968 (match_operator:SWI 4 "ix86_carry_flag_operator"
7969 [(match_operand 3 "flags_reg_operand")
7972 (match_operand:SWI 2 "memory_operand")))
7973 (clobber (reg:CC FLAGS_REG))])
7974 (set (match_dup 1) (match_dup 0))]
7975 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
7976 && peep2_reg_dead_p (3, operands[0])
7977 && !reg_overlap_mentioned_p (operands[0], operands[1])
7978 && !reg_overlap_mentioned_p (operands[0], operands[2])"
7979 [(set (match_dup 0) (match_dup 2))
7980 (parallel [(set (match_dup 1)
7981 (plus:SWI (plus:SWI (match_op_dup 4
7982 [(match_dup 3) (const_int 0)])
7985 (clobber (reg:CC FLAGS_REG))])])
7988 [(set (match_operand:SWI 0 "general_reg_operand")
7989 (match_operand:SWI 1 "memory_operand"))
7990 (parallel [(set (match_dup 0)
7993 (match_operator:SWI 4 "ix86_carry_flag_operator"
7994 [(match_operand 3 "flags_reg_operand")
7997 (match_operand:SWI 2 "memory_operand")))
7998 (clobber (reg:CC FLAGS_REG))])
7999 (set (match_operand:SWI 5 "general_reg_operand") (match_dup 0))
8000 (set (match_dup 1) (match_dup 5))]
8001 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8002 && peep2_reg_dead_p (3, operands[0])
8003 && peep2_reg_dead_p (4, operands[5])
8004 && !reg_overlap_mentioned_p (operands[0], operands[1])
8005 && !reg_overlap_mentioned_p (operands[0], operands[2])
8006 && !reg_overlap_mentioned_p (operands[5], operands[1])"
8007 [(set (match_dup 0) (match_dup 2))
8008 (parallel [(set (match_dup 1)
8009 (plus:SWI (plus:SWI (match_op_dup 4
8010 [(match_dup 3) (const_int 0)])
8013 (clobber (reg:CC FLAGS_REG))])])
8015 (define_insn "*add<mode>3_carry_0"
8016 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8018 (match_operator:SWI 2 "ix86_carry_flag_operator"
8019 [(reg FLAGS_REG) (const_int 0)])
8020 (match_operand:SWI 1 "nonimmediate_operand" "0")))
8021 (clobber (reg:CC FLAGS_REG))]
8022 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8023 "adc{<imodesuffix>}\t{$0, %0|%0, 0}"
8024 [(set_attr "type" "alu")
8025 (set_attr "use_carry" "1")
8026 (set_attr "pent_pair" "pu")
8027 (set_attr "mode" "<MODE>")])
8029 (define_insn "*add<mode>3_carry_0r"
8030 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8032 (match_operator:SWI 2 "ix86_carry_flag_unset_operator"
8033 [(reg FLAGS_REG) (const_int 0)])
8034 (match_operand:SWI 1 "nonimmediate_operand" "0")))
8035 (clobber (reg:CC FLAGS_REG))]
8036 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8037 "sbb{<imodesuffix>}\t{$-1, %0|%0, -1}"
8038 [(set_attr "type" "alu")
8039 (set_attr "use_carry" "1")
8040 (set_attr "pent_pair" "pu")
8041 (set_attr "mode" "<MODE>")])
8043 (define_insn "*addsi3_carry_zext"
8044 [(set (match_operand:DI 0 "register_operand" "=r")
8047 (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
8048 [(reg FLAGS_REG) (const_int 0)])
8049 (match_operand:SI 1 "register_operand" "%0"))
8050 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
8051 (clobber (reg:CC FLAGS_REG))]
8052 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
8053 "adc{l}\t{%2, %k0|%k0, %2}"
8054 [(set_attr "type" "alu")
8055 (set_attr "use_carry" "1")
8056 (set_attr "pent_pair" "pu")
8057 (set_attr "mode" "SI")])
8059 (define_insn "*addsi3_carry_zext_0"
8060 [(set (match_operand:DI 0 "register_operand" "=r")
8062 (plus:SI (match_operator:SI 2 "ix86_carry_flag_operator"
8063 [(reg FLAGS_REG) (const_int 0)])
8064 (match_operand:SI 1 "register_operand" "0"))))
8065 (clobber (reg:CC FLAGS_REG))]
8067 "adc{l}\t{$0, %k0|%k0, 0}"
8068 [(set_attr "type" "alu")
8069 (set_attr "use_carry" "1")
8070 (set_attr "pent_pair" "pu")
8071 (set_attr "mode" "SI")])
8073 (define_insn "*addsi3_carry_zext_0r"
8074 [(set (match_operand:DI 0 "register_operand" "=r")
8076 (plus:SI (match_operator:SI 2 "ix86_carry_flag_unset_operator"
8077 [(reg FLAGS_REG) (const_int 0)])
8078 (match_operand:SI 1 "register_operand" "0"))))
8079 (clobber (reg:CC FLAGS_REG))]
8081 "sbb{l}\t{$-1, %k0|%k0, -1}"
8082 [(set_attr "type" "alu")
8083 (set_attr "use_carry" "1")
8084 (set_attr "pent_pair" "pu")
8085 (set_attr "mode" "SI")])
8087 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
8089 (define_insn "addcarry<mode>"
8090 [(set (reg:CCC FLAGS_REG)
8095 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8096 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8097 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0"))
8098 (match_operand:SWI48 2 "nonimmediate_operand" "r,rm")))
8100 (zero_extend:<DWI> (match_dup 2))
8101 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8102 [(match_dup 3) (const_int 0)]))))
8103 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
8104 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8105 [(match_dup 3) (const_int 0)])
8108 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
8109 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
8110 [(set_attr "type" "alu")
8111 (set_attr "use_carry" "1")
8112 (set_attr "pent_pair" "pu")
8113 (set_attr "mode" "<MODE>")])
8116 [(parallel [(set (reg:CCC FLAGS_REG)
8121 (match_operator:SWI48 4 "ix86_carry_flag_operator"
8122 [(match_operand 2 "flags_reg_operand")
8124 (match_operand:SWI48 0 "general_reg_operand"))
8125 (match_operand:SWI48 1 "memory_operand")))
8127 (zero_extend:<DWI> (match_dup 1))
8128 (match_operator:<DWI> 3 "ix86_carry_flag_operator"
8129 [(match_dup 2) (const_int 0)]))))
8131 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8132 [(match_dup 2) (const_int 0)])
8135 (set (match_dup 1) (match_dup 0))]
8136 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8137 && peep2_reg_dead_p (2, operands[0])
8138 && !reg_overlap_mentioned_p (operands[0], operands[1])"
8139 [(parallel [(set (reg:CCC FLAGS_REG)
8145 [(match_dup 2) (const_int 0)])
8149 (zero_extend:<DWI> (match_dup 0))
8151 [(match_dup 2) (const_int 0)]))))
8153 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8154 [(match_dup 2) (const_int 0)])
8159 [(set (match_operand:SWI48 0 "general_reg_operand")
8160 (match_operand:SWI48 1 "memory_operand"))
8161 (parallel [(set (reg:CCC FLAGS_REG)
8166 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8167 [(match_operand 3 "flags_reg_operand")
8170 (match_operand:SWI48 2 "memory_operand")))
8172 (zero_extend:<DWI> (match_dup 2))
8173 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8174 [(match_dup 3) (const_int 0)]))))
8176 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8177 [(match_dup 3) (const_int 0)])
8180 (set (match_dup 1) (match_dup 0))]
8181 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8182 && peep2_reg_dead_p (3, operands[0])
8183 && !reg_overlap_mentioned_p (operands[0], operands[1])
8184 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8185 [(set (match_dup 0) (match_dup 2))
8186 (parallel [(set (reg:CCC FLAGS_REG)
8192 [(match_dup 3) (const_int 0)])
8196 (zero_extend:<DWI> (match_dup 0))
8198 [(match_dup 3) (const_int 0)]))))
8200 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8201 [(match_dup 3) (const_int 0)])
8206 [(parallel [(set (reg:CCC FLAGS_REG)
8211 (match_operator:SWI48 4 "ix86_carry_flag_operator"
8212 [(match_operand 2 "flags_reg_operand")
8214 (match_operand:SWI48 0 "general_reg_operand"))
8215 (match_operand:SWI48 1 "memory_operand")))
8217 (zero_extend:<DWI> (match_dup 1))
8218 (match_operator:<DWI> 3 "ix86_carry_flag_operator"
8219 [(match_dup 2) (const_int 0)]))))
8221 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8222 [(match_dup 2) (const_int 0)])
8225 (set (match_operand:QI 5 "general_reg_operand")
8226 (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8227 (set (match_operand:SWI48 6 "general_reg_operand")
8228 (zero_extend:SWI48 (match_dup 5)))
8229 (set (match_dup 1) (match_dup 0))]
8230 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8231 && peep2_reg_dead_p (4, operands[0])
8232 && !reg_overlap_mentioned_p (operands[0], operands[1])
8233 && !reg_overlap_mentioned_p (operands[0], operands[5])
8234 && !reg_overlap_mentioned_p (operands[5], operands[1])
8235 && !reg_overlap_mentioned_p (operands[0], operands[6])
8236 && !reg_overlap_mentioned_p (operands[6], operands[1])"
8237 [(parallel [(set (reg:CCC FLAGS_REG)
8243 [(match_dup 2) (const_int 0)])
8247 (zero_extend:<DWI> (match_dup 0))
8249 [(match_dup 2) (const_int 0)]))))
8251 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8252 [(match_dup 2) (const_int 0)])
8255 (set (match_dup 5) (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8256 (set (match_dup 6) (zero_extend:SWI48 (match_dup 5)))])
8258 (define_expand "addcarry<mode>_0"
8260 [(set (reg:CCC FLAGS_REG)
8263 (match_operand:SWI48 1 "nonimmediate_operand")
8264 (match_operand:SWI48 2 "x86_64_general_operand"))
8266 (set (match_operand:SWI48 0 "nonimmediate_operand")
8267 (plus:SWI48 (match_dup 1) (match_dup 2)))])]
8268 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)")
8270 (define_insn "*addcarry<mode>_1"
8271 [(set (reg:CCC FLAGS_REG)
8276 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8277 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8278 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
8279 (match_operand:SWI48 2 "x86_64_immediate_operand" "e")))
8281 (match_operand:<DWI> 6 "const_scalar_int_operand")
8282 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8283 [(match_dup 3) (const_int 0)]))))
8284 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
8285 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8286 [(match_dup 3) (const_int 0)])
8289 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
8290 && CONST_INT_P (operands[2])
8291 /* Check that operands[6] is operands[2] zero extended from
8292 <MODE>mode to <DWI>mode. */
8293 && ((<MODE>mode == SImode || INTVAL (operands[2]) >= 0)
8294 ? (CONST_INT_P (operands[6])
8295 && UINTVAL (operands[6]) == (UINTVAL (operands[2])
8296 & GET_MODE_MASK (<MODE>mode)))
8297 : (CONST_WIDE_INT_P (operands[6])
8298 && CONST_WIDE_INT_NUNITS (operands[6]) == 2
8299 && ((unsigned HOST_WIDE_INT) CONST_WIDE_INT_ELT (operands[6], 0)
8300 == UINTVAL (operands[2]))
8301 && CONST_WIDE_INT_ELT (operands[6], 1) == 0))"
8302 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
8303 [(set_attr "type" "alu")
8304 (set_attr "use_carry" "1")
8305 (set_attr "pent_pair" "pu")
8306 (set_attr "mode" "<MODE>")
8307 (set (attr "length_immediate")
8308 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
8310 (const_string "4")))])
8312 (define_insn "@sub<mode>3_carry"
8313 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
8316 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
8317 (match_operator:SWI 4 "ix86_carry_flag_operator"
8318 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
8319 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
8320 (clobber (reg:CC FLAGS_REG))]
8321 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
8322 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8323 [(set_attr "type" "alu")
8324 (set_attr "use_carry" "1")
8325 (set_attr "pent_pair" "pu")
8326 (set_attr "mode" "<MODE>")])
8329 [(set (match_operand:SWI 0 "general_reg_operand")
8330 (match_operand:SWI 1 "memory_operand"))
8331 (parallel [(set (match_dup 0)
8335 (match_operator:SWI 4 "ix86_carry_flag_operator"
8336 [(match_operand 3 "flags_reg_operand")
8338 (match_operand:SWI 2 "memory_operand")))
8339 (clobber (reg:CC FLAGS_REG))])
8340 (set (match_dup 1) (match_dup 0))]
8341 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8342 && peep2_reg_dead_p (3, operands[0])
8343 && !reg_overlap_mentioned_p (operands[0], operands[1])
8344 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8345 [(set (match_dup 0) (match_dup 2))
8346 (parallel [(set (match_dup 1)
8347 (minus:SWI (minus:SWI (match_dup 1)
8349 [(match_dup 3) (const_int 0)]))
8351 (clobber (reg:CC FLAGS_REG))])])
8354 [(set (match_operand:SWI 0 "general_reg_operand")
8355 (match_operand:SWI 1 "memory_operand"))
8356 (parallel [(set (match_dup 0)
8360 (match_operator:SWI 4 "ix86_carry_flag_operator"
8361 [(match_operand 3 "flags_reg_operand")
8363 (match_operand:SWI 2 "memory_operand")))
8364 (clobber (reg:CC FLAGS_REG))])
8365 (set (match_operand:SWI 5 "general_reg_operand") (match_dup 0))
8366 (set (match_dup 1) (match_dup 5))]
8367 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8368 && peep2_reg_dead_p (3, operands[0])
8369 && peep2_reg_dead_p (4, operands[5])
8370 && !reg_overlap_mentioned_p (operands[0], operands[1])
8371 && !reg_overlap_mentioned_p (operands[0], operands[2])
8372 && !reg_overlap_mentioned_p (operands[5], operands[1])"
8373 [(set (match_dup 0) (match_dup 2))
8374 (parallel [(set (match_dup 1)
8375 (minus:SWI (minus:SWI (match_dup 1)
8377 [(match_dup 3) (const_int 0)]))
8379 (clobber (reg:CC FLAGS_REG))])])
8381 (define_insn "*sub<mode>3_carry_0"
8382 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8384 (match_operand:SWI 1 "nonimmediate_operand" "0")
8385 (match_operator:SWI 2 "ix86_carry_flag_operator"
8386 [(reg FLAGS_REG) (const_int 0)])))
8387 (clobber (reg:CC FLAGS_REG))]
8388 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8389 "sbb{<imodesuffix>}\t{$0, %0|%0, 0}"
8390 [(set_attr "type" "alu")
8391 (set_attr "use_carry" "1")
8392 (set_attr "pent_pair" "pu")
8393 (set_attr "mode" "<MODE>")])
8395 (define_insn "*sub<mode>3_carry_0r"
8396 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8398 (match_operand:SWI 1 "nonimmediate_operand" "0")
8399 (match_operator:SWI 2 "ix86_carry_flag_unset_operator"
8400 [(reg FLAGS_REG) (const_int 0)])))
8401 (clobber (reg:CC FLAGS_REG))]
8402 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8403 "adc{<imodesuffix>}\t{$-1, %0|%0, -1}"
8404 [(set_attr "type" "alu")
8405 (set_attr "use_carry" "1")
8406 (set_attr "pent_pair" "pu")
8407 (set_attr "mode" "<MODE>")])
8409 (define_insn "*subsi3_carry_zext"
8410 [(set (match_operand:DI 0 "register_operand" "=r")
8414 (match_operand:SI 1 "register_operand" "0")
8415 (match_operator:SI 3 "ix86_carry_flag_operator"
8416 [(reg FLAGS_REG) (const_int 0)]))
8417 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
8418 (clobber (reg:CC FLAGS_REG))]
8419 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
8420 "sbb{l}\t{%2, %k0|%k0, %2}"
8421 [(set_attr "type" "alu")
8422 (set_attr "use_carry" "1")
8423 (set_attr "pent_pair" "pu")
8424 (set_attr "mode" "SI")])
8426 (define_insn "*subsi3_carry_zext_0"
8427 [(set (match_operand:DI 0 "register_operand" "=r")
8430 (match_operand:SI 1 "register_operand" "0")
8431 (match_operator:SI 2 "ix86_carry_flag_operator"
8432 [(reg FLAGS_REG) (const_int 0)]))))
8433 (clobber (reg:CC FLAGS_REG))]
8435 "sbb{l}\t{$0, %k0|%k0, 0}"
8436 [(set_attr "type" "alu")
8437 (set_attr "use_carry" "1")
8438 (set_attr "pent_pair" "pu")
8439 (set_attr "mode" "SI")])
8441 (define_insn "*subsi3_carry_zext_0r"
8442 [(set (match_operand:DI 0 "register_operand" "=r")
8445 (match_operand:SI 1 "register_operand" "0")
8446 (match_operator:SI 2 "ix86_carry_flag_unset_operator"
8447 [(reg FLAGS_REG) (const_int 0)]))))
8448 (clobber (reg:CC FLAGS_REG))]
8450 "adc{l}\t{$-1, %k0|%k0, -1}"
8451 [(set_attr "type" "alu")
8452 (set_attr "use_carry" "1")
8453 (set_attr "pent_pair" "pu")
8454 (set_attr "mode" "SI")])
8456 (define_insn "@sub<mode>3_carry_ccc"
8457 [(set (reg:CCC FLAGS_REG)
8459 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
8461 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
8463 (match_operand:DWIH 2 "x86_64_sext_operand" "rmWe")))))
8464 (clobber (match_scratch:DWIH 0 "=r"))]
8466 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8467 [(set_attr "type" "alu")
8468 (set_attr "mode" "<MODE>")])
8470 (define_insn "*sub<mode>3_carry_ccc_1"
8471 [(set (reg:CCC FLAGS_REG)
8473 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
8475 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
8476 (match_operand:<DWI> 2 "x86_64_dwzext_immediate_operand" "Wf"))))
8477 (clobber (match_scratch:DWIH 0 "=r"))]
8480 operands[3] = simplify_subreg (<MODE>mode, operands[2], <DWI>mode, 0);
8481 return "sbb{<imodesuffix>}\t{%3, %0|%0, %3}";
8483 [(set_attr "type" "alu")
8484 (set_attr "mode" "<MODE>")])
8486 ;; The sign flag is set from the
8487 ;; (compare (match_dup 1) (plus:DWIH (ltu:DWIH ...) (match_dup 2)))
8488 ;; result, the overflow flag likewise, but the overflow flag is also
8489 ;; set if the (plus:DWIH (ltu:DWIH ...) (match_dup 2)) overflows.
8490 (define_insn "@sub<mode>3_carry_ccgz"
8491 [(set (reg:CCGZ FLAGS_REG)
8492 (unspec:CCGZ [(match_operand:DWIH 1 "register_operand" "0")
8493 (match_operand:DWIH 2 "x86_64_general_operand" "rBMe")
8494 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))]
8496 (clobber (match_scratch:DWIH 0 "=r"))]
8498 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8499 [(set_attr "type" "alu")
8500 (set_attr "mode" "<MODE>")])
8502 (define_insn "subborrow<mode>"
8503 [(set (reg:CCC FLAGS_REG)
8506 (match_operand:SWI48 1 "nonimmediate_operand" "0,0"))
8508 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8509 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8511 (match_operand:SWI48 2 "nonimmediate_operand" "r,rm")))))
8512 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
8513 (minus:SWI48 (minus:SWI48
8515 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8516 [(match_dup 3) (const_int 0)]))
8518 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
8519 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8520 [(set_attr "type" "alu")
8521 (set_attr "use_carry" "1")
8522 (set_attr "pent_pair" "pu")
8523 (set_attr "mode" "<MODE>")])
8526 [(set (match_operand:SWI48 0 "general_reg_operand")
8527 (match_operand:SWI48 1 "memory_operand"))
8528 (parallel [(set (reg:CCC FLAGS_REG)
8530 (zero_extend:<DWI> (match_dup 0))
8532 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8533 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8535 (match_operand:SWI48 2 "memory_operand")))))
8540 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8541 [(match_dup 3) (const_int 0)]))
8543 (set (match_dup 1) (match_dup 0))]
8544 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8545 && peep2_reg_dead_p (3, operands[0])
8546 && !reg_overlap_mentioned_p (operands[0], operands[1])
8547 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8548 [(set (match_dup 0) (match_dup 2))
8549 (parallel [(set (reg:CCC FLAGS_REG)
8551 (zero_extend:<DWI> (match_dup 1))
8552 (plus:<DWI> (match_op_dup 4
8553 [(match_dup 3) (const_int 0)])
8554 (zero_extend:<DWI> (match_dup 0)))))
8556 (minus:SWI48 (minus:SWI48 (match_dup 1)
8558 [(match_dup 3) (const_int 0)]))
8562 [(set (match_operand:SWI48 6 "general_reg_operand")
8563 (match_operand:SWI48 7 "memory_operand"))
8564 (set (match_operand:SWI48 8 "general_reg_operand")
8565 (match_operand:SWI48 9 "memory_operand"))
8566 (parallel [(set (reg:CCC FLAGS_REG)
8569 (match_operand:SWI48 0 "general_reg_operand"))
8571 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8572 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8574 (match_operand:SWI48 2 "general_reg_operand")))))
8579 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8580 [(match_dup 3) (const_int 0)]))
8582 (set (match_operand:SWI48 1 "memory_operand") (match_dup 0))]
8583 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8584 && peep2_reg_dead_p (4, operands[0])
8585 && peep2_reg_dead_p (3, operands[2])
8586 && !reg_overlap_mentioned_p (operands[0], operands[1])
8587 && !reg_overlap_mentioned_p (operands[2], operands[1])
8588 && !reg_overlap_mentioned_p (operands[6], operands[9])
8589 && (rtx_equal_p (operands[6], operands[0])
8590 ? (rtx_equal_p (operands[7], operands[1])
8591 && rtx_equal_p (operands[8], operands[2]))
8592 : (rtx_equal_p (operands[8], operands[0])
8593 && rtx_equal_p (operands[9], operands[1])
8594 && rtx_equal_p (operands[6], operands[2])))"
8595 [(set (match_dup 0) (match_dup 9))
8596 (parallel [(set (reg:CCC FLAGS_REG)
8598 (zero_extend:<DWI> (match_dup 1))
8599 (plus:<DWI> (match_op_dup 4
8600 [(match_dup 3) (const_int 0)])
8601 (zero_extend:<DWI> (match_dup 0)))))
8603 (minus:SWI48 (minus:SWI48 (match_dup 1)
8605 [(match_dup 3) (const_int 0)]))
8608 if (!rtx_equal_p (operands[6], operands[0]))
8609 operands[9] = operands[7];
8613 [(set (match_operand:SWI48 6 "general_reg_operand")
8614 (match_operand:SWI48 7 "memory_operand"))
8615 (set (match_operand:SWI48 8 "general_reg_operand")
8616 (match_operand:SWI48 9 "memory_operand"))
8617 (parallel [(set (reg:CCC FLAGS_REG)
8620 (match_operand:SWI48 0 "general_reg_operand"))
8622 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8623 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8625 (match_operand:SWI48 2 "general_reg_operand")))))
8630 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8631 [(match_dup 3) (const_int 0)]))
8633 (set (match_operand:QI 10 "general_reg_operand")
8634 (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8635 (set (match_operand:SWI48 11 "general_reg_operand")
8636 (zero_extend:SWI48 (match_dup 10)))
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 (6, 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 && !reg_overlap_mentioned_p (operands[0], operands[10])
8645 && !reg_overlap_mentioned_p (operands[10], operands[1])
8646 && !reg_overlap_mentioned_p (operands[0], operands[11])
8647 && !reg_overlap_mentioned_p (operands[11], operands[1])
8648 && (rtx_equal_p (operands[6], operands[0])
8649 ? (rtx_equal_p (operands[7], operands[1])
8650 && rtx_equal_p (operands[8], operands[2]))
8651 : (rtx_equal_p (operands[8], operands[0])
8652 && rtx_equal_p (operands[9], operands[1])
8653 && rtx_equal_p (operands[6], operands[2])))"
8654 [(set (match_dup 0) (match_dup 9))
8655 (parallel [(set (reg:CCC FLAGS_REG)
8657 (zero_extend:<DWI> (match_dup 1))
8658 (plus:<DWI> (match_op_dup 4
8659 [(match_dup 3) (const_int 0)])
8660 (zero_extend:<DWI> (match_dup 0)))))
8662 (minus:SWI48 (minus:SWI48 (match_dup 1)
8664 [(match_dup 3) (const_int 0)]))
8666 (set (match_dup 10) (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8667 (set (match_dup 11) (zero_extend:SWI48 (match_dup 10)))]
8669 if (!rtx_equal_p (operands[6], operands[0]))
8670 operands[9] = operands[7];
8673 (define_expand "subborrow<mode>_0"
8675 [(set (reg:CC FLAGS_REG)
8677 (match_operand:SWI48 1 "nonimmediate_operand")
8678 (match_operand:SWI48 2 "<general_operand>")))
8679 (set (match_operand:SWI48 0 "register_operand")
8680 (minus:SWI48 (match_dup 1) (match_dup 2)))])]
8681 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)")
8683 (define_expand "uaddc<mode>5"
8684 [(match_operand:SWI48 0 "register_operand")
8685 (match_operand:SWI48 1 "register_operand")
8686 (match_operand:SWI48 2 "register_operand")
8687 (match_operand:SWI48 3 "register_operand")
8688 (match_operand:SWI48 4 "nonmemory_operand")]
8691 rtx cf = gen_rtx_REG (CCCmode, FLAGS_REG), pat, pat2;
8692 if (operands[4] == const0_rtx)
8693 emit_insn (gen_addcarry<mode>_0 (operands[0], operands[2], operands[3]));
8696 ix86_expand_carry (operands[4]);
8697 pat = gen_rtx_LTU (<DWI>mode, cf, const0_rtx);
8698 pat2 = gen_rtx_LTU (<MODE>mode, cf, const0_rtx);
8699 emit_insn (gen_addcarry<mode> (operands[0], operands[2], operands[3],
8702 rtx cc = gen_reg_rtx (QImode);
8703 pat = gen_rtx_LTU (QImode, cf, const0_rtx);
8704 emit_insn (gen_rtx_SET (cc, pat));
8705 emit_insn (gen_zero_extendqi<mode>2 (operands[1], cc));
8709 (define_expand "usubc<mode>5"
8710 [(match_operand:SWI48 0 "register_operand")
8711 (match_operand:SWI48 1 "register_operand")
8712 (match_operand:SWI48 2 "register_operand")
8713 (match_operand:SWI48 3 "register_operand")
8714 (match_operand:SWI48 4 "nonmemory_operand")]
8718 if (operands[4] == const0_rtx)
8720 cf = gen_rtx_REG (CCmode, FLAGS_REG);
8721 emit_insn (gen_subborrow<mode>_0 (operands[0], operands[2],
8726 cf = gen_rtx_REG (CCCmode, FLAGS_REG);
8727 ix86_expand_carry (operands[4]);
8728 pat = gen_rtx_LTU (<DWI>mode, cf, const0_rtx);
8729 pat2 = gen_rtx_LTU (<MODE>mode, cf, const0_rtx);
8730 emit_insn (gen_subborrow<mode> (operands[0], operands[2], operands[3],
8733 rtx cc = gen_reg_rtx (QImode);
8734 pat = gen_rtx_LTU (QImode, cf, const0_rtx);
8735 emit_insn (gen_rtx_SET (cc, pat));
8736 emit_insn (gen_zero_extendqi<mode>2 (operands[1], cc));
8740 (define_mode_iterator CC_CCC [CC CCC])
8742 ;; Pre-reload splitter to optimize
8743 ;; *setcc_qi followed by *addqi3_cconly_overflow_1 with the same QI
8744 ;; operand and no intervening flags modifications into nothing.
8745 (define_insn_and_split "*setcc_qi_addqi3_cconly_overflow_1_<mode>"
8746 [(set (reg:CCC FLAGS_REG)
8747 (compare:CCC (neg:QI (geu:QI (reg:CC_CCC FLAGS_REG) (const_int 0)))
8748 (ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))))]
8749 "ix86_pre_reload_split ()"
8753 "emit_note (NOTE_INSN_DELETED); DONE;")
8755 ;; Set the carry flag from the carry flag.
8756 (define_insn_and_split "*setccc"
8757 [(set (reg:CCC FLAGS_REG)
8758 (reg:CCC FLAGS_REG))]
8759 "ix86_pre_reload_split ()"
8763 "emit_note (NOTE_INSN_DELETED); DONE;")
8765 ;; Set the carry flag from the carry flag.
8766 (define_insn_and_split "*setcc_qi_negqi_ccc_1_<mode>"
8767 [(set (reg:CCC FLAGS_REG)
8768 (ltu:CCC (reg:CC_CCC FLAGS_REG) (const_int 0)))]
8769 "ix86_pre_reload_split ()"
8773 "emit_note (NOTE_INSN_DELETED); DONE;")
8775 ;; Set the carry flag from the carry flag.
8776 (define_insn_and_split "*setcc_qi_negqi_ccc_2_<mode>"
8777 [(set (reg:CCC FLAGS_REG)
8778 (unspec:CCC [(ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))
8779 (const_int 0)] UNSPEC_CC_NE))]
8780 "ix86_pre_reload_split ()"
8784 "emit_note (NOTE_INSN_DELETED); DONE;")
8786 ;; Overflow setting add instructions
8788 (define_expand "addqi3_cconly_overflow"
8790 [(set (reg:CCC FLAGS_REG)
8793 (match_operand:QI 0 "nonimmediate_operand")
8794 (match_operand:QI 1 "general_operand"))
8796 (clobber (scratch:QI))])]
8797 "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
8799 (define_insn "*add<mode>3_cconly_overflow_1"
8800 [(set (reg:CCC FLAGS_REG)
8803 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8804 (match_operand:SWI 2 "<general_operand>" "<g>"))
8806 (clobber (match_scratch:SWI 0 "=<r>"))]
8807 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8808 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
8809 [(set_attr "type" "alu")
8810 (set_attr "mode" "<MODE>")])
8812 (define_insn "*add<mode>3_cc_overflow_1"
8813 [(set (reg:CCC FLAGS_REG)
8816 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8817 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
8819 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
8820 (plus:SWI (match_dup 1) (match_dup 2)))]
8821 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
8822 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
8823 [(set_attr "type" "alu")
8824 (set_attr "mode" "<MODE>")])
8827 [(parallel [(set (reg:CCC FLAGS_REG)
8829 (plus:SWI (match_operand:SWI 0 "general_reg_operand")
8830 (match_operand:SWI 1 "memory_operand"))
8832 (set (match_dup 0) (plus:SWI (match_dup 0) (match_dup 1)))])
8833 (set (match_dup 1) (match_dup 0))]
8834 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8835 && peep2_reg_dead_p (2, operands[0])
8836 && !reg_overlap_mentioned_p (operands[0], operands[1])"
8837 [(parallel [(set (reg:CCC FLAGS_REG)
8839 (plus:SWI (match_dup 1) (match_dup 0))
8841 (set (match_dup 1) (plus:SWI (match_dup 1) (match_dup 0)))])])
8844 [(set (match_operand:SWI 0 "general_reg_operand")
8845 (match_operand:SWI 1 "memory_operand"))
8846 (parallel [(set (reg:CCC FLAGS_REG)
8848 (plus:SWI (match_dup 0)
8849 (match_operand:SWI 2 "memory_operand"))
8851 (set (match_dup 0) (plus:SWI (match_dup 0) (match_dup 2)))])
8852 (set (match_dup 1) (match_dup 0))]
8853 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8854 && peep2_reg_dead_p (3, operands[0])
8855 && !reg_overlap_mentioned_p (operands[0], operands[1])
8856 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8857 [(set (match_dup 0) (match_dup 2))
8858 (parallel [(set (reg:CCC FLAGS_REG)
8860 (plus:SWI (match_dup 1) (match_dup 0))
8862 (set (match_dup 1) (plus:SWI (match_dup 1) (match_dup 0)))])])
8864 (define_insn "*addsi3_zext_cc_overflow_1"
8865 [(set (reg:CCC FLAGS_REG)
8868 (match_operand:SI 1 "nonimmediate_operand" "%0")
8869 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
8871 (set (match_operand:DI 0 "register_operand" "=r")
8872 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8873 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
8874 "add{l}\t{%2, %k0|%k0, %2}"
8875 [(set_attr "type" "alu")
8876 (set_attr "mode" "SI")])
8878 (define_insn "*add<mode>3_cconly_overflow_2"
8879 [(set (reg:CCC FLAGS_REG)
8882 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8883 (match_operand:SWI 2 "<general_operand>" "<g>"))
8885 (clobber (match_scratch:SWI 0 "=<r>"))]
8886 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8887 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
8888 [(set_attr "type" "alu")
8889 (set_attr "mode" "<MODE>")])
8891 (define_insn "*add<mode>3_cc_overflow_2"
8892 [(set (reg:CCC FLAGS_REG)
8895 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8896 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
8898 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
8899 (plus:SWI (match_dup 1) (match_dup 2)))]
8900 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
8901 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
8902 [(set_attr "type" "alu")
8903 (set_attr "mode" "<MODE>")])
8905 (define_insn "*addsi3_zext_cc_overflow_2"
8906 [(set (reg:CCC FLAGS_REG)
8909 (match_operand:SI 1 "nonimmediate_operand" "%0")
8910 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
8912 (set (match_operand:DI 0 "register_operand" "=r")
8913 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8914 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
8915 "add{l}\t{%2, %k0|%k0, %2}"
8916 [(set_attr "type" "alu")
8917 (set_attr "mode" "SI")])
8919 (define_insn_and_split "*add<dwi>3_doubleword_cc_overflow_1"
8920 [(set (reg:CCC FLAGS_REG)
8923 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
8924 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o"))
8926 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
8927 (plus:<DWI> (match_dup 1) (match_dup 2)))]
8928 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
8930 "&& reload_completed"
8931 [(parallel [(set (reg:CCC FLAGS_REG)
8933 (plus:DWIH (match_dup 1) (match_dup 2))
8936 (plus:DWIH (match_dup 1) (match_dup 2)))])
8937 (parallel [(set (reg:CCC FLAGS_REG)
8942 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8947 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))))
8950 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8954 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
8955 if (operands[2] == const0_rtx)
8957 emit_insn (gen_addcarry<mode>_0 (operands[3], operands[4], operands[5]));
8960 if (CONST_INT_P (operands[5]))
8961 operands[6] = simplify_unary_operation (ZERO_EXTEND, <DWI>mode,
8962 operands[5], <MODE>mode);
8964 operands[6] = gen_rtx_ZERO_EXTEND (<DWI>mode, operands[5]);
8967 ;; x == 0 with zero flag test can be done also as x < 1U with carry flag
8968 ;; test, where the latter is preferrable if we have some carry consuming
8970 ;; For x != 0, we need to use x < 1U with negation of carry, i.e.
8972 (define_insn_and_split "*add<mode>3_eq"
8973 [(set (match_operand:SWI 0 "nonimmediate_operand")
8976 (eq:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0))
8977 (match_operand:SWI 1 "nonimmediate_operand"))
8978 (match_operand:SWI 2 "<general_operand>")))
8979 (clobber (reg:CC FLAGS_REG))]
8980 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
8981 && ix86_pre_reload_split ()"
8984 [(set (reg:CC FLAGS_REG)
8985 (compare:CC (match_dup 3) (const_int 1)))
8986 (parallel [(set (match_dup 0)
8988 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
8991 (clobber (reg:CC FLAGS_REG))])])
8993 (define_insn_and_split "*add<mode>3_ne"
8994 [(set (match_operand:SWI 0 "nonimmediate_operand")
8997 (ne:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0))
8998 (match_operand:SWI 1 "nonimmediate_operand"))
8999 (match_operand:SWI 2 "<immediate_operand>")))
9000 (clobber (reg:CC FLAGS_REG))]
9001 "CONST_INT_P (operands[2])
9002 && (<MODE>mode != DImode
9003 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
9004 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
9005 && ix86_pre_reload_split ()"
9008 [(set (reg:CC FLAGS_REG)
9009 (compare:CC (match_dup 3) (const_int 1)))
9010 (parallel [(set (match_dup 0)
9012 (minus:SWI (match_dup 1)
9013 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9015 (clobber (reg:CC FLAGS_REG))])]
9017 operands[2] = gen_int_mode (~INTVAL (operands[2]),
9018 <MODE>mode == DImode ? SImode : <MODE>mode);
9021 (define_insn_and_split "*add<mode>3_eq_0"
9022 [(set (match_operand:SWI 0 "nonimmediate_operand")
9024 (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))
9025 (match_operand:SWI 1 "<general_operand>")))
9026 (clobber (reg:CC FLAGS_REG))]
9027 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)
9028 && ix86_pre_reload_split ()"
9031 [(set (reg:CC FLAGS_REG)
9032 (compare:CC (match_dup 2) (const_int 1)))
9033 (parallel [(set (match_dup 0)
9034 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9036 (clobber (reg:CC FLAGS_REG))])]
9038 if (!nonimmediate_operand (operands[1], <MODE>mode))
9039 operands[1] = force_reg (<MODE>mode, operands[1]);
9042 (define_insn_and_split "*add<mode>3_ne_0"
9043 [(set (match_operand:SWI 0 "nonimmediate_operand")
9045 (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))
9046 (match_operand:SWI 1 "<general_operand>")))
9047 (clobber (reg:CC FLAGS_REG))]
9048 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)
9049 && ix86_pre_reload_split ()"
9052 [(set (reg:CC FLAGS_REG)
9053 (compare:CC (match_dup 2) (const_int 1)))
9054 (parallel [(set (match_dup 0)
9055 (minus:SWI (minus:SWI
9057 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9059 (clobber (reg:CC FLAGS_REG))])]
9061 if (!nonimmediate_operand (operands[1], <MODE>mode))
9062 operands[1] = force_reg (<MODE>mode, operands[1]);
9065 (define_insn_and_split "*sub<mode>3_eq"
9066 [(set (match_operand:SWI 0 "nonimmediate_operand")
9069 (match_operand:SWI 1 "nonimmediate_operand")
9070 (eq:SWI (match_operand 3 "int_nonimmediate_operand")
9072 (match_operand:SWI 2 "<general_operand>")))
9073 (clobber (reg:CC FLAGS_REG))]
9074 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
9075 && ix86_pre_reload_split ()"
9078 [(set (reg:CC FLAGS_REG)
9079 (compare:CC (match_dup 3) (const_int 1)))
9080 (parallel [(set (match_dup 0)
9082 (minus:SWI (match_dup 1)
9083 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9085 (clobber (reg:CC FLAGS_REG))])])
9087 (define_insn_and_split "*sub<mode>3_ne"
9088 [(set (match_operand:SWI 0 "nonimmediate_operand")
9091 (match_operand:SWI 1 "nonimmediate_operand")
9092 (ne:SWI (match_operand 3 "int_nonimmediate_operand")
9094 (match_operand:SWI 2 "<immediate_operand>")))
9095 (clobber (reg:CC FLAGS_REG))]
9096 "CONST_INT_P (operands[2])
9097 && (<MODE>mode != DImode
9098 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
9099 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
9100 && ix86_pre_reload_split ()"
9103 [(set (reg:CC FLAGS_REG)
9104 (compare:CC (match_dup 3) (const_int 1)))
9105 (parallel [(set (match_dup 0)
9107 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9110 (clobber (reg:CC FLAGS_REG))])]
9112 operands[2] = gen_int_mode (INTVAL (operands[2]) - 1,
9113 <MODE>mode == DImode ? SImode : <MODE>mode);
9116 (define_insn_and_split "*sub<mode>3_eq_1"
9117 [(set (match_operand:SWI 0 "nonimmediate_operand")
9120 (match_operand:SWI 1 "nonimmediate_operand")
9121 (eq:SWI (match_operand 3 "int_nonimmediate_operand")
9123 (match_operand:SWI 2 "<immediate_operand>")))
9124 (clobber (reg:CC FLAGS_REG))]
9125 "CONST_INT_P (operands[2])
9126 && (<MODE>mode != DImode
9127 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
9128 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
9129 && ix86_pre_reload_split ()"
9132 [(set (reg:CC FLAGS_REG)
9133 (compare:CC (match_dup 3) (const_int 1)))
9134 (parallel [(set (match_dup 0)
9136 (minus:SWI (match_dup 1)
9137 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9139 (clobber (reg:CC FLAGS_REG))])]
9141 operands[2] = gen_int_mode (-INTVAL (operands[2]),
9142 <MODE>mode == DImode ? SImode : <MODE>mode);
9145 (define_insn_and_split "*sub<mode>3_eq_0"
9146 [(set (match_operand:SWI 0 "nonimmediate_operand")
9148 (match_operand:SWI 1 "<general_operand>")
9149 (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))))
9150 (clobber (reg:CC FLAGS_REG))]
9151 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)
9152 && ix86_pre_reload_split ()"
9155 [(set (reg:CC FLAGS_REG)
9156 (compare:CC (match_dup 2) (const_int 1)))
9157 (parallel [(set (match_dup 0)
9158 (minus:SWI (match_dup 1)
9159 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))))
9160 (clobber (reg:CC FLAGS_REG))])]
9162 if (!nonimmediate_operand (operands[1], <MODE>mode))
9163 operands[1] = force_reg (<MODE>mode, operands[1]);
9166 (define_insn_and_split "*sub<mode>3_ne_0"
9167 [(set (match_operand:SWI 0 "nonimmediate_operand")
9169 (match_operand:SWI 1 "<general_operand>")
9170 (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))))
9171 (clobber (reg:CC FLAGS_REG))]
9172 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)
9173 && ix86_pre_reload_split ()"
9176 [(set (reg:CC FLAGS_REG)
9177 (compare:CC (match_dup 2) (const_int 1)))
9178 (parallel [(set (match_dup 0)
9180 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9183 (clobber (reg:CC FLAGS_REG))])]
9185 if (!nonimmediate_operand (operands[1], <MODE>mode))
9186 operands[1] = force_reg (<MODE>mode, operands[1]);
9189 ;; The patterns that match these are at the end of this file.
9191 (define_expand "<insn>xf3"
9192 [(set (match_operand:XF 0 "register_operand")
9194 (match_operand:XF 1 "register_operand")
9195 (match_operand:XF 2 "register_operand")))]
9198 (define_expand "<insn>hf3"
9199 [(set (match_operand:HF 0 "register_operand")
9201 (match_operand:HF 1 "register_operand")
9202 (match_operand:HF 2 "nonimmediate_operand")))]
9203 "TARGET_AVX512FP16")
9205 (define_expand "<insn><mode>3"
9206 [(set (match_operand:MODEF 0 "register_operand")
9208 (match_operand:MODEF 1 "register_operand")
9209 (match_operand:MODEF 2 "nonimmediate_operand")))]
9210 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
9211 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
9213 ;; Multiply instructions
9215 (define_expand "mul<mode>3"
9216 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
9218 (match_operand:SWIM248 1 "register_operand")
9219 (match_operand:SWIM248 2 "<general_operand>")))
9220 (clobber (reg:CC FLAGS_REG))])])
9222 (define_expand "mulqi3"
9223 [(parallel [(set (match_operand:QI 0 "register_operand")
9225 (match_operand:QI 1 "register_operand")
9226 (match_operand:QI 2 "nonimmediate_operand")))
9227 (clobber (reg:CC FLAGS_REG))])]
9228 "TARGET_QIMODE_MATH")
9231 ;; IMUL reg32/64, reg32/64, imm8 Direct
9232 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
9233 ;; IMUL reg32/64, reg32/64, imm32 Direct
9234 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
9235 ;; IMUL reg32/64, reg32/64 Direct
9236 ;; IMUL reg32/64, mem32/64 Direct
9238 ;; On BDVER1, all above IMULs use DirectPath
9241 ;; IMUL reg16, reg16, imm8 VectorPath
9242 ;; IMUL reg16, mem16, imm8 VectorPath
9243 ;; IMUL reg16, reg16, imm16 VectorPath
9244 ;; IMUL reg16, mem16, imm16 VectorPath
9245 ;; IMUL reg16, reg16 Direct
9246 ;; IMUL reg16, mem16 Direct
9248 ;; On BDVER1, all HI MULs use DoublePath
9250 (define_insn "*mul<mode>3_1"
9251 [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
9253 (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
9254 (match_operand:SWIM248 2 "<general_operand>" "K,<i>,<m>r")))
9255 (clobber (reg:CC FLAGS_REG))]
9256 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9258 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9259 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9260 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
9261 [(set_attr "type" "imul")
9262 (set_attr "prefix_0f" "0,0,1")
9263 (set (attr "athlon_decode")
9264 (cond [(eq_attr "cpu" "athlon")
9265 (const_string "vector")
9266 (eq_attr "alternative" "1")
9267 (const_string "vector")
9268 (and (eq_attr "alternative" "2")
9269 (ior (match_test "<MODE>mode == HImode")
9270 (match_operand 1 "memory_operand")))
9271 (const_string "vector")]
9272 (const_string "direct")))
9273 (set (attr "amdfam10_decode")
9274 (cond [(and (eq_attr "alternative" "0,1")
9275 (ior (match_test "<MODE>mode == HImode")
9276 (match_operand 1 "memory_operand")))
9277 (const_string "vector")]
9278 (const_string "direct")))
9279 (set (attr "bdver1_decode")
9281 (match_test "<MODE>mode == HImode")
9282 (const_string "double")
9283 (const_string "direct")))
9284 (set_attr "mode" "<MODE>")])
9286 (define_insn "*mulsi3_1_zext"
9287 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9289 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
9290 (match_operand:SI 2 "x86_64_general_operand" "K,e,BMr"))))
9291 (clobber (reg:CC FLAGS_REG))]
9293 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9295 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
9296 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
9297 imul{l}\t{%2, %k0|%k0, %2}"
9298 [(set_attr "type" "imul")
9299 (set_attr "prefix_0f" "0,0,1")
9300 (set (attr "athlon_decode")
9301 (cond [(eq_attr "cpu" "athlon")
9302 (const_string "vector")
9303 (eq_attr "alternative" "1")
9304 (const_string "vector")
9305 (and (eq_attr "alternative" "2")
9306 (match_operand 1 "memory_operand"))
9307 (const_string "vector")]
9308 (const_string "direct")))
9309 (set (attr "amdfam10_decode")
9310 (cond [(and (eq_attr "alternative" "0,1")
9311 (match_operand 1 "memory_operand"))
9312 (const_string "vector")]
9313 (const_string "direct")))
9314 (set_attr "bdver1_decode" "direct")
9315 (set_attr "mode" "SI")])
9317 ;;On AMDFAM10 and BDVER1
9321 (define_insn "*mulqi3_1"
9322 [(set (match_operand:QI 0 "register_operand" "=a")
9323 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9324 (match_operand:QI 2 "nonimmediate_operand" "qm")))
9325 (clobber (reg:CC FLAGS_REG))]
9327 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9329 [(set_attr "type" "imul")
9330 (set_attr "length_immediate" "0")
9331 (set (attr "athlon_decode")
9332 (if_then_else (eq_attr "cpu" "athlon")
9333 (const_string "vector")
9334 (const_string "direct")))
9335 (set_attr "amdfam10_decode" "direct")
9336 (set_attr "bdver1_decode" "direct")
9337 (set_attr "mode" "QI")])
9339 ;; Multiply with jump on overflow.
9340 (define_expand "mulv<mode>4"
9341 [(parallel [(set (reg:CCO FLAGS_REG)
9344 (match_operand:SWI248 1 "register_operand"))
9347 (mult:SWI248 (match_dup 1)
9348 (match_operand:SWI248 2
9349 "<general_operand>")))))
9350 (set (match_operand:SWI248 0 "register_operand")
9351 (mult:SWI248 (match_dup 1) (match_dup 2)))])
9352 (set (pc) (if_then_else
9353 (eq (reg:CCO FLAGS_REG) (const_int 0))
9354 (label_ref (match_operand 3))
9358 if (CONST_INT_P (operands[2]))
9359 operands[4] = operands[2];
9361 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
9364 (define_insn "*mulv<mode>4"
9365 [(set (reg:CCO FLAGS_REG)
9368 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
9370 (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
9372 (mult:SWI48 (match_dup 1) (match_dup 2)))))
9373 (set (match_operand:SWI48 0 "register_operand" "=r,r")
9374 (mult:SWI48 (match_dup 1) (match_dup 2)))]
9375 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9377 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9378 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
9379 [(set_attr "type" "imul")
9380 (set_attr "prefix_0f" "0,1")
9381 (set (attr "athlon_decode")
9382 (cond [(eq_attr "cpu" "athlon")
9383 (const_string "vector")
9384 (eq_attr "alternative" "0")
9385 (const_string "vector")
9386 (and (eq_attr "alternative" "1")
9387 (match_operand 1 "memory_operand"))
9388 (const_string "vector")]
9389 (const_string "direct")))
9390 (set (attr "amdfam10_decode")
9391 (cond [(and (eq_attr "alternative" "1")
9392 (match_operand 1 "memory_operand"))
9393 (const_string "vector")]
9394 (const_string "direct")))
9395 (set_attr "bdver1_decode" "direct")
9396 (set_attr "mode" "<MODE>")])
9398 (define_insn "*mulvhi4"
9399 [(set (reg:CCO FLAGS_REG)
9402 (match_operand:HI 1 "nonimmediate_operand" "%0"))
9404 (match_operand:HI 2 "nonimmediate_operand" "mr")))
9406 (mult:HI (match_dup 1) (match_dup 2)))))
9407 (set (match_operand:HI 0 "register_operand" "=r")
9408 (mult:HI (match_dup 1) (match_dup 2)))]
9409 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9410 "imul{w}\t{%2, %0|%0, %2}"
9411 [(set_attr "type" "imul")
9412 (set_attr "prefix_0f" "1")
9413 (set_attr "athlon_decode" "vector")
9414 (set_attr "amdfam10_decode" "direct")
9415 (set_attr "bdver1_decode" "double")
9416 (set_attr "mode" "HI")])
9418 (define_insn "*mulv<mode>4_1"
9419 [(set (reg:CCO FLAGS_REG)
9422 (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
9423 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
9425 (mult:SWI248 (match_dup 1)
9426 (match_operand:SWI248 2
9427 "<immediate_operand>" "K,<i>")))))
9428 (set (match_operand:SWI248 0 "register_operand" "=r,r")
9429 (mult:SWI248 (match_dup 1) (match_dup 2)))]
9430 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
9431 && CONST_INT_P (operands[2])
9432 && INTVAL (operands[2]) == INTVAL (operands[3])"
9433 "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
9434 [(set_attr "type" "imul")
9435 (set (attr "prefix_0f")
9437 (match_test "<MODE>mode == HImode")
9439 (const_string "*")))
9440 (set (attr "athlon_decode")
9441 (cond [(eq_attr "cpu" "athlon")
9442 (const_string "vector")
9443 (eq_attr "alternative" "1")
9444 (const_string "vector")]
9445 (const_string "direct")))
9446 (set (attr "amdfam10_decode")
9447 (cond [(ior (match_test "<MODE>mode == HImode")
9448 (match_operand 1 "memory_operand"))
9449 (const_string "vector")]
9450 (const_string "direct")))
9451 (set (attr "bdver1_decode")
9453 (match_test "<MODE>mode == HImode")
9454 (const_string "double")
9455 (const_string "direct")))
9456 (set_attr "mode" "<MODE>")
9457 (set (attr "length_immediate")
9458 (cond [(eq_attr "alternative" "0")
9460 (match_test "<MODE_SIZE> == 8")
9462 (const_string "<MODE_SIZE>")))])
9464 (define_expand "umulv<mode>4"
9465 [(parallel [(set (reg:CCO FLAGS_REG)
9468 (match_operand:SWI248 1
9469 "nonimmediate_operand"))
9471 (match_operand:SWI248 2
9472 "nonimmediate_operand")))
9474 (mult:SWI248 (match_dup 1) (match_dup 2)))))
9475 (set (match_operand:SWI248 0 "register_operand")
9476 (mult:SWI248 (match_dup 1) (match_dup 2)))
9477 (clobber (scratch:SWI248))])
9478 (set (pc) (if_then_else
9479 (eq (reg:CCO FLAGS_REG) (const_int 0))
9480 (label_ref (match_operand 3))
9484 if (MEM_P (operands[1]) && MEM_P (operands[2]))
9485 operands[1] = force_reg (<MODE>mode, operands[1]);
9488 (define_insn "*umulv<mode>4"
9489 [(set (reg:CCO FLAGS_REG)
9492 (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
9494 (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
9496 (mult:SWI248 (match_dup 1) (match_dup 2)))))
9497 (set (match_operand:SWI248 0 "register_operand" "=a")
9498 (mult:SWI248 (match_dup 1) (match_dup 2)))
9499 (clobber (match_scratch:SWI248 3 "=d"))]
9500 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9501 "mul{<imodesuffix>}\t%2"
9502 [(set_attr "type" "imul")
9503 (set_attr "length_immediate" "0")
9504 (set (attr "athlon_decode")
9505 (if_then_else (eq_attr "cpu" "athlon")
9506 (const_string "vector")
9507 (const_string "double")))
9508 (set_attr "amdfam10_decode" "double")
9509 (set_attr "bdver1_decode" "direct")
9510 (set_attr "mode" "<MODE>")])
9512 (define_expand "<u>mulvqi4"
9513 [(parallel [(set (reg:CCO FLAGS_REG)
9516 (match_operand:QI 1 "nonimmediate_operand"))
9518 (match_operand:QI 2 "nonimmediate_operand")))
9520 (mult:QI (match_dup 1) (match_dup 2)))))
9521 (set (match_operand:QI 0 "register_operand")
9522 (mult:QI (match_dup 1) (match_dup 2)))])
9523 (set (pc) (if_then_else
9524 (eq (reg:CCO FLAGS_REG) (const_int 0))
9525 (label_ref (match_operand 3))
9527 "TARGET_QIMODE_MATH"
9529 if (MEM_P (operands[1]) && MEM_P (operands[2]))
9530 operands[1] = force_reg (QImode, operands[1]);
9533 (define_insn "*<u>mulvqi4"
9534 [(set (reg:CCO FLAGS_REG)
9537 (match_operand:QI 1 "nonimmediate_operand" "%0"))
9539 (match_operand:QI 2 "nonimmediate_operand" "qm")))
9541 (mult:QI (match_dup 1) (match_dup 2)))))
9542 (set (match_operand:QI 0 "register_operand" "=a")
9543 (mult:QI (match_dup 1) (match_dup 2)))]
9545 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9546 "<sgnprefix>mul{b}\t%2"
9547 [(set_attr "type" "imul")
9548 (set_attr "length_immediate" "0")
9549 (set (attr "athlon_decode")
9550 (if_then_else (eq_attr "cpu" "athlon")
9551 (const_string "vector")
9552 (const_string "direct")))
9553 (set_attr "amdfam10_decode" "direct")
9554 (set_attr "bdver1_decode" "direct")
9555 (set_attr "mode" "QI")])
9557 (define_expand "<u>mul<mode><dwi>3"
9558 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
9561 (match_operand:DWIH 1 "nonimmediate_operand"))
9563 (match_operand:DWIH 2 "register_operand"))))
9564 (clobber (reg:CC FLAGS_REG))])])
9566 (define_expand "<u>mulqihi3"
9567 [(parallel [(set (match_operand:HI 0 "register_operand")
9570 (match_operand:QI 1 "nonimmediate_operand"))
9572 (match_operand:QI 2 "register_operand"))))
9573 (clobber (reg:CC FLAGS_REG))])]
9574 "TARGET_QIMODE_MATH")
9576 (define_insn "*bmi2_umul<mode><dwi>3_1"
9577 [(set (match_operand:DWIH 0 "register_operand" "=r")
9579 (match_operand:DWIH 2 "nonimmediate_operand" "%d")
9580 (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
9581 (set (match_operand:DWIH 1 "register_operand" "=r")
9584 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
9585 (zero_extend:<DWI> (match_dup 3)))
9586 (match_operand:QI 4 "const_int_operand"))))]
9587 "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
9588 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
9589 "mulx\t{%3, %0, %1|%1, %0, %3}"
9590 [(set_attr "type" "imulx")
9591 (set_attr "prefix" "vex")
9592 (set_attr "mode" "<MODE>")])
9594 (define_insn "*umul<mode><dwi>3_1"
9595 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
9598 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
9600 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
9601 (clobber (reg:CC FLAGS_REG))]
9602 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9605 mul{<imodesuffix>}\t%2"
9606 [(set_attr "isa" "bmi2,*")
9607 (set_attr "type" "imulx,imul")
9608 (set_attr "length_immediate" "*,0")
9609 (set (attr "athlon_decode")
9610 (cond [(eq_attr "alternative" "1")
9611 (if_then_else (eq_attr "cpu" "athlon")
9612 (const_string "vector")
9613 (const_string "double"))]
9614 (const_string "*")))
9615 (set_attr "amdfam10_decode" "*,double")
9616 (set_attr "bdver1_decode" "*,direct")
9617 (set_attr "prefix" "vex,orig")
9618 (set_attr "mode" "<MODE>")])
9620 ;; Convert mul to the mulx pattern to avoid flags dependency.
9622 [(set (match_operand:<DWI> 0 "register_operand")
9625 (match_operand:DWIH 1 "register_operand"))
9627 (match_operand:DWIH 2 "nonimmediate_operand"))))
9628 (clobber (reg:CC FLAGS_REG))]
9629 "TARGET_BMI2 && reload_completed
9630 && REGNO (operands[1]) == DX_REG"
9631 [(parallel [(set (match_dup 3)
9632 (mult:DWIH (match_dup 1) (match_dup 2)))
9636 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
9637 (zero_extend:<DWI> (match_dup 2)))
9640 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
9642 operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
9645 (define_insn "*mul<mode><dwi>3_1"
9646 [(set (match_operand:<DWI> 0 "register_operand" "=A")
9649 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
9651 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
9652 (clobber (reg:CC FLAGS_REG))]
9653 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9654 "imul{<imodesuffix>}\t%2"
9655 [(set_attr "type" "imul")
9656 (set_attr "length_immediate" "0")
9657 (set (attr "athlon_decode")
9658 (if_then_else (eq_attr "cpu" "athlon")
9659 (const_string "vector")
9660 (const_string "double")))
9661 (set_attr "amdfam10_decode" "double")
9662 (set_attr "bdver1_decode" "direct")
9663 (set_attr "mode" "<MODE>")])
9665 (define_insn "*<u>mulqihi3_1"
9666 [(set (match_operand:HI 0 "register_operand" "=a")
9669 (match_operand:QI 1 "nonimmediate_operand" "%0"))
9671 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
9672 (clobber (reg:CC FLAGS_REG))]
9674 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9675 "<sgnprefix>mul{b}\t%2"
9676 [(set_attr "type" "imul")
9677 (set_attr "length_immediate" "0")
9678 (set (attr "athlon_decode")
9679 (if_then_else (eq_attr "cpu" "athlon")
9680 (const_string "vector")
9681 (const_string "direct")))
9682 (set_attr "amdfam10_decode" "direct")
9683 (set_attr "bdver1_decode" "direct")
9684 (set_attr "mode" "QI")])
9686 ;; Highpart multiplication patterns
9687 (define_insn "<s>mul<mode>3_highpart"
9688 [(set (match_operand:DWIH 0 "register_operand" "=d")
9689 (any_mul_highpart:DWIH
9690 (match_operand:DWIH 1 "register_operand" "%a")
9691 (match_operand:DWIH 2 "nonimmediate_operand" "rm")))
9692 (clobber (match_scratch:DWIH 3 "=1"))
9693 (clobber (reg:CC FLAGS_REG))]
9695 "<sgnprefix>mul{<imodesuffix>}\t%2"
9696 [(set_attr "type" "imul")
9697 (set_attr "length_immediate" "0")
9698 (set (attr "athlon_decode")
9699 (if_then_else (eq_attr "cpu" "athlon")
9700 (const_string "vector")
9701 (const_string "double")))
9702 (set_attr "amdfam10_decode" "double")
9703 (set_attr "bdver1_decode" "direct")
9704 (set_attr "mode" "<MODE>")])
9706 (define_insn "*<s>mulsi3_highpart_zext"
9707 [(set (match_operand:DI 0 "register_operand" "=d")
9709 (any_mul_highpart:SI
9710 (match_operand:SI 1 "register_operand" "%a")
9711 (match_operand:SI 2 "nonimmediate_operand" "rm"))))
9712 (clobber (match_scratch:SI 3 "=1"))
9713 (clobber (reg:CC FLAGS_REG))]
9715 "<sgnprefix>mul{l}\t%2"
9716 [(set_attr "type" "imul")
9717 (set_attr "length_immediate" "0")
9718 (set (attr "athlon_decode")
9719 (if_then_else (eq_attr "cpu" "athlon")
9720 (const_string "vector")
9721 (const_string "double")))
9722 (set_attr "amdfam10_decode" "double")
9723 (set_attr "bdver1_decode" "direct")
9724 (set_attr "mode" "SI")])
9726 (define_insn "*<s>muldi3_highpart_1"
9727 [(set (match_operand:DI 0 "register_operand" "=d")
9732 (match_operand:DI 1 "nonimmediate_operand" "%a"))
9734 (match_operand:DI 2 "nonimmediate_operand" "rm")))
9736 (clobber (match_scratch:DI 3 "=1"))
9737 (clobber (reg:CC FLAGS_REG))]
9739 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9740 "<sgnprefix>mul{q}\t%2"
9741 [(set_attr "type" "imul")
9742 (set_attr "length_immediate" "0")
9743 (set (attr "athlon_decode")
9744 (if_then_else (eq_attr "cpu" "athlon")
9745 (const_string "vector")
9746 (const_string "double")))
9747 (set_attr "amdfam10_decode" "double")
9748 (set_attr "bdver1_decode" "direct")
9749 (set_attr "mode" "DI")])
9751 (define_insn "*<s>mulsi3_highpart_zext"
9752 [(set (match_operand:DI 0 "register_operand" "=d")
9753 (zero_extend:DI (truncate:SI
9755 (mult:DI (any_extend:DI
9756 (match_operand:SI 1 "nonimmediate_operand" "%a"))
9758 (match_operand:SI 2 "nonimmediate_operand" "rm")))
9760 (clobber (match_scratch:SI 3 "=1"))
9761 (clobber (reg:CC FLAGS_REG))]
9763 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9764 "<sgnprefix>mul{l}\t%2"
9765 [(set_attr "type" "imul")
9766 (set_attr "length_immediate" "0")
9767 (set (attr "athlon_decode")
9768 (if_then_else (eq_attr "cpu" "athlon")
9769 (const_string "vector")
9770 (const_string "double")))
9771 (set_attr "amdfam10_decode" "double")
9772 (set_attr "bdver1_decode" "direct")
9773 (set_attr "mode" "SI")])
9775 (define_insn "*<s>mulsi3_highpart_1"
9776 [(set (match_operand:SI 0 "register_operand" "=d")
9781 (match_operand:SI 1 "nonimmediate_operand" "%a"))
9783 (match_operand:SI 2 "nonimmediate_operand" "rm")))
9785 (clobber (match_scratch:SI 3 "=1"))
9786 (clobber (reg:CC FLAGS_REG))]
9787 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9788 "<sgnprefix>mul{l}\t%2"
9789 [(set_attr "type" "imul")
9790 (set_attr "length_immediate" "0")
9791 (set (attr "athlon_decode")
9792 (if_then_else (eq_attr "cpu" "athlon")
9793 (const_string "vector")
9794 (const_string "double")))
9795 (set_attr "amdfam10_decode" "double")
9796 (set_attr "bdver1_decode" "direct")
9797 (set_attr "mode" "SI")])
9799 ;; Highpart multiplication peephole2s to tweak register allocation.
9800 ;; mov imm,%rdx; mov %rdi,%rax; imulq %rdx -> mov imm,%rax; imulq %rdi
9802 [(set (match_operand:SWI48 0 "general_reg_operand")
9803 (match_operand:SWI48 1 "immediate_operand"))
9804 (set (match_operand:SWI48 2 "general_reg_operand")
9805 (match_operand:SWI48 3 "general_reg_operand"))
9806 (parallel [(set (match_operand:SWI48 4 "general_reg_operand")
9807 (any_mul_highpart:SWI48 (match_dup 2) (match_dup 0)))
9808 (clobber (match_dup 2))
9809 (clobber (reg:CC FLAGS_REG))])]
9810 "REGNO (operands[3]) != AX_REG
9811 && REGNO (operands[0]) != REGNO (operands[2])
9812 && REGNO (operands[0]) != REGNO (operands[3])
9813 && (REGNO (operands[0]) == REGNO (operands[4])
9814 || peep2_reg_dead_p (3, operands[0]))"
9815 [(set (match_dup 2) (match_dup 1))
9816 (parallel [(set (match_dup 4)
9817 (any_mul_highpart:SWI48 (match_dup 2) (match_dup 3)))
9818 (clobber (match_dup 2))
9819 (clobber (reg:CC FLAGS_REG))])])
9822 [(set (match_operand:SI 0 "general_reg_operand")
9823 (match_operand:SI 1 "immediate_operand"))
9824 (set (match_operand:SI 2 "general_reg_operand")
9825 (match_operand:SI 3 "general_reg_operand"))
9826 (parallel [(set (match_operand:DI 4 "general_reg_operand")
9828 (any_mul_highpart:SI (match_dup 2) (match_dup 0))))
9829 (clobber (match_dup 2))
9830 (clobber (reg:CC FLAGS_REG))])]
9832 && REGNO (operands[3]) != AX_REG
9833 && REGNO (operands[0]) != REGNO (operands[2])
9834 && REGNO (operands[2]) != REGNO (operands[3])
9835 && REGNO (operands[0]) != REGNO (operands[3])
9836 && (REGNO (operands[0]) == REGNO (operands[4])
9837 || peep2_reg_dead_p (3, operands[0]))"
9838 [(set (match_dup 2) (match_dup 1))
9839 (parallel [(set (match_dup 4)
9841 (any_mul_highpart:SI (match_dup 2) (match_dup 3))))
9842 (clobber (match_dup 2))
9843 (clobber (reg:CC FLAGS_REG))])])
9845 ;; The patterns that match these are at the end of this file.
9847 (define_expand "mulxf3"
9848 [(set (match_operand:XF 0 "register_operand")
9849 (mult:XF (match_operand:XF 1 "register_operand")
9850 (match_operand:XF 2 "register_operand")))]
9853 (define_expand "mulhf3"
9854 [(set (match_operand:HF 0 "register_operand")
9855 (mult:HF (match_operand:HF 1 "register_operand")
9856 (match_operand:HF 2 "nonimmediate_operand")))]
9857 "TARGET_AVX512FP16")
9859 (define_expand "mul<mode>3"
9860 [(set (match_operand:MODEF 0 "register_operand")
9861 (mult:MODEF (match_operand:MODEF 1 "register_operand")
9862 (match_operand:MODEF 2 "nonimmediate_operand")))]
9863 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
9864 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
9866 ;; Divide instructions
9868 ;; The patterns that match these are at the end of this file.
9870 (define_expand "divxf3"
9871 [(set (match_operand:XF 0 "register_operand")
9872 (div:XF (match_operand:XF 1 "register_operand")
9873 (match_operand:XF 2 "register_operand")))]
9876 /* There is no more precision loss than Newton-Rhapson approximation
9877 when using HFmode rcp/rsqrt, so do the transformation directly under
9878 TARGET_RECIP_DIV and fast-math. */
9879 (define_expand "divhf3"
9880 [(set (match_operand:HF 0 "register_operand")
9881 (div:HF (match_operand:HF 1 "register_operand")
9882 (match_operand:HF 2 "nonimmediate_operand")))]
9885 if (TARGET_RECIP_DIV
9886 && optimize_insn_for_speed_p ()
9887 && flag_finite_math_only && !flag_trapping_math
9888 && flag_unsafe_math_optimizations)
9890 rtx op = gen_reg_rtx (HFmode);
9891 operands[2] = force_reg (HFmode, operands[2]);
9892 emit_insn (gen_rcphf2 (op, operands[2]));
9893 emit_insn (gen_mulhf3 (operands[0], operands[1], op));
9898 (define_expand "div<mode>3"
9899 [(set (match_operand:MODEF 0 "register_operand")
9900 (div:MODEF (match_operand:MODEF 1 "register_operand")
9901 (match_operand:MODEF 2 "nonimmediate_operand")))]
9902 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
9903 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9905 if (<MODE>mode == SFmode
9906 && TARGET_SSE && TARGET_SSE_MATH
9908 && optimize_insn_for_speed_p ()
9909 && flag_finite_math_only && !flag_trapping_math
9910 && flag_unsafe_math_optimizations)
9912 ix86_emit_swdivsf (operands[0], operands[1],
9913 operands[2], SFmode);
9918 ;; Divmod instructions.
9920 (define_code_iterator any_div [div udiv])
9921 (define_code_attr paired_mod [(div "mod") (udiv "umod")])
9923 (define_expand "<u>divmod<mode>4"
9924 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
9926 (match_operand:SWIM248 1 "register_operand")
9927 (match_operand:SWIM248 2 "nonimmediate_operand")))
9928 (set (match_operand:SWIM248 3 "register_operand")
9929 (<paired_mod>:SWIM248 (match_dup 1) (match_dup 2)))
9930 (clobber (reg:CC FLAGS_REG))])])
9932 ;; Split with 8bit unsigned divide:
9933 ;; if (dividend an divisor are in [0-255])
9934 ;; use 8bit unsigned integer divide
9936 ;; use original integer divide
9938 [(set (match_operand:SWI48 0 "register_operand")
9939 (any_div:SWI48 (match_operand:SWI48 2 "register_operand")
9940 (match_operand:SWI48 3 "nonimmediate_operand")))
9941 (set (match_operand:SWI48 1 "register_operand")
9942 (<paired_mod>:SWI48 (match_dup 2) (match_dup 3)))
9943 (clobber (reg:CC FLAGS_REG))]
9944 "TARGET_USE_8BIT_IDIV
9945 && TARGET_QIMODE_MATH
9946 && can_create_pseudo_p ()
9947 && !optimize_insn_for_size_p ()"
9949 "ix86_split_idivmod (<MODE>mode, operands, <u_bool>); DONE;")
9952 [(set (match_operand:DI 0 "register_operand")
9954 (any_div:SI (match_operand:SI 2 "register_operand")
9955 (match_operand:SI 3 "nonimmediate_operand"))))
9956 (set (match_operand:SI 1 "register_operand")
9957 (<paired_mod>:SI (match_dup 2) (match_dup 3)))
9958 (clobber (reg:CC FLAGS_REG))]
9960 && TARGET_USE_8BIT_IDIV
9961 && TARGET_QIMODE_MATH
9962 && can_create_pseudo_p ()
9963 && !optimize_insn_for_size_p ()"
9965 "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
9968 [(set (match_operand:DI 1 "register_operand")
9970 (<paired_mod>:SI (match_operand:SI 2 "register_operand")
9971 (match_operand:SI 3 "nonimmediate_operand"))))
9972 (set (match_operand:SI 0 "register_operand")
9973 (any_div:SI (match_dup 2) (match_dup 3)))
9974 (clobber (reg:CC FLAGS_REG))]
9976 && TARGET_USE_8BIT_IDIV
9977 && TARGET_QIMODE_MATH
9978 && can_create_pseudo_p ()
9979 && !optimize_insn_for_size_p ()"
9981 "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
9983 (define_insn_and_split "divmod<mode>4_1"
9984 [(set (match_operand:SWI48 0 "register_operand" "=a")
9985 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
9986 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
9987 (set (match_operand:SWI48 1 "register_operand" "=&d")
9988 (mod:SWI48 (match_dup 2) (match_dup 3)))
9989 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
9990 (clobber (reg:CC FLAGS_REG))]
9994 [(parallel [(set (match_dup 1)
9995 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
9996 (clobber (reg:CC FLAGS_REG))])
9997 (parallel [(set (match_dup 0)
9998 (div:SWI48 (match_dup 2) (match_dup 3)))
10000 (mod:SWI48 (match_dup 2) (match_dup 3)))
10001 (use (match_dup 1))
10002 (clobber (reg:CC FLAGS_REG))])]
10004 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
10006 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10007 operands[4] = operands[2];
10010 /* Avoid use of cltd in favor of a mov+shift. */
10011 emit_move_insn (operands[1], operands[2]);
10012 operands[4] = operands[1];
10015 [(set_attr "type" "multi")
10016 (set_attr "mode" "<MODE>")])
10018 (define_insn_and_split "udivmod<mode>4_1"
10019 [(set (match_operand:SWI48 0 "register_operand" "=a")
10020 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
10021 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
10022 (set (match_operand:SWI48 1 "register_operand" "=&d")
10023 (umod:SWI48 (match_dup 2) (match_dup 3)))
10024 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10025 (clobber (reg:CC FLAGS_REG))]
10029 [(set (match_dup 1) (const_int 0))
10030 (parallel [(set (match_dup 0)
10031 (udiv:SWI48 (match_dup 2) (match_dup 3)))
10033 (umod:SWI48 (match_dup 2) (match_dup 3)))
10034 (use (match_dup 1))
10035 (clobber (reg:CC FLAGS_REG))])]
10037 [(set_attr "type" "multi")
10038 (set_attr "mode" "<MODE>")])
10040 (define_insn_and_split "divmodsi4_zext_1"
10041 [(set (match_operand:DI 0 "register_operand" "=a")
10043 (div:SI (match_operand:SI 2 "register_operand" "0")
10044 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10045 (set (match_operand:SI 1 "register_operand" "=&d")
10046 (mod:SI (match_dup 2) (match_dup 3)))
10047 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10048 (clobber (reg:CC FLAGS_REG))]
10051 "&& reload_completed"
10052 [(parallel [(set (match_dup 1)
10053 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10054 (clobber (reg:CC FLAGS_REG))])
10055 (parallel [(set (match_dup 0)
10056 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
10058 (mod:SI (match_dup 2) (match_dup 3)))
10059 (use (match_dup 1))
10060 (clobber (reg:CC FLAGS_REG))])]
10062 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10064 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10065 operands[4] = operands[2];
10068 /* Avoid use of cltd in favor of a mov+shift. */
10069 emit_move_insn (operands[1], operands[2]);
10070 operands[4] = operands[1];
10073 [(set_attr "type" "multi")
10074 (set_attr "mode" "SI")])
10076 (define_insn_and_split "udivmodsi4_zext_1"
10077 [(set (match_operand:DI 0 "register_operand" "=a")
10079 (udiv:SI (match_operand:SI 2 "register_operand" "0")
10080 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10081 (set (match_operand:SI 1 "register_operand" "=&d")
10082 (umod:SI (match_dup 2) (match_dup 3)))
10083 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10084 (clobber (reg:CC FLAGS_REG))]
10087 "&& reload_completed"
10088 [(set (match_dup 1) (const_int 0))
10089 (parallel [(set (match_dup 0)
10090 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
10092 (umod:SI (match_dup 2) (match_dup 3)))
10093 (use (match_dup 1))
10094 (clobber (reg:CC FLAGS_REG))])]
10096 [(set_attr "type" "multi")
10097 (set_attr "mode" "SI")])
10099 (define_insn_and_split "divmodsi4_zext_2"
10100 [(set (match_operand:DI 1 "register_operand" "=&d")
10102 (mod:SI (match_operand:SI 2 "register_operand" "0")
10103 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10104 (set (match_operand:SI 0 "register_operand" "=a")
10105 (div:SI (match_dup 2) (match_dup 3)))
10106 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10107 (clobber (reg:CC FLAGS_REG))]
10110 "&& reload_completed"
10111 [(parallel [(set (match_dup 6)
10112 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10113 (clobber (reg:CC FLAGS_REG))])
10114 (parallel [(set (match_dup 1)
10115 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
10117 (div:SI (match_dup 2) (match_dup 3)))
10118 (use (match_dup 6))
10119 (clobber (reg:CC FLAGS_REG))])]
10121 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10122 operands[6] = gen_lowpart (SImode, operands[1]);
10124 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10125 operands[4] = operands[2];
10128 /* Avoid use of cltd in favor of a mov+shift. */
10129 emit_move_insn (operands[6], operands[2]);
10130 operands[4] = operands[6];
10133 [(set_attr "type" "multi")
10134 (set_attr "mode" "SI")])
10136 (define_insn_and_split "udivmodsi4_zext_2"
10137 [(set (match_operand:DI 1 "register_operand" "=&d")
10139 (umod:SI (match_operand:SI 2 "register_operand" "0")
10140 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10141 (set (match_operand:SI 0 "register_operand" "=a")
10142 (udiv:SI (match_dup 2) (match_dup 3)))
10143 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10144 (clobber (reg:CC FLAGS_REG))]
10147 "&& reload_completed"
10148 [(set (match_dup 4) (const_int 0))
10149 (parallel [(set (match_dup 1)
10150 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
10152 (udiv:SI (match_dup 2) (match_dup 3)))
10153 (use (match_dup 4))
10154 (clobber (reg:CC FLAGS_REG))])]
10155 "operands[4] = gen_lowpart (SImode, operands[1]);"
10156 [(set_attr "type" "multi")
10157 (set_attr "mode" "SI")])
10159 (define_insn_and_split "*divmod<mode>4"
10160 [(set (match_operand:SWIM248 0 "register_operand" "=a")
10161 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
10162 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
10163 (set (match_operand:SWIM248 1 "register_operand" "=&d")
10164 (mod:SWIM248 (match_dup 2) (match_dup 3)))
10165 (clobber (reg:CC FLAGS_REG))]
10169 [(parallel [(set (match_dup 1)
10170 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
10171 (clobber (reg:CC FLAGS_REG))])
10172 (parallel [(set (match_dup 0)
10173 (div:SWIM248 (match_dup 2) (match_dup 3)))
10175 (mod:SWIM248 (match_dup 2) (match_dup 3)))
10176 (use (match_dup 1))
10177 (clobber (reg:CC FLAGS_REG))])]
10179 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
10181 if (<MODE>mode != HImode
10182 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
10183 operands[4] = operands[2];
10186 /* Avoid use of cltd in favor of a mov+shift. */
10187 emit_move_insn (operands[1], operands[2]);
10188 operands[4] = operands[1];
10191 [(set_attr "type" "multi")
10192 (set_attr "mode" "<MODE>")])
10194 (define_insn_and_split "*udivmod<mode>4"
10195 [(set (match_operand:SWIM248 0 "register_operand" "=a")
10196 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
10197 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
10198 (set (match_operand:SWIM248 1 "register_operand" "=&d")
10199 (umod:SWIM248 (match_dup 2) (match_dup 3)))
10200 (clobber (reg:CC FLAGS_REG))]
10204 [(set (match_dup 1) (const_int 0))
10205 (parallel [(set (match_dup 0)
10206 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
10208 (umod:SWIM248 (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" "<MODE>")])
10215 ;; Optimize division or modulo by constant power of 2, if the constant
10216 ;; materializes only after expansion.
10217 (define_insn_and_split "*udivmod<mode>4_pow2"
10218 [(set (match_operand:SWI48 0 "register_operand" "=r")
10219 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
10220 (match_operand:SWI48 3 "const_int_operand")))
10221 (set (match_operand:SWI48 1 "register_operand" "=r")
10222 (umod:SWI48 (match_dup 2) (match_dup 3)))
10223 (clobber (reg:CC FLAGS_REG))]
10224 "IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
10226 "&& reload_completed"
10227 [(set (match_dup 1) (match_dup 2))
10228 (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
10229 (clobber (reg:CC FLAGS_REG))])
10230 (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
10231 (clobber (reg:CC FLAGS_REG))])]
10233 int v = exact_log2 (UINTVAL (operands[3]));
10234 operands[4] = GEN_INT (v);
10235 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
10237 [(set_attr "type" "multi")
10238 (set_attr "mode" "<MODE>")])
10240 (define_insn_and_split "*divmodsi4_zext_1"
10241 [(set (match_operand:DI 0 "register_operand" "=a")
10243 (div:SI (match_operand:SI 2 "register_operand" "0")
10244 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10245 (set (match_operand:SI 1 "register_operand" "=&d")
10246 (mod:SI (match_dup 2) (match_dup 3)))
10247 (clobber (reg:CC FLAGS_REG))]
10250 "&& reload_completed"
10251 [(parallel [(set (match_dup 1)
10252 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10253 (clobber (reg:CC FLAGS_REG))])
10254 (parallel [(set (match_dup 0)
10255 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
10257 (mod:SI (match_dup 2) (match_dup 3)))
10258 (use (match_dup 1))
10259 (clobber (reg:CC FLAGS_REG))])]
10261 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10263 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10264 operands[4] = operands[2];
10267 /* Avoid use of cltd in favor of a mov+shift. */
10268 emit_move_insn (operands[1], operands[2]);
10269 operands[4] = operands[1];
10272 [(set_attr "type" "multi")
10273 (set_attr "mode" "SI")])
10275 (define_insn_and_split "*udivmodsi4_zext_1"
10276 [(set (match_operand:DI 0 "register_operand" "=a")
10278 (udiv:SI (match_operand:SI 2 "register_operand" "0")
10279 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10280 (set (match_operand:SI 1 "register_operand" "=&d")
10281 (umod:SI (match_dup 2) (match_dup 3)))
10282 (clobber (reg:CC FLAGS_REG))]
10285 "&& reload_completed"
10286 [(set (match_dup 1) (const_int 0))
10287 (parallel [(set (match_dup 0)
10288 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
10290 (umod:SI (match_dup 2) (match_dup 3)))
10291 (use (match_dup 1))
10292 (clobber (reg:CC FLAGS_REG))])]
10294 [(set_attr "type" "multi")
10295 (set_attr "mode" "SI")])
10297 (define_insn_and_split "*udivmodsi4_pow2_zext_1"
10298 [(set (match_operand:DI 0 "register_operand" "=r")
10300 (udiv:SI (match_operand:SI 2 "register_operand" "0")
10301 (match_operand:SI 3 "const_int_operand"))))
10302 (set (match_operand:SI 1 "register_operand" "=r")
10303 (umod:SI (match_dup 2) (match_dup 3)))
10304 (clobber (reg:CC FLAGS_REG))]
10306 && IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
10308 "&& reload_completed"
10309 [(set (match_dup 1) (match_dup 2))
10310 (parallel [(set (match_dup 0)
10311 (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4))))
10312 (clobber (reg:CC FLAGS_REG))])
10313 (parallel [(set (match_dup 1) (and:SI (match_dup 1) (match_dup 5)))
10314 (clobber (reg:CC FLAGS_REG))])]
10316 int v = exact_log2 (UINTVAL (operands[3]));
10317 operands[4] = GEN_INT (v);
10318 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
10320 [(set_attr "type" "multi")
10321 (set_attr "mode" "SI")])
10323 (define_insn_and_split "*divmodsi4_zext_2"
10324 [(set (match_operand:DI 1 "register_operand" "=&d")
10326 (mod:SI (match_operand:SI 2 "register_operand" "0")
10327 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10328 (set (match_operand:SI 0 "register_operand" "=a")
10329 (div:SI (match_dup 2) (match_dup 3)))
10330 (clobber (reg:CC FLAGS_REG))]
10333 "&& reload_completed"
10334 [(parallel [(set (match_dup 6)
10335 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10336 (clobber (reg:CC FLAGS_REG))])
10337 (parallel [(set (match_dup 1)
10338 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
10340 (div:SI (match_dup 2) (match_dup 3)))
10341 (use (match_dup 6))
10342 (clobber (reg:CC FLAGS_REG))])]
10344 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10345 operands[6] = gen_lowpart (SImode, operands[1]);
10347 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10348 operands[4] = operands[2];
10351 /* Avoid use of cltd in favor of a mov+shift. */
10352 emit_move_insn (operands[6], operands[2]);
10353 operands[4] = operands[6];
10356 [(set_attr "type" "multi")
10357 (set_attr "mode" "SI")])
10359 (define_insn_and_split "*udivmodsi4_zext_2"
10360 [(set (match_operand:DI 1 "register_operand" "=&d")
10362 (umod:SI (match_operand:SI 2 "register_operand" "0")
10363 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10364 (set (match_operand:SI 0 "register_operand" "=a")
10365 (udiv:SI (match_dup 2) (match_dup 3)))
10366 (clobber (reg:CC FLAGS_REG))]
10369 "&& reload_completed"
10370 [(set (match_dup 4) (const_int 0))
10371 (parallel [(set (match_dup 1)
10372 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
10374 (udiv:SI (match_dup 2) (match_dup 3)))
10375 (use (match_dup 4))
10376 (clobber (reg:CC FLAGS_REG))])]
10377 "operands[4] = gen_lowpart (SImode, operands[1]);"
10378 [(set_attr "type" "multi")
10379 (set_attr "mode" "SI")])
10381 (define_insn_and_split "*udivmodsi4_pow2_zext_2"
10382 [(set (match_operand:DI 1 "register_operand" "=r")
10384 (umod:SI (match_operand:SI 2 "register_operand" "0")
10385 (match_operand:SI 3 "const_int_operand"))))
10386 (set (match_operand:SI 0 "register_operand" "=r")
10387 (udiv:SI (match_dup 2) (match_dup 3)))
10388 (clobber (reg:CC FLAGS_REG))]
10390 && IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
10392 "&& reload_completed"
10393 [(set (match_dup 1) (match_dup 2))
10394 (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4)))
10395 (clobber (reg:CC FLAGS_REG))])
10396 (parallel [(set (match_dup 1)
10397 (zero_extend:DI (and:SI (match_dup 1) (match_dup 5))))
10398 (clobber (reg:CC FLAGS_REG))])]
10400 int v = exact_log2 (UINTVAL (operands[3]));
10401 operands[4] = GEN_INT (v);
10402 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
10404 [(set_attr "type" "multi")
10405 (set_attr "mode" "SI")])
10407 (define_insn "*<u>divmod<mode>4_noext"
10408 [(set (match_operand:SWIM248 0 "register_operand" "=a")
10410 (match_operand:SWIM248 2 "register_operand" "0")
10411 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
10412 (set (match_operand:SWIM248 1 "register_operand" "=d")
10413 (<paired_mod>:SWIM248 (match_dup 2) (match_dup 3)))
10414 (use (match_operand:SWIM248 4 "register_operand" "1"))
10415 (clobber (reg:CC FLAGS_REG))]
10417 "<sgnprefix>div{<imodesuffix>}\t%3"
10418 [(set_attr "type" "idiv")
10419 (set_attr "mode" "<MODE>")])
10421 (define_insn "*<u>divmodsi4_noext_zext_1"
10422 [(set (match_operand:DI 0 "register_operand" "=a")
10424 (any_div:SI (match_operand:SI 2 "register_operand" "0")
10425 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10426 (set (match_operand:SI 1 "register_operand" "=d")
10427 (<paired_mod>:SI (match_dup 2) (match_dup 3)))
10428 (use (match_operand:SI 4 "register_operand" "1"))
10429 (clobber (reg:CC FLAGS_REG))]
10431 "<sgnprefix>div{l}\t%3"
10432 [(set_attr "type" "idiv")
10433 (set_attr "mode" "SI")])
10435 (define_insn "*<u>divmodsi4_noext_zext_2"
10436 [(set (match_operand:DI 1 "register_operand" "=d")
10438 (<paired_mod>:SI (match_operand:SI 2 "register_operand" "0")
10439 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10440 (set (match_operand:SI 0 "register_operand" "=a")
10441 (any_div:SI (match_dup 2) (match_dup 3)))
10442 (use (match_operand:SI 4 "register_operand" "1"))
10443 (clobber (reg:CC FLAGS_REG))]
10445 "<sgnprefix>div{l}\t%3"
10446 [(set_attr "type" "idiv")
10447 (set_attr "mode" "SI")])
10449 ;; Avoid sign-extension (using cdq) for constant numerators.
10450 (define_insn_and_split "*divmodsi4_const"
10451 [(set (match_operand:SI 0 "register_operand" "=&a")
10452 (div:SI (match_operand:SI 2 "const_int_operand")
10453 (match_operand:SI 3 "nonimmediate_operand" "rm")))
10454 (set (match_operand:SI 1 "register_operand" "=&d")
10455 (mod:SI (match_dup 2) (match_dup 3)))
10456 (clobber (reg:CC FLAGS_REG))]
10457 "!optimize_function_for_size_p (cfun)"
10459 "&& reload_completed"
10460 [(set (match_dup 0) (match_dup 2))
10461 (set (match_dup 1) (match_dup 4))
10462 (parallel [(set (match_dup 0)
10463 (div:SI (match_dup 0) (match_dup 3)))
10465 (mod:SI (match_dup 0) (match_dup 3)))
10466 (use (match_dup 1))
10467 (clobber (reg:CC FLAGS_REG))])]
10469 operands[4] = INTVAL (operands[2]) < 0 ? constm1_rtx : const0_rtx;
10471 [(set_attr "type" "multi")
10472 (set_attr "mode" "SI")])
10474 (define_expand "divmodqi4"
10475 [(parallel [(set (match_operand:QI 0 "register_operand")
10477 (match_operand:QI 1 "register_operand")
10478 (match_operand:QI 2 "nonimmediate_operand")))
10479 (set (match_operand:QI 3 "register_operand")
10480 (mod:QI (match_dup 1) (match_dup 2)))
10481 (clobber (reg:CC FLAGS_REG))])]
10482 "TARGET_QIMODE_MATH"
10487 tmp0 = gen_reg_rtx (HImode);
10488 tmp1 = gen_reg_rtx (HImode);
10490 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
10491 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
10492 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
10494 /* Extract remainder from AH. */
10495 tmp1 = gen_rtx_ZERO_EXTRACT (HImode, tmp0, GEN_INT (8), GEN_INT (8));
10496 tmp1 = lowpart_subreg (QImode, tmp1, HImode);
10497 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
10499 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
10500 set_unique_reg_note (insn, REG_EQUAL, mod);
10502 /* Extract quotient from AL. */
10503 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
10505 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
10506 set_unique_reg_note (insn, REG_EQUAL, div);
10511 (define_expand "udivmodqi4"
10512 [(parallel [(set (match_operand:QI 0 "register_operand")
10514 (match_operand:QI 1 "register_operand")
10515 (match_operand:QI 2 "nonimmediate_operand")))
10516 (set (match_operand:QI 3 "register_operand")
10517 (umod:QI (match_dup 1) (match_dup 2)))
10518 (clobber (reg:CC FLAGS_REG))])]
10519 "TARGET_QIMODE_MATH"
10524 tmp0 = gen_reg_rtx (HImode);
10525 tmp1 = gen_reg_rtx (HImode);
10527 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
10528 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
10529 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
10531 /* Extract remainder from AH. */
10532 tmp1 = gen_rtx_ZERO_EXTRACT (HImode, tmp0, GEN_INT (8), GEN_INT (8));
10533 tmp1 = lowpart_subreg (QImode, tmp1, HImode);
10534 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
10536 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
10537 set_unique_reg_note (insn, REG_EQUAL, mod);
10539 /* Extract quotient from AL. */
10540 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
10542 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
10543 set_unique_reg_note (insn, REG_EQUAL, div);
10548 ;; Divide AX by r/m8, with result stored in
10551 ;; Change div/mod to HImode and extend the second argument to HImode
10552 ;; so that mode of div/mod matches with mode of arguments. Otherwise
10553 ;; combine may fail.
10554 (define_insn "<u>divmodhiqi3"
10555 [(set (match_operand:HI 0 "register_operand" "=a")
10560 (mod:HI (match_operand:HI 1 "register_operand" "0")
10562 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
10566 (div:HI (match_dup 1) (any_extend:HI (match_dup 2)))))))
10567 (clobber (reg:CC FLAGS_REG))]
10568 "TARGET_QIMODE_MATH"
10569 "<sgnprefix>div{b}\t%2"
10570 [(set_attr "type" "idiv")
10571 (set_attr "mode" "QI")])
10573 ;; We cannot use div/idiv for double division, because it causes
10574 ;; "division by zero" on the overflow and that's not what we expect
10575 ;; from truncate. Because true (non truncating) double division is
10576 ;; never generated, we can't create this insn anyway.
10579 ; [(set (match_operand:SI 0 "register_operand" "=a")
10581 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
10583 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
10584 ; (set (match_operand:SI 3 "register_operand" "=d")
10586 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
10587 ; (clobber (reg:CC FLAGS_REG))]
10589 ; "div{l}\t{%2, %0|%0, %2}"
10590 ; [(set_attr "type" "idiv")])
10592 ;;- Logical AND instructions
10594 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
10595 ;; Note that this excludes ah.
10597 (define_expand "@test<mode>_ccno_1"
10598 [(set (reg:CCNO FLAGS_REG)
10601 (match_operand:SWI48 0 "nonimmediate_operand")
10602 (match_operand:SWI48 1 "<nonmemory_szext_operand>"))
10605 (define_expand "testqi_ccz_1"
10606 [(set (reg:CCZ FLAGS_REG)
10609 (match_operand:QI 0 "nonimmediate_operand")
10610 (match_operand:QI 1 "nonmemory_operand"))
10613 (define_insn "*testdi_1"
10614 [(set (reg FLAGS_REG)
10617 (match_operand:DI 0 "nonimmediate_operand" "%r,rm")
10618 (match_operand:DI 1 "x86_64_szext_nonmemory_operand" "Z,re"))
10621 && ix86_match_ccmode
10623 /* If we are going to emit testl instead of testq, and the operands[1]
10624 constant might have the SImode sign bit set, make sure the sign
10625 flag isn't tested, because the instruction will set the sign flag
10626 based on bit 31 rather than bit 63. If it isn't CONST_INT,
10627 conservatively assume it might have bit 31 set. */
10628 (satisfies_constraint_Z (operands[1])
10629 && (!CONST_INT_P (operands[1])
10630 || val_signbit_known_set_p (SImode, INTVAL (operands[1]))))
10631 ? CCZmode : CCNOmode)"
10633 test{l}\t{%k1, %k0|%k0, %k1}
10634 test{q}\t{%1, %0|%0, %1}"
10635 [(set_attr "type" "test")
10636 (set_attr "mode" "SI,DI")])
10638 (define_insn "*testqi_1_maybe_si"
10639 [(set (reg FLAGS_REG)
10642 (match_operand:QI 0 "nonimmediate_operand" "%qm,qm,r")
10643 (match_operand:QI 1 "nonmemory_operand" "q,n,n"))
10645 "ix86_match_ccmode (insn,
10646 CONST_INT_P (operands[1])
10647 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
10649 if (get_attr_mode (insn) == MODE_SI)
10651 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
10652 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
10653 return "test{l}\t{%1, %k0|%k0, %1}";
10655 return "test{b}\t{%1, %0|%0, %1}";
10657 [(set_attr "type" "test")
10659 (cond [(eq_attr "alternative" "2")
10660 (const_string "SI")
10661 (and (match_test "optimize_insn_for_size_p ()")
10662 (and (match_operand 0 "ext_QIreg_operand")
10663 (match_operand 1 "const_0_to_127_operand")))
10664 (const_string "SI")
10666 (const_string "QI")))
10667 (set_attr "pent_pair" "uv,np,np")])
10669 (define_insn "*test<mode>_1"
10670 [(set (reg FLAGS_REG)
10673 (match_operand:SWI124 0 "nonimmediate_operand" "%<r>m,*a,<r>m")
10674 (match_operand:SWI124 1 "<nonmemory_szext_operand>" "<r>,<i>,<i>"))
10676 "ix86_match_ccmode (insn, CCNOmode)"
10677 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
10678 [(set_attr "type" "test")
10679 (set_attr "mode" "<MODE>")
10680 (set_attr "pent_pair" "uv,uv,np")])
10682 (define_expand "testqi_ext_1_ccno"
10683 [(set (reg:CCNO FLAGS_REG)
10688 (match_operand:HI 0 "register_operand")
10691 (match_operand:QI 1 "const_int_operand"))
10694 (define_insn "*testqi_ext<mode>_1"
10695 [(set (reg FLAGS_REG)
10699 (match_operator:SWI248 2 "extract_operator"
10700 [(match_operand 0 "int248_register_operand" "Q,Q")
10703 (match_operand:QI 1 "general_x64constmem_operand" "QnBc,m"))
10705 "ix86_match_ccmode (insn, CCNOmode)"
10706 "test{b}\t{%1, %h0|%h0, %1}"
10707 [(set_attr "isa" "*,nox64")
10708 (set_attr "type" "test")
10709 (set_attr "mode" "QI")])
10711 (define_insn "*testqi_ext<mode>_2"
10712 [(set (reg FLAGS_REG)
10716 (match_operator:SWI248 2 "extract_operator"
10717 [(match_operand 0 "int248_register_operand" "Q")
10721 (match_operator:SWI248 3 "extract_operator"
10722 [(match_operand 1 "int248_register_operand" "Q")
10724 (const_int 8)]) 0))
10726 "ix86_match_ccmode (insn, CCNOmode)"
10727 "test{b}\t{%h1, %h0|%h0, %h1}"
10728 [(set_attr "type" "test")
10729 (set_attr "mode" "QI")])
10731 ;; Provide a *testti instruction that STV can implement using ptest.
10732 ;; This pattern splits into *andti3_doubleword and *cmpti_doubleword.
10733 (define_insn_and_split "*testti_doubleword"
10734 [(set (reg:CCZ FLAGS_REG)
10736 (and:TI (match_operand:TI 0 "register_operand")
10737 (match_operand:TI 1 "general_operand"))
10740 && ix86_pre_reload_split ()"
10743 [(parallel [(set (match_dup 2) (and:TI (match_dup 0) (match_dup 1)))
10744 (clobber (reg:CC FLAGS_REG))])
10745 (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 2) (const_int 0)))]
10747 operands[2] = gen_reg_rtx (TImode);
10748 if (!x86_64_hilo_general_operand (operands[1], TImode))
10749 operands[1] = force_reg (TImode, operands[1]);
10752 ;; Combine likes to form bit extractions for some tests. Humor it.
10753 (define_insn_and_split "*testqi_ext_3"
10754 [(set (match_operand 0 "flags_reg_operand")
10755 (match_operator 1 "compare_operator"
10756 [(zero_extract:SWI248
10757 (match_operand 2 "int_nonimmediate_operand" "rm")
10758 (match_operand 3 "const_int_operand")
10759 (match_operand 4 "const_int_operand"))
10761 "/* Ensure that resulting mask is zero or sign extended operand. */
10762 INTVAL (operands[4]) >= 0
10763 && ((INTVAL (operands[3]) > 0
10764 && INTVAL (operands[3]) + INTVAL (operands[4]) <= 32)
10765 || (<MODE>mode == DImode
10766 && INTVAL (operands[3]) > 32
10767 && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))
10768 && ix86_match_ccmode (insn,
10769 /* If zero_extract mode precision is the same
10770 as len, the SF of the zero_extract
10771 comparison will be the most significant
10772 extracted bit, but this could be matched
10773 after splitting only for pos 0 len all bits
10774 trivial extractions. Require CCZmode. */
10775 (GET_MODE_PRECISION (<MODE>mode)
10776 == INTVAL (operands[3]))
10777 /* Otherwise, require CCZmode if we'd use a mask
10778 with the most significant bit set and can't
10779 widen it to wider mode. *testdi_1 also
10780 requires CCZmode if the mask has bit
10781 31 set and all bits above it clear. */
10782 || (INTVAL (operands[3]) + INTVAL (operands[4])
10784 /* We can't widen also if val is not a REG. */
10785 || (INTVAL (operands[3]) + INTVAL (operands[4])
10786 == GET_MODE_PRECISION (GET_MODE (operands[2]))
10787 && !register_operand (operands[2],
10788 GET_MODE (operands[2])))
10789 /* And we shouldn't widen if
10790 TARGET_PARTIAL_REG_STALL. */
10791 || (TARGET_PARTIAL_REG_STALL
10792 && (INTVAL (operands[3]) + INTVAL (operands[4])
10793 >= (paradoxical_subreg_p (operands[2])
10795 (GET_MODE (SUBREG_REG (operands[2])))
10797 ? GET_MODE_PRECISION
10798 (GET_MODE (SUBREG_REG (operands[2])))
10799 : GET_MODE_PRECISION
10800 (GET_MODE (operands[2])))))
10801 ? CCZmode : CCNOmode)"
10804 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
10806 rtx val = operands[2];
10807 HOST_WIDE_INT len = INTVAL (operands[3]);
10808 HOST_WIDE_INT pos = INTVAL (operands[4]);
10809 machine_mode mode = GET_MODE (val);
10811 if (SUBREG_P (val))
10813 machine_mode submode = GET_MODE (SUBREG_REG (val));
10815 /* Narrow paradoxical subregs to prevent partial register stalls. */
10816 if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)
10817 && GET_MODE_CLASS (submode) == MODE_INT
10818 && (GET_MODE (operands[0]) == CCZmode
10819 || pos + len < GET_MODE_PRECISION (submode)
10820 || REG_P (SUBREG_REG (val))))
10822 val = SUBREG_REG (val);
10827 /* Small HImode tests can be converted to QImode. */
10829 && register_operand (val, HImode))
10831 rtx nval = gen_lowpart (QImode, val);
10833 || GET_MODE (operands[0]) == CCZmode
10841 gcc_assert (pos + len <= GET_MODE_PRECISION (mode));
10843 /* If the mask is going to have the sign bit set in the mode
10844 we want to do the comparison in and user isn't interested just
10845 in the zero flag, then we must widen the target mode. */
10846 if (pos + len == GET_MODE_PRECISION (mode)
10847 && GET_MODE (operands[0]) != CCZmode)
10849 gcc_assert (pos + len < 32 && !MEM_P (val));
10851 val = gen_lowpart (mode, val);
10855 = wi::shifted_mask (pos, len, false, GET_MODE_PRECISION (mode));
10857 operands[2] = gen_rtx_AND (mode, val, immed_wide_int_const (mask, mode));
10860 ;; Split and;cmp (as optimized by combine) into not;test
10861 ;; Except when TARGET_BMI provides andn (*andn_<mode>_ccno).
10862 (define_insn_and_split "*test<mode>_not"
10863 [(set (reg:CCZ FLAGS_REG)
10866 (not:SWI (match_operand:SWI 0 "register_operand"))
10867 (match_operand:SWI 1 "<nonmemory_szext_operand>"))
10869 "ix86_pre_reload_split ()
10870 && (!TARGET_BMI || !REG_P (operands[1]))"
10873 [(set (match_dup 2) (not:SWI (match_dup 0)))
10874 (set (reg:CCZ FLAGS_REG)
10875 (compare:CCZ (and:SWI (match_dup 2) (match_dup 1))
10877 "operands[2] = gen_reg_rtx (<MODE>mode);")
10879 ;; Split and;cmp (as optimized by combine) into andn;cmp $0
10880 (define_insn_and_split "*test<mode>_not_doubleword"
10881 [(set (reg:CCZ FLAGS_REG)
10884 (not:DWI (match_operand:DWI 0 "nonimmediate_operand"))
10885 (match_operand:DWI 1 "nonimmediate_operand"))
10887 "ix86_pre_reload_split ()"
10891 [(set (match_dup 2) (and:DWI (not:DWI (match_dup 0)) (match_dup 1)))
10892 (clobber (reg:CC FLAGS_REG))])
10893 (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 2) (const_int 0)))]
10895 operands[0] = force_reg (<MODE>mode, operands[0]);
10896 operands[2] = gen_reg_rtx (<MODE>mode);
10899 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
10900 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
10901 ;; this is relatively important trick.
10902 ;; Do the conversion only post-reload to avoid limiting of the register class
10905 [(set (match_operand 0 "flags_reg_operand")
10906 (match_operator 1 "compare_operator"
10907 [(and (match_operand 2 "QIreg_operand")
10908 (match_operand 3 "const_int_operand"))
10911 && GET_MODE (operands[2]) != QImode
10912 && ((ix86_match_ccmode (insn, CCZmode)
10913 && !(INTVAL (operands[3]) & ~(255 << 8)))
10914 || (ix86_match_ccmode (insn, CCNOmode)
10915 && !(INTVAL (operands[3]) & ~(127 << 8))))"
10916 [(set (match_dup 0)
10920 (zero_extract:HI (match_dup 2)
10926 operands[2] = gen_lowpart (HImode, operands[2]);
10927 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, QImode);
10931 [(set (match_operand 0 "flags_reg_operand")
10932 (match_operator 1 "compare_operator"
10933 [(and (match_operand 2 "nonimmediate_operand")
10934 (match_operand 3 "const_int_operand"))
10937 && GET_MODE (operands[2]) != QImode
10938 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
10939 && ((ix86_match_ccmode (insn, CCZmode)
10940 && !(INTVAL (operands[3]) & ~255))
10941 || (ix86_match_ccmode (insn, CCNOmode)
10942 && !(INTVAL (operands[3]) & ~127)))"
10943 [(set (match_dup 0)
10944 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
10947 operands[2] = gen_lowpart (QImode, operands[2]);
10948 operands[3] = gen_int_mode (INTVAL (operands[3]), QImode);
10951 ;; %%% This used to optimize known byte-wide and operations to memory,
10952 ;; and sometimes to QImode registers. If this is considered useful,
10953 ;; it should be done with splitters.
10955 (define_expand "and<mode>3"
10956 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
10957 (and:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
10958 (match_operand:SDWIM 2 "<general_szext_operand>")))]
10961 machine_mode mode = <MODE>mode;
10963 if (GET_MODE_SIZE (<MODE>mode) > UNITS_PER_WORD
10964 && !x86_64_hilo_general_operand (operands[2], <MODE>mode))
10965 operands[2] = force_reg (<MODE>mode, operands[2]);
10967 if (GET_MODE_SIZE (<MODE>mode) <= UNITS_PER_WORD
10968 && const_int_operand (operands[2], <MODE>mode)
10969 && register_operand (operands[0], <MODE>mode)
10970 && !(TARGET_ZERO_EXTEND_WITH_AND
10971 && optimize_function_for_speed_p (cfun)))
10973 unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
10975 if (ival == GET_MODE_MASK (SImode))
10977 else if (ival == GET_MODE_MASK (HImode))
10979 else if (ival == GET_MODE_MASK (QImode))
10983 if (mode != <MODE>mode)
10984 emit_insn (gen_extend_insn
10985 (operands[0], gen_lowpart (mode, operands[1]),
10986 <MODE>mode, mode, 1));
10988 ix86_expand_binary_operator (AND, <MODE>mode, operands);
10993 (define_insn_and_split "*and<dwi>3_doubleword"
10994 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
10996 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
10997 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
10998 (clobber (reg:CC FLAGS_REG))]
10999 "ix86_binary_operator_ok (AND, <DWI>mode, operands)"
11001 "&& reload_completed"
11002 [(const_int:DWIH 0)]
11004 bool emit_insn_deleted_note_p = false;
11006 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
11008 if (operands[2] == const0_rtx)
11009 emit_move_insn (operands[0], const0_rtx);
11010 else if (operands[2] == constm1_rtx)
11011 emit_insn_deleted_note_p = true;
11013 ix86_expand_binary_operator (AND, <MODE>mode, &operands[0]);
11015 if (operands[5] == const0_rtx)
11016 emit_move_insn (operands[3], const0_rtx);
11017 else if (operands[5] == constm1_rtx)
11019 if (emit_insn_deleted_note_p)
11020 emit_note (NOTE_INSN_DELETED);
11023 ix86_expand_binary_operator (AND, <MODE>mode, &operands[3]);
11028 (define_insn "*anddi_1"
11029 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,?k")
11031 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
11032 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m,L,k")))
11033 (clobber (reg:CC FLAGS_REG))]
11034 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
11036 and{l}\t{%k2, %k0|%k0, %k2}
11037 and{q}\t{%2, %0|%0, %2}
11038 and{q}\t{%2, %0|%0, %2}
11041 [(set_attr "isa" "x64,x64,x64,x64,avx512bw")
11042 (set_attr "type" "alu,alu,alu,imovx,msklog")
11043 (set_attr "length_immediate" "*,*,*,0,*")
11044 (set (attr "prefix_rex")
11046 (and (eq_attr "type" "imovx")
11047 (and (match_test "INTVAL (operands[2]) == 0xff")
11048 (match_operand 1 "ext_QIreg_operand")))
11050 (const_string "*")))
11051 (set_attr "mode" "SI,DI,DI,SI,DI")])
11053 (define_insn_and_split "*anddi_1_btr"
11054 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11056 (match_operand:DI 1 "nonimmediate_operand" "%0")
11057 (match_operand:DI 2 "const_int_operand" "n")))
11058 (clobber (reg:CC FLAGS_REG))]
11059 "TARGET_64BIT && TARGET_USE_BT
11060 && ix86_binary_operator_ok (AND, DImode, operands)
11061 && IN_RANGE (exact_log2 (~INTVAL (operands[2])), 31, 63)"
11063 "&& reload_completed"
11064 [(parallel [(set (zero_extract:DI (match_dup 0)
11068 (clobber (reg:CC FLAGS_REG))])]
11069 "operands[3] = GEN_INT (exact_log2 (~INTVAL (operands[2])));"
11070 [(set_attr "type" "alu1")
11071 (set_attr "prefix_0f" "1")
11072 (set_attr "znver1_decode" "double")
11073 (set_attr "mode" "DI")])
11075 ;; Turn *anddi_1 into *andsi_1_zext if possible.
11077 [(set (match_operand:DI 0 "register_operand")
11078 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
11079 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
11080 (clobber (reg:CC FLAGS_REG))]
11082 [(parallel [(set (match_dup 0)
11083 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
11084 (clobber (reg:CC FLAGS_REG))])]
11086 if (GET_CODE (operands[2]) == SYMBOL_REF
11087 || GET_CODE (operands[2]) == LABEL_REF)
11089 operands[2] = shallow_copy_rtx (operands[2]);
11090 PUT_MODE (operands[2], SImode);
11092 else if (GET_CODE (operands[2]) == CONST)
11094 /* (const:DI (plus:DI (symbol_ref:DI ("...")) (const_int N))) */
11095 operands[2] = copy_rtx (operands[2]);
11096 PUT_MODE (operands[2], SImode);
11097 PUT_MODE (XEXP (operands[2], 0), SImode);
11098 PUT_MODE (XEXP (XEXP (operands[2], 0), 0), SImode);
11101 operands[2] = gen_lowpart (SImode, operands[2]);
11104 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
11105 (define_insn "*andsi_1_zext"
11106 [(set (match_operand:DI 0 "register_operand" "=r")
11108 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
11109 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
11110 (clobber (reg:CC FLAGS_REG))]
11111 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
11112 "and{l}\t{%2, %k0|%k0, %2}"
11113 [(set_attr "type" "alu")
11114 (set_attr "mode" "SI")])
11116 (define_insn "*and<mode>_1"
11117 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya,?k")
11118 (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm,k")
11119 (match_operand:SWI24 2 "<general_operand>" "r<i>,<m>,L,k")))
11120 (clobber (reg:CC FLAGS_REG))]
11121 "ix86_binary_operator_ok (AND, <MODE>mode, operands)"
11123 and{<imodesuffix>}\t{%2, %0|%0, %2}
11124 and{<imodesuffix>}\t{%2, %0|%0, %2}
11128 (cond [(eq_attr "alternative" "3")
11129 (if_then_else (eq_attr "mode" "SI")
11130 (const_string "avx512bw")
11131 (const_string "avx512f"))
11133 (const_string "*")))
11134 (set_attr "type" "alu,alu,imovx,msklog")
11135 (set_attr "length_immediate" "*,*,0,*")
11136 (set (attr "prefix_rex")
11138 (and (eq_attr "type" "imovx")
11139 (and (match_test "INTVAL (operands[2]) == 0xff")
11140 (match_operand 1 "ext_QIreg_operand")))
11142 (const_string "*")))
11143 (set_attr "mode" "<MODE>,<MODE>,SI,<MODE>")])
11145 (define_insn "*andqi_1"
11146 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,?k")
11147 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
11148 (match_operand:QI 2 "general_operand" "qn,m,rn,k")))
11149 (clobber (reg:CC FLAGS_REG))]
11150 "ix86_binary_operator_ok (AND, QImode, operands)"
11152 and{b}\t{%2, %0|%0, %2}
11153 and{b}\t{%2, %0|%0, %2}
11154 and{l}\t{%k2, %k0|%k0, %k2}
11156 [(set_attr "type" "alu,alu,alu,msklog")
11158 (cond [(eq_attr "alternative" "2")
11159 (const_string "SI")
11160 (and (eq_attr "alternative" "3")
11161 (match_test "!TARGET_AVX512DQ"))
11162 (const_string "HI")
11164 (const_string "QI")))
11165 ;; Potential partial reg stall on alternative 2.
11166 (set (attr "preferred_for_speed")
11167 (cond [(eq_attr "alternative" "2")
11168 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
11169 (symbol_ref "true")))])
11171 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
11172 (define_insn_and_split "*and<mode>_1_slp"
11173 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
11174 (and:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0,!<r>")
11175 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
11176 (clobber (reg:CC FLAGS_REG))]
11177 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
11179 and{<imodesuffix>}\t{%2, %0|%0, %2}
11181 "&& reload_completed"
11182 [(set (strict_low_part (match_dup 0)) (match_dup 1))
11184 [(set (strict_low_part (match_dup 0))
11185 (and:SWI12 (match_dup 0) (match_dup 2)))
11186 (clobber (reg:CC FLAGS_REG))])]
11188 [(set_attr "type" "alu")
11189 (set_attr "mode" "<MODE>")])
11192 [(set (match_operand:SWI248 0 "register_operand")
11193 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
11194 (match_operand:SWI248 2 "const_int_operand")))
11195 (clobber (reg:CC FLAGS_REG))]
11197 && (!REG_P (operands[1])
11198 || REGNO (operands[0]) != REGNO (operands[1]))"
11201 unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
11204 if (ival == GET_MODE_MASK (SImode))
11206 else if (ival == GET_MODE_MASK (HImode))
11208 else if (ival == GET_MODE_MASK (QImode))
11211 gcc_unreachable ();
11213 /* Zero extend to SImode to avoid partial register stalls. */
11214 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
11215 operands[0] = gen_lowpart (SImode, operands[0]);
11217 emit_insn (gen_extend_insn
11218 (operands[0], gen_lowpart (mode, operands[1]),
11219 GET_MODE (operands[0]), mode, 1));
11224 [(set (match_operand:SWI48 0 "register_operand")
11225 (and:SWI48 (match_dup 0)
11226 (const_int -65536)))
11227 (clobber (reg:CC FLAGS_REG))]
11228 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
11229 || optimize_function_for_size_p (cfun)"
11230 [(set (strict_low_part (match_dup 1)) (const_int 0))]
11231 "operands[1] = gen_lowpart (HImode, operands[0]);")
11234 [(set (match_operand:SWI248 0 "any_QIreg_operand")
11235 (and:SWI248 (match_dup 0)
11237 (clobber (reg:CC FLAGS_REG))]
11238 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11239 && reload_completed"
11240 [(set (strict_low_part (match_dup 1)) (const_int 0))]
11241 "operands[1] = gen_lowpart (QImode, operands[0]);")
11244 [(set (match_operand:SWI248 0 "QIreg_operand")
11245 (and:SWI248 (match_dup 0)
11246 (const_int -65281)))
11247 (clobber (reg:CC FLAGS_REG))]
11248 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11249 && reload_completed"
11251 [(set (zero_extract:HI (match_dup 0)
11257 (zero_extract:HI (match_dup 0)
11261 (zero_extract:HI (match_dup 0)
11263 (const_int 8)) 0)) 0))
11264 (clobber (reg:CC FLAGS_REG))])]
11265 "operands[0] = gen_lowpart (HImode, operands[0]);")
11267 (define_insn "*anddi_2"
11268 [(set (reg FLAGS_REG)
11271 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
11272 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m"))
11274 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
11275 (and:DI (match_dup 1) (match_dup 2)))]
11277 && ix86_match_ccmode
11279 /* If we are going to emit andl instead of andq, and the operands[2]
11280 constant might have the SImode sign bit set, make sure the sign
11281 flag isn't tested, because the instruction will set the sign flag
11282 based on bit 31 rather than bit 63. If it isn't CONST_INT,
11283 conservatively assume it might have bit 31 set. */
11284 (satisfies_constraint_Z (operands[2])
11285 && (!CONST_INT_P (operands[2])
11286 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
11287 ? CCZmode : CCNOmode)
11288 && ix86_binary_operator_ok (AND, DImode, operands)"
11290 and{l}\t{%k2, %k0|%k0, %k2}
11291 and{q}\t{%2, %0|%0, %2}
11292 and{q}\t{%2, %0|%0, %2}"
11293 [(set_attr "type" "alu")
11294 (set_attr "mode" "SI,DI,DI")])
11296 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
11297 (define_insn "*andsi_2_zext"
11298 [(set (reg FLAGS_REG)
11300 (match_operand:SI 1 "nonimmediate_operand" "%0")
11301 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
11303 (set (match_operand:DI 0 "register_operand" "=r")
11304 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
11305 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
11306 && ix86_binary_operator_ok (AND, SImode, operands)"
11307 "and{l}\t{%2, %k0|%k0, %2}"
11308 [(set_attr "type" "alu")
11309 (set_attr "mode" "SI")])
11311 (define_insn "*andqi_2_maybe_si"
11312 [(set (reg FLAGS_REG)
11314 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
11315 (match_operand:QI 2 "general_operand" "qn,m,n"))
11317 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
11318 (and:QI (match_dup 1) (match_dup 2)))]
11319 "ix86_binary_operator_ok (AND, QImode, operands)
11320 && ix86_match_ccmode (insn,
11321 CONST_INT_P (operands[2])
11322 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
11324 if (get_attr_mode (insn) == MODE_SI)
11326 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
11327 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
11328 return "and{l}\t{%2, %k0|%k0, %2}";
11330 return "and{b}\t{%2, %0|%0, %2}";
11332 [(set_attr "type" "alu")
11334 (cond [(eq_attr "alternative" "2")
11335 (const_string "SI")
11336 (and (match_test "optimize_insn_for_size_p ()")
11337 (and (match_operand 0 "ext_QIreg_operand")
11338 (match_operand 2 "const_0_to_127_operand")))
11339 (const_string "SI")
11341 (const_string "QI")))
11342 ;; Potential partial reg stall on alternative 2.
11343 (set (attr "preferred_for_speed")
11344 (cond [(eq_attr "alternative" "2")
11345 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
11346 (symbol_ref "true")))])
11348 (define_insn "*and<mode>_2"
11349 [(set (reg FLAGS_REG)
11350 (compare (and:SWI124
11351 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
11352 (match_operand:SWI124 2 "<general_operand>" "<r><i>,<m>"))
11354 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>m,<r>")
11355 (and:SWI124 (match_dup 1) (match_dup 2)))]
11356 "ix86_match_ccmode (insn, CCNOmode)
11357 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
11358 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
11359 [(set_attr "type" "alu")
11360 (set_attr "mode" "<MODE>")])
11362 (define_insn "*andqi_ext<mode>_0"
11363 [(set (match_operand:QI 0 "nonimm_x64constmem_operand" "=QBc,m")
11366 (match_operator:SWI248 3 "extract_operator"
11367 [(match_operand 2 "int248_register_operand" "Q,Q")
11370 (match_operand:QI 1 "nonimm_x64constmem_operand" "0,0")))
11371 (clobber (reg:CC FLAGS_REG))]
11373 "and{b}\t{%h2, %0|%0, %h2}"
11374 [(set_attr "isa" "*,nox64")
11375 (set_attr "type" "alu")
11376 (set_attr "mode" "QI")])
11378 (define_expand "andqi_ext_1"
11380 [(set (zero_extract:HI (match_operand:HI 0 "register_operand")
11386 (zero_extract:HI (match_operand:HI 1 "register_operand")
11389 (match_operand:QI 2 "const_int_operand")) 0))
11390 (clobber (reg:CC FLAGS_REG))])])
11392 (define_insn "*andqi_ext<mode>_1"
11393 [(set (zero_extract:SWI248
11394 (match_operand 0 "int248_register_operand" "+Q,Q")
11400 (match_operator:SWI248 3 "extract_operator"
11401 [(match_operand 1 "int248_register_operand" "0,0")
11404 (match_operand:QI 2 "general_x64constmem_operand" "QnBc,m")) 0))
11405 (clobber (reg:CC FLAGS_REG))]
11406 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
11407 rtx_equal_p (operands[0], operands[1])"
11408 "and{b}\t{%2, %h0|%h0, %2}"
11409 [(set_attr "isa" "*,nox64")
11410 (set_attr "type" "alu")
11411 (set_attr "mode" "QI")])
11413 ;; Generated by peephole translating test to and. This shows up
11414 ;; often in fp comparisons.
11415 (define_insn "*andqi_ext<mode>_1_cc"
11416 [(set (reg FLAGS_REG)
11420 (match_operator:SWI248 3 "extract_operator"
11421 [(match_operand 1 "int248_register_operand" "0,0")
11424 (match_operand:QI 2 "general_x64constmem_operand" "QnBc,m"))
11426 (set (zero_extract:SWI248
11427 (match_operand 0 "int248_register_operand" "+Q,Q")
11437 (match_dup 2)) 0))]
11438 "ix86_match_ccmode (insn, CCNOmode)
11439 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
11440 && rtx_equal_p (operands[0], operands[1])"
11441 "and{b}\t{%2, %h0|%h0, %2}"
11442 [(set_attr "isa" "*,nox64")
11443 (set_attr "type" "alu")
11444 (set_attr "mode" "QI")])
11446 (define_insn "*andqi_ext<mode>_2"
11447 [(set (zero_extract:SWI248
11448 (match_operand 0 "int248_register_operand" "+Q")
11454 (match_operator:SWI248 3 "extract_operator"
11455 [(match_operand 1 "int248_register_operand" "%0")
11459 (match_operator:SWI248 4 "extract_operator"
11460 [(match_operand 2 "int248_register_operand" "Q")
11462 (const_int 8)]) 0)) 0))
11463 (clobber (reg:CC FLAGS_REG))]
11464 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
11465 rtx_equal_p (operands[0], operands[1])
11466 || rtx_equal_p (operands[0], operands[2])"
11467 "and{b}\t{%h2, %h0|%h0, %h2}"
11468 [(set_attr "type" "alu")
11469 (set_attr "mode" "QI")])
11471 ;; *andqi_ext<mode>_3 is defined via *<code>qi_ext<mode>_3 below.
11473 ;; Convert wide AND instructions with immediate operand to shorter QImode
11474 ;; equivalents when possible.
11475 ;; Don't do the splitting with memory operands, since it introduces risk
11476 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
11477 ;; for size, but that can (should?) be handled by generic code instead.
11479 [(set (match_operand:SWI248 0 "QIreg_operand")
11480 (and:SWI248 (match_operand:SWI248 1 "register_operand")
11481 (match_operand:SWI248 2 "const_int_operand")))
11482 (clobber (reg:CC FLAGS_REG))]
11484 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11485 && !(~INTVAL (operands[2]) & ~(255 << 8))"
11487 [(set (zero_extract:HI (match_dup 0)
11493 (zero_extract:HI (match_dup 1)
11497 (clobber (reg:CC FLAGS_REG))])]
11499 operands[0] = gen_lowpart (HImode, operands[0]);
11500 operands[1] = gen_lowpart (HImode, operands[1]);
11501 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
11504 ;; Since AND can be encoded with sign extended immediate, this is only
11505 ;; profitable when 7th bit is not set.
11507 [(set (match_operand:SWI248 0 "any_QIreg_operand")
11508 (and:SWI248 (match_operand:SWI248 1 "general_operand")
11509 (match_operand:SWI248 2 "const_int_operand")))
11510 (clobber (reg:CC FLAGS_REG))]
11512 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11513 && !(~INTVAL (operands[2]) & ~255)
11514 && !(INTVAL (operands[2]) & 128)"
11515 [(parallel [(set (strict_low_part (match_dup 0))
11516 (and:QI (match_dup 1)
11518 (clobber (reg:CC FLAGS_REG))])]
11520 operands[0] = gen_lowpart (QImode, operands[0]);
11521 operands[1] = gen_lowpart (QImode, operands[1]);
11522 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
11525 (define_insn_and_split "*andn<dwi>3_doubleword_bmi"
11526 [(set (match_operand:<DWI> 0 "register_operand" "=&r,r,r")
11528 (not:<DWI> (match_operand:<DWI> 1 "register_operand" "r,0,r"))
11529 (match_operand:<DWI> 2 "nonimmediate_operand" "ro,ro,0")))
11530 (clobber (reg:CC FLAGS_REG))]
11533 "&& reload_completed"
11534 [(parallel [(set (match_dup 0)
11535 (and:DWIH (not:DWIH (match_dup 1)) (match_dup 2)))
11536 (clobber (reg:CC FLAGS_REG))])
11537 (parallel [(set (match_dup 3)
11538 (and:DWIH (not:DWIH (match_dup 4)) (match_dup 5)))
11539 (clobber (reg:CC FLAGS_REG))])]
11540 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
11542 (define_insn_and_split "*andn<mode>3_doubleword"
11543 [(set (match_operand:DWI 0 "register_operand")
11545 (not:DWI (match_operand:DWI 1 "register_operand"))
11546 (match_operand:DWI 2 "nonimmediate_operand")))
11547 (clobber (reg:CC FLAGS_REG))]
11549 && ix86_pre_reload_split ()"
11552 [(set (match_dup 3) (not:DWI (match_dup 1)))
11553 (parallel [(set (match_dup 0)
11554 (and:DWI (match_dup 3) (match_dup 2)))
11555 (clobber (reg:CC FLAGS_REG))])]
11556 "operands[3] = gen_reg_rtx (<MODE>mode);")
11558 (define_insn "*andn<mode>_1"
11559 [(set (match_operand:SWI48 0 "register_operand" "=r,r,?k")
11561 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r,k"))
11562 (match_operand:SWI48 2 "nonimmediate_operand" "r,m,k")))
11563 (clobber (reg:CC FLAGS_REG))]
11564 "TARGET_BMI || TARGET_AVX512BW"
11566 andn\t{%2, %1, %0|%0, %1, %2}
11567 andn\t{%2, %1, %0|%0, %1, %2}
11569 [(set_attr "isa" "bmi,bmi,avx512bw")
11570 (set_attr "type" "bitmanip,bitmanip,msklog")
11571 (set_attr "btver2_decode" "direct, double,*")
11572 (set_attr "mode" "<MODE>")])
11574 (define_insn "*andn<mode>_1"
11575 [(set (match_operand:SWI12 0 "register_operand" "=r,?k")
11577 (not:SWI12 (match_operand:SWI12 1 "register_operand" "r,k"))
11578 (match_operand:SWI12 2 "register_operand" "r,k")))
11579 (clobber (reg:CC FLAGS_REG))]
11580 "TARGET_BMI || TARGET_AVX512BW"
11582 andn\t{%k2, %k1, %k0|%k0, %k1, %k2}
11584 [(set_attr "isa" "bmi,avx512f")
11585 (set_attr "type" "bitmanip,msklog")
11586 (set_attr "btver2_decode" "direct,*")
11588 (cond [(eq_attr "alternative" "0")
11589 (const_string "SI")
11590 (and (eq_attr "alternative" "1")
11591 (match_test "!TARGET_AVX512DQ"))
11592 (const_string "HI")
11594 (const_string "<MODE>")))])
11596 (define_insn "*andn_<mode>_ccno"
11597 [(set (reg FLAGS_REG)
11600 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
11601 (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
11603 (clobber (match_scratch:SWI48 0 "=r,r"))]
11604 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
11605 "andn\t{%2, %1, %0|%0, %1, %2}"
11606 [(set_attr "type" "bitmanip")
11607 (set_attr "btver2_decode" "direct, double")
11608 (set_attr "mode" "<MODE>")])
11610 ;; Split *andnsi_1 after reload with -Oz when not;and is shorter.
11612 [(set (match_operand:SI 0 "register_operand")
11613 (and:SI (not:SI (match_operand:SI 1 "register_operand"))
11614 (match_operand:SI 2 "nonimmediate_operand")))
11615 (clobber (reg:CC FLAGS_REG))]
11617 && optimize_insn_for_size_p () && optimize_size > 1
11618 && REGNO (operands[0]) == REGNO (operands[1])
11619 && LEGACY_INT_REG_P (operands[0])
11620 && !REX_INT_REG_P (operands[2])
11621 && !reg_overlap_mentioned_p (operands[0], operands[2])"
11622 [(set (match_dup 0) (not:SI (match_dup 1)))
11623 (parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
11624 (clobber (reg:CC FLAGS_REG))])])
11626 ;; Split *andn_si_ccno with -Oz when not;test is shorter.
11628 [(set (match_operand 0 "flags_reg_operand")
11629 (match_operator 1 "compare_operator"
11630 [(and:SI (not:SI (match_operand:SI 2 "general_reg_operand"))
11631 (match_operand:SI 3 "nonimmediate_operand"))
11633 (clobber (match_dup 2))]
11635 && optimize_insn_for_size_p () && optimize_size > 1
11636 && LEGACY_INT_REG_P (operands[2])
11637 && !REX_INT_REG_P (operands[3])
11638 && !reg_overlap_mentioned_p (operands[2], operands[3])"
11639 [(set (match_dup 2) (not:SI (match_dup 2)))
11640 (set (match_dup 0) (match_op_dup 1
11641 [(and:SI (match_dup 3) (match_dup 2))
11644 ;; Variant 1 of 4: Split ((A | B) ^ A) ^ C as (B & ~A) ^ C.
11646 [(set (match_operand:SWI48 0 "register_operand")
11649 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
11650 (match_operand:SWI48 2 "nonimmediate_operand"))
11652 (match_operand:SWI48 3 "nonimmediate_operand")))
11653 (clobber (reg:CC FLAGS_REG))]
11656 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 1)) (match_dup 2)))
11657 (clobber (reg:CC FLAGS_REG))])
11659 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
11660 (clobber (reg:CC FLAGS_REG))])]
11661 "operands[4] = gen_reg_rtx (<MODE>mode);")
11663 ;; Variant 2 of 4: Split ((A | B) ^ B) ^ C as (A & ~B) ^ C.
11665 [(set (match_operand:SWI48 0 "register_operand")
11668 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
11669 (match_operand:SWI48 2 "register_operand"))
11671 (match_operand:SWI48 3 "nonimmediate_operand")))
11672 (clobber (reg:CC FLAGS_REG))]
11675 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 2)) (match_dup 1)))
11676 (clobber (reg:CC FLAGS_REG))])
11678 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
11679 (clobber (reg:CC FLAGS_REG))])]
11680 "operands[4] = gen_reg_rtx (<MODE>mode);")
11682 ;; Variant 3 of 4: Split ((A | B) ^ C) ^ A as (B & ~A) ^ C.
11684 [(set (match_operand:SWI48 0 "register_operand")
11687 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
11688 (match_operand:SWI48 2 "nonimmediate_operand"))
11689 (match_operand:SWI48 3 "nonimmediate_operand"))
11691 (clobber (reg:CC FLAGS_REG))]
11694 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 1)) (match_dup 2)))
11695 (clobber (reg:CC FLAGS_REG))])
11697 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
11698 (clobber (reg:CC FLAGS_REG))])]
11699 "operands[4] = gen_reg_rtx (<MODE>mode);")
11701 ;; Variant 4 of 4: Split ((A | B) ^ C) ^ B as (A & ~B) ^ C.
11703 [(set (match_operand:SWI48 0 "register_operand")
11706 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
11707 (match_operand:SWI48 2 "register_operand"))
11708 (match_operand:SWI48 3 "nonimmediate_operand"))
11710 (clobber (reg:CC FLAGS_REG))]
11713 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 2)) (match_dup 1)))
11714 (clobber (reg:CC FLAGS_REG))])
11716 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
11717 (clobber (reg:CC FLAGS_REG))])]
11718 "operands[4] = gen_reg_rtx (<MODE>mode);")
11720 ;; Logical inclusive and exclusive OR instructions
11722 ;; %%% This used to optimize known byte-wide and operations to memory.
11723 ;; If this is considered useful, it should be done with splitters.
11725 (define_expand "<code><mode>3"
11726 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
11727 (any_or:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
11728 (match_operand:SDWIM 2 "<general_operand>")))]
11731 if (GET_MODE_SIZE (<MODE>mode) > UNITS_PER_WORD
11732 && !x86_64_hilo_general_operand (operands[2], <MODE>mode))
11733 operands[2] = force_reg (<MODE>mode, operands[2]);
11735 ix86_expand_binary_operator (<CODE>, <MODE>mode, operands);
11739 (define_insn_and_split "*<code><dwi>3_doubleword"
11740 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
11742 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
11743 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
11744 (clobber (reg:CC FLAGS_REG))]
11745 "ix86_binary_operator_ok (<CODE>, <DWI>mode, operands)"
11747 "&& reload_completed"
11748 [(const_int:DWIH 0)]
11750 /* This insn may disappear completely when operands[2] == const0_rtx
11751 and operands[0] == operands[1], which requires a NOTE_INSN_DELETED. */
11752 bool emit_insn_deleted_note_p = false;
11754 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
11756 if (operands[2] == const0_rtx)
11757 emit_insn_deleted_note_p = true;
11758 else if (operands[2] == constm1_rtx)
11761 emit_move_insn (operands[0], constm1_rtx);
11763 ix86_expand_unary_operator (NOT, <MODE>mode, &operands[0]);
11766 ix86_expand_binary_operator (<CODE>, <MODE>mode, &operands[0]);
11768 if (operands[5] == const0_rtx)
11770 if (emit_insn_deleted_note_p)
11771 emit_note (NOTE_INSN_DELETED);
11773 else if (operands[5] == constm1_rtx)
11776 emit_move_insn (operands[3], constm1_rtx);
11778 ix86_expand_unary_operator (NOT, <MODE>mode, &operands[3]);
11781 ix86_expand_binary_operator (<CODE>, <MODE>mode, &operands[3]);
11786 (define_insn "*<code><mode>_1"
11787 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,?k")
11789 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,k")
11790 (match_operand:SWI248 2 "<general_operand>" "r<i>,<m>,k")))
11791 (clobber (reg:CC FLAGS_REG))]
11792 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11794 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
11795 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
11798 (cond [(eq_attr "alternative" "2")
11799 (if_then_else (eq_attr "mode" "SI,DI")
11800 (const_string "avx512bw")
11801 (const_string "avx512f"))
11803 (const_string "*")))
11804 (set_attr "type" "alu, alu, msklog")
11805 (set_attr "mode" "<MODE>")])
11807 (define_insn_and_split "*notxor<mode>_1"
11808 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,?k")
11811 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,k")
11812 (match_operand:SWI248 2 "<general_operand>" "r<i>,<m>,k"))))
11813 (clobber (reg:CC FLAGS_REG))]
11814 "ix86_binary_operator_ok (XOR, <MODE>mode, operands)"
11816 "&& reload_completed"
11818 [(set (match_dup 0)
11819 (xor:SWI248 (match_dup 1) (match_dup 2)))
11820 (clobber (reg:CC FLAGS_REG))])
11822 (not:SWI248 (match_dup 0)))]
11824 if (MASK_REG_P (operands[0]))
11826 emit_insn (gen_kxnor<mode> (operands[0], operands[1], operands[2]));
11831 (cond [(eq_attr "alternative" "2")
11832 (if_then_else (eq_attr "mode" "SI,DI")
11833 (const_string "avx512bw")
11834 (const_string "avx512f"))
11836 (const_string "*")))
11837 (set_attr "type" "alu, alu, msklog")
11838 (set_attr "mode" "<MODE>")])
11840 (define_insn_and_split "*iordi_1_bts"
11841 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11843 (match_operand:DI 1 "nonimmediate_operand" "%0")
11844 (match_operand:DI 2 "const_int_operand" "n")))
11845 (clobber (reg:CC FLAGS_REG))]
11846 "TARGET_64BIT && TARGET_USE_BT
11847 && ix86_binary_operator_ok (IOR, DImode, operands)
11848 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
11850 "&& reload_completed"
11851 [(parallel [(set (zero_extract:DI (match_dup 0)
11855 (clobber (reg:CC FLAGS_REG))])]
11856 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
11857 [(set_attr "type" "alu1")
11858 (set_attr "prefix_0f" "1")
11859 (set_attr "znver1_decode" "double")
11860 (set_attr "mode" "DI")])
11862 (define_insn_and_split "*xordi_1_btc"
11863 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11865 (match_operand:DI 1 "nonimmediate_operand" "%0")
11866 (match_operand:DI 2 "const_int_operand" "n")))
11867 (clobber (reg:CC FLAGS_REG))]
11868 "TARGET_64BIT && TARGET_USE_BT
11869 && ix86_binary_operator_ok (XOR, DImode, operands)
11870 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
11872 "&& reload_completed"
11873 [(parallel [(set (zero_extract:DI (match_dup 0)
11876 (not:DI (zero_extract:DI (match_dup 0)
11879 (clobber (reg:CC FLAGS_REG))])]
11880 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
11881 [(set_attr "type" "alu1")
11882 (set_attr "prefix_0f" "1")
11883 (set_attr "znver1_decode" "double")
11884 (set_attr "mode" "DI")])
11886 ;; Optimize a ^ ((a ^ b) & mask) to (~mask & a) | (b & mask)
11887 (define_insn_and_split "*xor2andn"
11888 [(set (match_operand:SWI248 0 "register_operand")
11892 (match_operand:SWI248 1 "nonimmediate_operand")
11893 (match_operand:SWI248 2 "nonimmediate_operand"))
11894 (match_operand:SWI248 3 "nonimmediate_operand"))
11896 (clobber (reg:CC FLAGS_REG))]
11897 "TARGET_BMI && ix86_pre_reload_split ()"
11900 [(parallel [(set (match_dup 4)
11905 (clobber (reg:CC FLAGS_REG))])
11906 (parallel [(set (match_dup 5)
11910 (clobber (reg:CC FLAGS_REG))])
11911 (parallel [(set (match_dup 0)
11915 (clobber (reg:CC FLAGS_REG))])]
11917 operands[1] = force_reg (<MODE>mode, operands[1]);
11918 operands[3] = force_reg (<MODE>mode, operands[3]);
11919 operands[4] = gen_reg_rtx (<MODE>mode);
11920 operands[5] = gen_reg_rtx (<MODE>mode);
11923 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
11924 (define_insn "*<code>si_1_zext"
11925 [(set (match_operand:DI 0 "register_operand" "=r")
11927 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
11928 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
11929 (clobber (reg:CC FLAGS_REG))]
11930 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11931 "<logic>{l}\t{%2, %k0|%k0, %2}"
11932 [(set_attr "type" "alu")
11933 (set_attr "mode" "SI")])
11935 (define_insn "*<code>si_1_zext_imm"
11936 [(set (match_operand:DI 0 "register_operand" "=r")
11938 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
11939 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
11940 (clobber (reg:CC FLAGS_REG))]
11941 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11942 "<logic>{l}\t{%2, %k0|%k0, %2}"
11943 [(set_attr "type" "alu")
11944 (set_attr "mode" "SI")])
11946 (define_insn "*<code>qi_1"
11947 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,?k")
11948 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
11949 (match_operand:QI 2 "general_operand" "qn,m,rn,k")))
11950 (clobber (reg:CC FLAGS_REG))]
11951 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
11953 <logic>{b}\t{%2, %0|%0, %2}
11954 <logic>{b}\t{%2, %0|%0, %2}
11955 <logic>{l}\t{%k2, %k0|%k0, %k2}
11957 [(set_attr "isa" "*,*,*,avx512f")
11958 (set_attr "type" "alu,alu,alu,msklog")
11960 (cond [(eq_attr "alternative" "2")
11961 (const_string "SI")
11962 (and (eq_attr "alternative" "3")
11963 (match_test "!TARGET_AVX512DQ"))
11964 (const_string "HI")
11966 (const_string "QI")))
11967 ;; Potential partial reg stall on alternative 2.
11968 (set (attr "preferred_for_speed")
11969 (cond [(eq_attr "alternative" "2")
11970 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
11971 (symbol_ref "true")))])
11973 (define_insn_and_split "*notxorqi_1"
11974 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,?k")
11976 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
11977 (match_operand:QI 2 "general_operand" "qn,m,rn,k"))))
11978 (clobber (reg:CC FLAGS_REG))]
11979 "ix86_binary_operator_ok (XOR, QImode, operands)"
11981 "&& reload_completed"
11983 [(set (match_dup 0)
11984 (xor:QI (match_dup 1) (match_dup 2)))
11985 (clobber (reg:CC FLAGS_REG))])
11987 (not:QI (match_dup 0)))]
11989 if (mask_reg_operand (operands[0], QImode))
11991 emit_insn (gen_kxnorqi (operands[0], operands[1], operands[2]));
11995 [(set_attr "isa" "*,*,*,avx512f")
11996 (set_attr "type" "alu,alu,alu,msklog")
11998 (cond [(eq_attr "alternative" "2")
11999 (const_string "SI")
12000 (and (eq_attr "alternative" "3")
12001 (match_test "!TARGET_AVX512DQ"))
12002 (const_string "HI")
12004 (const_string "QI")))
12005 ;; Potential partial reg stall on alternative 2.
12006 (set (attr "preferred_for_speed")
12007 (cond [(eq_attr "alternative" "2")
12008 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
12009 (symbol_ref "true")))])
12011 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
12012 (define_insn_and_split "*<code><mode>_1_slp"
12013 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
12014 (any_or:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0,!<r>")
12015 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
12016 (clobber (reg:CC FLAGS_REG))]
12017 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
12019 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
12021 "&& reload_completed"
12022 [(set (strict_low_part (match_dup 0)) (match_dup 1))
12024 [(set (strict_low_part (match_dup 0))
12025 (any_or:SWI12 (match_dup 0) (match_dup 2)))
12026 (clobber (reg:CC FLAGS_REG))])]
12028 [(set_attr "type" "alu")
12029 (set_attr "mode" "<MODE>")])
12031 ;; convert (sign_extend:WIDE (any_logic:NARROW (memory, immediate)))
12032 ;; to (any_logic:WIDE (sign_extend (memory)), (sign_extend (immediate))).
12033 ;; This eliminates sign extension after logic operation.
12036 [(set (match_operand:SWI248 0 "register_operand")
12037 (sign_extend:SWI248
12038 (any_logic:QI (match_operand:QI 1 "memory_operand")
12039 (match_operand:QI 2 "const_int_operand"))))]
12041 [(set (match_dup 3) (sign_extend:SWI248 (match_dup 1)))
12042 (set (match_dup 0) (any_logic:SWI248 (match_dup 3) (match_dup 2)))]
12043 "operands[3] = gen_reg_rtx (<MODE>mode);")
12046 [(set (match_operand:SWI48 0 "register_operand")
12048 (any_logic:HI (match_operand:HI 1 "memory_operand")
12049 (match_operand:HI 2 "const_int_operand"))))]
12051 [(set (match_dup 3) (sign_extend:SWI48 (match_dup 1)))
12052 (set (match_dup 0) (any_logic:SWI48 (match_dup 3) (match_dup 2)))]
12053 "operands[3] = gen_reg_rtx (<MODE>mode);")
12056 [(set (match_operand:DI 0 "register_operand")
12058 (any_logic:SI (match_operand:SI 1 "memory_operand")
12059 (match_operand:SI 2 "const_int_operand"))))]
12061 [(set (match_dup 3) (sign_extend:DI (match_dup 1)))
12062 (set (match_dup 0) (any_logic:DI (match_dup 3) (match_dup 2)))]
12063 "operands[3] = gen_reg_rtx (DImode);")
12065 (define_insn "*<code><mode>_2"
12066 [(set (reg FLAGS_REG)
12067 (compare (any_or:SWI
12068 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
12069 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
12071 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
12072 (any_or:SWI (match_dup 1) (match_dup 2)))]
12073 "ix86_match_ccmode (insn, CCNOmode)
12074 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
12075 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
12076 [(set_attr "type" "alu")
12077 (set_attr "mode" "<MODE>")])
12079 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
12080 ;; ??? Special case for immediate operand is missing - it is tricky.
12081 (define_insn "*<code>si_2_zext"
12082 [(set (reg FLAGS_REG)
12083 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
12084 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
12086 (set (match_operand:DI 0 "register_operand" "=r")
12087 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
12088 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
12089 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12090 "<logic>{l}\t{%2, %k0|%k0, %2}"
12091 [(set_attr "type" "alu")
12092 (set_attr "mode" "SI")])
12094 (define_insn "*<code>si_2_zext_imm"
12095 [(set (reg FLAGS_REG)
12096 (compare (any_or:SI
12097 (match_operand:SI 1 "nonimmediate_operand" "%0")
12098 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
12100 (set (match_operand:DI 0 "register_operand" "=r")
12101 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12102 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
12103 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12104 "<logic>{l}\t{%2, %k0|%k0, %2}"
12105 [(set_attr "type" "alu")
12106 (set_attr "mode" "SI")])
12108 (define_insn "*<code><mode>_3"
12109 [(set (reg FLAGS_REG)
12110 (compare (any_or:SWI
12111 (match_operand:SWI 1 "nonimmediate_operand" "%0")
12112 (match_operand:SWI 2 "<general_operand>" "<g>"))
12114 (clobber (match_scratch:SWI 0 "=<r>"))]
12115 "ix86_match_ccmode (insn, CCNOmode)
12116 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12117 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
12118 [(set_attr "type" "alu")
12119 (set_attr "mode" "<MODE>")])
12121 (define_insn "*<code>qi_ext<mode>_0"
12122 [(set (match_operand:QI 0 "nonimm_x64constmem_operand" "=QBc,m")
12125 (match_operator:SWI248 3 "extract_operator"
12126 [(match_operand 2 "int248_register_operand" "Q,Q")
12129 (match_operand:QI 1 "nonimm_x64constmem_operand" "0,0")))
12130 (clobber (reg:CC FLAGS_REG))]
12132 "<logic>{b}\t{%h2, %0|%0, %h2}"
12133 [(set_attr "isa" "*,nox64")
12134 (set_attr "type" "alu")
12135 (set_attr "mode" "QI")])
12137 (define_insn "*<code>qi_ext<mode>_1"
12138 [(set (zero_extract:SWI248
12139 (match_operand 0 "int248_register_operand" "+Q,Q")
12145 (match_operator:SWI248 3 "extract_operator"
12146 [(match_operand 1 "int248_register_operand" "0,0")
12149 (match_operand:QI 2 "general_x64constmem_operand" "QnBc,m")) 0))
12150 (clobber (reg:CC FLAGS_REG))]
12151 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12152 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
12153 && rtx_equal_p (operands[0], operands[1])"
12154 "<logic>{b}\t{%2, %h0|%h0, %2}"
12155 [(set_attr "isa" "*,nox64")
12156 (set_attr "type" "alu")
12157 (set_attr "mode" "QI")])
12159 (define_insn "*<code>qi_ext<mode>_2"
12160 [(set (zero_extract:SWI248
12161 (match_operand 0 "int248_register_operand" "+Q")
12167 (match_operator:SWI248 3 "extract_operator"
12168 [(match_operand 1 "int248_register_operand" "%0")
12172 (match_operator:SWI248 4 "extract_operator"
12173 [(match_operand 2 "int248_register_operand" "Q")
12175 (const_int 8)]) 0)) 0))
12176 (clobber (reg:CC FLAGS_REG))]
12177 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12178 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
12179 && (rtx_equal_p (operands[0], operands[1])
12180 || rtx_equal_p (operands[0], operands[2]))"
12181 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
12182 [(set_attr "type" "alu")
12183 (set_attr "mode" "QI")])
12185 (define_insn "*<code>qi_ext<mode>_3"
12186 [(set (zero_extract:SWI248
12187 (match_operand 0 "int248_register_operand" "+Q")
12190 (zero_extract:SWI248
12192 (match_operand 1 "int248_register_operand" "%0")
12193 (match_operand 2 "int248_register_operand" "Q"))
12196 (clobber (reg:CC FLAGS_REG))]
12197 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12198 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
12199 && (rtx_equal_p (operands[0], operands[1])
12200 || rtx_equal_p (operands[0], operands[2]))"
12201 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
12202 [(set_attr "type" "alu")
12203 (set_attr "mode" "QI")])
12205 ;; Convert wide OR instructions with immediate operand to shorter QImode
12206 ;; equivalents when possible.
12207 ;; Don't do the splitting with memory operands, since it introduces risk
12208 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
12209 ;; for size, but that can (should?) be handled by generic code instead.
12211 [(set (match_operand:SWI248 0 "QIreg_operand")
12212 (any_or:SWI248 (match_operand:SWI248 1 "register_operand")
12213 (match_operand:SWI248 2 "const_int_operand")))
12214 (clobber (reg:CC FLAGS_REG))]
12216 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12217 && !(INTVAL (operands[2]) & ~(255 << 8))"
12219 [(set (zero_extract:HI (match_dup 0)
12225 (zero_extract:HI (match_dup 1)
12229 (clobber (reg:CC FLAGS_REG))])]
12231 /* Handle the case where INTVAL (operands[2]) == 0. */
12232 if (operands[2] == const0_rtx)
12234 if (!rtx_equal_p (operands[0], operands[1]))
12235 emit_move_insn (operands[0], operands[1]);
12237 emit_note (NOTE_INSN_DELETED);
12240 operands[0] = gen_lowpart (HImode, operands[0]);
12241 operands[1] = gen_lowpart (HImode, operands[1]);
12242 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
12245 ;; Since OR can be encoded with sign extended immediate, this is only
12246 ;; profitable when 7th bit is set.
12248 [(set (match_operand:SWI248 0 "any_QIreg_operand")
12249 (any_or:SWI248 (match_operand:SWI248 1 "general_operand")
12250 (match_operand:SWI248 2 "const_int_operand")))
12251 (clobber (reg:CC FLAGS_REG))]
12253 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12254 && !(INTVAL (operands[2]) & ~255)
12255 && (INTVAL (operands[2]) & 128)"
12256 [(parallel [(set (strict_low_part (match_dup 0))
12257 (any_or:QI (match_dup 1)
12259 (clobber (reg:CC FLAGS_REG))])]
12261 operands[0] = gen_lowpart (QImode, operands[0]);
12262 operands[1] = gen_lowpart (QImode, operands[1]);
12263 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
12266 (define_expand "xorqi_ext_1_cc"
12268 [(set (reg:CCNO FLAGS_REG)
12272 (zero_extract:HI (match_operand:HI 1 "register_operand")
12275 (match_operand:QI 2 "const_int_operand"))
12277 (set (zero_extract:HI (match_operand:HI 0 "register_operand")
12283 (zero_extract:HI (match_dup 1)
12286 (match_dup 2)) 0))])])
12288 (define_insn "*xorqi_ext<mode>_1_cc"
12289 [(set (reg FLAGS_REG)
12293 (match_operator:SWI248 3 "extract_operator"
12294 [(match_operand 1 "int248_register_operand" "0,0")
12297 (match_operand:QI 2 "general_x64constmem_operand" "QnBc,m"))
12299 (set (zero_extract:SWI248
12300 (match_operand 0 "int248_register_operand" "+Q,Q")
12310 (match_dup 2)) 0))]
12311 "ix86_match_ccmode (insn, CCNOmode)
12312 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
12313 && rtx_equal_p (operands[0], operands[1])"
12314 "xor{b}\t{%2, %h0|%h0, %2}"
12315 [(set_attr "isa" "*,nox64")
12316 (set_attr "type" "alu")
12317 (set_attr "mode" "QI")])
12319 ;; Peephole2 rega = 0; rega op= regb into rega = regb.
12321 [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
12323 (clobber (reg:CC FLAGS_REG))])
12324 (parallel [(set (match_dup 0)
12325 (any_or_plus:SWI (match_dup 0)
12326 (match_operand:SWI 1 "<general_operand>")))
12327 (clobber (reg:CC FLAGS_REG))])]
12329 [(set (match_dup 0) (match_dup 1))])
12331 ;; Split DST = (HI<<32)|LO early to minimize register usage.
12332 (define_insn_and_split "*concat<mode><dwi>3_1"
12333 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
12335 (ashift:<DWI> (match_operand:<DWI> 1 "register_operand" "r,r")
12336 (match_operand:QI 2 "const_int_operand"))
12338 (match_operand:DWIH 3 "nonimmediate_operand" "r,m"))))]
12339 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT"
12341 "&& reload_completed"
12344 split_double_concat (<DWI>mode, operands[0], operands[3],
12345 gen_lowpart (<MODE>mode, operands[1]));
12349 (define_insn_and_split "*concat<mode><dwi>3_2"
12350 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
12353 (match_operand:DWIH 1 "nonimmediate_operand" "r,m"))
12354 (ashift:<DWI> (match_operand:<DWI> 2 "register_operand" "r,r")
12355 (match_operand:QI 3 "const_int_operand"))))]
12356 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12358 "&& reload_completed"
12361 split_double_concat (<DWI>mode, operands[0], operands[1],
12362 gen_lowpart (<MODE>mode, operands[2]));
12366 (define_insn_and_split "*concat<mode><dwi>3_3"
12367 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,r,&r")
12371 (match_operand:DWIH 1 "nonimmediate_operand" "r,m,r,m"))
12372 (match_operand:QI 2 "const_int_operand"))
12374 (match_operand:DWIH 3 "nonimmediate_operand" "r,r,m,m"))))]
12375 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT"
12377 "&& reload_completed"
12380 split_double_concat (<DWI>mode, operands[0], operands[3], operands[1]);
12384 (define_insn_and_split "*concat<mode><dwi>3_4"
12385 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,r,&r")
12388 (match_operand:DWIH 1 "nonimmediate_operand" "r,m,r,m"))
12391 (match_operand:DWIH 2 "nonimmediate_operand" "r,r,m,m"))
12392 (match_operand:QI 3 "const_int_operand"))))]
12393 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12395 "&& reload_completed"
12398 split_double_concat (<DWI>mode, operands[0], operands[1], operands[2]);
12402 (define_insn_and_split "*concat<half><mode>3_5"
12403 [(set (match_operand:DWI 0 "nonimmediate_operand" "=r,o,o")
12405 (ashift:DWI (match_operand:DWI 1 "register_operand" "r,r,r")
12406 (match_operand:QI 2 "const_int_operand"))
12407 (match_operand:DWI 3 "const_scalar_int_operand" "n,n,Wd")))]
12408 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT / 2
12409 && (<MODE>mode == DImode
12410 ? CONST_INT_P (operands[3])
12411 && (UINTVAL (operands[3]) & ~GET_MODE_MASK (SImode)) == 0
12412 : CONST_INT_P (operands[3])
12413 ? INTVAL (operands[3]) >= 0
12414 : CONST_WIDE_INT_NUNITS (operands[3]) == 2
12415 && CONST_WIDE_INT_ELT (operands[3], 1) == 0)
12416 && !(CONST_INT_P (operands[3])
12417 ? ix86_endbr_immediate_operand (operands[3], VOIDmode)
12418 : ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[3],
12422 "&& reload_completed"
12425 rtx op3 = simplify_subreg (<HALF>mode, operands[3], <MODE>mode, 0);
12426 split_double_concat (<MODE>mode, operands[0], op3,
12427 gen_lowpart (<HALF>mode, operands[1]));
12430 [(set_attr "isa" "*,nox64,x64")])
12432 (define_insn_and_split "*concat<mode><dwi>3_6"
12433 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,o,r")
12437 (match_operand:DWIH 1 "nonimmediate_operand" "r,r,r,m"))
12438 (match_operand:QI 2 "const_int_operand"))
12439 (match_operand:<DWI> 3 "const_scalar_int_operand" "n,n,Wd,n")))]
12440 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT
12441 && (<DWI>mode == DImode
12442 ? CONST_INT_P (operands[3])
12443 && (UINTVAL (operands[3]) & ~GET_MODE_MASK (SImode)) == 0
12444 : CONST_INT_P (operands[3])
12445 ? INTVAL (operands[3]) >= 0
12446 : CONST_WIDE_INT_NUNITS (operands[3]) == 2
12447 && CONST_WIDE_INT_ELT (operands[3], 1) == 0)
12448 && !(CONST_INT_P (operands[3])
12449 ? ix86_endbr_immediate_operand (operands[3], VOIDmode)
12450 : ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[3],
12454 "&& reload_completed"
12457 rtx op3 = simplify_subreg (<MODE>mode, operands[3], <DWI>mode, 0);
12458 split_double_concat (<DWI>mode, operands[0], op3, operands[1]);
12461 [(set_attr "isa" "*,nox64,x64,*")])
12463 (define_insn_and_split "*concat<mode><dwi>3_7"
12464 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,o,r")
12467 (match_operand:DWIH 1 "nonimmediate_operand" "r,r,r,m"))
12468 (match_operand:<DWI> 2 "const_scalar_int_operand" "n,n,Wd,n")))]
12469 "<DWI>mode == DImode
12470 ? CONST_INT_P (operands[2])
12471 && (UINTVAL (operands[2]) & GET_MODE_MASK (SImode)) == 0
12472 && !ix86_endbr_immediate_operand (operands[2], VOIDmode)
12473 : CONST_WIDE_INT_P (operands[2])
12474 && CONST_WIDE_INT_NUNITS (operands[2]) == 2
12475 && CONST_WIDE_INT_ELT (operands[2], 0) == 0
12476 && !ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[2],
12480 "&& reload_completed"
12484 if (<DWI>mode == DImode)
12485 op2 = gen_int_mode (INTVAL (operands[2]) >> 32, <MODE>mode);
12487 op2 = gen_int_mode (CONST_WIDE_INT_ELT (operands[2], 1), <MODE>mode);
12488 split_double_concat (<DWI>mode, operands[0], operands[1], op2);
12491 [(set_attr "isa" "*,nox64,x64,*")])
12493 ;; Negation instructions
12495 (define_expand "neg<mode>2"
12496 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
12497 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
12499 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
12501 (define_insn_and_split "*neg<dwi>2_doubleword"
12502 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
12503 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
12504 (clobber (reg:CC FLAGS_REG))]
12505 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
12507 "&& reload_completed"
12509 [(set (reg:CCC FLAGS_REG)
12510 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
12511 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
12513 [(set (match_dup 2)
12514 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
12517 (clobber (reg:CC FLAGS_REG))])
12519 [(set (match_dup 2)
12520 (neg:DWIH (match_dup 2)))
12521 (clobber (reg:CC FLAGS_REG))])]
12522 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
12535 [(set (match_operand:SWI48 0 "general_reg_operand")
12536 (match_operand:SWI48 1 "nonimmediate_gr_operand"))
12538 [(set (reg:CCC FLAGS_REG)
12539 (unspec:CCC [(match_operand:SWI48 2 "general_reg_operand")
12540 (const_int 0)] UNSPEC_CC_NE))
12541 (set (match_dup 2) (neg:SWI48 (match_dup 2)))])
12543 [(set (match_dup 0)
12544 (plus:SWI48 (plus:SWI48
12545 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
12548 (clobber (reg:CC FLAGS_REG))])
12550 [(set (match_dup 0)
12551 (neg:SWI48 (match_dup 0)))
12552 (clobber (reg:CC FLAGS_REG))])]
12553 "REGNO (operands[0]) != REGNO (operands[2])
12554 && !reg_mentioned_p (operands[0], operands[1])
12555 && !reg_mentioned_p (operands[2], operands[1])"
12557 [(set (reg:CCC FLAGS_REG)
12558 (unspec:CCC [(match_dup 2) (const_int 0)] UNSPEC_CC_NE))
12559 (set (match_dup 2) (neg:SWI48 (match_dup 2)))])
12561 [(set (match_dup 0)
12562 (minus:SWI48 (minus:SWI48
12564 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0)))
12566 (clobber (reg:CC FLAGS_REG))])]
12567 "ix86_expand_clear (operands[0]);")
12576 ;; sbbl %edx, %edx // *x86_mov<mode>cc_0_m1
12580 [(set (match_operand:SWI48 0 "general_reg_operand") (const_int 0))
12581 (clobber (reg:CC FLAGS_REG))])
12583 [(set (reg:CCC FLAGS_REG)
12584 (unspec:CCC [(match_operand:SWI48 1 "general_reg_operand")
12585 (const_int 0)] UNSPEC_CC_NE))
12586 (set (match_dup 1) (neg:SWI48 (match_dup 1)))])
12588 [(set (match_dup 0)
12589 (plus:SWI48 (plus:SWI48
12590 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
12593 (clobber (reg:CC FLAGS_REG))])
12595 [(set (match_dup 0)
12596 (neg:SWI48 (match_dup 0)))
12597 (clobber (reg:CC FLAGS_REG))])]
12598 "REGNO (operands[0]) != REGNO (operands[1])"
12600 [(set (reg:CCC FLAGS_REG)
12601 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
12602 (set (match_dup 1) (neg:SWI48 (match_dup 1)))])
12604 [(set (match_dup 0)
12605 (if_then_else:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
12608 (clobber (reg:CC FLAGS_REG))])])
12610 (define_insn "*neg<mode>_1"
12611 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
12612 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
12613 (clobber (reg:CC FLAGS_REG))]
12614 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
12615 "neg{<imodesuffix>}\t%0"
12616 [(set_attr "type" "negnot")
12617 (set_attr "mode" "<MODE>")])
12619 (define_insn "*negsi_1_zext"
12620 [(set (match_operand:DI 0 "register_operand" "=r")
12622 (neg:SI (match_operand:SI 1 "register_operand" "0"))))
12623 (clobber (reg:CC FLAGS_REG))]
12624 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
12626 [(set_attr "type" "negnot")
12627 (set_attr "mode" "SI")])
12629 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
12630 (define_insn_and_split "*neg<mode>_1_slp"
12631 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
12632 (neg:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")))
12633 (clobber (reg:CC FLAGS_REG))]
12634 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
12636 neg{<imodesuffix>}\t%0
12638 "&& reload_completed"
12639 [(set (strict_low_part (match_dup 0)) (match_dup 1))
12641 [(set (strict_low_part (match_dup 0))
12642 (neg:SWI12 (match_dup 0)))
12643 (clobber (reg:CC FLAGS_REG))])]
12645 [(set_attr "type" "negnot")
12646 (set_attr "mode" "<MODE>")])
12648 (define_insn "*neg<mode>_2"
12649 [(set (reg FLAGS_REG)
12651 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
12653 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
12654 (neg:SWI (match_dup 1)))]
12655 "ix86_match_ccmode (insn, CCGOCmode)
12656 && ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
12657 "neg{<imodesuffix>}\t%0"
12658 [(set_attr "type" "negnot")
12659 (set_attr "mode" "<MODE>")])
12661 (define_insn "*negsi_2_zext"
12662 [(set (reg FLAGS_REG)
12664 (neg:SI (match_operand:SI 1 "register_operand" "0"))
12666 (set (match_operand:DI 0 "register_operand" "=r")
12668 (neg:SI (match_dup 1))))]
12669 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12670 && ix86_unary_operator_ok (NEG, SImode, operands)"
12672 [(set_attr "type" "negnot")
12673 (set_attr "mode" "SI")])
12675 (define_insn "*neg<mode>_ccc_1"
12676 [(set (reg:CCC FLAGS_REG)
12678 [(match_operand:SWI 1 "nonimmediate_operand" "0")
12679 (const_int 0)] UNSPEC_CC_NE))
12680 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
12681 (neg:SWI (match_dup 1)))]
12683 "neg{<imodesuffix>}\t%0"
12684 [(set_attr "type" "negnot")
12685 (set_attr "mode" "<MODE>")])
12687 (define_insn "*neg<mode>_ccc_2"
12688 [(set (reg:CCC FLAGS_REG)
12690 [(match_operand:SWI 1 "nonimmediate_operand" "0")
12691 (const_int 0)] UNSPEC_CC_NE))
12692 (clobber (match_scratch:SWI 0 "=<r>"))]
12694 "neg{<imodesuffix>}\t%0"
12695 [(set_attr "type" "negnot")
12696 (set_attr "mode" "<MODE>")])
12698 (define_expand "x86_neg<mode>_ccc"
12700 [(set (reg:CCC FLAGS_REG)
12701 (unspec:CCC [(match_operand:SWI48 1 "register_operand")
12702 (const_int 0)] UNSPEC_CC_NE))
12703 (set (match_operand:SWI48 0 "register_operand")
12704 (neg:SWI48 (match_dup 1)))])])
12706 (define_insn "*negqi_ext<mode>_2"
12707 [(set (zero_extract:SWI248
12708 (match_operand 0 "int248_register_operand" "+Q")
12714 (match_operator:SWI248 2 "extract_operator"
12715 [(match_operand 1 "int248_register_operand" "0")
12717 (const_int 8)]) 0)) 0))
12718 (clobber (reg:CC FLAGS_REG))]
12719 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
12720 rtx_equal_p (operands[0], operands[1])"
12722 [(set_attr "type" "negnot")
12723 (set_attr "mode" "QI")])
12725 ;; Negate with jump on overflow.
12726 (define_expand "negv<mode>3"
12727 [(parallel [(set (reg:CCO FLAGS_REG)
12729 [(match_operand:SWI 1 "register_operand")
12730 (match_dup 3)] UNSPEC_CC_NE))
12731 (set (match_operand:SWI 0 "register_operand")
12732 (neg:SWI (match_dup 1)))])
12733 (set (pc) (if_then_else
12734 (eq (reg:CCO FLAGS_REG) (const_int 0))
12735 (label_ref (match_operand 2))
12740 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
12744 (define_insn "*negv<mode>3"
12745 [(set (reg:CCO FLAGS_REG)
12746 (unspec:CCO [(match_operand:SWI 1 "nonimmediate_operand" "0")
12747 (match_operand:SWI 2 "const_int_operand")]
12749 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
12750 (neg:SWI (match_dup 1)))]
12751 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
12752 && mode_signbit_p (<MODE>mode, operands[2])"
12753 "neg{<imodesuffix>}\t%0"
12754 [(set_attr "type" "negnot")
12755 (set_attr "mode" "<MODE>")])
12757 ;; Optimize *negsi_1 followed by *cmpsi_ccno_1 (PR target/91384)
12759 [(set (match_operand:SWI 0 "general_reg_operand")
12760 (match_operand:SWI 1 "general_reg_operand"))
12761 (parallel [(set (match_dup 0) (neg:SWI (match_dup 0)))
12762 (clobber (reg:CC FLAGS_REG))])
12763 (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))]
12765 [(set (match_dup 0) (match_dup 1))
12766 (parallel [(set (reg:CCZ FLAGS_REG)
12767 (compare:CCZ (neg:SWI (match_dup 0)) (const_int 0)))
12768 (set (match_dup 0) (neg:SWI (match_dup 0)))])])
12770 ;; Special expand pattern to handle integer mode abs
12772 (define_expand "abs<mode>2"
12774 [(set (match_operand:SDWIM 0 "register_operand")
12776 (match_operand:SDWIM 1 "general_operand")))
12777 (clobber (reg:CC FLAGS_REG))])]
12779 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)"
12781 if (TARGET_EXPAND_ABS)
12783 machine_mode mode = <MODE>mode;
12784 operands[1] = force_reg (mode, operands[1]);
12786 /* Generate rtx abs using:
12787 abs (x) = (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)) */
12789 rtx shift_amount = gen_int_mode (GET_MODE_PRECISION (mode) - 1, QImode);
12790 rtx shift_dst = expand_simple_binop (mode, ASHIFTRT, operands[1],
12791 shift_amount, NULL_RTX,
12793 rtx xor_dst = expand_simple_binop (mode, XOR, shift_dst, operands[1],
12794 operands[0], 0, OPTAB_DIRECT);
12795 rtx minus_dst = expand_simple_binop (mode, MINUS, xor_dst, shift_dst,
12796 operands[0], 0, OPTAB_DIRECT);
12797 if (!rtx_equal_p (minus_dst, operands[0]))
12798 emit_move_insn (operands[0], minus_dst);
12803 (define_insn_and_split "*abs<dwi>2_doubleword"
12804 [(set (match_operand:<DWI> 0 "register_operand")
12806 (match_operand:<DWI> 1 "general_operand")))
12807 (clobber (reg:CC FLAGS_REG))]
12809 && ix86_pre_reload_split ()"
12813 [(set (reg:CCC FLAGS_REG)
12814 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
12815 (set (match_dup 2) (neg:DWIH (match_dup 1)))])
12817 [(set (match_dup 5)
12818 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
12821 (clobber (reg:CC FLAGS_REG))])
12823 [(set (reg:CCGOC FLAGS_REG)
12825 (neg:DWIH (match_dup 5))
12828 (neg:DWIH (match_dup 5)))])
12831 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
12836 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
12840 operands[1] = force_reg (<DWI>mode, operands[1]);
12841 operands[2] = gen_reg_rtx (<DWI>mode);
12843 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
12846 (define_insn_and_split "*nabs<dwi>2_doubleword"
12847 [(set (match_operand:<DWI> 0 "register_operand")
12850 (match_operand:<DWI> 1 "general_operand"))))
12851 (clobber (reg:CC FLAGS_REG))]
12853 && ix86_pre_reload_split ()"
12857 [(set (reg:CCC FLAGS_REG)
12858 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
12859 (set (match_dup 2) (neg:DWIH (match_dup 1)))])
12861 [(set (match_dup 5)
12862 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
12865 (clobber (reg:CC FLAGS_REG))])
12867 [(set (reg:CCGOC FLAGS_REG)
12869 (neg:DWIH (match_dup 5))
12872 (neg:DWIH (match_dup 5)))])
12875 (lt (reg:CCGOC FLAGS_REG) (const_int 0))
12880 (lt (reg:CCGOC FLAGS_REG) (const_int 0))
12884 operands[1] = force_reg (<DWI>mode, operands[1]);
12885 operands[2] = gen_reg_rtx (<DWI>mode);
12887 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
12890 (define_insn_and_split "*abs<mode>2_1"
12891 [(set (match_operand:SWI 0 "register_operand")
12893 (match_operand:SWI 1 "general_operand")))
12894 (clobber (reg:CC FLAGS_REG))]
12896 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
12897 && ix86_pre_reload_split ()"
12901 [(set (reg:CCGOC FLAGS_REG)
12903 (neg:SWI (match_dup 1))
12906 (neg:SWI (match_dup 1)))])
12909 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
12913 operands[1] = force_reg (<MODE>mode, operands[1]);
12914 operands[2] = gen_reg_rtx (<MODE>mode);
12917 (define_insn_and_split "*nabs<mode>2_1"
12918 [(set (match_operand:SWI 0 "register_operand")
12921 (match_operand:SWI 1 "general_operand"))))
12922 (clobber (reg:CC FLAGS_REG))]
12924 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
12925 && ix86_pre_reload_split ()"
12929 [(set (reg:CCGOC FLAGS_REG)
12931 (neg:SWI (match_dup 1))
12934 (neg:SWI (match_dup 1)))])
12937 (lt (reg:CCGOC FLAGS_REG) (const_int 0))
12941 operands[1] = force_reg (<MODE>mode, operands[1]);
12942 operands[2] = gen_reg_rtx (<MODE>mode);
12945 (define_expand "<code>tf2"
12946 [(set (match_operand:TF 0 "register_operand")
12947 (absneg:TF (match_operand:TF 1 "register_operand")))]
12949 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
12951 (define_insn_and_split "*<code>tf2_1"
12952 [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
12954 (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m")))
12955 (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))]
12958 "&& reload_completed"
12959 [(set (match_dup 0)
12960 (<absneg_op>:TF (match_dup 1) (match_dup 2)))]
12964 if (MEM_P (operands[1]))
12965 std::swap (operands[1], operands[2]);
12969 if (operands_match_p (operands[0], operands[2]))
12970 std::swap (operands[1], operands[2]);
12973 [(set_attr "isa" "noavx,noavx,avx,avx")])
12975 (define_insn_and_split "*nabstf2_1"
12976 [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
12979 (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m"))))
12980 (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))]
12983 "&& reload_completed"
12984 [(set (match_dup 0)
12985 (ior:TF (match_dup 1) (match_dup 2)))]
12989 if (MEM_P (operands[1]))
12990 std::swap (operands[1], operands[2]);
12994 if (operands_match_p (operands[0], operands[2]))
12995 std::swap (operands[1], operands[2]);
12998 [(set_attr "isa" "noavx,noavx,avx,avx")])
13000 (define_expand "<code>hf2"
13001 [(set (match_operand:HF 0 "register_operand")
13002 (absneg:HF (match_operand:HF 1 "register_operand")))]
13003 "TARGET_AVX512FP16"
13004 "ix86_expand_fp_absneg_operator (<CODE>, HFmode, operands); DONE;")
13006 (define_expand "<code><mode>2"
13007 [(set (match_operand:X87MODEF 0 "register_operand")
13008 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
13009 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13010 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
13012 ;; Changing of sign for FP values is doable using integer unit too.
13013 (define_insn "*<code><mode>2_i387_1"
13014 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
13016 (match_operand:X87MODEF 1 "register_operand" "0,0")))
13017 (clobber (reg:CC FLAGS_REG))]
13018 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13022 [(set (match_operand:X87MODEF 0 "fp_register_operand")
13023 (absneg:X87MODEF (match_operand:X87MODEF 1 "fp_register_operand")))
13024 (clobber (reg:CC FLAGS_REG))]
13025 "TARGET_80387 && reload_completed"
13026 [(set (match_dup 0) (absneg:X87MODEF (match_dup 1)))])
13029 [(set (match_operand:X87MODEF 0 "general_reg_operand")
13030 (absneg:X87MODEF (match_operand:X87MODEF 1 "general_reg_operand")))
13031 (clobber (reg:CC FLAGS_REG))]
13032 "TARGET_80387 && reload_completed"
13034 "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
13036 (define_insn_and_split "*<code>hf2_1"
13037 [(set (match_operand:HF 0 "register_operand" "=Yv")
13039 (match_operand:HF 1 "register_operand" "Yv")))
13040 (use (match_operand:V8HF 2 "vector_operand" "Yvm"))
13041 (clobber (reg:CC FLAGS_REG))]
13042 "TARGET_AVX512FP16"
13044 "&& reload_completed"
13045 [(set (match_dup 0)
13046 (<absneg_op>:V8HF (match_dup 1) (match_dup 2)))]
13048 operands[0] = lowpart_subreg (V8HFmode, operands[0], HFmode);
13049 operands[1] = lowpart_subreg (V8HFmode, operands[1], HFmode);
13052 (define_insn "*<code><mode>2_1"
13053 [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv,f,!r")
13055 (match_operand:MODEF 1 "register_operand" "0,x,Yv,0,0")))
13056 (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm,X,X"))
13057 (clobber (reg:CC FLAGS_REG))]
13058 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13060 [(set_attr "isa" "noavx,noavx,avx,*,*")
13061 (set (attr "enabled")
13063 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
13065 (eq_attr "alternative" "3,4")
13066 (symbol_ref "TARGET_MIX_SSE_I387")
13067 (const_string "*"))
13069 (eq_attr "alternative" "3,4")
13070 (symbol_ref "true")
13071 (symbol_ref "false"))))])
13074 [(set (match_operand:MODEF 0 "sse_reg_operand")
13076 (match_operand:MODEF 1 "sse_reg_operand")))
13077 (use (match_operand:<ssevecmodef> 2 "vector_operand"))
13078 (clobber (reg:CC FLAGS_REG))]
13079 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13080 && reload_completed"
13081 [(set (match_dup 0)
13082 (<absneg_op>:<ssevecmodef> (match_dup 1) (match_dup 2)))]
13084 machine_mode mode = <MODE>mode;
13085 machine_mode vmode = <ssevecmodef>mode;
13087 operands[0] = lowpart_subreg (vmode, operands[0], mode);
13088 operands[1] = lowpart_subreg (vmode, operands[1], mode);
13090 if (!TARGET_AVX && operands_match_p (operands[0], operands[2]))
13091 std::swap (operands[1], operands[2]);
13095 [(set (match_operand:MODEF 0 "fp_register_operand")
13096 (absneg:MODEF (match_operand:MODEF 1 "fp_register_operand")))
13097 (use (match_operand 2))
13098 (clobber (reg:CC FLAGS_REG))]
13099 "TARGET_80387 && reload_completed"
13100 [(set (match_dup 0) (absneg:MODEF (match_dup 1)))])
13103 [(set (match_operand:MODEF 0 "general_reg_operand")
13104 (absneg:MODEF (match_operand:MODEF 1 "general_reg_operand")))
13105 (use (match_operand 2))
13106 (clobber (reg:CC FLAGS_REG))]
13107 "TARGET_80387 && reload_completed"
13109 "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
13111 (define_insn_and_split "*nabs<mode>2_1"
13112 [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv")
13115 (match_operand:MODEF 1 "register_operand" "0,x,Yv"))))
13116 (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm"))]
13117 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13119 "&& reload_completed"
13120 [(set (match_dup 0)
13121 (ior:<ssevecmodef> (match_dup 1) (match_dup 2)))]
13123 machine_mode mode = <MODE>mode;
13124 machine_mode vmode = <ssevecmodef>mode;
13126 operands[0] = lowpart_subreg (vmode, operands[0], mode);
13127 operands[1] = lowpart_subreg (vmode, operands[1], mode);
13129 if (!TARGET_AVX && operands_match_p (operands[0], operands[2]))
13130 std::swap (operands[1], operands[2]);
13132 [(set_attr "isa" "noavx,noavx,avx")])
13134 ;; Conditionalize these after reload. If they match before reload, we
13135 ;; lose the clobber and ability to use integer instructions.
13137 (define_insn "*<code><mode>2_i387"
13138 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
13139 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
13140 "TARGET_80387 && reload_completed"
13141 "<absneg_mnemonic>"
13142 [(set_attr "type" "fsgn")
13143 (set_attr "mode" "<MODE>")])
13145 ;; Copysign instructions
13147 (define_expand "copysign<mode>3"
13148 [(match_operand:SSEMODEF 0 "register_operand")
13149 (match_operand:SSEMODEF 1 "nonmemory_operand")
13150 (match_operand:SSEMODEF 2 "register_operand")]
13151 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13152 || (TARGET_SSE && (<MODE>mode == TFmode))
13153 || (TARGET_AVX512FP16 && (<MODE>mode ==HFmode))"
13154 "ix86_expand_copysign (operands); DONE;")
13156 (define_expand "xorsign<mode>3"
13157 [(match_operand:MODEFH 0 "register_operand")
13158 (match_operand:MODEFH 1 "register_operand")
13159 (match_operand:MODEFH 2 "register_operand")]
13160 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13161 || <MODE>mode == HFmode"
13163 if (rtx_equal_p (operands[1], operands[2]))
13164 emit_insn (gen_abs<mode>2 (operands[0], operands[1]));
13166 ix86_expand_xorsign (operands);
13170 ;; One complement instructions
13172 (define_expand "one_cmpl<mode>2"
13173 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
13174 (not:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
13176 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
13178 (define_insn_and_split "*one_cmpl<dwi>2_doubleword"
13179 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
13180 (not:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))]
13181 "ix86_unary_operator_ok (NOT, <DWI>mode, operands)"
13183 "&& reload_completed"
13184 [(set (match_dup 0)
13185 (not:DWIH (match_dup 1)))
13187 (not:DWIH (match_dup 3)))]
13188 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
13190 (define_insn "*one_cmpl<mode>2_1"
13191 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,?k")
13192 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0,k")))]
13193 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
13195 not{<imodesuffix>}\t%0
13198 (cond [(eq_attr "alternative" "1")
13199 (if_then_else (eq_attr "mode" "SI,DI")
13200 (const_string "avx512bw")
13201 (const_string "avx512f"))
13203 (const_string "*")))
13204 (set_attr "type" "negnot,msklog")
13205 (set_attr "mode" "<MODE>")])
13207 (define_insn "*one_cmplsi2_1_zext"
13208 [(set (match_operand:DI 0 "register_operand" "=r,?k")
13210 (not:SI (match_operand:SI 1 "register_operand" "0,k"))))]
13211 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
13215 [(set_attr "isa" "x64,avx512bw")
13216 (set_attr "type" "negnot,msklog")
13217 (set_attr "mode" "SI,SI")])
13219 (define_insn "*one_cmplqi2_1"
13220 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,?k")
13221 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
13222 "ix86_unary_operator_ok (NOT, QImode, operands)"
13227 [(set_attr "isa" "*,*,avx512f")
13228 (set_attr "type" "negnot,negnot,msklog")
13230 (cond [(eq_attr "alternative" "1")
13231 (const_string "SI")
13232 (and (eq_attr "alternative" "2")
13233 (match_test "!TARGET_AVX512DQ"))
13234 (const_string "HI")
13236 (const_string "QI")))
13237 ;; Potential partial reg stall on alternative 1.
13238 (set (attr "preferred_for_speed")
13239 (cond [(eq_attr "alternative" "1")
13240 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
13241 (symbol_ref "true")))])
13243 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
13244 (define_insn_and_split "*one_cmpl<mode>_1_slp"
13245 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
13246 (not:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")))]
13247 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
13249 not{<imodesuffix>}\t%0
13251 "&& reload_completed"
13252 [(set (strict_low_part (match_dup 0)) (match_dup 1))
13253 (set (strict_low_part (match_dup 0))
13254 (not:SWI12 (match_dup 0)))]
13256 [(set_attr "type" "negnot")
13257 (set_attr "mode" "<MODE>")])
13259 (define_insn "*one_cmpl<mode>2_2"
13260 [(set (reg FLAGS_REG)
13261 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
13263 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
13264 (not:SWI (match_dup 1)))]
13265 "ix86_match_ccmode (insn, CCNOmode)
13266 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
13268 [(set_attr "type" "alu1")
13269 (set_attr "mode" "<MODE>")])
13272 [(set (match_operand 0 "flags_reg_operand")
13273 (match_operator 2 "compare_operator"
13274 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
13276 (set (match_operand:SWI 1 "nonimmediate_operand")
13277 (not:SWI (match_dup 3)))]
13278 "ix86_match_ccmode (insn, CCNOmode)"
13279 [(parallel [(set (match_dup 0)
13280 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
13283 (xor:SWI (match_dup 3) (const_int -1)))])])
13285 (define_insn "*one_cmplsi2_2_zext"
13286 [(set (reg FLAGS_REG)
13287 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
13289 (set (match_operand:DI 0 "register_operand" "=r")
13290 (zero_extend:DI (not:SI (match_dup 1))))]
13291 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
13292 && ix86_unary_operator_ok (NOT, SImode, operands)"
13294 [(set_attr "type" "alu1")
13295 (set_attr "mode" "SI")])
13298 [(set (match_operand 0 "flags_reg_operand")
13299 (match_operator 2 "compare_operator"
13300 [(not:SI (match_operand:SI 3 "register_operand"))
13302 (set (match_operand:DI 1 "register_operand")
13303 (zero_extend:DI (not:SI (match_dup 3))))]
13304 "ix86_match_ccmode (insn, CCNOmode)"
13305 [(parallel [(set (match_dup 0)
13306 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
13309 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
13311 ;; Shift instructions
13313 ;; DImode shifts are implemented using the i386 "shift double" opcode,
13314 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
13315 ;; is variable, then the count is in %cl and the "imm" operand is dropped
13316 ;; from the assembler input.
13318 ;; This instruction shifts the target reg/mem as usual, but instead of
13319 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
13320 ;; is a left shift double, bits are taken from the high order bits of
13321 ;; reg, else if the insn is a shift right double, bits are taken from the
13322 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
13323 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
13325 ;; Since sh[lr]d does not change the `reg' operand, that is done
13326 ;; separately, making all shifts emit pairs of shift double and normal
13327 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
13328 ;; support a 63 bit shift, each shift where the count is in a reg expands
13329 ;; to a pair of shifts, a branch, a shift by 32 and a label.
13331 ;; If the shift count is a constant, we need never emit more than one
13332 ;; shift pair, instead using moves and sign extension for counts greater
13335 (define_expand "ashl<mode>3"
13336 [(set (match_operand:SDWIM 0 "<shift_operand>")
13337 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
13338 (match_operand:QI 2 "nonmemory_operand")))]
13340 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
13342 (define_insn_and_split "*ashl<dwi>3_doubleword_mask"
13343 [(set (match_operand:<DWI> 0 "register_operand")
13345 (match_operand:<DWI> 1 "register_operand")
13348 (match_operand 2 "int248_register_operand" "c")
13349 (match_operand 3 "const_int_operand")) 0)))
13350 (clobber (reg:CC FLAGS_REG))]
13351 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
13352 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
13353 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
13354 && ix86_pre_reload_split ()"
13358 [(set (match_dup 6)
13359 (ior:DWIH (ashift:DWIH (match_dup 6)
13360 (and:QI (match_dup 2) (match_dup 8)))
13362 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
13363 (minus:QI (match_dup 9)
13364 (and:QI (match_dup 2) (match_dup 8)))) 0)))
13365 (clobber (reg:CC FLAGS_REG))])
13367 [(set (match_dup 4)
13368 (ashift:DWIH (match_dup 5) (match_dup 2)))
13369 (clobber (reg:CC FLAGS_REG))])]
13371 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
13373 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
13374 operands[2] = gen_lowpart (QImode, operands[2]);
13375 emit_insn (gen_ashl<dwi>3_doubleword (operands[0], operands[1],
13380 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
13382 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
13383 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
13385 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13386 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13389 xops[0] = gen_reg_rtx (GET_MODE (operands[2]));
13390 xops[1] = operands[2];
13391 xops[2] = GEN_INT (INTVAL (operands[3])
13392 & ((<MODE_SIZE> * BITS_PER_UNIT) - 1));
13393 ix86_expand_binary_operator (AND, GET_MODE (operands[2]), xops);
13394 operands[2] = xops[0];
13397 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
13398 operands[2] = gen_lowpart (QImode, operands[2]);
13400 if (!rtx_equal_p (operands[6], operands[7]))
13401 emit_move_insn (operands[6], operands[7]);
13404 (define_insn_and_split "*ashl<dwi>3_doubleword_mask_1"
13405 [(set (match_operand:<DWI> 0 "register_operand")
13407 (match_operand:<DWI> 1 "register_operand")
13409 (match_operand:QI 2 "register_operand" "c")
13410 (match_operand:QI 3 "const_int_operand"))))
13411 (clobber (reg:CC FLAGS_REG))]
13412 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
13413 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
13414 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
13415 && ix86_pre_reload_split ()"
13419 [(set (match_dup 6)
13420 (ior:DWIH (ashift:DWIH (match_dup 6)
13421 (and:QI (match_dup 2) (match_dup 8)))
13423 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
13424 (minus:QI (match_dup 9)
13425 (and:QI (match_dup 2) (match_dup 8)))) 0)))
13426 (clobber (reg:CC FLAGS_REG))])
13428 [(set (match_dup 4)
13429 (ashift:DWIH (match_dup 5) (match_dup 2)))
13430 (clobber (reg:CC FLAGS_REG))])]
13432 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
13434 emit_insn (gen_ashl<dwi>3_doubleword (operands[0], operands[1],
13439 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
13441 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
13442 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
13444 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13445 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13447 rtx tem = gen_reg_rtx (QImode);
13448 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
13452 if (!rtx_equal_p (operands[6], operands[7]))
13453 emit_move_insn (operands[6], operands[7]);
13456 (define_insn "ashl<mode>3_doubleword"
13457 [(set (match_operand:DWI 0 "register_operand" "=&r")
13458 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n")
13459 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
13460 (clobber (reg:CC FLAGS_REG))]
13463 [(set_attr "type" "multi")])
13466 [(set (match_operand:DWI 0 "register_operand")
13467 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
13468 (match_operand:QI 2 "nonmemory_operand")))
13469 (clobber (reg:CC FLAGS_REG))]
13470 "epilogue_completed"
13472 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
13474 ;; By default we don't ask for a scratch register, because when DWImode
13475 ;; values are manipulated, registers are already at a premium. But if
13476 ;; we have one handy, we won't turn it away.
13479 [(match_scratch:DWIH 3 "r")
13480 (parallel [(set (match_operand:<DWI> 0 "register_operand")
13482 (match_operand:<DWI> 1 "nonmemory_operand")
13483 (match_operand:QI 2 "nonmemory_operand")))
13484 (clobber (reg:CC FLAGS_REG))])
13488 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
13490 (define_insn_and_split "*ashl<dwi>3_doubleword_highpart"
13491 [(set (match_operand:<DWI> 0 "register_operand" "=r")
13493 (any_extend:<DWI> (match_operand:DWIH 1 "nonimmediate_operand" "rm"))
13494 (match_operand:QI 2 "const_int_operand")))
13495 (clobber (reg:CC FLAGS_REG))]
13496 "INTVAL (operands[2]) >= <MODE_SIZE> * BITS_PER_UNIT
13497 && INTVAL (operands[2]) < <MODE_SIZE> * BITS_PER_UNIT * 2"
13499 "&& reload_completed"
13502 split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[3]);
13503 int bits = INTVAL (operands[2]) - (<MODE_SIZE> * BITS_PER_UNIT);
13504 if (!rtx_equal_p (operands[3], operands[1]))
13505 emit_move_insn (operands[3], operands[1]);
13507 emit_insn (gen_ashl<mode>3 (operands[3], operands[3], GEN_INT (bits)));
13508 ix86_expand_clear (operands[0]);
13512 (define_insn "x86_64_shld"
13513 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
13514 (ior:DI (ashift:DI (match_dup 0)
13515 (and:QI (match_operand:QI 2 "nonmemory_operand" "Jc")
13520 (match_operand:DI 1 "register_operand" "r"))
13521 (minus:QI (const_int 64)
13522 (and:QI (match_dup 2) (const_int 63)))) 0)))
13523 (clobber (reg:CC FLAGS_REG))]
13525 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
13526 [(set_attr "type" "ishift")
13527 (set_attr "prefix_0f" "1")
13528 (set_attr "mode" "DI")
13529 (set_attr "athlon_decode" "vector")
13530 (set_attr "amdfam10_decode" "vector")
13531 (set_attr "bdver1_decode" "vector")])
13533 (define_insn "x86_64_shld_1"
13534 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
13535 (ior:DI (ashift:DI (match_dup 0)
13536 (match_operand:QI 2 "const_0_to_63_operand"))
13540 (match_operand:DI 1 "register_operand" "r"))
13541 (match_operand:QI 3 "const_0_to_255_operand")) 0)))
13542 (clobber (reg:CC FLAGS_REG))]
13544 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])"
13545 "shld{q}\t{%2, %1, %0|%0, %1, %2}"
13546 [(set_attr "type" "ishift")
13547 (set_attr "prefix_0f" "1")
13548 (set_attr "mode" "DI")
13549 (set_attr "length_immediate" "1")
13550 (set_attr "athlon_decode" "vector")
13551 (set_attr "amdfam10_decode" "vector")
13552 (set_attr "bdver1_decode" "vector")])
13554 (define_insn_and_split "*x86_64_shld_shrd_1_nozext"
13555 [(set (match_operand:DI 0 "nonimmediate_operand")
13556 (ior:DI (ashift:DI (match_operand:DI 4 "nonimmediate_operand")
13557 (match_operand:QI 2 "const_0_to_63_operand"))
13559 (match_operand:DI 1 "nonimmediate_operand")
13560 (match_operand:QI 3 "const_0_to_63_operand"))))
13561 (clobber (reg:CC FLAGS_REG))]
13563 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])
13564 && ix86_pre_reload_split ()"
13569 if (rtx_equal_p (operands[4], operands[0]))
13571 operands[1] = force_reg (DImode, operands[1]);
13572 emit_insn (gen_x86_64_shld_1 (operands[0], operands[1], operands[2], operands[3]));
13574 else if (rtx_equal_p (operands[1], operands[0]))
13576 operands[4] = force_reg (DImode, operands[4]);
13577 emit_insn (gen_x86_64_shrd_1 (operands[0], operands[4], operands[3], operands[2]));
13581 operands[1] = force_reg (DImode, operands[1]);
13582 rtx tmp = gen_reg_rtx (DImode);
13583 emit_move_insn (tmp, operands[4]);
13584 emit_insn (gen_x86_64_shld_1 (tmp, operands[1], operands[2], operands[3]));
13585 emit_move_insn (operands[0], tmp);
13590 (define_insn_and_split "*x86_64_shld_2"
13591 [(set (match_operand:DI 0 "nonimmediate_operand")
13592 (ior:DI (ashift:DI (match_dup 0)
13593 (match_operand:QI 2 "nonmemory_operand"))
13594 (lshiftrt:DI (match_operand:DI 1 "register_operand")
13595 (minus:QI (const_int 64) (match_dup 2)))))
13596 (clobber (reg:CC FLAGS_REG))]
13597 "TARGET_64BIT && ix86_pre_reload_split ()"
13600 [(parallel [(set (match_dup 0)
13601 (ior:DI (ashift:DI (match_dup 0)
13602 (and:QI (match_dup 2) (const_int 63)))
13605 (zero_extend:TI (match_dup 1))
13606 (minus:QI (const_int 64)
13607 (and:QI (match_dup 2)
13608 (const_int 63)))) 0)))
13609 (clobber (reg:CC FLAGS_REG))])])
13611 (define_insn "x86_shld"
13612 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
13613 (ior:SI (ashift:SI (match_dup 0)
13614 (and:QI (match_operand:QI 2 "nonmemory_operand" "Ic")
13619 (match_operand:SI 1 "register_operand" "r"))
13620 (minus:QI (const_int 32)
13621 (and:QI (match_dup 2) (const_int 31)))) 0)))
13622 (clobber (reg:CC FLAGS_REG))]
13624 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
13625 [(set_attr "type" "ishift")
13626 (set_attr "prefix_0f" "1")
13627 (set_attr "mode" "SI")
13628 (set_attr "pent_pair" "np")
13629 (set_attr "athlon_decode" "vector")
13630 (set_attr "amdfam10_decode" "vector")
13631 (set_attr "bdver1_decode" "vector")])
13633 (define_insn "x86_shld_1"
13634 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
13635 (ior:SI (ashift:SI (match_dup 0)
13636 (match_operand:QI 2 "const_0_to_31_operand"))
13640 (match_operand:SI 1 "register_operand" "r"))
13641 (match_operand:QI 3 "const_0_to_63_operand")) 0)))
13642 (clobber (reg:CC FLAGS_REG))]
13643 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])"
13644 "shld{l}\t{%2, %1, %0|%0, %1, %2}"
13645 [(set_attr "type" "ishift")
13646 (set_attr "prefix_0f" "1")
13647 (set_attr "length_immediate" "1")
13648 (set_attr "mode" "SI")
13649 (set_attr "pent_pair" "np")
13650 (set_attr "athlon_decode" "vector")
13651 (set_attr "amdfam10_decode" "vector")
13652 (set_attr "bdver1_decode" "vector")])
13654 (define_insn_and_split "*x86_shld_shrd_1_nozext"
13655 [(set (match_operand:SI 0 "nonimmediate_operand")
13656 (ior:SI (ashift:SI (match_operand:SI 4 "nonimmediate_operand")
13657 (match_operand:QI 2 "const_0_to_31_operand"))
13659 (match_operand:SI 1 "nonimmediate_operand")
13660 (match_operand:QI 3 "const_0_to_31_operand"))))
13661 (clobber (reg:CC FLAGS_REG))]
13662 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])
13663 && ix86_pre_reload_split ()"
13668 if (rtx_equal_p (operands[4], operands[0]))
13670 operands[1] = force_reg (SImode, operands[1]);
13671 emit_insn (gen_x86_shld_1 (operands[0], operands[1], operands[2], operands[3]));
13673 else if (rtx_equal_p (operands[1], operands[0]))
13675 operands[4] = force_reg (SImode, operands[4]);
13676 emit_insn (gen_x86_shrd_1 (operands[0], operands[4], operands[3], operands[2]));
13680 operands[1] = force_reg (SImode, operands[1]);
13681 rtx tmp = gen_reg_rtx (SImode);
13682 emit_move_insn (tmp, operands[4]);
13683 emit_insn (gen_x86_shld_1 (tmp, operands[1], operands[2], operands[3]));
13684 emit_move_insn (operands[0], tmp);
13689 (define_insn_and_split "*x86_shld_2"
13690 [(set (match_operand:SI 0 "nonimmediate_operand")
13691 (ior:SI (ashift:SI (match_dup 0)
13692 (match_operand:QI 2 "nonmemory_operand"))
13693 (lshiftrt:SI (match_operand:SI 1 "register_operand")
13694 (minus:QI (const_int 32) (match_dup 2)))))
13695 (clobber (reg:CC FLAGS_REG))]
13696 "TARGET_64BIT && ix86_pre_reload_split ()"
13699 [(parallel [(set (match_dup 0)
13700 (ior:SI (ashift:SI (match_dup 0)
13701 (and:QI (match_dup 2) (const_int 31)))
13704 (zero_extend:DI (match_dup 1))
13705 (minus:QI (const_int 32)
13706 (and:QI (match_dup 2)
13707 (const_int 31)))) 0)))
13708 (clobber (reg:CC FLAGS_REG))])])
13710 (define_expand "@x86_shift<mode>_adj_1"
13711 [(set (reg:CCZ FLAGS_REG)
13712 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
13715 (set (match_operand:SWI48 0 "register_operand")
13716 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
13717 (match_operand:SWI48 1 "register_operand")
13720 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
13721 (match_operand:SWI48 3 "register_operand")
13724 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
13726 (define_expand "@x86_shift<mode>_adj_2"
13727 [(use (match_operand:SWI48 0 "register_operand"))
13728 (use (match_operand:SWI48 1 "register_operand"))
13729 (use (match_operand:QI 2 "register_operand"))]
13732 rtx_code_label *label = gen_label_rtx ();
13735 emit_insn (gen_testqi_ccz_1 (operands[2],
13736 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
13738 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
13739 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
13740 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
13741 gen_rtx_LABEL_REF (VOIDmode, label),
13743 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
13744 JUMP_LABEL (tmp) = label;
13746 emit_move_insn (operands[0], operands[1]);
13747 ix86_expand_clear (operands[1]);
13749 emit_label (label);
13750 LABEL_NUSES (label) = 1;
13755 ;; Avoid useless masking of count operand.
13756 (define_insn_and_split "*ashl<mode>3_mask"
13757 [(set (match_operand:SWI48 0 "nonimmediate_operand")
13759 (match_operand:SWI48 1 "nonimmediate_operand")
13762 (match_operand 2 "int248_register_operand" "c,r")
13763 (match_operand 3 "const_int_operand")) 0)))
13764 (clobber (reg:CC FLAGS_REG))]
13765 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
13766 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
13767 == GET_MODE_BITSIZE (<MODE>mode)-1
13768 && ix86_pre_reload_split ()"
13772 [(set (match_dup 0)
13773 (ashift:SWI48 (match_dup 1)
13775 (clobber (reg:CC FLAGS_REG))])]
13777 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
13778 operands[2] = gen_lowpart (QImode, operands[2]);
13780 [(set_attr "isa" "*,bmi2")])
13782 (define_insn_and_split "*ashl<mode>3_mask_1"
13783 [(set (match_operand:SWI48 0 "nonimmediate_operand")
13785 (match_operand:SWI48 1 "nonimmediate_operand")
13787 (match_operand:QI 2 "register_operand" "c,r")
13788 (match_operand:QI 3 "const_int_operand"))))
13789 (clobber (reg:CC FLAGS_REG))]
13790 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
13791 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
13792 == GET_MODE_BITSIZE (<MODE>mode)-1
13793 && ix86_pre_reload_split ()"
13797 [(set (match_dup 0)
13798 (ashift:SWI48 (match_dup 1)
13800 (clobber (reg:CC FLAGS_REG))])]
13802 [(set_attr "isa" "*,bmi2")])
13804 (define_insn "*bmi2_ashl<mode>3_1"
13805 [(set (match_operand:SWI48 0 "register_operand" "=r")
13806 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13807 (match_operand:SWI48 2 "register_operand" "r")))]
13809 "shlx\t{%2, %1, %0|%0, %1, %2}"
13810 [(set_attr "type" "ishiftx")
13811 (set_attr "mode" "<MODE>")])
13813 (define_insn "*ashl<mode>3_1"
13814 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,?k")
13815 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm,k")
13816 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r,<KS>")))
13817 (clobber (reg:CC FLAGS_REG))]
13818 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
13820 switch (get_attr_type (insn))
13828 gcc_assert (operands[2] == const1_rtx);
13829 gcc_assert (rtx_equal_p (operands[0], operands[1]));
13830 return "add{<imodesuffix>}\t%0, %0";
13833 if (operands[2] == const1_rtx
13834 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
13835 return "sal{<imodesuffix>}\t%0";
13837 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
13840 [(set_attr "isa" "*,*,bmi2,avx512bw")
13842 (cond [(eq_attr "alternative" "1")
13843 (const_string "lea")
13844 (eq_attr "alternative" "2")
13845 (const_string "ishiftx")
13846 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
13847 (match_operand 0 "register_operand"))
13848 (match_operand 2 "const1_operand"))
13849 (const_string "alu")
13850 (eq_attr "alternative" "3")
13851 (const_string "msklog")
13853 (const_string "ishift")))
13854 (set (attr "length_immediate")
13856 (ior (eq_attr "type" "alu")
13857 (and (eq_attr "type" "ishift")
13858 (and (match_operand 2 "const1_operand")
13859 (ior (match_test "TARGET_SHIFT1")
13860 (match_test "optimize_function_for_size_p (cfun)")))))
13862 (const_string "*")))
13863 (set_attr "mode" "<MODE>")])
13865 ;; Convert shift to the shiftx pattern to avoid flags dependency.
13867 [(set (match_operand:SWI48 0 "register_operand")
13868 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
13869 (match_operand:QI 2 "register_operand")))
13870 (clobber (reg:CC FLAGS_REG))]
13871 "TARGET_BMI2 && reload_completed"
13872 [(set (match_dup 0)
13873 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
13874 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
13876 (define_insn "*bmi2_ashlsi3_1_zext"
13877 [(set (match_operand:DI 0 "register_operand" "=r")
13879 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
13880 (match_operand:SI 2 "register_operand" "r"))))]
13881 "TARGET_64BIT && TARGET_BMI2"
13882 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
13883 [(set_attr "type" "ishiftx")
13884 (set_attr "mode" "SI")])
13886 (define_insn "*ashlsi3_1_zext"
13887 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
13889 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
13890 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
13891 (clobber (reg:CC FLAGS_REG))]
13892 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
13894 switch (get_attr_type (insn))
13901 gcc_assert (operands[2] == const1_rtx);
13902 return "add{l}\t%k0, %k0";
13905 if (operands[2] == const1_rtx
13906 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
13907 return "sal{l}\t%k0";
13909 return "sal{l}\t{%2, %k0|%k0, %2}";
13912 [(set_attr "isa" "*,*,bmi2")
13914 (cond [(eq_attr "alternative" "1")
13915 (const_string "lea")
13916 (eq_attr "alternative" "2")
13917 (const_string "ishiftx")
13918 (and (match_test "TARGET_DOUBLE_WITH_ADD")
13919 (match_operand 2 "const1_operand"))
13920 (const_string "alu")
13922 (const_string "ishift")))
13923 (set (attr "length_immediate")
13925 (ior (eq_attr "type" "alu")
13926 (and (eq_attr "type" "ishift")
13927 (and (match_operand 2 "const1_operand")
13928 (ior (match_test "TARGET_SHIFT1")
13929 (match_test "optimize_function_for_size_p (cfun)")))))
13931 (const_string "*")))
13932 (set_attr "mode" "SI")])
13934 ;; Convert shift to the shiftx pattern to avoid flags dependency.
13936 [(set (match_operand:DI 0 "register_operand")
13938 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
13939 (match_operand:QI 2 "register_operand"))))
13940 (clobber (reg:CC FLAGS_REG))]
13941 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
13942 [(set (match_dup 0)
13943 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
13944 "operands[2] = gen_lowpart (SImode, operands[2]);")
13946 (define_insn "*ashlhi3_1"
13947 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp,?k")
13948 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l,k")
13949 (match_operand:QI 2 "nonmemory_operand" "cI,M,Ww")))
13950 (clobber (reg:CC FLAGS_REG))]
13951 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
13953 switch (get_attr_type (insn))
13960 gcc_assert (operands[2] == const1_rtx);
13961 return "add{w}\t%0, %0";
13964 if (operands[2] == const1_rtx
13965 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
13966 return "sal{w}\t%0";
13968 return "sal{w}\t{%2, %0|%0, %2}";
13971 [(set_attr "isa" "*,*,avx512f")
13973 (cond [(eq_attr "alternative" "1")
13974 (const_string "lea")
13975 (eq_attr "alternative" "2")
13976 (const_string "msklog")
13977 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
13978 (match_operand 0 "register_operand"))
13979 (match_operand 2 "const1_operand"))
13980 (const_string "alu")
13982 (const_string "ishift")))
13983 (set (attr "length_immediate")
13985 (ior (eq_attr "type" "alu")
13986 (and (eq_attr "type" "ishift")
13987 (and (match_operand 2 "const1_operand")
13988 (ior (match_test "TARGET_SHIFT1")
13989 (match_test "optimize_function_for_size_p (cfun)")))))
13991 (const_string "*")))
13992 (set_attr "mode" "HI,SI,HI")])
13994 (define_insn "*ashlqi3_1"
13995 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp,?k")
13996 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l,k")
13997 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M,Wb")))
13998 (clobber (reg:CC FLAGS_REG))]
13999 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
14001 switch (get_attr_type (insn))
14008 gcc_assert (operands[2] == const1_rtx);
14009 if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
14010 return "add{l}\t%k0, %k0";
14012 return "add{b}\t%0, %0";
14015 if (operands[2] == const1_rtx
14016 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14018 if (get_attr_mode (insn) == MODE_SI)
14019 return "sal{l}\t%k0";
14021 return "sal{b}\t%0";
14025 if (get_attr_mode (insn) == MODE_SI)
14026 return "sal{l}\t{%2, %k0|%k0, %2}";
14028 return "sal{b}\t{%2, %0|%0, %2}";
14032 [(set_attr "isa" "*,*,*,avx512dq")
14034 (cond [(eq_attr "alternative" "2")
14035 (const_string "lea")
14036 (eq_attr "alternative" "3")
14037 (const_string "msklog")
14038 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14039 (match_operand 0 "register_operand"))
14040 (match_operand 2 "const1_operand"))
14041 (const_string "alu")
14043 (const_string "ishift")))
14044 (set (attr "length_immediate")
14046 (ior (eq_attr "type" "alu")
14047 (and (eq_attr "type" "ishift")
14048 (and (match_operand 2 "const1_operand")
14049 (ior (match_test "TARGET_SHIFT1")
14050 (match_test "optimize_function_for_size_p (cfun)")))))
14052 (const_string "*")))
14053 (set_attr "mode" "QI,SI,SI,QI")
14054 ;; Potential partial reg stall on alternative 1.
14055 (set (attr "preferred_for_speed")
14056 (cond [(eq_attr "alternative" "1")
14057 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
14058 (symbol_ref "true")))])
14060 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
14061 (define_insn_and_split "*ashl<mode>3_1_slp"
14062 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
14063 (ashift:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
14064 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
14065 (clobber (reg:CC FLAGS_REG))]
14066 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
14068 if (which_alternative)
14071 switch (get_attr_type (insn))
14074 gcc_assert (operands[2] == const1_rtx);
14075 return "add{<imodesuffix>}\t%0, %0";
14078 if (operands[2] == const1_rtx
14079 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14080 return "sal{<imodesuffix>}\t%0";
14082 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14085 "&& reload_completed"
14086 [(set (strict_low_part (match_dup 0)) (match_dup 1))
14088 [(set (strict_low_part (match_dup 0))
14089 (ashift:SWI12 (match_dup 0) (match_dup 2)))
14090 (clobber (reg:CC FLAGS_REG))])]
14092 [(set (attr "type")
14093 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
14094 (match_operand 2 "const1_operand"))
14095 (const_string "alu")
14097 (const_string "ishift")))
14098 (set (attr "length_immediate")
14100 (ior (eq_attr "type" "alu")
14101 (and (eq_attr "type" "ishift")
14102 (and (match_operand 2 "const1_operand")
14103 (ior (match_test "TARGET_SHIFT1")
14104 (match_test "optimize_function_for_size_p (cfun)")))))
14106 (const_string "*")))
14107 (set_attr "mode" "<MODE>")])
14109 ;; Convert ashift to the lea pattern to avoid flags dependency.
14111 [(set (match_operand:SWI 0 "general_reg_operand")
14112 (ashift:SWI (match_operand:SWI 1 "index_reg_operand")
14113 (match_operand 2 "const_0_to_3_operand")))
14114 (clobber (reg:CC FLAGS_REG))]
14116 && REGNO (operands[0]) != REGNO (operands[1])"
14117 [(set (match_dup 0)
14118 (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
14120 if (<MODE>mode != <LEAMODE>mode)
14122 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
14123 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
14125 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
14128 ;; Convert ashift to the lea pattern to avoid flags dependency.
14130 [(set (match_operand:DI 0 "general_reg_operand")
14132 (ashift:SI (match_operand:SI 1 "index_reg_operand")
14133 (match_operand 2 "const_0_to_3_operand"))))
14134 (clobber (reg:CC FLAGS_REG))]
14135 "TARGET_64BIT && reload_completed
14136 && REGNO (operands[0]) != REGNO (operands[1])"
14137 [(set (match_dup 0)
14138 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
14140 operands[1] = gen_lowpart (SImode, operands[1]);
14141 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
14144 ;; This pattern can't accept a variable shift count, since shifts by
14145 ;; zero don't affect the flags. We assume that shifts by constant
14146 ;; zero are optimized away.
14147 (define_insn "*ashl<mode>3_cmp"
14148 [(set (reg FLAGS_REG)
14150 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
14151 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
14153 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
14154 (ashift:SWI (match_dup 1) (match_dup 2)))]
14155 "(optimize_function_for_size_p (cfun)
14156 || !TARGET_PARTIAL_FLAG_REG_STALL
14157 || (operands[2] == const1_rtx
14159 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
14160 && ix86_match_ccmode (insn, CCGOCmode)
14161 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
14163 switch (get_attr_type (insn))
14166 gcc_assert (operands[2] == const1_rtx);
14167 return "add{<imodesuffix>}\t%0, %0";
14170 if (operands[2] == const1_rtx
14171 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14172 return "sal{<imodesuffix>}\t%0";
14174 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14177 [(set (attr "type")
14178 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14179 (match_operand 0 "register_operand"))
14180 (match_operand 2 "const1_operand"))
14181 (const_string "alu")
14183 (const_string "ishift")))
14184 (set (attr "length_immediate")
14186 (ior (eq_attr "type" "alu")
14187 (and (eq_attr "type" "ishift")
14188 (and (match_operand 2 "const1_operand")
14189 (ior (match_test "TARGET_SHIFT1")
14190 (match_test "optimize_function_for_size_p (cfun)")))))
14192 (const_string "*")))
14193 (set_attr "mode" "<MODE>")])
14195 (define_insn "*ashlsi3_cmp_zext"
14196 [(set (reg FLAGS_REG)
14198 (ashift:SI (match_operand:SI 1 "register_operand" "0")
14199 (match_operand:QI 2 "const_1_to_31_operand"))
14201 (set (match_operand:DI 0 "register_operand" "=r")
14202 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
14204 && (optimize_function_for_size_p (cfun)
14205 || !TARGET_PARTIAL_FLAG_REG_STALL
14206 || (operands[2] == const1_rtx
14208 || TARGET_DOUBLE_WITH_ADD)))
14209 && ix86_match_ccmode (insn, CCGOCmode)
14210 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
14212 switch (get_attr_type (insn))
14215 gcc_assert (operands[2] == const1_rtx);
14216 return "add{l}\t%k0, %k0";
14219 if (operands[2] == const1_rtx
14220 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14221 return "sal{l}\t%k0";
14223 return "sal{l}\t{%2, %k0|%k0, %2}";
14226 [(set (attr "type")
14227 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
14228 (match_operand 2 "const1_operand"))
14229 (const_string "alu")
14231 (const_string "ishift")))
14232 (set (attr "length_immediate")
14234 (ior (eq_attr "type" "alu")
14235 (and (eq_attr "type" "ishift")
14236 (and (match_operand 2 "const1_operand")
14237 (ior (match_test "TARGET_SHIFT1")
14238 (match_test "optimize_function_for_size_p (cfun)")))))
14240 (const_string "*")))
14241 (set_attr "mode" "SI")])
14243 (define_insn "*ashl<mode>3_cconly"
14244 [(set (reg FLAGS_REG)
14246 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
14247 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
14249 (clobber (match_scratch:SWI 0 "=<r>"))]
14250 "(optimize_function_for_size_p (cfun)
14251 || !TARGET_PARTIAL_FLAG_REG_STALL
14252 || (operands[2] == const1_rtx
14254 || TARGET_DOUBLE_WITH_ADD)))
14255 && ix86_match_ccmode (insn, CCGOCmode)"
14257 switch (get_attr_type (insn))
14260 gcc_assert (operands[2] == const1_rtx);
14261 return "add{<imodesuffix>}\t%0, %0";
14264 if (operands[2] == const1_rtx
14265 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14266 return "sal{<imodesuffix>}\t%0";
14268 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14271 [(set (attr "type")
14272 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14273 (match_operand 0 "register_operand"))
14274 (match_operand 2 "const1_operand"))
14275 (const_string "alu")
14277 (const_string "ishift")))
14278 (set (attr "length_immediate")
14280 (ior (eq_attr "type" "alu")
14281 (and (eq_attr "type" "ishift")
14282 (and (match_operand 2 "const1_operand")
14283 (ior (match_test "TARGET_SHIFT1")
14284 (match_test "optimize_function_for_size_p (cfun)")))))
14286 (const_string "*")))
14287 (set_attr "mode" "<MODE>")])
14289 (define_insn "*ashlqi_ext<mode>_2"
14290 [(set (zero_extract:SWI248
14291 (match_operand 0 "int248_register_operand" "+Q")
14297 (match_operator:SWI248 3 "extract_operator"
14298 [(match_operand 1 "int248_register_operand" "0")
14301 (match_operand:QI 2 "nonmemory_operand" "cI")) 0))
14302 (clobber (reg:CC FLAGS_REG))]
14303 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
14304 rtx_equal_p (operands[0], operands[1])"
14306 switch (get_attr_type (insn))
14309 gcc_assert (operands[2] == const1_rtx);
14310 return "add{b}\t%h0, %h0";
14313 if (operands[2] == const1_rtx
14314 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14315 return "sal{b}\t%h0";
14317 return "sal{b}\t{%2, %h0|%h0, %2}";
14320 [(set (attr "type")
14321 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
14322 (match_operand 2 "const1_operand"))
14323 (const_string "alu")
14325 (const_string "ishift")))
14326 (set (attr "length_immediate")
14328 (ior (eq_attr "type" "alu")
14329 (and (eq_attr "type" "ishift")
14330 (and (match_operand 2 "const1_operand")
14331 (ior (match_test "TARGET_SHIFT1")
14332 (match_test "optimize_function_for_size_p (cfun)")))))
14334 (const_string "*")))
14335 (set_attr "mode" "QI")])
14337 ;; See comment above `ashl<mode>3' about how this works.
14339 (define_expand "<insn><mode>3"
14340 [(set (match_operand:SDWIM 0 "<shift_operand>")
14341 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
14342 (match_operand:QI 2 "nonmemory_operand")))]
14344 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
14346 ;; Avoid useless masking of count operand.
14347 (define_insn_and_split "*<insn><mode>3_mask"
14348 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14350 (match_operand:SWI48 1 "nonimmediate_operand")
14353 (match_operand 2 "int248_register_operand" "c,r")
14354 (match_operand 3 "const_int_operand")) 0)))
14355 (clobber (reg:CC FLAGS_REG))]
14356 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
14357 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
14358 == GET_MODE_BITSIZE (<MODE>mode)-1
14359 && ix86_pre_reload_split ()"
14363 [(set (match_dup 0)
14364 (any_shiftrt:SWI48 (match_dup 1)
14366 (clobber (reg:CC FLAGS_REG))])]
14368 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14369 operands[2] = gen_lowpart (QImode, operands[2]);
14371 [(set_attr "isa" "*,bmi2")])
14373 (define_insn_and_split "*<insn><mode>3_mask_1"
14374 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14376 (match_operand:SWI48 1 "nonimmediate_operand")
14378 (match_operand:QI 2 "register_operand" "c,r")
14379 (match_operand:QI 3 "const_int_operand"))))
14380 (clobber (reg:CC FLAGS_REG))]
14381 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
14382 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
14383 == GET_MODE_BITSIZE (<MODE>mode)-1
14384 && ix86_pre_reload_split ()"
14388 [(set (match_dup 0)
14389 (any_shiftrt:SWI48 (match_dup 1)
14391 (clobber (reg:CC FLAGS_REG))])]
14393 [(set_attr "isa" "*,bmi2")])
14395 (define_insn_and_split "*<insn><dwi>3_doubleword_mask"
14396 [(set (match_operand:<DWI> 0 "register_operand")
14398 (match_operand:<DWI> 1 "register_operand")
14401 (match_operand 2 "int248_register_operand" "c")
14402 (match_operand 3 "const_int_operand")) 0)))
14403 (clobber (reg:CC FLAGS_REG))]
14404 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
14405 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
14406 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
14407 && ix86_pre_reload_split ()"
14411 [(set (match_dup 4)
14412 (ior:DWIH (lshiftrt:DWIH (match_dup 4)
14413 (and:QI (match_dup 2) (match_dup 8)))
14415 (ashift:<DWI> (zero_extend:<DWI> (match_dup 7))
14416 (minus:QI (match_dup 9)
14417 (and:QI (match_dup 2) (match_dup 8)))) 0)))
14418 (clobber (reg:CC FLAGS_REG))])
14420 [(set (match_dup 6)
14421 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
14422 (clobber (reg:CC FLAGS_REG))])]
14424 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
14426 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14427 operands[2] = gen_lowpart (QImode, operands[2]);
14428 emit_insn (gen_<insn><dwi>3_doubleword (operands[0], operands[1],
14433 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
14435 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
14436 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
14438 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14439 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14442 xops[0] = gen_reg_rtx (GET_MODE (operands[2]));
14443 xops[1] = operands[2];
14444 xops[2] = GEN_INT (INTVAL (operands[3])
14445 & ((<MODE_SIZE> * BITS_PER_UNIT) - 1));
14446 ix86_expand_binary_operator (AND, GET_MODE (operands[2]), xops);
14447 operands[2] = xops[0];
14450 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14451 operands[2] = gen_lowpart (QImode, operands[2]);
14453 if (!rtx_equal_p (operands[4], operands[5]))
14454 emit_move_insn (operands[4], operands[5]);
14457 (define_insn_and_split "*<insn><dwi>3_doubleword_mask_1"
14458 [(set (match_operand:<DWI> 0 "register_operand")
14460 (match_operand:<DWI> 1 "register_operand")
14462 (match_operand:QI 2 "register_operand" "c")
14463 (match_operand:QI 3 "const_int_operand"))))
14464 (clobber (reg:CC FLAGS_REG))]
14465 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
14466 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
14467 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
14468 && ix86_pre_reload_split ()"
14472 [(set (match_dup 4)
14473 (ior:DWIH (lshiftrt:DWIH (match_dup 4)
14474 (and:QI (match_dup 2) (match_dup 8)))
14476 (ashift:<DWI> (zero_extend:<DWI> (match_dup 7))
14477 (minus:QI (match_dup 9)
14478 (and:QI (match_dup 2) (match_dup 8)))) 0)))
14479 (clobber (reg:CC FLAGS_REG))])
14481 [(set (match_dup 6)
14482 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
14483 (clobber (reg:CC FLAGS_REG))])]
14485 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
14487 emit_insn (gen_<insn><dwi>3_doubleword (operands[0], operands[1],
14492 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
14494 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
14495 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
14497 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14498 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14500 rtx tem = gen_reg_rtx (QImode);
14501 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
14505 if (!rtx_equal_p (operands[4], operands[5]))
14506 emit_move_insn (operands[4], operands[5]);
14509 (define_insn_and_split "<insn><mode>3_doubleword"
14510 [(set (match_operand:DWI 0 "register_operand" "=&r")
14511 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
14512 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
14513 (clobber (reg:CC FLAGS_REG))]
14516 "epilogue_completed"
14518 "ix86_split_<insn> (operands, NULL_RTX, <MODE>mode); DONE;"
14519 [(set_attr "type" "multi")])
14521 ;; By default we don't ask for a scratch register, because when DWImode
14522 ;; values are manipulated, registers are already at a premium. But if
14523 ;; we have one handy, we won't turn it away.
14526 [(match_scratch:DWIH 3 "r")
14527 (parallel [(set (match_operand:<DWI> 0 "register_operand")
14529 (match_operand:<DWI> 1 "register_operand")
14530 (match_operand:QI 2 "nonmemory_operand")))
14531 (clobber (reg:CC FLAGS_REG))])
14535 "ix86_split_<insn> (operands, operands[3], <DWI>mode); DONE;")
14537 (define_insn "x86_64_shrd"
14538 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
14539 (ior:DI (lshiftrt:DI (match_dup 0)
14540 (and:QI (match_operand:QI 2 "nonmemory_operand" "Jc")
14545 (match_operand:DI 1 "register_operand" "r"))
14546 (minus:QI (const_int 64)
14547 (and:QI (match_dup 2) (const_int 63)))) 0)))
14548 (clobber (reg:CC FLAGS_REG))]
14550 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
14551 [(set_attr "type" "ishift")
14552 (set_attr "prefix_0f" "1")
14553 (set_attr "mode" "DI")
14554 (set_attr "athlon_decode" "vector")
14555 (set_attr "amdfam10_decode" "vector")
14556 (set_attr "bdver1_decode" "vector")])
14558 (define_insn "x86_64_shrd_1"
14559 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
14560 (ior:DI (lshiftrt:DI (match_dup 0)
14561 (match_operand:QI 2 "const_0_to_63_operand"))
14565 (match_operand:DI 1 "register_operand" "r"))
14566 (match_operand:QI 3 "const_0_to_255_operand")) 0)))
14567 (clobber (reg:CC FLAGS_REG))]
14569 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])"
14570 "shrd{q}\t{%2, %1, %0|%0, %1, %2}"
14571 [(set_attr "type" "ishift")
14572 (set_attr "prefix_0f" "1")
14573 (set_attr "length_immediate" "1")
14574 (set_attr "mode" "DI")
14575 (set_attr "athlon_decode" "vector")
14576 (set_attr "amdfam10_decode" "vector")
14577 (set_attr "bdver1_decode" "vector")])
14579 (define_insn_and_split "*x86_64_shrd_shld_1_nozext"
14580 [(set (match_operand:DI 0 "nonimmediate_operand")
14581 (ior:DI (lshiftrt:DI (match_operand:DI 4 "nonimmediate_operand")
14582 (match_operand:QI 2 "const_0_to_63_operand"))
14584 (match_operand:DI 1 "nonimmediate_operand")
14585 (match_operand:QI 3 "const_0_to_63_operand"))))
14586 (clobber (reg:CC FLAGS_REG))]
14588 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])
14589 && ix86_pre_reload_split ()"
14594 if (rtx_equal_p (operands[4], operands[0]))
14596 operands[1] = force_reg (DImode, operands[1]);
14597 emit_insn (gen_x86_64_shrd_1 (operands[0], operands[1], operands[2], operands[3]));
14599 else if (rtx_equal_p (operands[1], operands[0]))
14601 operands[4] = force_reg (DImode, operands[4]);
14602 emit_insn (gen_x86_64_shld_1 (operands[0], operands[4], operands[3], operands[2]));
14606 operands[1] = force_reg (DImode, operands[1]);
14607 rtx tmp = gen_reg_rtx (DImode);
14608 emit_move_insn (tmp, operands[4]);
14609 emit_insn (gen_x86_64_shrd_1 (tmp, operands[1], operands[2], operands[3]));
14610 emit_move_insn (operands[0], tmp);
14615 (define_insn_and_split "*x86_64_shrd_2"
14616 [(set (match_operand:DI 0 "nonimmediate_operand")
14617 (ior:DI (lshiftrt:DI (match_dup 0)
14618 (match_operand:QI 2 "nonmemory_operand"))
14619 (ashift:DI (match_operand:DI 1 "register_operand")
14620 (minus:QI (const_int 64) (match_dup 2)))))
14621 (clobber (reg:CC FLAGS_REG))]
14622 "TARGET_64BIT && ix86_pre_reload_split ()"
14625 [(parallel [(set (match_dup 0)
14626 (ior:DI (lshiftrt:DI (match_dup 0)
14627 (and:QI (match_dup 2) (const_int 63)))
14630 (zero_extend:TI (match_dup 1))
14631 (minus:QI (const_int 64)
14632 (and:QI (match_dup 2)
14633 (const_int 63)))) 0)))
14634 (clobber (reg:CC FLAGS_REG))])])
14636 (define_insn "x86_shrd"
14637 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
14638 (ior:SI (lshiftrt:SI (match_dup 0)
14639 (and:QI (match_operand:QI 2 "nonmemory_operand" "Ic")
14644 (match_operand:SI 1 "register_operand" "r"))
14645 (minus:QI (const_int 32)
14646 (and:QI (match_dup 2) (const_int 31)))) 0)))
14647 (clobber (reg:CC FLAGS_REG))]
14649 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
14650 [(set_attr "type" "ishift")
14651 (set_attr "prefix_0f" "1")
14652 (set_attr "mode" "SI")
14653 (set_attr "pent_pair" "np")
14654 (set_attr "athlon_decode" "vector")
14655 (set_attr "amdfam10_decode" "vector")
14656 (set_attr "bdver1_decode" "vector")])
14658 (define_insn "x86_shrd_1"
14659 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
14660 (ior:SI (lshiftrt:SI (match_dup 0)
14661 (match_operand:QI 2 "const_0_to_31_operand"))
14665 (match_operand:SI 1 "register_operand" "r"))
14666 (match_operand:QI 3 "const_0_to_63_operand")) 0)))
14667 (clobber (reg:CC FLAGS_REG))]
14668 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])"
14669 "shrd{l}\t{%2, %1, %0|%0, %1, %2}"
14670 [(set_attr "type" "ishift")
14671 (set_attr "prefix_0f" "1")
14672 (set_attr "length_immediate" "1")
14673 (set_attr "mode" "SI")
14674 (set_attr "pent_pair" "np")
14675 (set_attr "athlon_decode" "vector")
14676 (set_attr "amdfam10_decode" "vector")
14677 (set_attr "bdver1_decode" "vector")])
14679 (define_insn_and_split "*x86_shrd_shld_1_nozext"
14680 [(set (match_operand:SI 0 "nonimmediate_operand")
14681 (ior:SI (lshiftrt:SI (match_operand:SI 4 "nonimmediate_operand")
14682 (match_operand:QI 2 "const_0_to_31_operand"))
14684 (match_operand:SI 1 "nonimmediate_operand")
14685 (match_operand:QI 3 "const_0_to_31_operand"))))
14686 (clobber (reg:CC FLAGS_REG))]
14687 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])
14688 && ix86_pre_reload_split ()"
14693 if (rtx_equal_p (operands[4], operands[0]))
14695 operands[1] = force_reg (SImode, operands[1]);
14696 emit_insn (gen_x86_shrd_1 (operands[0], operands[1], operands[2], operands[3]));
14698 else if (rtx_equal_p (operands[1], operands[0]))
14700 operands[4] = force_reg (SImode, operands[4]);
14701 emit_insn (gen_x86_shld_1 (operands[0], operands[4], operands[3], operands[2]));
14705 operands[1] = force_reg (SImode, operands[1]);
14706 rtx tmp = gen_reg_rtx (SImode);
14707 emit_move_insn (tmp, operands[4]);
14708 emit_insn (gen_x86_shrd_1 (tmp, operands[1], operands[2], operands[3]));
14709 emit_move_insn (operands[0], tmp);
14714 (define_insn_and_split "*x86_shrd_2"
14715 [(set (match_operand:SI 0 "nonimmediate_operand")
14716 (ior:SI (lshiftrt:SI (match_dup 0)
14717 (match_operand:QI 2 "nonmemory_operand"))
14718 (ashift:SI (match_operand:SI 1 "register_operand")
14719 (minus:QI (const_int 32) (match_dup 2)))))
14720 (clobber (reg:CC FLAGS_REG))]
14721 "TARGET_64BIT && ix86_pre_reload_split ()"
14724 [(parallel [(set (match_dup 0)
14725 (ior:SI (lshiftrt:SI (match_dup 0)
14726 (and:QI (match_dup 2) (const_int 31)))
14729 (zero_extend:DI (match_dup 1))
14730 (minus:QI (const_int 32)
14731 (and:QI (match_dup 2)
14732 (const_int 31)))) 0)))
14733 (clobber (reg:CC FLAGS_REG))])])
14735 ;; Base name for insn mnemonic.
14736 (define_mode_attr cvt_mnemonic
14737 [(SI "{cltd|cdq}") (DI "{cqto|cqo}")])
14739 (define_insn "ashr<mode>3_cvt"
14740 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=*d,rm")
14742 (match_operand:SWI48 1 "nonimmediate_operand" "*a,0")
14743 (match_operand:QI 2 "const_int_operand")))
14744 (clobber (reg:CC FLAGS_REG))]
14745 "INTVAL (operands[2]) == GET_MODE_BITSIZE (<MODE>mode)-1
14746 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
14747 && ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
14750 sar{<imodesuffix>}\t{%2, %0|%0, %2}"
14751 [(set_attr "type" "imovx,ishift")
14752 (set_attr "prefix_0f" "0,*")
14753 (set_attr "length_immediate" "0,*")
14754 (set_attr "modrm" "0,1")
14755 (set_attr "mode" "<MODE>")])
14757 (define_insn "*ashrsi3_cvt_zext"
14758 [(set (match_operand:DI 0 "register_operand" "=*d,r")
14760 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
14761 (match_operand:QI 2 "const_int_operand"))))
14762 (clobber (reg:CC FLAGS_REG))]
14763 "TARGET_64BIT && INTVAL (operands[2]) == 31
14764 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
14765 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
14768 sar{l}\t{%2, %k0|%k0, %2}"
14769 [(set_attr "type" "imovx,ishift")
14770 (set_attr "prefix_0f" "0,*")
14771 (set_attr "length_immediate" "0,*")
14772 (set_attr "modrm" "0,1")
14773 (set_attr "mode" "SI")])
14775 (define_expand "@x86_shift<mode>_adj_3"
14776 [(use (match_operand:SWI48 0 "register_operand"))
14777 (use (match_operand:SWI48 1 "register_operand"))
14778 (use (match_operand:QI 2 "register_operand"))]
14781 rtx_code_label *label = gen_label_rtx ();
14784 emit_insn (gen_testqi_ccz_1 (operands[2],
14785 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
14787 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
14788 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
14789 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
14790 gen_rtx_LABEL_REF (VOIDmode, label),
14792 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
14793 JUMP_LABEL (tmp) = label;
14795 emit_move_insn (operands[0], operands[1]);
14796 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
14797 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
14798 emit_label (label);
14799 LABEL_NUSES (label) = 1;
14804 (define_insn "*bmi2_<insn><mode>3_1"
14805 [(set (match_operand:SWI48 0 "register_operand" "=r")
14806 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14807 (match_operand:SWI48 2 "register_operand" "r")))]
14809 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
14810 [(set_attr "type" "ishiftx")
14811 (set_attr "mode" "<MODE>")])
14813 (define_insn "*ashr<mode>3_1"
14814 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
14816 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
14817 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
14818 (clobber (reg:CC FLAGS_REG))]
14819 "ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
14821 switch (get_attr_type (insn))
14827 if (operands[2] == const1_rtx
14828 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14829 return "sar{<imodesuffix>}\t%0";
14831 return "sar{<imodesuffix>}\t{%2, %0|%0, %2}";
14834 [(set_attr "isa" "*,bmi2")
14835 (set_attr "type" "ishift,ishiftx")
14836 (set (attr "length_immediate")
14838 (and (match_operand 2 "const1_operand")
14839 (ior (match_test "TARGET_SHIFT1")
14840 (match_test "optimize_function_for_size_p (cfun)")))
14842 (const_string "*")))
14843 (set_attr "mode" "<MODE>")])
14845 ;; Specialization of *lshr<mode>3_1 below, extracting the SImode
14846 ;; highpart of a DI to be extracted, but allowing it to be clobbered.
14847 (define_insn_and_split "*highpartdisi2"
14848 [(set (subreg:DI (match_operand:SI 0 "register_operand" "=r,x,?k") 0)
14849 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0,k")
14851 (clobber (reg:CC FLAGS_REG))]
14854 "&& reload_completed"
14856 [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 32)))
14857 (clobber (reg:CC FLAGS_REG))])]
14859 if (SSE_REG_P (operands[0]))
14861 rtx tmp = gen_rtx_REG (V4SImode, REGNO (operands[0]));
14862 emit_insn (gen_sse_shufps_v4si (tmp, tmp, tmp,
14863 const1_rtx, const1_rtx,
14864 GEN_INT (5), GEN_INT (5)));
14867 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
14870 (define_insn "*lshr<mode>3_1"
14871 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,?k")
14873 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm,k")
14874 (match_operand:QI 2 "nonmemory_operand" "c<S>,r,<KS>")))
14875 (clobber (reg:CC FLAGS_REG))]
14876 "ix86_binary_operator_ok (LSHIFTRT, <MODE>mode, operands)"
14878 switch (get_attr_type (insn))
14885 if (operands[2] == const1_rtx
14886 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14887 return "shr{<imodesuffix>}\t%0";
14889 return "shr{<imodesuffix>}\t{%2, %0|%0, %2}";
14892 [(set_attr "isa" "*,bmi2,avx512bw")
14893 (set_attr "type" "ishift,ishiftx,msklog")
14894 (set (attr "length_immediate")
14896 (and (and (match_operand 2 "const1_operand")
14897 (eq_attr "alternative" "0"))
14898 (ior (match_test "TARGET_SHIFT1")
14899 (match_test "optimize_function_for_size_p (cfun)")))
14901 (const_string "*")))
14902 (set_attr "mode" "<MODE>")])
14904 ;; Convert shift to the shiftx pattern to avoid flags dependency.
14906 [(set (match_operand:SWI48 0 "register_operand")
14907 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
14908 (match_operand:QI 2 "register_operand")))
14909 (clobber (reg:CC FLAGS_REG))]
14910 "TARGET_BMI2 && reload_completed"
14911 [(set (match_dup 0)
14912 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
14913 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
14915 (define_insn "*bmi2_<insn>si3_1_zext"
14916 [(set (match_operand:DI 0 "register_operand" "=r")
14918 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
14919 (match_operand:SI 2 "register_operand" "r"))))]
14920 "TARGET_64BIT && TARGET_BMI2"
14921 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
14922 [(set_attr "type" "ishiftx")
14923 (set_attr "mode" "SI")])
14925 (define_insn "*<insn>si3_1_zext"
14926 [(set (match_operand:DI 0 "register_operand" "=r,r")
14928 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
14929 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
14930 (clobber (reg:CC FLAGS_REG))]
14931 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
14933 switch (get_attr_type (insn))
14939 if (operands[2] == const1_rtx
14940 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14941 return "<shift>{l}\t%k0";
14943 return "<shift>{l}\t{%2, %k0|%k0, %2}";
14946 [(set_attr "isa" "*,bmi2")
14947 (set_attr "type" "ishift,ishiftx")
14948 (set (attr "length_immediate")
14950 (and (match_operand 2 "const1_operand")
14951 (ior (match_test "TARGET_SHIFT1")
14952 (match_test "optimize_function_for_size_p (cfun)")))
14954 (const_string "*")))
14955 (set_attr "mode" "SI")])
14957 ;; Convert shift to the shiftx pattern to avoid flags dependency.
14959 [(set (match_operand:DI 0 "register_operand")
14961 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
14962 (match_operand:QI 2 "register_operand"))))
14963 (clobber (reg:CC FLAGS_REG))]
14964 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
14965 [(set (match_dup 0)
14966 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
14967 "operands[2] = gen_lowpart (SImode, operands[2]);")
14969 (define_insn "*ashr<mode>3_1"
14970 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
14972 (match_operand:SWI12 1 "nonimmediate_operand" "0")
14973 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
14974 (clobber (reg:CC FLAGS_REG))]
14975 "ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
14977 if (operands[2] == const1_rtx
14978 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14979 return "sar{<imodesuffix>}\t%0";
14981 return "sar{<imodesuffix>}\t{%2, %0|%0, %2}";
14983 [(set_attr "type" "ishift")
14984 (set (attr "length_immediate")
14986 (and (match_operand 2 "const1_operand")
14987 (ior (match_test "TARGET_SHIFT1")
14988 (match_test "optimize_function_for_size_p (cfun)")))
14990 (const_string "*")))
14991 (set_attr "mode" "<MODE>")])
14993 (define_insn "*lshrqi3_1"
14994 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,?k")
14996 (match_operand:QI 1 "nonimmediate_operand" "0, k")
14997 (match_operand:QI 2 "nonmemory_operand" "cI,Wb")))
14998 (clobber (reg:CC FLAGS_REG))]
14999 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
15001 switch (get_attr_type (insn))
15004 if (operands[2] == const1_rtx
15005 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15006 return "shr{b}\t%0";
15008 return "shr{b}\t{%2, %0|%0, %2}";
15012 gcc_unreachable ();
15015 [(set_attr "isa" "*,avx512dq")
15016 (set_attr "type" "ishift,msklog")
15017 (set (attr "length_immediate")
15019 (and (and (match_operand 2 "const1_operand")
15020 (eq_attr "alternative" "0"))
15021 (ior (match_test "TARGET_SHIFT1")
15022 (match_test "optimize_function_for_size_p (cfun)")))
15024 (const_string "*")))
15025 (set_attr "mode" "QI")])
15027 (define_insn "*lshrhi3_1"
15028 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm, ?k")
15030 (match_operand:HI 1 "nonimmediate_operand" "0, k")
15031 (match_operand:QI 2 "nonmemory_operand" "cI, Ww")))
15032 (clobber (reg:CC FLAGS_REG))]
15033 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
15035 switch (get_attr_type (insn))
15038 if (operands[2] == const1_rtx
15039 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15040 return "shr{w}\t%0";
15042 return "shr{w}\t{%2, %0|%0, %2}";
15046 gcc_unreachable ();
15049 [(set_attr "isa" "*, avx512f")
15050 (set_attr "type" "ishift,msklog")
15051 (set (attr "length_immediate")
15053 (and (and (match_operand 2 "const1_operand")
15054 (eq_attr "alternative" "0"))
15055 (ior (match_test "TARGET_SHIFT1")
15056 (match_test "optimize_function_for_size_p (cfun)")))
15058 (const_string "*")))
15059 (set_attr "mode" "HI")])
15061 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
15062 (define_insn_and_split "*<insn><mode>3_1_slp"
15063 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
15064 (any_shiftrt:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
15065 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
15066 (clobber (reg:CC FLAGS_REG))]
15067 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
15069 if (which_alternative)
15072 if (operands[2] == const1_rtx
15073 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15074 return "<shift>{<imodesuffix>}\t%0";
15076 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
15078 "&& reload_completed"
15079 [(set (strict_low_part (match_dup 0)) (match_dup 1))
15081 [(set (strict_low_part (match_dup 0))
15082 (any_shiftrt:SWI12 (match_dup 0) (match_dup 2)))
15083 (clobber (reg:CC FLAGS_REG))])]
15085 [(set_attr "type" "ishift")
15086 (set (attr "length_immediate")
15088 (and (match_operand 2 "const1_operand")
15089 (ior (match_test "TARGET_SHIFT1")
15090 (match_test "optimize_function_for_size_p (cfun)")))
15092 (const_string "*")))
15093 (set_attr "mode" "<MODE>")])
15095 ;; This pattern can't accept a variable shift count, since shifts by
15096 ;; zero don't affect the flags. We assume that shifts by constant
15097 ;; zero are optimized away.
15098 (define_insn "*<insn><mode>3_cmp"
15099 [(set (reg FLAGS_REG)
15102 (match_operand:SWI 1 "nonimmediate_operand" "0")
15103 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
15105 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
15106 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
15107 "(optimize_function_for_size_p (cfun)
15108 || !TARGET_PARTIAL_FLAG_REG_STALL
15109 || (operands[2] == const1_rtx
15111 && ix86_match_ccmode (insn, CCGOCmode)
15112 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
15114 if (operands[2] == const1_rtx
15115 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15116 return "<shift>{<imodesuffix>}\t%0";
15118 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
15120 [(set_attr "type" "ishift")
15121 (set (attr "length_immediate")
15123 (and (match_operand 2 "const1_operand")
15124 (ior (match_test "TARGET_SHIFT1")
15125 (match_test "optimize_function_for_size_p (cfun)")))
15127 (const_string "*")))
15128 (set_attr "mode" "<MODE>")])
15130 (define_insn "*<insn>si3_cmp_zext"
15131 [(set (reg FLAGS_REG)
15133 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
15134 (match_operand:QI 2 "const_1_to_31_operand"))
15136 (set (match_operand:DI 0 "register_operand" "=r")
15137 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
15139 && (optimize_function_for_size_p (cfun)
15140 || !TARGET_PARTIAL_FLAG_REG_STALL
15141 || (operands[2] == const1_rtx
15143 && ix86_match_ccmode (insn, CCGOCmode)
15144 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
15146 if (operands[2] == const1_rtx
15147 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15148 return "<shift>{l}\t%k0";
15150 return "<shift>{l}\t{%2, %k0|%k0, %2}";
15152 [(set_attr "type" "ishift")
15153 (set (attr "length_immediate")
15155 (and (match_operand 2 "const1_operand")
15156 (ior (match_test "TARGET_SHIFT1")
15157 (match_test "optimize_function_for_size_p (cfun)")))
15159 (const_string "*")))
15160 (set_attr "mode" "SI")])
15162 (define_insn "*<insn><mode>3_cconly"
15163 [(set (reg FLAGS_REG)
15166 (match_operand:SWI 1 "register_operand" "0")
15167 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
15169 (clobber (match_scratch:SWI 0 "=<r>"))]
15170 "(optimize_function_for_size_p (cfun)
15171 || !TARGET_PARTIAL_FLAG_REG_STALL
15172 || (operands[2] == const1_rtx
15174 && ix86_match_ccmode (insn, CCGOCmode)"
15176 if (operands[2] == const1_rtx
15177 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15178 return "<shift>{<imodesuffix>}\t%0";
15180 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
15182 [(set_attr "type" "ishift")
15183 (set (attr "length_immediate")
15185 (and (match_operand 2 "const1_operand")
15186 (ior (match_test "TARGET_SHIFT1")
15187 (match_test "optimize_function_for_size_p (cfun)")))
15189 (const_string "*")))
15190 (set_attr "mode" "<MODE>")])
15192 (define_insn "*<insn>qi_ext<mode>_2"
15193 [(set (zero_extract:SWI248
15194 (match_operand 0 "int248_register_operand" "+Q")
15200 (match_operator:SWI248 3 "extract_operator"
15201 [(match_operand 1 "int248_register_operand" "0")
15204 (match_operand:QI 2 "nonmemory_operand" "cI")) 0))
15205 (clobber (reg:CC FLAGS_REG))]
15206 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
15207 rtx_equal_p (operands[0], operands[1])"
15209 if (operands[2] == const1_rtx
15210 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15211 return "<shift>{b}\t%h0";
15213 return "<shift>{b}\t{%2, %h0|%h0, %2}";
15215 [(set_attr "type" "ishift")
15216 (set (attr "length_immediate")
15218 (and (match_operand 2 "const1_operand")
15219 (ior (match_test "TARGET_SHIFT1")
15220 (match_test "optimize_function_for_size_p (cfun)")))
15222 (const_string "*")))
15223 (set_attr "mode" "QI")])
15225 ;; Rotate instructions
15227 (define_expand "<insn>ti3"
15228 [(set (match_operand:TI 0 "register_operand")
15229 (any_rotate:TI (match_operand:TI 1 "register_operand")
15230 (match_operand:QI 2 "nonmemory_operand")))]
15233 if (const_1_to_63_operand (operands[2], VOIDmode))
15234 emit_insn (gen_ix86_<insn>ti3_doubleword
15235 (operands[0], operands[1], operands[2]));
15236 else if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 64)
15237 emit_insn (gen_<insn>64ti2_doubleword (operands[0], operands[1]));
15240 rtx amount = force_reg (QImode, operands[2]);
15241 rtx src_lo = gen_lowpart (DImode, operands[1]);
15242 rtx src_hi = gen_highpart (DImode, operands[1]);
15243 rtx tmp_lo = gen_reg_rtx (DImode);
15244 rtx tmp_hi = gen_reg_rtx (DImode);
15245 emit_move_insn (tmp_lo, src_lo);
15246 emit_move_insn (tmp_hi, src_hi);
15247 rtx (*shiftd) (rtx, rtx, rtx)
15248 = (<CODE> == ROTATE) ? gen_x86_64_shld : gen_x86_64_shrd;
15249 emit_insn (shiftd (tmp_lo, src_hi, amount));
15250 emit_insn (shiftd (tmp_hi, src_lo, amount));
15251 rtx dst_lo = gen_lowpart (DImode, operands[0]);
15252 rtx dst_hi = gen_highpart (DImode, operands[0]);
15253 emit_move_insn (dst_lo, tmp_lo);
15254 emit_move_insn (dst_hi, tmp_hi);
15255 emit_insn (gen_x86_shiftdi_adj_1 (dst_lo, dst_hi, amount, tmp_lo));
15260 (define_expand "<insn>di3"
15261 [(set (match_operand:DI 0 "shiftdi_operand")
15262 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
15263 (match_operand:QI 2 "nonmemory_operand")))]
15267 ix86_expand_binary_operator (<CODE>, DImode, operands);
15268 else if (const_1_to_31_operand (operands[2], VOIDmode))
15269 emit_insn (gen_ix86_<insn>di3_doubleword
15270 (operands[0], operands[1], operands[2]));
15271 else if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 32)
15272 emit_insn (gen_<insn>32di2_doubleword (operands[0], operands[1]));
15279 (define_expand "<insn><mode>3"
15280 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
15281 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
15282 (match_operand:QI 2 "nonmemory_operand")))]
15284 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
15286 ;; Avoid useless masking of count operand.
15287 (define_insn_and_split "*<insn><mode>3_mask"
15288 [(set (match_operand:SWI 0 "nonimmediate_operand")
15290 (match_operand:SWI 1 "nonimmediate_operand")
15293 (match_operand 2 "int248_register_operand" "c")
15294 (match_operand 3 "const_int_operand")) 0)))
15295 (clobber (reg:CC FLAGS_REG))]
15296 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
15297 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15298 == GET_MODE_BITSIZE (<MODE>mode)-1
15299 && ix86_pre_reload_split ()"
15303 [(set (match_dup 0)
15304 (any_rotate:SWI (match_dup 1)
15306 (clobber (reg:CC FLAGS_REG))])]
15308 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
15309 operands[2] = gen_lowpart (QImode, operands[2]);
15313 [(set (match_operand:SWI 0 "register_operand")
15315 (match_operand:SWI 1 "const_int_operand")
15318 (match_operand 2 "int248_register_operand")
15319 (match_operand 3 "const_int_operand")) 0)))]
15320 "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode) - 1))
15321 == GET_MODE_BITSIZE (<MODE>mode) - 1"
15322 [(set (match_dup 4) (match_dup 1))
15324 (any_rotate:SWI (match_dup 4)
15325 (subreg:QI (match_dup 2) 0)))]
15326 "operands[4] = gen_reg_rtx (<MODE>mode);")
15328 (define_insn_and_split "*<insn><mode>3_mask_1"
15329 [(set (match_operand:SWI 0 "nonimmediate_operand")
15331 (match_operand:SWI 1 "nonimmediate_operand")
15333 (match_operand:QI 2 "register_operand" "c")
15334 (match_operand:QI 3 "const_int_operand"))))
15335 (clobber (reg:CC FLAGS_REG))]
15336 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
15337 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15338 == GET_MODE_BITSIZE (<MODE>mode)-1
15339 && ix86_pre_reload_split ()"
15343 [(set (match_dup 0)
15344 (any_rotate:SWI (match_dup 1)
15346 (clobber (reg:CC FLAGS_REG))])])
15349 [(set (match_operand:SWI 0 "register_operand")
15351 (match_operand:SWI 1 "const_int_operand")
15353 (match_operand:QI 2 "register_operand")
15354 (match_operand:QI 3 "const_int_operand"))))]
15355 "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode) - 1))
15356 == GET_MODE_BITSIZE (<MODE>mode) - 1"
15357 [(set (match_dup 4) (match_dup 1))
15359 (any_rotate:SWI (match_dup 4) (match_dup 2)))]
15360 "operands[4] = gen_reg_rtx (<MODE>mode);")
15362 ;; Implement rotation using two double-precision
15363 ;; shift instructions and a scratch register.
15365 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
15366 [(set (match_operand:<DWI> 0 "register_operand" "=r")
15367 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
15368 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
15369 (clobber (reg:CC FLAGS_REG))
15370 (clobber (match_scratch:DWIH 3 "=&r"))]
15374 [(set (match_dup 3) (match_dup 4))
15376 [(set (match_dup 4)
15377 (ior:DWIH (ashift:DWIH (match_dup 4)
15378 (and:QI (match_dup 2) (match_dup 6)))
15380 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
15381 (minus:QI (match_dup 7)
15382 (and:QI (match_dup 2)
15383 (match_dup 6)))) 0)))
15384 (clobber (reg:CC FLAGS_REG))])
15386 [(set (match_dup 5)
15387 (ior:DWIH (ashift:DWIH (match_dup 5)
15388 (and:QI (match_dup 2) (match_dup 6)))
15390 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 3))
15391 (minus:QI (match_dup 7)
15392 (and:QI (match_dup 2)
15393 (match_dup 6)))) 0)))
15394 (clobber (reg:CC FLAGS_REG))])]
15396 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
15397 operands[7] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
15399 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
15402 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
15403 [(set (match_operand:<DWI> 0 "register_operand" "=r")
15404 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
15405 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
15406 (clobber (reg:CC FLAGS_REG))
15407 (clobber (match_scratch:DWIH 3 "=&r"))]
15411 [(set (match_dup 3) (match_dup 4))
15413 [(set (match_dup 4)
15414 (ior:DWIH (lshiftrt:DWIH (match_dup 4)
15415 (and:QI (match_dup 2) (match_dup 6)))
15417 (ashift:<DWI> (zero_extend:<DWI> (match_dup 5))
15418 (minus:QI (match_dup 7)
15419 (and:QI (match_dup 2)
15420 (match_dup 6)))) 0)))
15421 (clobber (reg:CC FLAGS_REG))])
15423 [(set (match_dup 5)
15424 (ior:DWIH (lshiftrt:DWIH (match_dup 5)
15425 (and:QI (match_dup 2) (match_dup 6)))
15427 (ashift:<DWI> (zero_extend:<DWI> (match_dup 3))
15428 (minus:QI (match_dup 7)
15429 (and:QI (match_dup 2)
15430 (match_dup 6)))) 0)))
15431 (clobber (reg:CC FLAGS_REG))])]
15433 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
15434 operands[7] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
15436 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
15439 (define_insn_and_split "<insn>32di2_doubleword"
15440 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
15441 (any_rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,r,o")
15445 "&& reload_completed"
15446 [(set (match_dup 0) (match_dup 3))
15447 (set (match_dup 2) (match_dup 1))]
15449 split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);
15450 if (rtx_equal_p (operands[0], operands[1]))
15452 emit_insn (gen_swapsi (operands[0], operands[2]));
15457 (define_insn_and_split "<insn>64ti2_doubleword"
15458 [(set (match_operand:TI 0 "register_operand" "=r,r,r")
15459 (any_rotate:TI (match_operand:TI 1 "nonimmediate_operand" "0,r,o")
15463 "&& reload_completed"
15464 [(set (match_dup 0) (match_dup 3))
15465 (set (match_dup 2) (match_dup 1))]
15467 split_double_mode (TImode, &operands[0], 2, &operands[0], &operands[2]);
15468 if (rtx_equal_p (operands[0], operands[1]))
15470 emit_insn (gen_swapdi (operands[0], operands[2]));
15475 (define_mode_attr rorx_immediate_operand
15476 [(SI "const_0_to_31_operand")
15477 (DI "const_0_to_63_operand")])
15479 (define_insn "*bmi2_rorx<mode>3_1"
15480 [(set (match_operand:SWI48 0 "register_operand" "=r")
15482 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
15483 (match_operand:QI 2 "<rorx_immediate_operand>" "<S>")))]
15484 "TARGET_BMI2 && !optimize_function_for_size_p (cfun)"
15485 "rorx\t{%2, %1, %0|%0, %1, %2}"
15486 [(set_attr "type" "rotatex")
15487 (set_attr "mode" "<MODE>")])
15489 (define_insn "*<insn><mode>3_1"
15490 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
15492 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
15493 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
15494 (clobber (reg:CC FLAGS_REG))]
15495 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
15497 switch (get_attr_type (insn))
15503 if (operands[2] == const1_rtx
15504 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15505 return "<rotate>{<imodesuffix>}\t%0";
15507 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
15510 [(set_attr "isa" "*,bmi2")
15511 (set_attr "type" "rotate,rotatex")
15512 (set (attr "preferred_for_size")
15513 (cond [(eq_attr "alternative" "0")
15514 (symbol_ref "true")]
15515 (symbol_ref "false")))
15516 (set (attr "length_immediate")
15518 (and (eq_attr "type" "rotate")
15519 (and (match_operand 2 "const1_operand")
15520 (ior (match_test "TARGET_SHIFT1")
15521 (match_test "optimize_function_for_size_p (cfun)"))))
15523 (const_string "*")))
15524 (set_attr "mode" "<MODE>")])
15526 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
15528 [(set (match_operand:SWI48 0 "register_operand")
15529 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
15530 (match_operand:QI 2 "const_int_operand")))
15531 (clobber (reg:CC FLAGS_REG))]
15532 "TARGET_BMI2 && reload_completed && !optimize_function_for_size_p (cfun)"
15533 [(set (match_dup 0)
15534 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
15536 int bitsize = GET_MODE_BITSIZE (<MODE>mode);
15538 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
15542 [(set (match_operand:SWI48 0 "register_operand")
15543 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
15544 (match_operand:QI 2 "const_int_operand")))
15545 (clobber (reg:CC FLAGS_REG))]
15546 "TARGET_BMI2 && reload_completed && !optimize_function_for_size_p (cfun)"
15547 [(set (match_dup 0)
15548 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
15550 (define_insn "*bmi2_rorxsi3_1_zext"
15551 [(set (match_operand:DI 0 "register_operand" "=r")
15553 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
15554 (match_operand:QI 2 "const_0_to_31_operand"))))]
15555 "TARGET_64BIT && TARGET_BMI2 && !optimize_function_for_size_p (cfun)"
15556 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
15557 [(set_attr "type" "rotatex")
15558 (set_attr "mode" "SI")])
15560 (define_insn "*<insn>si3_1_zext"
15561 [(set (match_operand:DI 0 "register_operand" "=r,r")
15563 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
15564 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
15565 (clobber (reg:CC FLAGS_REG))]
15566 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
15568 switch (get_attr_type (insn))
15574 if (operands[2] == const1_rtx
15575 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15576 return "<rotate>{l}\t%k0";
15578 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
15581 [(set_attr "isa" "*,bmi2")
15582 (set_attr "type" "rotate,rotatex")
15583 (set (attr "preferred_for_size")
15584 (cond [(eq_attr "alternative" "0")
15585 (symbol_ref "true")]
15586 (symbol_ref "false")))
15587 (set (attr "length_immediate")
15589 (and (eq_attr "type" "rotate")
15590 (and (match_operand 2 "const1_operand")
15591 (ior (match_test "TARGET_SHIFT1")
15592 (match_test "optimize_function_for_size_p (cfun)"))))
15594 (const_string "*")))
15595 (set_attr "mode" "SI")])
15597 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
15599 [(set (match_operand:DI 0 "register_operand")
15601 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
15602 (match_operand:QI 2 "const_int_operand"))))
15603 (clobber (reg:CC FLAGS_REG))]
15604 "TARGET_64BIT && TARGET_BMI2 && reload_completed
15605 && !optimize_function_for_size_p (cfun)"
15606 [(set (match_dup 0)
15607 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
15609 int bitsize = GET_MODE_BITSIZE (SImode);
15611 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
15615 [(set (match_operand:DI 0 "register_operand")
15617 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
15618 (match_operand:QI 2 "const_int_operand"))))
15619 (clobber (reg:CC FLAGS_REG))]
15620 "TARGET_64BIT && TARGET_BMI2 && reload_completed
15621 && !optimize_function_for_size_p (cfun)"
15622 [(set (match_dup 0)
15623 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
15625 (define_insn "*<insn><mode>3_1"
15626 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
15627 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
15628 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
15629 (clobber (reg:CC FLAGS_REG))]
15630 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
15632 if (operands[2] == const1_rtx
15633 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15634 return "<rotate>{<imodesuffix>}\t%0";
15636 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
15638 [(set_attr "type" "rotate")
15639 (set (attr "length_immediate")
15641 (and (match_operand 2 "const1_operand")
15642 (ior (match_test "TARGET_SHIFT1")
15643 (match_test "optimize_function_for_size_p (cfun)")))
15645 (const_string "*")))
15646 (set_attr "mode" "<MODE>")])
15648 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
15649 (define_insn_and_split "*<insn><mode>3_1_slp"
15650 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
15651 (any_rotate:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
15652 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
15653 (clobber (reg:CC FLAGS_REG))]
15654 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
15656 if (which_alternative)
15659 if (operands[2] == const1_rtx
15660 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15661 return "<rotate>{<imodesuffix>}\t%0";
15663 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
15665 "&& reload_completed"
15666 [(set (strict_low_part (match_dup 0)) (match_dup 1))
15668 [(set (strict_low_part (match_dup 0))
15669 (any_rotate:SWI12 (match_dup 0) (match_dup 2)))
15670 (clobber (reg:CC FLAGS_REG))])]
15672 [(set_attr "type" "rotate")
15673 (set (attr "length_immediate")
15675 (and (match_operand 2 "const1_operand")
15676 (ior (match_test "TARGET_SHIFT1")
15677 (match_test "optimize_function_for_size_p (cfun)")))
15679 (const_string "*")))
15680 (set_attr "mode" "<MODE>")])
15683 [(set (match_operand:HI 0 "QIreg_operand")
15684 (any_rotate:HI (match_dup 0) (const_int 8)))
15685 (clobber (reg:CC FLAGS_REG))]
15687 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
15688 [(parallel [(set (strict_low_part (match_dup 0))
15689 (bswap:HI (match_dup 0)))
15690 (clobber (reg:CC FLAGS_REG))])])
15692 ;; Bit set / bit test instructions
15694 ;; %%% bts, btr, btc
15696 ;; These instructions are *slow* when applied to memory.
15698 (define_code_attr btsc [(ior "bts") (xor "btc")])
15700 (define_insn "*<btsc><mode>"
15701 [(set (match_operand:SWI48 0 "register_operand" "=r")
15703 (ashift:SWI48 (const_int 1)
15704 (match_operand:QI 2 "register_operand" "r"))
15705 (match_operand:SWI48 1 "register_operand" "0")))
15706 (clobber (reg:CC FLAGS_REG))]
15708 "<btsc>{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
15709 [(set_attr "type" "alu1")
15710 (set_attr "prefix_0f" "1")
15711 (set_attr "znver1_decode" "double")
15712 (set_attr "mode" "<MODE>")])
15714 ;; Avoid useless masking of count operand.
15715 (define_insn_and_split "*<btsc><mode>_mask"
15716 [(set (match_operand:SWI48 0 "register_operand")
15722 (match_operand 1 "int248_register_operand")
15723 (match_operand 2 "const_int_operand")) 0))
15724 (match_operand:SWI48 3 "register_operand")))
15725 (clobber (reg:CC FLAGS_REG))]
15727 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15728 == GET_MODE_BITSIZE (<MODE>mode)-1
15729 && ix86_pre_reload_split ()"
15733 [(set (match_dup 0)
15735 (ashift:SWI48 (const_int 1)
15738 (clobber (reg:CC FLAGS_REG))])]
15740 operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
15741 operands[1] = gen_lowpart (QImode, operands[1]);
15744 (define_insn_and_split "*<btsc><mode>_mask_1"
15745 [(set (match_operand:SWI48 0 "register_operand")
15750 (match_operand:QI 1 "register_operand")
15751 (match_operand:QI 2 "const_int_operand")))
15752 (match_operand:SWI48 3 "register_operand")))
15753 (clobber (reg:CC FLAGS_REG))]
15755 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15756 == GET_MODE_BITSIZE (<MODE>mode)-1
15757 && ix86_pre_reload_split ()"
15761 [(set (match_dup 0)
15763 (ashift:SWI48 (const_int 1)
15766 (clobber (reg:CC FLAGS_REG))])])
15768 (define_insn "*btr<mode>"
15769 [(set (match_operand:SWI48 0 "register_operand" "=r")
15771 (rotate:SWI48 (const_int -2)
15772 (match_operand:QI 2 "register_operand" "r"))
15773 (match_operand:SWI48 1 "register_operand" "0")))
15774 (clobber (reg:CC FLAGS_REG))]
15776 "btr{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
15777 [(set_attr "type" "alu1")
15778 (set_attr "prefix_0f" "1")
15779 (set_attr "znver1_decode" "double")
15780 (set_attr "mode" "<MODE>")])
15782 ;; Avoid useless masking of count operand.
15783 (define_insn_and_split "*btr<mode>_mask"
15784 [(set (match_operand:SWI48 0 "register_operand")
15790 (match_operand 1 "int248_register_operand")
15791 (match_operand 2 "const_int_operand")) 0))
15792 (match_operand:SWI48 3 "register_operand")))
15793 (clobber (reg:CC FLAGS_REG))]
15795 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15796 == GET_MODE_BITSIZE (<MODE>mode)-1
15797 && ix86_pre_reload_split ()"
15801 [(set (match_dup 0)
15803 (rotate:SWI48 (const_int -2)
15806 (clobber (reg:CC FLAGS_REG))])]
15808 operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
15809 operands[1] = gen_lowpart (QImode, operands[1]);
15812 (define_insn_and_split "*btr<mode>_mask_1"
15813 [(set (match_operand:SWI48 0 "register_operand")
15818 (match_operand:QI 1 "register_operand")
15819 (match_operand:QI 2 "const_int_operand")))
15820 (match_operand:SWI48 3 "register_operand")))
15821 (clobber (reg:CC FLAGS_REG))]
15823 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15824 == GET_MODE_BITSIZE (<MODE>mode)-1
15825 && ix86_pre_reload_split ()"
15829 [(set (match_dup 0)
15831 (rotate:SWI48 (const_int -2)
15834 (clobber (reg:CC FLAGS_REG))])])
15836 (define_insn_and_split "*btr<mode>_1"
15837 [(set (match_operand:SWI12 0 "register_operand")
15840 (rotate:SI (const_int -2)
15841 (match_operand:QI 2 "register_operand")) 0)
15842 (match_operand:SWI12 1 "nonimmediate_operand")))
15843 (clobber (reg:CC FLAGS_REG))]
15844 "TARGET_USE_BT && ix86_pre_reload_split ()"
15848 [(set (match_dup 0)
15849 (and:SI (rotate:SI (const_int -2) (match_dup 2))
15851 (clobber (reg:CC FLAGS_REG))])]
15853 operands[0] = lowpart_subreg (SImode, operands[0], <MODE>mode);
15854 operands[1] = force_reg (<MODE>mode, operands[1]);
15855 operands[1] = lowpart_subreg (SImode, operands[1], <MODE>mode);
15858 (define_insn_and_split "*btr<mode>_2"
15859 [(set (zero_extract:HI
15860 (match_operand:SWI12 0 "nonimmediate_operand")
15862 (zero_extend:SI (match_operand:QI 1 "register_operand")))
15864 (clobber (reg:CC FLAGS_REG))]
15865 "TARGET_USE_BT && ix86_pre_reload_split ()"
15867 "&& MEM_P (operands[0])"
15868 [(set (match_dup 2) (match_dup 0))
15870 [(set (match_dup 3)
15871 (and:SI (rotate:SI (const_int -2) (match_dup 1))
15873 (clobber (reg:CC FLAGS_REG))])
15874 (set (match_dup 0) (match_dup 5))]
15876 operands[2] = gen_reg_rtx (<MODE>mode);
15877 operands[5] = gen_reg_rtx (<MODE>mode);
15878 operands[3] = lowpart_subreg (SImode, operands[5], <MODE>mode);
15879 operands[4] = lowpart_subreg (SImode, operands[2], <MODE>mode);
15883 [(set (zero_extract:HI
15884 (match_operand:SWI12 0 "register_operand")
15886 (zero_extend:SI (match_operand:QI 1 "register_operand")))
15888 (clobber (reg:CC FLAGS_REG))]
15889 "TARGET_USE_BT && ix86_pre_reload_split ()"
15891 [(set (match_dup 0)
15892 (and:SI (rotate:SI (const_int -2) (match_dup 1))
15894 (clobber (reg:CC FLAGS_REG))])]
15896 operands[2] = lowpart_subreg (SImode, operands[0], <MODE>mode);
15897 operands[0] = lowpart_subreg (SImode, operands[0], <MODE>mode);
15900 ;; These instructions are never faster than the corresponding
15901 ;; and/ior/xor operations when using immediate operand, so with
15902 ;; 32-bit there's no point. But in 64-bit, we can't hold the
15903 ;; relevant immediates within the instruction itself, so operating
15904 ;; on bits in the high 32-bits of a register becomes easier.
15906 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
15907 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
15908 ;; negdf respectively, so they can never be disabled entirely.
15910 (define_insn "*btsq_imm"
15911 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
15913 (match_operand 1 "const_0_to_63_operand"))
15915 (clobber (reg:CC FLAGS_REG))]
15916 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
15917 "bts{q}\t{%1, %0|%0, %1}"
15918 [(set_attr "type" "alu1")
15919 (set_attr "prefix_0f" "1")
15920 (set_attr "znver1_decode" "double")
15921 (set_attr "mode" "DI")])
15923 (define_insn "*btrq_imm"
15924 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
15926 (match_operand 1 "const_0_to_63_operand"))
15928 (clobber (reg:CC FLAGS_REG))]
15929 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
15930 "btr{q}\t{%1, %0|%0, %1}"
15931 [(set_attr "type" "alu1")
15932 (set_attr "prefix_0f" "1")
15933 (set_attr "znver1_decode" "double")
15934 (set_attr "mode" "DI")])
15936 (define_insn "*btcq_imm"
15937 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
15939 (match_operand 1 "const_0_to_63_operand"))
15940 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
15941 (clobber (reg:CC FLAGS_REG))]
15942 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
15943 "btc{q}\t{%1, %0|%0, %1}"
15944 [(set_attr "type" "alu1")
15945 (set_attr "prefix_0f" "1")
15946 (set_attr "znver1_decode" "double")
15947 (set_attr "mode" "DI")])
15949 ;; Allow Nocona to avoid these instructions if a register is available.
15952 [(match_scratch:DI 2 "r")
15953 (parallel [(set (zero_extract:DI
15954 (match_operand:DI 0 "nonimmediate_operand")
15956 (match_operand 1 "const_0_to_63_operand"))
15958 (clobber (reg:CC FLAGS_REG))])]
15959 "TARGET_64BIT && !TARGET_USE_BT"
15960 [(parallel [(set (match_dup 0)
15961 (ior:DI (match_dup 0) (match_dup 3)))
15962 (clobber (reg:CC FLAGS_REG))])]
15964 int i = INTVAL (operands[1]);
15966 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
15968 if (!x86_64_immediate_operand (operands[3], DImode))
15970 emit_move_insn (operands[2], operands[3]);
15971 operands[3] = operands[2];
15976 [(match_scratch:DI 2 "r")
15977 (parallel [(set (zero_extract:DI
15978 (match_operand:DI 0 "nonimmediate_operand")
15980 (match_operand 1 "const_0_to_63_operand"))
15982 (clobber (reg:CC FLAGS_REG))])]
15983 "TARGET_64BIT && !TARGET_USE_BT"
15984 [(parallel [(set (match_dup 0)
15985 (and:DI (match_dup 0) (match_dup 3)))
15986 (clobber (reg:CC FLAGS_REG))])]
15988 int i = INTVAL (operands[1]);
15990 operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
15992 if (!x86_64_immediate_operand (operands[3], DImode))
15994 emit_move_insn (operands[2], operands[3]);
15995 operands[3] = operands[2];
16000 [(match_scratch:DI 2 "r")
16001 (parallel [(set (zero_extract:DI
16002 (match_operand:DI 0 "nonimmediate_operand")
16004 (match_operand 1 "const_0_to_63_operand"))
16005 (not:DI (zero_extract:DI
16006 (match_dup 0) (const_int 1) (match_dup 1))))
16007 (clobber (reg:CC FLAGS_REG))])]
16008 "TARGET_64BIT && !TARGET_USE_BT"
16009 [(parallel [(set (match_dup 0)
16010 (xor:DI (match_dup 0) (match_dup 3)))
16011 (clobber (reg:CC FLAGS_REG))])]
16013 int i = INTVAL (operands[1]);
16015 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
16017 if (!x86_64_immediate_operand (operands[3], DImode))
16019 emit_move_insn (operands[2], operands[3]);
16020 operands[3] = operands[2];
16026 (define_insn "*bt<mode>"
16027 [(set (reg:CCC FLAGS_REG)
16029 (zero_extract:SWI48
16030 (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
16032 (match_operand:SI 1 "nonmemory_operand" "r<S>,<S>"))
16036 switch (get_attr_mode (insn))
16039 return "bt{l}\t{%1, %k0|%k0, %1}";
16042 return "bt{q}\t{%q1, %0|%0, %q1}";
16045 gcc_unreachable ();
16048 [(set_attr "type" "alu1")
16049 (set_attr "prefix_0f" "1")
16052 (and (match_test "CONST_INT_P (operands[1])")
16053 (match_test "INTVAL (operands[1]) < 32"))
16054 (const_string "SI")
16055 (const_string "<MODE>")))])
16057 (define_insn_and_split "*jcc_bt<mode>"
16059 (if_then_else (match_operator 0 "bt_comparison_operator"
16060 [(zero_extract:SWI48
16061 (match_operand:SWI48 1 "nonimmediate_operand")
16063 (match_operand:SI 2 "nonmemory_operand"))
16065 (label_ref (match_operand 3))
16067 (clobber (reg:CC FLAGS_REG))]
16068 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
16069 && (CONST_INT_P (operands[2])
16070 ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
16071 && INTVAL (operands[2])
16072 >= (optimize_function_for_size_p (cfun) ? 8 : 32))
16073 : !memory_operand (operands[1], <MODE>mode))
16074 && ix86_pre_reload_split ()"
16077 [(set (reg:CCC FLAGS_REG)
16079 (zero_extract:SWI48
16085 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16086 (label_ref (match_dup 3))
16089 operands[0] = shallow_copy_rtx (operands[0]);
16090 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16093 (define_insn_and_split "*jcc_bt<mode>_1"
16095 (if_then_else (match_operator 0 "bt_comparison_operator"
16096 [(zero_extract:SWI48
16097 (match_operand:SWI48 1 "register_operand")
16100 (match_operand:QI 2 "register_operand")))
16102 (label_ref (match_operand 3))
16104 (clobber (reg:CC FLAGS_REG))]
16105 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
16106 && ix86_pre_reload_split ()"
16109 [(set (reg:CCC FLAGS_REG)
16111 (zero_extract:SWI48
16117 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16118 (label_ref (match_dup 3))
16121 operands[2] = lowpart_subreg (SImode, operands[2], QImode);
16122 operands[0] = shallow_copy_rtx (operands[0]);
16123 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16126 ;; Avoid useless masking of bit offset operand.
16127 (define_insn_and_split "*jcc_bt<mode>_mask"
16129 (if_then_else (match_operator 0 "bt_comparison_operator"
16130 [(zero_extract:SWI48
16131 (match_operand:SWI48 1 "register_operand")
16134 (match_operand:SI 2 "register_operand")
16135 (match_operand 3 "const_int_operand")))])
16136 (label_ref (match_operand 4))
16138 (clobber (reg:CC FLAGS_REG))]
16139 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
16140 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16141 == GET_MODE_BITSIZE (<MODE>mode)-1
16142 && ix86_pre_reload_split ()"
16145 [(set (reg:CCC FLAGS_REG)
16147 (zero_extract:SWI48
16153 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16154 (label_ref (match_dup 4))
16157 operands[0] = shallow_copy_rtx (operands[0]);
16158 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16161 (define_insn_and_split "*jcc_bt<mode>_mask_1"
16163 (if_then_else (match_operator 0 "bt_comparison_operator"
16164 [(zero_extract:SWI48
16165 (match_operand:SWI48 1 "register_operand")
16170 (match_operand 2 "int248_register_operand")
16171 (match_operand 3 "const_int_operand")) 0)))])
16172 (label_ref (match_operand 4))
16174 (clobber (reg:CC FLAGS_REG))]
16175 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
16176 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16177 == GET_MODE_BITSIZE (<MODE>mode)-1
16178 && ix86_pre_reload_split ()"
16181 [(set (reg:CCC FLAGS_REG)
16183 (zero_extract:SWI48
16189 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16190 (label_ref (match_dup 4))
16193 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
16194 operands[2] = gen_lowpart (SImode, operands[2]);
16195 operands[0] = shallow_copy_rtx (operands[0]);
16196 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16199 ;; Help combine recognize bt followed by cmov
16201 [(set (match_operand:SWI248 0 "register_operand")
16202 (if_then_else:SWI248
16203 (match_operator 5 "bt_comparison_operator"
16204 [(zero_extract:SWI48
16205 (match_operand:SWI48 1 "register_operand")
16207 (zero_extend:SI (match_operand:QI 2 "register_operand")))
16209 (match_operand:SWI248 3 "nonimmediate_operand")
16210 (match_operand:SWI248 4 "nonimmediate_operand")))]
16211 "TARGET_USE_BT && TARGET_CMOVE
16212 && !(MEM_P (operands[3]) && MEM_P (operands[4]))
16213 && ix86_pre_reload_split ()"
16214 [(set (reg:CCC FLAGS_REG)
16216 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16219 (if_then_else:SWI248 (eq (reg:CCC FLAGS_REG) (const_int 0))
16223 if (GET_CODE (operands[5]) == EQ)
16224 std::swap (operands[3], operands[4]);
16225 operands[2] = lowpart_subreg (SImode, operands[2], QImode);
16228 ;; Help combine recognize bt followed by setc
16229 (define_insn_and_split "*bt<mode>_setcqi"
16230 [(set (subreg:SWI48 (match_operand:QI 0 "register_operand") 0)
16231 (zero_extract:SWI48
16232 (match_operand:SWI48 1 "register_operand")
16234 (zero_extend:SI (match_operand:QI 2 "register_operand"))))
16235 (clobber (reg:CC FLAGS_REG))]
16236 "TARGET_USE_BT && ix86_pre_reload_split ()"
16239 [(set (reg:CCC FLAGS_REG)
16241 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16244 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
16246 operands[2] = lowpart_subreg (SImode, operands[2], QImode);
16249 ;; Help combine recognize bt followed by setnc
16250 (define_insn_and_split "*bt<mode>_setncqi"
16251 [(set (match_operand:QI 0 "register_operand")
16255 (lshiftrt:SWI48 (match_operand:SWI48 1 "register_operand")
16256 (match_operand:QI 2 "register_operand")) 0))
16258 (clobber (reg:CC FLAGS_REG))]
16259 "TARGET_USE_BT && ix86_pre_reload_split ()"
16262 [(set (reg:CCC FLAGS_REG)
16264 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16267 (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))]
16269 operands[2] = lowpart_subreg (SImode, operands[2], QImode);
16272 (define_insn_and_split "*bt<mode>_setnc<mode>"
16273 [(set (match_operand:SWI48 0 "register_operand")
16276 (lshiftrt:SWI48 (match_operand:SWI48 1 "register_operand")
16277 (match_operand:QI 2 "register_operand")))
16279 (clobber (reg:CC FLAGS_REG))]
16280 "TARGET_USE_BT && ix86_pre_reload_split ()"
16283 [(set (reg:CCC FLAGS_REG)
16285 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16288 (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))
16289 (set (match_dup 0) (zero_extend:SWI48 (match_dup 3)))]
16291 operands[2] = lowpart_subreg (SImode, operands[2], QImode);
16292 operands[3] = gen_reg_rtx (QImode);
16295 ;; Store-flag instructions.
16298 [(set (match_operand:QI 0 "nonimmediate_operand")
16299 (match_operator:QI 1 "add_comparison_operator"
16300 [(not:SWI (match_operand:SWI 2 "register_operand"))
16301 (match_operand:SWI 3 "nonimmediate_operand")]))]
16303 [(set (reg:CCC FLAGS_REG)
16305 (plus:SWI (match_dup 2) (match_dup 3))
16308 (match_op_dup 1 [(reg:CCC FLAGS_REG) (const_int 0)]))])
16311 [(set (match_operand:QI 0 "nonimmediate_operand")
16312 (match_operator:QI 1 "shr_comparison_operator"
16313 [(match_operand:DI 2 "register_operand")
16314 (match_operand 3 "const_int_operand")]))]
16316 && IN_RANGE (exact_log2 (UINTVAL (operands[3]) + 1), 32, 63)"
16317 [(set (reg:CCZ FLAGS_REG)
16319 (lshiftrt:DI (match_dup 2) (match_dup 4))
16322 (match_op_dup 1 [(reg:CCZ FLAGS_REG) (const_int 0)]))]
16324 enum rtx_code new_code;
16326 operands[1] = shallow_copy_rtx (operands[1]);
16327 switch (GET_CODE (operands[1]))
16329 case GTU: new_code = NE; break;
16330 case LEU: new_code = EQ; break;
16331 default: gcc_unreachable ();
16333 PUT_CODE (operands[1], new_code);
16335 operands[4] = GEN_INT (exact_log2 (UINTVAL (operands[3]) + 1));
16338 ;; For all sCOND expanders, also expand the compare or test insn that
16339 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
16341 (define_insn_and_split "*setcc_di_1"
16342 [(set (match_operand:DI 0 "register_operand" "=q")
16343 (match_operator:DI 1 "ix86_comparison_operator"
16344 [(reg FLAGS_REG) (const_int 0)]))]
16345 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
16347 "&& reload_completed"
16348 [(set (match_dup 2) (match_dup 1))
16349 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
16351 operands[1] = shallow_copy_rtx (operands[1]);
16352 PUT_MODE (operands[1], QImode);
16353 operands[2] = gen_lowpart (QImode, operands[0]);
16356 (define_insn_and_split "*setcc_<mode>_1_and"
16357 [(set (match_operand:SWI24 0 "register_operand" "=q")
16358 (match_operator:SWI24 1 "ix86_comparison_operator"
16359 [(reg FLAGS_REG) (const_int 0)]))
16360 (clobber (reg:CC FLAGS_REG))]
16361 "!TARGET_PARTIAL_REG_STALL
16362 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
16364 "&& reload_completed"
16365 [(set (match_dup 2) (match_dup 1))
16366 (parallel [(set (match_dup 0) (zero_extend:SWI24 (match_dup 2)))
16367 (clobber (reg:CC FLAGS_REG))])]
16369 operands[1] = shallow_copy_rtx (operands[1]);
16370 PUT_MODE (operands[1], QImode);
16371 operands[2] = gen_lowpart (QImode, operands[0]);
16374 (define_insn_and_split "*setcc_<mode>_1_movzbl"
16375 [(set (match_operand:SWI24 0 "register_operand" "=q")
16376 (match_operator:SWI24 1 "ix86_comparison_operator"
16377 [(reg FLAGS_REG) (const_int 0)]))]
16378 "!TARGET_PARTIAL_REG_STALL
16379 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
16381 "&& reload_completed"
16382 [(set (match_dup 2) (match_dup 1))
16383 (set (match_dup 0) (zero_extend:SWI24 (match_dup 2)))]
16385 operands[1] = shallow_copy_rtx (operands[1]);
16386 PUT_MODE (operands[1], QImode);
16387 operands[2] = gen_lowpart (QImode, operands[0]);
16390 (define_insn "*setcc_qi"
16391 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
16392 (match_operator:QI 1 "ix86_comparison_operator"
16393 [(reg FLAGS_REG) (const_int 0)]))]
16396 [(set_attr "type" "setcc")
16397 (set_attr "mode" "QI")])
16399 (define_insn "*setcc_qi_slp"
16400 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+q"))
16401 (match_operator:QI 1 "ix86_comparison_operator"
16402 [(reg FLAGS_REG) (const_int 0)]))]
16405 [(set_attr "type" "setcc")
16406 (set_attr "mode" "QI")])
16408 ;; In general it is not safe to assume too much about CCmode registers,
16409 ;; so simplify-rtx stops when it sees a second one. Under certain
16410 ;; conditions this is safe on x86, so help combine not create
16417 [(set (match_operand:QI 0 "nonimmediate_operand")
16418 (ne:QI (match_operator 1 "ix86_comparison_operator"
16419 [(reg FLAGS_REG) (const_int 0)])
16422 [(set (match_dup 0) (match_dup 1))]
16424 operands[1] = shallow_copy_rtx (operands[1]);
16425 PUT_MODE (operands[1], QImode);
16429 [(set (strict_low_part (match_operand:QI 0 "register_operand"))
16430 (ne:QI (match_operator 1 "ix86_comparison_operator"
16431 [(reg FLAGS_REG) (const_int 0)])
16434 [(set (match_dup 0) (match_dup 1))]
16436 operands[1] = shallow_copy_rtx (operands[1]);
16437 PUT_MODE (operands[1], QImode);
16441 [(set (match_operand:QI 0 "nonimmediate_operand")
16442 (eq:QI (match_operator 1 "ix86_comparison_operator"
16443 [(reg FLAGS_REG) (const_int 0)])
16446 [(set (match_dup 0) (match_dup 1))]
16448 operands[1] = shallow_copy_rtx (operands[1]);
16449 PUT_MODE (operands[1], QImode);
16450 PUT_CODE (operands[1],
16451 ix86_reverse_condition (GET_CODE (operands[1]),
16452 GET_MODE (XEXP (operands[1], 0))));
16454 /* Make sure that (a) the CCmode we have for the flags is strong
16455 enough for the reversed compare or (b) we have a valid FP compare. */
16456 if (! ix86_comparison_operator (operands[1], VOIDmode))
16461 [(set (strict_low_part (match_operand:QI 0 "register_operand"))
16462 (eq:QI (match_operator 1 "ix86_comparison_operator"
16463 [(reg FLAGS_REG) (const_int 0)])
16466 [(set (match_dup 0) (match_dup 1))]
16468 operands[1] = shallow_copy_rtx (operands[1]);
16469 PUT_MODE (operands[1], QImode);
16470 PUT_CODE (operands[1],
16471 ix86_reverse_condition (GET_CODE (operands[1]),
16472 GET_MODE (XEXP (operands[1], 0))));
16474 /* Make sure that (a) the CCmode we have for the flags is strong
16475 enough for the reversed compare or (b) we have a valid FP compare. */
16476 if (! ix86_comparison_operator (operands[1], VOIDmode))
16480 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
16481 ;; subsequent logical operations are used to imitate conditional moves.
16482 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
16485 (define_insn "setcc_<mode>_sse"
16486 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16487 (match_operator:MODEF 3 "sse_comparison_operator"
16488 [(match_operand:MODEF 1 "register_operand" "0,x")
16489 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
16490 "SSE_FLOAT_MODE_P (<MODE>mode)"
16492 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
16493 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16494 [(set_attr "isa" "noavx,avx")
16495 (set_attr "type" "ssecmp")
16496 (set_attr "length_immediate" "1")
16497 (set_attr "prefix" "orig,vex")
16498 (set_attr "mode" "<MODE>")])
16500 (define_insn "setcc_hf_mask"
16501 [(set (match_operand:QI 0 "register_operand" "=k")
16503 [(match_operand:HF 1 "register_operand" "v")
16504 (match_operand:HF 2 "nonimmediate_operand" "vm")
16505 (match_operand:SI 3 "const_0_to_31_operand")]
16507 "TARGET_AVX512FP16"
16508 "vcmpsh\t{%3, %2, %1, %0|%0, %1, %2, %3}"
16509 [(set_attr "type" "ssecmp")
16510 (set_attr "prefix" "evex")
16511 (set_attr "mode" "HF")])
16514 ;; Basic conditional jump instructions.
16519 (match_operator 1 "add_comparison_operator"
16520 [(not:SWI (match_operand:SWI 2 "register_operand"))
16521 (match_operand:SWI 3 "nonimmediate_operand")])
16522 (label_ref (match_operand 0))
16525 [(set (reg:CCC FLAGS_REG)
16527 (plus:SWI (match_dup 2) (match_dup 3))
16530 (if_then_else (match_op_dup 1 [(reg:CCC FLAGS_REG) (const_int 0)])
16531 (label_ref (match_operand 0))
16537 (match_operator 1 "shr_comparison_operator"
16538 [(match_operand:DI 2 "register_operand")
16539 (match_operand 3 "const_int_operand")])
16540 (label_ref (match_operand 0))
16543 && IN_RANGE (exact_log2 (UINTVAL (operands[3]) + 1), 32, 63)"
16544 [(set (reg:CCZ FLAGS_REG)
16546 (lshiftrt:DI (match_dup 2) (match_dup 4))
16549 (if_then_else (match_op_dup 1 [(reg:CCZ FLAGS_REG) (const_int 0)])
16550 (label_ref (match_operand 0))
16553 enum rtx_code new_code;
16555 operands[1] = shallow_copy_rtx (operands[1]);
16556 switch (GET_CODE (operands[1]))
16558 case GTU: new_code = NE; break;
16559 case LEU: new_code = EQ; break;
16560 default: gcc_unreachable ();
16562 PUT_CODE (operands[1], new_code);
16564 operands[4] = GEN_INT (exact_log2 (UINTVAL (operands[3]) + 1));
16567 ;; We ignore the overflow flag for signed branch instructions.
16569 (define_insn "*jcc"
16571 (if_then_else (match_operator 1 "ix86_comparison_operator"
16572 [(reg FLAGS_REG) (const_int 0)])
16573 (label_ref (match_operand 0))
16577 [(set_attr "type" "ibr")
16578 (set_attr "modrm" "0")
16579 (set (attr "length")
16581 (and (ge (minus (match_dup 0) (pc))
16583 (lt (minus (match_dup 0) (pc))
16588 ;; In general it is not safe to assume too much about CCmode registers,
16589 ;; so simplify-rtx stops when it sees a second one. Under certain
16590 ;; conditions this is safe on x86, so help combine not create
16598 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
16599 [(reg FLAGS_REG) (const_int 0)])
16601 (label_ref (match_operand 1))
16605 (if_then_else (match_dup 0)
16606 (label_ref (match_dup 1))
16609 operands[0] = shallow_copy_rtx (operands[0]);
16610 PUT_MODE (operands[0], VOIDmode);
16615 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
16616 [(reg FLAGS_REG) (const_int 0)])
16618 (label_ref (match_operand 1))
16622 (if_then_else (match_dup 0)
16623 (label_ref (match_dup 1))
16626 operands[0] = shallow_copy_rtx (operands[0]);
16627 PUT_MODE (operands[0], VOIDmode);
16628 PUT_CODE (operands[0],
16629 ix86_reverse_condition (GET_CODE (operands[0]),
16630 GET_MODE (XEXP (operands[0], 0))));
16632 /* Make sure that (a) the CCmode we have for the flags is strong
16633 enough for the reversed compare or (b) we have a valid FP compare. */
16634 if (! ix86_comparison_operator (operands[0], VOIDmode))
16638 ;; Unconditional and other jump instructions
16640 (define_insn "jump"
16642 (label_ref (match_operand 0)))]
16645 [(set_attr "type" "ibr")
16646 (set_attr "modrm" "0")
16647 (set (attr "length")
16649 (and (ge (minus (match_dup 0) (pc))
16651 (lt (minus (match_dup 0) (pc))
16656 (define_expand "indirect_jump"
16657 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
16660 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
16661 operands[0] = convert_memory_address (word_mode, operands[0]);
16662 cfun->machine->has_local_indirect_jump = true;
16665 (define_insn "*indirect_jump"
16666 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
16668 "* return ix86_output_indirect_jmp (operands[0]);"
16669 [(set (attr "type")
16670 (if_then_else (match_test "(cfun->machine->indirect_branch_type
16671 != indirect_branch_keep)")
16672 (const_string "multi")
16673 (const_string "ibr")))
16674 (set_attr "length_immediate" "0")])
16676 (define_expand "tablejump"
16677 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
16678 (use (label_ref (match_operand 1)))])]
16681 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
16682 relative. Convert the relative address to an absolute address. */
16686 enum rtx_code code;
16688 /* We can't use @GOTOFF for text labels on VxWorks;
16689 see gotoff_operand. */
16690 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
16694 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
16696 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
16700 op1 = pic_offset_table_rtx;
16705 op0 = pic_offset_table_rtx;
16709 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
16713 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
16714 operands[0] = convert_memory_address (word_mode, operands[0]);
16715 cfun->machine->has_local_indirect_jump = true;
16718 (define_insn "*tablejump_1"
16719 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
16720 (use (label_ref (match_operand 1)))]
16722 "* return ix86_output_indirect_jmp (operands[0]);"
16723 [(set (attr "type")
16724 (if_then_else (match_test "(cfun->machine->indirect_branch_type
16725 != indirect_branch_keep)")
16726 (const_string "multi")
16727 (const_string "ibr")))
16728 (set_attr "length_immediate" "0")])
16730 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
16733 [(set (match_operand 4 "flags_reg_operand") (match_operand 0))
16734 (set (match_operand:QI 1 "register_operand")
16735 (match_operator:QI 2 "ix86_comparison_operator"
16736 [(reg FLAGS_REG) (const_int 0)]))
16737 (set (match_operand 3 "any_QIreg_operand")
16738 (zero_extend (match_dup 1)))]
16739 "(peep2_reg_dead_p (3, operands[1])
16740 || operands_match_p (operands[1], operands[3]))
16741 && ! reg_overlap_mentioned_p (operands[3], operands[0])
16742 && peep2_regno_dead_p (0, FLAGS_REG)"
16743 [(set (match_dup 4) (match_dup 0))
16744 (set (strict_low_part (match_dup 5))
16747 operands[5] = gen_lowpart (QImode, operands[3]);
16748 ix86_expand_clear (operands[3]);
16752 [(parallel [(set (match_operand 5 "flags_reg_operand") (match_operand 0))
16753 (match_operand 4)])
16754 (set (match_operand:QI 1 "register_operand")
16755 (match_operator:QI 2 "ix86_comparison_operator"
16756 [(reg FLAGS_REG) (const_int 0)]))
16757 (set (match_operand 3 "any_QIreg_operand")
16758 (zero_extend (match_dup 1)))]
16759 "(peep2_reg_dead_p (3, operands[1])
16760 || operands_match_p (operands[1], operands[3]))
16761 && ! reg_overlap_mentioned_p (operands[3], operands[0])
16762 && ! reg_overlap_mentioned_p (operands[3], operands[4])
16763 && ! reg_set_p (operands[3], operands[4])
16764 && peep2_regno_dead_p (0, FLAGS_REG)"
16765 [(parallel [(set (match_dup 5) (match_dup 0))
16767 (set (strict_low_part (match_dup 6))
16770 operands[6] = gen_lowpart (QImode, operands[3]);
16771 ix86_expand_clear (operands[3]);
16775 [(set (match_operand 6 "flags_reg_operand") (match_operand 0))
16776 (parallel [(set (match_operand 7 "flags_reg_operand") (match_operand 1))
16777 (match_operand 5)])
16778 (set (match_operand:QI 2 "register_operand")
16779 (match_operator:QI 3 "ix86_comparison_operator"
16780 [(reg FLAGS_REG) (const_int 0)]))
16781 (set (match_operand 4 "any_QIreg_operand")
16782 (zero_extend (match_dup 2)))]
16783 "(peep2_reg_dead_p (4, operands[2])
16784 || operands_match_p (operands[2], operands[4]))
16785 && ! reg_overlap_mentioned_p (operands[4], operands[0])
16786 && ! reg_overlap_mentioned_p (operands[4], operands[1])
16787 && ! reg_overlap_mentioned_p (operands[4], operands[5])
16788 && ! reg_set_p (operands[4], operands[5])
16789 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
16790 && peep2_regno_dead_p (0, FLAGS_REG)"
16791 [(set (match_dup 6) (match_dup 0))
16792 (parallel [(set (match_dup 7) (match_dup 1))
16794 (set (strict_low_part (match_dup 8))
16797 operands[8] = gen_lowpart (QImode, operands[4]);
16798 ix86_expand_clear (operands[4]);
16801 ;; Similar, but match zero extend with andsi3.
16804 [(set (match_operand 4 "flags_reg_operand") (match_operand 0))
16805 (set (match_operand:QI 1 "register_operand")
16806 (match_operator:QI 2 "ix86_comparison_operator"
16807 [(reg FLAGS_REG) (const_int 0)]))
16808 (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
16809 (and:SI (match_dup 3) (const_int 255)))
16810 (clobber (reg:CC FLAGS_REG))])]
16811 "REGNO (operands[1]) == REGNO (operands[3])
16812 && ! reg_overlap_mentioned_p (operands[3], operands[0])
16813 && peep2_regno_dead_p (0, FLAGS_REG)"
16814 [(set (match_dup 4) (match_dup 0))
16815 (set (strict_low_part (match_dup 5))
16818 operands[5] = gen_lowpart (QImode, operands[3]);
16819 ix86_expand_clear (operands[3]);
16823 [(parallel [(set (match_operand 5 "flags_reg_operand") (match_operand 0))
16824 (match_operand 4)])
16825 (set (match_operand:QI 1 "register_operand")
16826 (match_operator:QI 2 "ix86_comparison_operator"
16827 [(reg FLAGS_REG) (const_int 0)]))
16828 (parallel [(set (match_operand 3 "any_QIreg_operand")
16829 (zero_extend (match_dup 1)))
16830 (clobber (reg:CC FLAGS_REG))])]
16831 "(peep2_reg_dead_p (3, operands[1])
16832 || operands_match_p (operands[1], operands[3]))
16833 && ! reg_overlap_mentioned_p (operands[3], operands[0])
16834 && ! reg_overlap_mentioned_p (operands[3], operands[4])
16835 && ! reg_set_p (operands[3], operands[4])
16836 && peep2_regno_dead_p (0, FLAGS_REG)"
16837 [(parallel [(set (match_dup 5) (match_dup 0))
16839 (set (strict_low_part (match_dup 6))
16842 operands[6] = gen_lowpart (QImode, operands[3]);
16843 ix86_expand_clear (operands[3]);
16847 [(set (match_operand 6 "flags_reg_operand") (match_operand 0))
16848 (parallel [(set (match_operand 7 "flags_reg_operand") (match_operand 1))
16849 (match_operand 5)])
16850 (set (match_operand:QI 2 "register_operand")
16851 (match_operator:QI 3 "ix86_comparison_operator"
16852 [(reg FLAGS_REG) (const_int 0)]))
16853 (parallel [(set (match_operand 4 "any_QIreg_operand")
16854 (zero_extend (match_dup 2)))
16855 (clobber (reg:CC FLAGS_REG))])]
16856 "(peep2_reg_dead_p (4, operands[2])
16857 || operands_match_p (operands[2], operands[4]))
16858 && ! reg_overlap_mentioned_p (operands[4], operands[0])
16859 && ! reg_overlap_mentioned_p (operands[4], operands[1])
16860 && ! reg_overlap_mentioned_p (operands[4], operands[5])
16861 && ! reg_set_p (operands[4], operands[5])
16862 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
16863 && peep2_regno_dead_p (0, FLAGS_REG)"
16864 [(set (match_dup 6) (match_dup 0))
16865 (parallel [(set (match_dup 7) (match_dup 1))
16867 (set (strict_low_part (match_dup 8))
16870 operands[8] = gen_lowpart (QImode, operands[4]);
16871 ix86_expand_clear (operands[4]);
16874 ;; Call instructions.
16876 ;; The predicates normally associated with named expanders are not properly
16877 ;; checked for calls. This is a bug in the generic code, but it isn't that
16878 ;; easy to fix. Ignore it for now and be prepared to fix things up.
16880 ;; P6 processors will jump to the address after the decrement when %esp
16881 ;; is used as a call operand, so they will execute return address as a code.
16882 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
16884 ;; Register constraint for call instruction.
16885 (define_mode_attr c [(SI "l") (DI "r")])
16887 ;; Call subroutine returning no value.
16889 (define_expand "call"
16890 [(call (match_operand:QI 0)
16892 (use (match_operand 2))]
16895 ix86_expand_call (NULL, operands[0], operands[1],
16896 operands[2], NULL, false);
16900 (define_expand "sibcall"
16901 [(call (match_operand:QI 0)
16903 (use (match_operand 2))]
16906 ix86_expand_call (NULL, operands[0], operands[1],
16907 operands[2], NULL, true);
16911 (define_insn "*call"
16912 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
16913 (match_operand 1))]
16914 "!SIBLING_CALL_P (insn)"
16915 "* return ix86_output_call_insn (insn, operands[0]);"
16916 [(set_attr "type" "call")])
16918 ;; This covers both call and sibcall since only GOT slot is allowed.
16919 (define_insn "*call_got_x32"
16920 [(call (mem:QI (zero_extend:DI
16921 (match_operand:SI 0 "GOT_memory_operand" "Bg")))
16922 (match_operand 1))]
16925 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
16926 return ix86_output_call_insn (insn, fnaddr);
16928 [(set_attr "type" "call")])
16930 ;; Since sibcall never returns, we can only use call-clobbered register
16932 (define_insn "*sibcall_GOT_32"
16935 (match_operand:SI 0 "register_no_elim_operand" "U")
16936 (match_operand:SI 1 "GOT32_symbol_operand"))))
16937 (match_operand 2))]
16940 && !TARGET_INDIRECT_BRANCH_REGISTER
16941 && SIBLING_CALL_P (insn)"
16943 rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
16944 fnaddr = gen_const_mem (SImode, fnaddr);
16945 return ix86_output_call_insn (insn, fnaddr);
16947 [(set_attr "type" "call")])
16949 (define_insn "*sibcall"
16950 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
16951 (match_operand 1))]
16952 "SIBLING_CALL_P (insn)"
16953 "* return ix86_output_call_insn (insn, operands[0]);"
16954 [(set_attr "type" "call")])
16956 (define_insn "*sibcall_memory"
16957 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
16959 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
16960 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
16961 "* return ix86_output_call_insn (insn, operands[0]);"
16962 [(set_attr "type" "call")])
16965 [(set (match_operand:W 0 "register_operand")
16966 (match_operand:W 1 "memory_operand"))
16967 (call (mem:QI (match_dup 0))
16968 (match_operand 3))]
16970 && !TARGET_INDIRECT_BRANCH_REGISTER
16971 && SIBLING_CALL_P (peep2_next_insn (1))
16972 && !reg_mentioned_p (operands[0],
16973 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
16974 [(parallel [(call (mem:QI (match_dup 1))
16976 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
16979 [(set (match_operand:W 0 "register_operand")
16980 (match_operand:W 1 "memory_operand"))
16981 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
16982 (call (mem:QI (match_dup 0))
16983 (match_operand 3))]
16985 && !TARGET_INDIRECT_BRANCH_REGISTER
16986 && SIBLING_CALL_P (peep2_next_insn (2))
16987 && !reg_mentioned_p (operands[0],
16988 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
16989 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
16990 (parallel [(call (mem:QI (match_dup 1))
16992 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
16994 (define_expand "call_pop"
16995 [(parallel [(call (match_operand:QI 0)
16996 (match_operand:SI 1))
16997 (set (reg:SI SP_REG)
16998 (plus:SI (reg:SI SP_REG)
16999 (match_operand:SI 3)))])]
17002 ix86_expand_call (NULL, operands[0], operands[1],
17003 operands[2], operands[3], false);
17007 (define_insn "*call_pop"
17008 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz"))
17010 (set (reg:SI SP_REG)
17011 (plus:SI (reg:SI SP_REG)
17012 (match_operand:SI 2 "immediate_operand" "i")))]
17013 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17014 "* return ix86_output_call_insn (insn, operands[0]);"
17015 [(set_attr "type" "call")])
17017 (define_insn "*sibcall_pop"
17018 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
17020 (set (reg:SI SP_REG)
17021 (plus:SI (reg:SI SP_REG)
17022 (match_operand:SI 2 "immediate_operand" "i")))]
17023 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17024 "* return ix86_output_call_insn (insn, operands[0]);"
17025 [(set_attr "type" "call")])
17027 (define_insn "*sibcall_pop_memory"
17028 [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs"))
17030 (set (reg:SI SP_REG)
17031 (plus:SI (reg:SI SP_REG)
17032 (match_operand:SI 2 "immediate_operand" "i")))
17033 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17035 "* return ix86_output_call_insn (insn, operands[0]);"
17036 [(set_attr "type" "call")])
17039 [(set (match_operand:SI 0 "register_operand")
17040 (match_operand:SI 1 "memory_operand"))
17041 (parallel [(call (mem:QI (match_dup 0))
17043 (set (reg:SI SP_REG)
17044 (plus:SI (reg:SI SP_REG)
17045 (match_operand:SI 4 "immediate_operand")))])]
17046 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
17047 && !reg_mentioned_p (operands[0],
17048 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17049 [(parallel [(call (mem:QI (match_dup 1))
17051 (set (reg:SI SP_REG)
17052 (plus:SI (reg:SI SP_REG)
17054 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17057 [(set (match_operand:SI 0 "register_operand")
17058 (match_operand:SI 1 "memory_operand"))
17059 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17060 (parallel [(call (mem:QI (match_dup 0))
17062 (set (reg:SI SP_REG)
17063 (plus:SI (reg:SI SP_REG)
17064 (match_operand:SI 4 "immediate_operand")))])]
17065 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
17066 && !reg_mentioned_p (operands[0],
17067 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17068 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17069 (parallel [(call (mem:QI (match_dup 1))
17071 (set (reg:SI SP_REG)
17072 (plus:SI (reg:SI SP_REG)
17074 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17076 ;; Combining simple memory jump instruction
17079 [(set (match_operand:W 0 "register_operand")
17080 (match_operand:W 1 "memory_operand"))
17081 (set (pc) (match_dup 0))]
17083 && !TARGET_INDIRECT_BRANCH_REGISTER
17084 && peep2_reg_dead_p (2, operands[0])"
17085 [(set (pc) (match_dup 1))])
17087 ;; Call subroutine, returning value in operand 0
17089 (define_expand "call_value"
17090 [(set (match_operand 0)
17091 (call (match_operand:QI 1)
17092 (match_operand 2)))
17093 (use (match_operand 3))]
17096 ix86_expand_call (operands[0], operands[1], operands[2],
17097 operands[3], NULL, false);
17101 (define_expand "sibcall_value"
17102 [(set (match_operand 0)
17103 (call (match_operand:QI 1)
17104 (match_operand 2)))
17105 (use (match_operand 3))]
17108 ix86_expand_call (operands[0], operands[1], operands[2],
17109 operands[3], NULL, true);
17113 (define_insn "*call_value"
17114 [(set (match_operand 0)
17115 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
17116 (match_operand 2)))]
17117 "!SIBLING_CALL_P (insn)"
17118 "* return ix86_output_call_insn (insn, operands[1]);"
17119 [(set_attr "type" "callv")])
17121 ;; This covers both call and sibcall since only GOT slot is allowed.
17122 (define_insn "*call_value_got_x32"
17123 [(set (match_operand 0)
17126 (match_operand:SI 1 "GOT_memory_operand" "Bg")))
17127 (match_operand 2)))]
17130 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
17131 return ix86_output_call_insn (insn, fnaddr);
17133 [(set_attr "type" "callv")])
17135 ;; Since sibcall never returns, we can only use call-clobbered register
17137 (define_insn "*sibcall_value_GOT_32"
17138 [(set (match_operand 0)
17141 (match_operand:SI 1 "register_no_elim_operand" "U")
17142 (match_operand:SI 2 "GOT32_symbol_operand"))))
17143 (match_operand 3)))]
17146 && !TARGET_INDIRECT_BRANCH_REGISTER
17147 && SIBLING_CALL_P (insn)"
17149 rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
17150 fnaddr = gen_const_mem (SImode, fnaddr);
17151 return ix86_output_call_insn (insn, fnaddr);
17153 [(set_attr "type" "callv")])
17155 (define_insn "*sibcall_value"
17156 [(set (match_operand 0)
17157 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
17158 (match_operand 2)))]
17159 "SIBLING_CALL_P (insn)"
17160 "* return ix86_output_call_insn (insn, operands[1]);"
17161 [(set_attr "type" "callv")])
17163 (define_insn "*sibcall_value_memory"
17164 [(set (match_operand 0)
17165 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
17166 (match_operand 2)))
17167 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17168 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
17169 "* return ix86_output_call_insn (insn, operands[1]);"
17170 [(set_attr "type" "callv")])
17173 [(set (match_operand:W 0 "register_operand")
17174 (match_operand:W 1 "memory_operand"))
17175 (set (match_operand 2)
17176 (call (mem:QI (match_dup 0))
17177 (match_operand 3)))]
17179 && !TARGET_INDIRECT_BRANCH_REGISTER
17180 && SIBLING_CALL_P (peep2_next_insn (1))
17181 && !reg_mentioned_p (operands[0],
17182 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17183 [(parallel [(set (match_dup 2)
17184 (call (mem:QI (match_dup 1))
17186 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17189 [(set (match_operand:W 0 "register_operand")
17190 (match_operand:W 1 "memory_operand"))
17191 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17192 (set (match_operand 2)
17193 (call (mem:QI (match_dup 0))
17194 (match_operand 3)))]
17196 && !TARGET_INDIRECT_BRANCH_REGISTER
17197 && SIBLING_CALL_P (peep2_next_insn (2))
17198 && !reg_mentioned_p (operands[0],
17199 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17200 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17201 (parallel [(set (match_dup 2)
17202 (call (mem:QI (match_dup 1))
17204 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17206 (define_expand "call_value_pop"
17207 [(parallel [(set (match_operand 0)
17208 (call (match_operand:QI 1)
17209 (match_operand:SI 2)))
17210 (set (reg:SI SP_REG)
17211 (plus:SI (reg:SI SP_REG)
17212 (match_operand:SI 4)))])]
17215 ix86_expand_call (operands[0], operands[1], operands[2],
17216 operands[3], operands[4], false);
17220 (define_insn "*call_value_pop"
17221 [(set (match_operand 0)
17222 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz"))
17223 (match_operand 2)))
17224 (set (reg:SI SP_REG)
17225 (plus:SI (reg:SI SP_REG)
17226 (match_operand:SI 3 "immediate_operand" "i")))]
17227 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17228 "* return ix86_output_call_insn (insn, operands[1]);"
17229 [(set_attr "type" "callv")])
17231 (define_insn "*sibcall_value_pop"
17232 [(set (match_operand 0)
17233 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
17234 (match_operand 2)))
17235 (set (reg:SI SP_REG)
17236 (plus:SI (reg:SI SP_REG)
17237 (match_operand:SI 3 "immediate_operand" "i")))]
17238 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17239 "* return ix86_output_call_insn (insn, operands[1]);"
17240 [(set_attr "type" "callv")])
17242 (define_insn "*sibcall_value_pop_memory"
17243 [(set (match_operand 0)
17244 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
17245 (match_operand 2)))
17246 (set (reg:SI SP_REG)
17247 (plus:SI (reg:SI SP_REG)
17248 (match_operand:SI 3 "immediate_operand" "i")))
17249 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17251 "* return ix86_output_call_insn (insn, operands[1]);"
17252 [(set_attr "type" "callv")])
17255 [(set (match_operand:SI 0 "register_operand")
17256 (match_operand:SI 1 "memory_operand"))
17257 (parallel [(set (match_operand 2)
17258 (call (mem:QI (match_dup 0))
17259 (match_operand 3)))
17260 (set (reg:SI SP_REG)
17261 (plus:SI (reg:SI SP_REG)
17262 (match_operand:SI 4 "immediate_operand")))])]
17263 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
17264 && !reg_mentioned_p (operands[0],
17265 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17266 [(parallel [(set (match_dup 2)
17267 (call (mem:QI (match_dup 1))
17269 (set (reg:SI SP_REG)
17270 (plus:SI (reg:SI SP_REG)
17272 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17275 [(set (match_operand:SI 0 "register_operand")
17276 (match_operand:SI 1 "memory_operand"))
17277 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17278 (parallel [(set (match_operand 2)
17279 (call (mem:QI (match_dup 0))
17280 (match_operand 3)))
17281 (set (reg:SI SP_REG)
17282 (plus:SI (reg:SI SP_REG)
17283 (match_operand:SI 4 "immediate_operand")))])]
17284 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
17285 && !reg_mentioned_p (operands[0],
17286 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17287 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17288 (parallel [(set (match_dup 2)
17289 (call (mem:QI (match_dup 1))
17291 (set (reg:SI SP_REG)
17292 (plus:SI (reg:SI SP_REG)
17294 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17296 ;; Call subroutine returning any type.
17298 (define_expand "untyped_call"
17299 [(parallel [(call (match_operand 0)
17302 (match_operand 2)])]
17307 /* In order to give reg-stack an easier job in validating two
17308 coprocessor registers as containing a possible return value,
17309 simply pretend the untyped call returns a complex long double
17312 We can't use SSE_REGPARM_MAX here since callee is unprototyped
17313 and should have the default ABI. */
17315 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
17316 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
17317 operands[0], const0_rtx,
17318 GEN_INT ((TARGET_64BIT
17319 ? (ix86_abi == SYSV_ABI
17320 ? X86_64_SSE_REGPARM_MAX
17321 : X86_64_MS_SSE_REGPARM_MAX)
17322 : X86_32_SSE_REGPARM_MAX)
17326 for (i = 0; i < XVECLEN (operands[2], 0); i++)
17328 rtx set = XVECEXP (operands[2], 0, i);
17329 emit_move_insn (SET_DEST (set), SET_SRC (set));
17332 /* The optimizer does not know that the call sets the function value
17333 registers we stored in the result block. We avoid problems by
17334 claiming that all hard registers are used and clobbered at this
17336 emit_insn (gen_blockage ());
17341 ;; Prologue and epilogue instructions
17343 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
17344 ;; all of memory. This blocks insns from being moved across this point.
17346 (define_insn "blockage"
17347 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
17350 [(set_attr "length" "0")])
17352 ;; Do not schedule instructions accessing memory across this point.
17354 (define_expand "memory_blockage"
17355 [(set (match_dup 0)
17356 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
17359 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
17360 MEM_VOLATILE_P (operands[0]) = 1;
17363 (define_insn "*memory_blockage"
17364 [(set (match_operand:BLK 0)
17365 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
17368 [(set_attr "length" "0")])
17370 ;; As USE insns aren't meaningful after reload, this is used instead
17371 ;; to prevent deleting instructions setting registers for PIC code
17372 (define_insn "prologue_use"
17373 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
17376 [(set_attr "length" "0")])
17378 ;; Insn emitted into the body of a function to return from a function.
17379 ;; This is only done if the function's epilogue is known to be simple.
17380 ;; See comments for ix86_can_use_return_insn_p in i386.cc.
17382 (define_expand "return"
17384 "ix86_can_use_return_insn_p ()"
17386 if (crtl->args.pops_args)
17388 rtx popc = GEN_INT (crtl->args.pops_args);
17389 emit_jump_insn (gen_simple_return_pop_internal (popc));
17394 ;; We need to disable this for TARGET_SEH, as otherwise
17395 ;; shrink-wrapped prologue gets enabled too. This might exceed
17396 ;; the maximum size of prologue in unwind information.
17397 ;; Also disallow shrink-wrapping if using stack slot to pass the
17398 ;; static chain pointer - the first instruction has to be pushl %esi
17399 ;; and it can't be moved around, as we use alternate entry points
17401 ;; Also disallow for ms_hook_prologue functions which have frame
17402 ;; pointer set up in function label which is correctly handled in
17403 ;; ix86_expand_{prologue|epligoue}() only.
17405 (define_expand "simple_return"
17407 "!TARGET_SEH && !ix86_static_chain_on_stack && !ix86_function_ms_hook_prologue (cfun->decl)"
17409 if (crtl->args.pops_args)
17411 rtx popc = GEN_INT (crtl->args.pops_args);
17412 emit_jump_insn (gen_simple_return_pop_internal (popc));
17417 (define_insn "simple_return_internal"
17420 "* return ix86_output_function_return (false);"
17421 [(set_attr "length" "1")
17422 (set_attr "atom_unit" "jeu")
17423 (set_attr "length_immediate" "0")
17424 (set_attr "modrm" "0")])
17426 (define_insn "interrupt_return"
17428 (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
17431 return TARGET_64BIT ? (TARGET_UINTR ? "uiret" : "iretq") : "iret";
17434 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
17435 ;; instruction Athlon and K8 have.
17437 (define_insn "simple_return_internal_long"
17439 (unspec [(const_int 0)] UNSPEC_REP)]
17441 "* return ix86_output_function_return (true);"
17442 [(set_attr "length" "2")
17443 (set_attr "atom_unit" "jeu")
17444 (set_attr "length_immediate" "0")
17445 (set_attr "prefix_rep" "1")
17446 (set_attr "modrm" "0")])
17448 (define_insn_and_split "simple_return_pop_internal"
17450 (use (match_operand:SI 0 "const_int_operand"))]
17453 "&& cfun->machine->function_return_type != indirect_branch_keep"
17455 "ix86_split_simple_return_pop_internal (operands[0]); DONE;"
17456 [(set_attr "length" "3")
17457 (set_attr "atom_unit" "jeu")
17458 (set_attr "length_immediate" "2")
17459 (set_attr "modrm" "0")])
17461 (define_expand "simple_return_indirect_internal"
17464 (use (match_operand 0 "register_operand"))])])
17466 (define_insn "*simple_return_indirect_internal<mode>"
17468 (use (match_operand:W 0 "register_operand" "r"))]
17470 "* return ix86_output_indirect_function_return (operands[0]);"
17471 [(set (attr "type")
17472 (if_then_else (match_test "(cfun->machine->indirect_branch_type
17473 != indirect_branch_keep)")
17474 (const_string "multi")
17475 (const_string "ibr")))
17476 (set_attr "length_immediate" "0")])
17482 [(set_attr "length" "1")
17483 (set_attr "length_immediate" "0")
17484 (set_attr "modrm" "0")])
17486 ;; Generate nops. Operand 0 is the number of nops, up to 8.
17487 (define_insn "nops"
17488 [(unspec_volatile [(match_operand 0 "const_int_operand")]
17492 int num = INTVAL (operands[0]);
17494 gcc_assert (IN_RANGE (num, 1, 8));
17497 fputs ("\tnop\n", asm_out_file);
17501 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
17502 (set_attr "length_immediate" "0")
17503 (set_attr "modrm" "0")])
17505 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
17506 ;; branch prediction penalty for the third jump in a 16-byte
17510 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
17513 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
17514 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
17516 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
17517 The align insn is used to avoid 3 jump instructions in the row to improve
17518 branch prediction and the benefits hardly outweigh the cost of extra 8
17519 nops on the average inserted by full alignment pseudo operation. */
17523 [(set_attr "length" "16")])
17525 (define_expand "prologue"
17528 "ix86_expand_prologue (); DONE;")
17530 (define_expand "set_got"
17532 [(set (match_operand:SI 0 "register_operand")
17533 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
17534 (clobber (reg:CC FLAGS_REG))])]
17537 if (flag_pic && !TARGET_VXWORKS_RTP)
17538 ix86_pc_thunk_call_expanded = true;
17541 (define_insn "*set_got"
17542 [(set (match_operand:SI 0 "register_operand" "=r")
17543 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
17544 (clobber (reg:CC FLAGS_REG))]
17546 "* return output_set_got (operands[0], NULL_RTX);"
17547 [(set_attr "type" "multi")
17548 (set_attr "length" "12")])
17550 (define_expand "set_got_labelled"
17552 [(set (match_operand:SI 0 "register_operand")
17553 (unspec:SI [(label_ref (match_operand 1))]
17555 (clobber (reg:CC FLAGS_REG))])]
17558 if (flag_pic && !TARGET_VXWORKS_RTP)
17559 ix86_pc_thunk_call_expanded = true;
17562 (define_insn "*set_got_labelled"
17563 [(set (match_operand:SI 0 "register_operand" "=r")
17564 (unspec:SI [(label_ref (match_operand 1))]
17566 (clobber (reg:CC FLAGS_REG))]
17568 "* return output_set_got (operands[0], operands[1]);"
17569 [(set_attr "type" "multi")
17570 (set_attr "length" "12")])
17572 (define_insn "set_got_rex64"
17573 [(set (match_operand:DI 0 "register_operand" "=r")
17574 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
17576 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
17577 [(set_attr "type" "lea")
17578 (set_attr "length_address" "4")
17579 (set_attr "mode" "DI")])
17581 (define_insn "set_rip_rex64"
17582 [(set (match_operand:DI 0 "register_operand" "=r")
17583 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
17585 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
17586 [(set_attr "type" "lea")
17587 (set_attr "length_address" "4")
17588 (set_attr "mode" "DI")])
17590 (define_insn "set_got_offset_rex64"
17591 [(set (match_operand:DI 0 "register_operand" "=r")
17593 [(label_ref (match_operand 1))]
17594 UNSPEC_SET_GOT_OFFSET))]
17596 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
17597 [(set_attr "type" "imov")
17598 (set_attr "length_immediate" "0")
17599 (set_attr "length_address" "8")
17600 (set_attr "mode" "DI")])
17602 (define_expand "epilogue"
17605 "ix86_expand_epilogue (1); DONE;")
17607 (define_expand "sibcall_epilogue"
17610 "ix86_expand_epilogue (0); DONE;")
17612 (define_expand "eh_return"
17613 [(use (match_operand 0 "register_operand"))]
17616 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
17618 /* Tricky bit: we write the address of the handler to which we will
17619 be returning into someone else's stack frame, one word below the
17620 stack address we wish to restore. */
17621 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
17622 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
17623 /* Return address is always in word_mode. */
17624 tmp = gen_rtx_MEM (word_mode, tmp);
17625 if (GET_MODE (ra) != word_mode)
17626 ra = convert_to_mode (word_mode, ra, 1);
17627 emit_move_insn (tmp, ra);
17629 emit_jump_insn (gen_eh_return_internal ());
17634 (define_insn_and_split "eh_return_internal"
17638 "epilogue_completed"
17640 "ix86_expand_epilogue (2); DONE;")
17642 (define_expand "@leave_<mode>"
17644 [(set (reg:W SP_REG) (plus:W (reg:W BP_REG) (match_dup 0)))
17645 (set (reg:W BP_REG) (mem:W (reg:W BP_REG)))
17646 (clobber (mem:BLK (scratch)))])]
17648 "operands[0] = GEN_INT (<MODE_SIZE>);")
17650 (define_insn "*leave"
17651 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
17652 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
17653 (clobber (mem:BLK (scratch)))]
17656 [(set_attr "type" "leave")])
17658 (define_insn "*leave_rex64"
17659 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
17660 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
17661 (clobber (mem:BLK (scratch)))]
17664 [(set_attr "type" "leave")])
17666 ;; Handle -fsplit-stack.
17668 (define_expand "split_stack_prologue"
17672 ix86_expand_split_stack_prologue ();
17676 ;; In order to support the call/return predictor, we use a return
17677 ;; instruction which the middle-end doesn't see.
17678 (define_insn "split_stack_return"
17679 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
17680 UNSPECV_SPLIT_STACK_RETURN)]
17683 if (operands[0] == const0_rtx)
17688 [(set_attr "atom_unit" "jeu")
17689 (set_attr "modrm" "0")
17690 (set (attr "length")
17691 (if_then_else (match_operand:SI 0 "const0_operand")
17694 (set (attr "length_immediate")
17695 (if_then_else (match_operand:SI 0 "const0_operand")
17699 ;; If there are operand 0 bytes available on the stack, jump to
17702 (define_expand "split_stack_space_check"
17703 [(set (pc) (if_then_else
17704 (ltu (minus (reg SP_REG)
17705 (match_operand 0 "register_operand"))
17707 (label_ref (match_operand 1))
17711 rtx reg = gen_reg_rtx (Pmode);
17713 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, operands[0]));
17715 operands[2] = ix86_split_stack_guard ();
17716 ix86_expand_branch (GEU, reg, operands[2], operands[1]);
17721 ;; Bit manipulation instructions.
17723 (define_expand "ffs<mode>2"
17724 [(set (match_dup 2) (const_int -1))
17725 (parallel [(set (match_dup 3) (match_dup 4))
17726 (set (match_operand:SWI48 0 "register_operand")
17728 (match_operand:SWI48 1 "nonimmediate_operand")))])
17729 (set (match_dup 0) (if_then_else:SWI48
17730 (eq (match_dup 3) (const_int 0))
17733 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
17734 (clobber (reg:CC FLAGS_REG))])]
17737 machine_mode flags_mode;
17739 if (<MODE>mode == SImode && !TARGET_CMOVE)
17741 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
17745 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
17747 operands[2] = gen_reg_rtx (<MODE>mode);
17748 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
17749 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
17752 (define_insn_and_split "ffssi2_no_cmove"
17753 [(set (match_operand:SI 0 "register_operand" "=r")
17754 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
17755 (clobber (match_scratch:SI 2 "=&q"))
17756 (clobber (reg:CC FLAGS_REG))]
17759 "&& reload_completed"
17760 [(parallel [(set (match_dup 4) (match_dup 5))
17761 (set (match_dup 0) (ctz:SI (match_dup 1)))])
17762 (set (strict_low_part (match_dup 3))
17763 (eq:QI (match_dup 4) (const_int 0)))
17764 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
17765 (clobber (reg:CC FLAGS_REG))])
17766 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
17767 (clobber (reg:CC FLAGS_REG))])
17768 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
17769 (clobber (reg:CC FLAGS_REG))])]
17771 machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
17773 operands[3] = gen_lowpart (QImode, operands[2]);
17774 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
17775 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
17777 ix86_expand_clear (operands[2]);
17780 (define_insn_and_split "*tzcnt<mode>_1"
17781 [(set (reg:CCC FLAGS_REG)
17782 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
17784 (set (match_operand:SWI48 0 "register_operand" "=r")
17785 (ctz:SWI48 (match_dup 1)))]
17787 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
17788 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
17789 && optimize_function_for_speed_p (cfun)
17790 && !reg_mentioned_p (operands[0], operands[1])"
17792 [(set (reg:CCC FLAGS_REG)
17793 (compare:CCC (match_dup 1) (const_int 0)))
17795 (ctz:SWI48 (match_dup 1)))
17796 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
17797 "ix86_expand_clear (operands[0]);"
17798 [(set_attr "type" "alu1")
17799 (set_attr "prefix_0f" "1")
17800 (set_attr "prefix_rep" "1")
17801 (set_attr "btver2_decode" "double")
17802 (set_attr "mode" "<MODE>")])
17804 ; False dependency happens when destination is only updated by tzcnt,
17805 ; lzcnt or popcnt. There is no false dependency when destination is
17806 ; also used in source.
17807 (define_insn "*tzcnt<mode>_1_falsedep"
17808 [(set (reg:CCC FLAGS_REG)
17809 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
17811 (set (match_operand:SWI48 0 "register_operand" "=r")
17812 (ctz:SWI48 (match_dup 1)))
17813 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
17814 UNSPEC_INSN_FALSE_DEP)]
17816 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
17817 [(set_attr "type" "alu1")
17818 (set_attr "prefix_0f" "1")
17819 (set_attr "prefix_rep" "1")
17820 (set_attr "btver2_decode" "double")
17821 (set_attr "mode" "<MODE>")])
17823 (define_insn "*bsf<mode>_1"
17824 [(set (reg:CCZ FLAGS_REG)
17825 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
17827 (set (match_operand:SWI48 0 "register_operand" "=r")
17828 (ctz:SWI48 (match_dup 1)))]
17830 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
17831 [(set_attr "type" "alu1")
17832 (set_attr "prefix_0f" "1")
17833 (set_attr "btver2_decode" "double")
17834 (set_attr "znver1_decode" "vector")
17835 (set_attr "mode" "<MODE>")])
17837 (define_insn_and_split "ctz<mode>2"
17838 [(set (match_operand:SWI48 0 "register_operand" "=r")
17840 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
17841 (clobber (reg:CC FLAGS_REG))]
17845 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
17846 else if (optimize_function_for_size_p (cfun))
17848 else if (TARGET_CPU_P (GENERIC))
17849 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
17850 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
17852 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
17854 "(TARGET_BMI || TARGET_CPU_P (GENERIC))
17855 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
17856 && optimize_function_for_speed_p (cfun)
17857 && !reg_mentioned_p (operands[0], operands[1])"
17859 [(set (match_dup 0)
17860 (ctz:SWI48 (match_dup 1)))
17861 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
17862 (clobber (reg:CC FLAGS_REG))])]
17863 "ix86_expand_clear (operands[0]);"
17864 [(set_attr "type" "alu1")
17865 (set_attr "prefix_0f" "1")
17866 (set (attr "prefix_rep")
17868 (ior (match_test "TARGET_BMI")
17869 (and (not (match_test "optimize_function_for_size_p (cfun)"))
17870 (match_test "TARGET_CPU_P (GENERIC)")))
17872 (const_string "0")))
17873 (set_attr "mode" "<MODE>")])
17875 ; False dependency happens when destination is only updated by tzcnt,
17876 ; lzcnt or popcnt. There is no false dependency when destination is
17877 ; also used in source.
17878 (define_insn "*ctz<mode>2_falsedep"
17879 [(set (match_operand:SWI48 0 "register_operand" "=r")
17881 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
17882 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
17883 UNSPEC_INSN_FALSE_DEP)
17884 (clobber (reg:CC FLAGS_REG))]
17888 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
17889 else if (TARGET_CPU_P (GENERIC))
17890 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
17891 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
17893 gcc_unreachable ();
17895 [(set_attr "type" "alu1")
17896 (set_attr "prefix_0f" "1")
17897 (set_attr "prefix_rep" "1")
17898 (set_attr "mode" "<MODE>")])
17900 (define_insn_and_split "*ctzsi2_zext"
17901 [(set (match_operand:DI 0 "register_operand" "=r")
17905 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
17907 (clobber (reg:CC FLAGS_REG))]
17908 "TARGET_BMI && TARGET_64BIT"
17909 "tzcnt{l}\t{%1, %k0|%k0, %1}"
17910 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
17911 && optimize_function_for_speed_p (cfun)
17912 && !reg_mentioned_p (operands[0], operands[1])"
17914 [(set (match_dup 0)
17915 (and:DI (subreg:DI (ctz:SI (match_dup 1)) 0) (const_int 63)))
17916 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
17917 (clobber (reg:CC FLAGS_REG))])]
17918 "ix86_expand_clear (operands[0]);"
17919 [(set_attr "type" "alu1")
17920 (set_attr "prefix_0f" "1")
17921 (set_attr "prefix_rep" "1")
17922 (set_attr "mode" "SI")])
17924 ; False dependency happens when destination is only updated by tzcnt,
17925 ; lzcnt or popcnt. There is no false dependency when destination is
17926 ; also used in source.
17927 (define_insn "*ctzsi2_zext_falsedep"
17928 [(set (match_operand:DI 0 "register_operand" "=r")
17932 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
17934 (unspec [(match_operand:DI 2 "register_operand" "0")]
17935 UNSPEC_INSN_FALSE_DEP)
17936 (clobber (reg:CC FLAGS_REG))]
17937 "TARGET_BMI && TARGET_64BIT"
17938 "tzcnt{l}\t{%1, %k0|%k0, %1}"
17939 [(set_attr "type" "alu1")
17940 (set_attr "prefix_0f" "1")
17941 (set_attr "prefix_rep" "1")
17942 (set_attr "mode" "SI")])
17944 (define_insn_and_split "*ctzsidi2_<s>ext"
17945 [(set (match_operand:DI 0 "register_operand" "=r")
17948 (match_operand:SI 1 "nonimmediate_operand" "rm"))))
17949 (clobber (reg:CC FLAGS_REG))]
17953 return "tzcnt{l}\t{%1, %k0|%k0, %1}";
17954 else if (TARGET_CPU_P (GENERIC)
17955 && !optimize_function_for_size_p (cfun))
17956 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
17957 return "rep%; bsf{l}\t{%1, %k0|%k0, %1}";
17958 return "bsf{l}\t{%1, %k0|%k0, %1}";
17960 "(TARGET_BMI || TARGET_CPU_P (GENERIC))
17961 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
17962 && optimize_function_for_speed_p (cfun)
17963 && !reg_mentioned_p (operands[0], operands[1])"
17965 [(set (match_dup 0)
17966 (any_extend:DI (ctz:SI (match_dup 1))))
17967 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
17968 (clobber (reg:CC FLAGS_REG))])]
17969 "ix86_expand_clear (operands[0]);"
17970 [(set_attr "type" "alu1")
17971 (set_attr "prefix_0f" "1")
17972 (set (attr "prefix_rep")
17974 (ior (match_test "TARGET_BMI")
17975 (and (not (match_test "optimize_function_for_size_p (cfun)"))
17976 (match_test "TARGET_CPU_P (GENERIC)")))
17978 (const_string "0")))
17979 (set_attr "mode" "SI")])
17981 (define_insn "*ctzsidi2_<s>ext_falsedep"
17982 [(set (match_operand:DI 0 "register_operand" "=r")
17985 (match_operand:SI 1 "nonimmediate_operand" "rm"))))
17986 (unspec [(match_operand:DI 2 "register_operand" "0")]
17987 UNSPEC_INSN_FALSE_DEP)
17988 (clobber (reg:CC FLAGS_REG))]
17992 return "tzcnt{l}\t{%1, %k0|%k0, %1}";
17993 else if (TARGET_CPU_P (GENERIC))
17994 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
17995 return "rep%; bsf{l}\t{%1, %k0|%k0, %1}";
17997 gcc_unreachable ();
17999 [(set_attr "type" "alu1")
18000 (set_attr "prefix_0f" "1")
18001 (set_attr "prefix_rep" "1")
18002 (set_attr "mode" "SI")])
18004 (define_insn "bsr_rex64"
18005 [(set (reg:CCZ FLAGS_REG)
18006 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
18008 (set (match_operand:DI 0 "register_operand" "=r")
18009 (minus:DI (const_int 63)
18010 (clz:DI (match_dup 1))))]
18012 "bsr{q}\t{%1, %0|%0, %1}"
18013 [(set_attr "type" "alu1")
18014 (set_attr "prefix_0f" "1")
18015 (set_attr "znver1_decode" "vector")
18016 (set_attr "mode" "DI")])
18018 (define_insn "bsr_rex64_1"
18019 [(set (match_operand:DI 0 "register_operand" "=r")
18020 (minus:DI (const_int 63)
18021 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
18022 (clobber (reg:CC FLAGS_REG))]
18023 "!TARGET_LZCNT && TARGET_64BIT"
18024 "bsr{q}\t{%1, %0|%0, %1}"
18025 [(set_attr "type" "alu1")
18026 (set_attr "prefix_0f" "1")
18027 (set_attr "znver1_decode" "vector")
18028 (set_attr "mode" "DI")])
18030 (define_insn "bsr_rex64_1_zext"
18031 [(set (match_operand:DI 0 "register_operand" "=r")
18033 (minus:SI (const_int 63)
18035 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
18037 (clobber (reg:CC FLAGS_REG))]
18038 "!TARGET_LZCNT && TARGET_64BIT"
18039 "bsr{q}\t{%1, %0|%0, %1}"
18040 [(set_attr "type" "alu1")
18041 (set_attr "prefix_0f" "1")
18042 (set_attr "znver1_decode" "vector")
18043 (set_attr "mode" "DI")])
18046 [(set (reg:CCZ FLAGS_REG)
18047 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
18049 (set (match_operand:SI 0 "register_operand" "=r")
18050 (minus:SI (const_int 31)
18051 (clz:SI (match_dup 1))))]
18053 "bsr{l}\t{%1, %0|%0, %1}"
18054 [(set_attr "type" "alu1")
18055 (set_attr "prefix_0f" "1")
18056 (set_attr "znver1_decode" "vector")
18057 (set_attr "mode" "SI")])
18059 (define_insn "bsr_1"
18060 [(set (match_operand:SI 0 "register_operand" "=r")
18061 (minus:SI (const_int 31)
18062 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18063 (clobber (reg:CC FLAGS_REG))]
18065 "bsr{l}\t{%1, %0|%0, %1}"
18066 [(set_attr "type" "alu1")
18067 (set_attr "prefix_0f" "1")
18068 (set_attr "znver1_decode" "vector")
18069 (set_attr "mode" "SI")])
18071 (define_insn "bsr_zext_1"
18072 [(set (match_operand:DI 0 "register_operand" "=r")
18076 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))))
18077 (clobber (reg:CC FLAGS_REG))]
18078 "!TARGET_LZCNT && TARGET_64BIT"
18079 "bsr{l}\t{%1, %k0|%k0, %1}"
18080 [(set_attr "type" "alu1")
18081 (set_attr "prefix_0f" "1")
18082 (set_attr "znver1_decode" "vector")
18083 (set_attr "mode" "SI")])
18085 ; As bsr is undefined behavior on zero and for other input
18086 ; values it is in range 0 to 63, we can optimize away sign-extends.
18087 (define_insn_and_split "*bsr_rex64_2"
18088 [(set (match_operand:DI 0 "register_operand")
18093 (subreg:SI (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
18096 (clobber (reg:CC FLAGS_REG))]
18097 "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
18100 [(parallel [(set (reg:CCZ FLAGS_REG)
18101 (compare:CCZ (match_dup 1) (const_int 0)))
18103 (minus:DI (const_int 63) (clz:DI (match_dup 1))))])
18104 (parallel [(set (match_dup 0)
18105 (zero_extend:DI (xor:SI (match_dup 3) (const_int 63))))
18106 (clobber (reg:CC FLAGS_REG))])]
18108 operands[2] = gen_reg_rtx (DImode);
18109 operands[3] = lowpart_subreg (SImode, operands[2], DImode);
18112 (define_insn_and_split "*bsr_2"
18113 [(set (match_operand:DI 0 "register_operand")
18118 (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
18120 (clobber (reg:CC FLAGS_REG))]
18121 "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
18124 [(parallel [(set (reg:CCZ FLAGS_REG)
18125 (compare:CCZ (match_dup 1) (const_int 0)))
18127 (minus:SI (const_int 31) (clz:SI (match_dup 1))))])
18128 (parallel [(set (match_dup 0)
18129 (zero_extend:DI (xor:SI (match_dup 2) (const_int 31))))
18130 (clobber (reg:CC FLAGS_REG))])]
18131 "operands[2] = gen_reg_rtx (SImode);")
18133 ; Splitters to optimize 64 - __builtin_clzl (x) or 32 - __builtin_clz (x).
18134 ; Again, as for !TARGET_LZCNT CLZ is UB at zero, CLZ is guaranteed to be
18135 ; in [0, 63] or [0, 31] range.
18137 [(set (match_operand:SI 0 "register_operand")
18139 (match_operand:SI 2 "const_int_operand")
18141 (minus:SI (const_int 63)
18143 (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
18146 "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
18147 [(set (match_dup 3)
18148 (minus:DI (const_int 63) (clz:DI (match_dup 1))))
18150 (plus:SI (match_dup 5) (match_dup 4)))]
18152 operands[3] = gen_reg_rtx (DImode);
18153 operands[5] = lowpart_subreg (SImode, operands[3], DImode);
18154 if (INTVAL (operands[2]) == 63)
18156 emit_insn (gen_bsr_rex64_1_zext (operands[3], operands[1]));
18157 emit_move_insn (operands[0], operands[5]);
18160 operands[4] = gen_int_mode (UINTVAL (operands[2]) - 63, SImode);
18164 [(set (match_operand:SI 0 "register_operand")
18166 (match_operand:SI 2 "const_int_operand")
18168 (minus:SI (const_int 31)
18169 (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
18171 "!TARGET_LZCNT && ix86_pre_reload_split ()"
18172 [(set (match_dup 3)
18173 (minus:SI (const_int 31) (clz:SI (match_dup 1))))
18175 (plus:SI (match_dup 3) (match_dup 4)))]
18177 if (INTVAL (operands[2]) == 31)
18179 emit_insn (gen_bsr_1 (operands[0], operands[1]));
18182 operands[3] = gen_reg_rtx (SImode);
18183 operands[4] = gen_int_mode (UINTVAL (operands[2]) - 31, SImode);
18187 [(set (match_operand:DI 0 "register_operand")
18189 (match_operand:DI 2 "const_int_operand")
18192 (minus:SI (const_int 63)
18194 (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
18199 && ix86_pre_reload_split ()
18200 && ((unsigned HOST_WIDE_INT)
18201 trunc_int_for_mode (UINTVAL (operands[2]) - 63, SImode)
18202 == UINTVAL (operands[2]) - 63)"
18203 [(set (match_dup 3)
18204 (minus:DI (const_int 63) (clz:DI (match_dup 1))))
18206 (plus:DI (match_dup 3) (match_dup 4)))]
18208 if (INTVAL (operands[2]) == 63)
18210 emit_insn (gen_bsr_rex64_1 (operands[0], operands[1]));
18213 operands[3] = gen_reg_rtx (DImode);
18214 operands[4] = GEN_INT (UINTVAL (operands[2]) - 63);
18218 [(set (match_operand:DI 0 "register_operand")
18220 (match_operand:DI 2 "const_int_operand")
18223 (minus:SI (const_int 31)
18224 (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
18225 (const_int 31)))))]
18228 && ix86_pre_reload_split ()
18229 && ((unsigned HOST_WIDE_INT)
18230 trunc_int_for_mode (UINTVAL (operands[2]) - 31, SImode)
18231 == UINTVAL (operands[2]) - 31)"
18232 [(set (match_dup 3)
18233 (zero_extend:DI (minus:SI (const_int 31) (clz:SI (match_dup 1)))))
18235 (plus:DI (match_dup 3) (match_dup 4)))]
18237 if (INTVAL (operands[2]) == 31)
18239 emit_insn (gen_bsr_zext_1 (operands[0], operands[1]));
18242 operands[3] = gen_reg_rtx (DImode);
18243 operands[4] = GEN_INT (UINTVAL (operands[2]) - 31);
18246 (define_expand "clz<mode>2"
18248 [(set (reg:CCZ FLAGS_REG)
18249 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18251 (set (match_dup 3) (minus:SWI48
18253 (clz:SWI48 (match_dup 1))))])
18255 [(set (match_operand:SWI48 0 "register_operand")
18256 (xor:SWI48 (match_dup 3) (match_dup 2)))
18257 (clobber (reg:CC FLAGS_REG))])]
18262 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
18265 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
18266 operands[3] = gen_reg_rtx (<MODE>mode);
18269 (define_insn_and_split "clz<mode>2_lzcnt"
18270 [(set (match_operand:SWI48 0 "register_operand" "=r")
18272 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18273 (clobber (reg:CC FLAGS_REG))]
18275 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
18276 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18277 && optimize_function_for_speed_p (cfun)
18278 && !reg_mentioned_p (operands[0], operands[1])"
18280 [(set (match_dup 0)
18281 (clz:SWI48 (match_dup 1)))
18282 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18283 (clobber (reg:CC FLAGS_REG))])]
18284 "ix86_expand_clear (operands[0]);"
18285 [(set_attr "prefix_rep" "1")
18286 (set_attr "type" "bitmanip")
18287 (set_attr "mode" "<MODE>")])
18289 ; False dependency happens when destination is only updated by tzcnt,
18290 ; lzcnt or popcnt. There is no false dependency when destination is
18291 ; also used in source.
18292 (define_insn "*clz<mode>2_lzcnt_falsedep"
18293 [(set (match_operand:SWI48 0 "register_operand" "=r")
18295 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18296 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18297 UNSPEC_INSN_FALSE_DEP)
18298 (clobber (reg:CC FLAGS_REG))]
18300 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
18301 [(set_attr "prefix_rep" "1")
18302 (set_attr "type" "bitmanip")
18303 (set_attr "mode" "<MODE>")])
18305 (define_insn_and_split "*clzsi2_lzcnt_zext"
18306 [(set (match_operand:DI 0 "register_operand" "=r")
18310 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
18312 (clobber (reg:CC FLAGS_REG))]
18313 "TARGET_LZCNT && TARGET_64BIT"
18314 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18315 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18316 && optimize_function_for_speed_p (cfun)
18317 && !reg_mentioned_p (operands[0], operands[1])"
18319 [(set (match_dup 0)
18320 (and:DI (subreg:DI (clz:SI (match_dup 1)) 0) (const_int 63)))
18321 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18322 (clobber (reg:CC FLAGS_REG))])]
18323 "ix86_expand_clear (operands[0]);"
18324 [(set_attr "prefix_rep" "1")
18325 (set_attr "type" "bitmanip")
18326 (set_attr "mode" "SI")])
18328 ; False dependency happens when destination is only updated by tzcnt,
18329 ; lzcnt or popcnt. There is no false dependency when destination is
18330 ; also used in source.
18331 (define_insn "*clzsi2_lzcnt_zext_falsedep"
18332 [(set (match_operand:DI 0 "register_operand" "=r")
18336 (match_operand:SWI48 1 "nonimmediate_operand" "rm")) 0)
18338 (unspec [(match_operand:DI 2 "register_operand" "0")]
18339 UNSPEC_INSN_FALSE_DEP)
18340 (clobber (reg:CC FLAGS_REG))]
18342 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18343 [(set_attr "prefix_rep" "1")
18344 (set_attr "type" "bitmanip")
18345 (set_attr "mode" "SI")])
18347 (define_insn_and_split "*clzsi2_lzcnt_zext_2"
18348 [(set (match_operand:DI 0 "register_operand" "=r")
18350 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18351 (clobber (reg:CC FLAGS_REG))]
18352 "TARGET_LZCNT && TARGET_64BIT"
18353 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18354 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18355 && optimize_function_for_speed_p (cfun)
18356 && !reg_mentioned_p (operands[0], operands[1])"
18358 [(set (match_dup 0)
18359 (zero_extend:DI (clz:SI (match_dup 1))))
18360 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18361 (clobber (reg:CC FLAGS_REG))])]
18362 "ix86_expand_clear (operands[0]);"
18363 [(set_attr "prefix_rep" "1")
18364 (set_attr "type" "bitmanip")
18365 (set_attr "mode" "SI")])
18367 ; False dependency happens when destination is only updated by tzcnt,
18368 ; lzcnt or popcnt. There is no false dependency when destination is
18369 ; also used in source.
18370 (define_insn "*clzsi2_lzcnt_zext_2_falsedep"
18371 [(set (match_operand:DI 0 "register_operand" "=r")
18373 (clz:SI (match_operand:SWI48 1 "nonimmediate_operand" "rm"))))
18374 (unspec [(match_operand:DI 2 "register_operand" "0")]
18375 UNSPEC_INSN_FALSE_DEP)
18376 (clobber (reg:CC FLAGS_REG))]
18378 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18379 [(set_attr "prefix_rep" "1")
18380 (set_attr "type" "bitmanip")
18381 (set_attr "mode" "SI")])
18383 (define_int_iterator LT_ZCNT
18384 [(UNSPEC_TZCNT "TARGET_BMI")
18385 (UNSPEC_LZCNT "TARGET_LZCNT")])
18387 (define_int_attr lt_zcnt
18388 [(UNSPEC_TZCNT "tzcnt")
18389 (UNSPEC_LZCNT "lzcnt")])
18391 (define_int_attr lt_zcnt_type
18392 [(UNSPEC_TZCNT "alu1")
18393 (UNSPEC_LZCNT "bitmanip")])
18395 ;; Version of lzcnt/tzcnt that is expanded from intrinsics. This version
18396 ;; provides operand size as output when source operand is zero.
18398 (define_insn_and_split "<lt_zcnt>_<mode>"
18399 [(set (match_operand:SWI48 0 "register_operand" "=r")
18401 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
18402 (clobber (reg:CC FLAGS_REG))]
18404 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
18405 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18406 && optimize_function_for_speed_p (cfun)
18407 && !reg_mentioned_p (operands[0], operands[1])"
18409 [(set (match_dup 0)
18410 (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
18411 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18412 (clobber (reg:CC FLAGS_REG))])]
18413 "ix86_expand_clear (operands[0]);"
18414 [(set_attr "type" "<lt_zcnt_type>")
18415 (set_attr "prefix_0f" "1")
18416 (set_attr "prefix_rep" "1")
18417 (set_attr "mode" "<MODE>")])
18419 ; False dependency happens when destination is only updated by tzcnt,
18420 ; lzcnt or popcnt. There is no false dependency when destination is
18421 ; also used in source.
18422 (define_insn "*<lt_zcnt>_<mode>_falsedep"
18423 [(set (match_operand:SWI48 0 "register_operand" "=r")
18425 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
18426 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18427 UNSPEC_INSN_FALSE_DEP)
18428 (clobber (reg:CC FLAGS_REG))]
18430 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
18431 [(set_attr "type" "<lt_zcnt_type>")
18432 (set_attr "prefix_0f" "1")
18433 (set_attr "prefix_rep" "1")
18434 (set_attr "mode" "<MODE>")])
18436 (define_insn "<lt_zcnt>_hi"
18437 [(set (match_operand:HI 0 "register_operand" "=r")
18439 [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT))
18440 (clobber (reg:CC FLAGS_REG))]
18442 "<lt_zcnt>{w}\t{%1, %0|%0, %1}"
18443 [(set_attr "type" "<lt_zcnt_type>")
18444 (set_attr "prefix_0f" "1")
18445 (set_attr "prefix_rep" "1")
18446 (set_attr "mode" "HI")])
18448 ;; BMI instructions.
18450 (define_insn "bmi_bextr_<mode>"
18451 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
18452 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
18453 (match_operand:SWI48 2 "register_operand" "r,r")]
18455 (clobber (reg:CC FLAGS_REG))]
18457 "bextr\t{%2, %1, %0|%0, %1, %2}"
18458 [(set_attr "type" "bitmanip")
18459 (set_attr "btver2_decode" "direct, double")
18460 (set_attr "mode" "<MODE>")])
18462 (define_insn "*bmi_bextr_<mode>_ccz"
18463 [(set (reg:CCZ FLAGS_REG)
18465 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
18466 (match_operand:SWI48 2 "register_operand" "r,r")]
18469 (clobber (match_scratch:SWI48 0 "=r,r"))]
18471 "bextr\t{%2, %1, %0|%0, %1, %2}"
18472 [(set_attr "type" "bitmanip")
18473 (set_attr "btver2_decode" "direct, double")
18474 (set_attr "mode" "<MODE>")])
18476 (define_insn "*bmi_blsi_<mode>"
18477 [(set (match_operand:SWI48 0 "register_operand" "=r")
18480 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
18482 (clobber (reg:CC FLAGS_REG))]
18484 "blsi\t{%1, %0|%0, %1}"
18485 [(set_attr "type" "bitmanip")
18486 (set_attr "btver2_decode" "double")
18487 (set_attr "mode" "<MODE>")])
18489 (define_insn "*bmi_blsi_<mode>_cmp"
18490 [(set (reg FLAGS_REG)
18493 (neg:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
18496 (set (match_operand:SWI48 0 "register_operand" "=r")
18497 (and:SWI48 (neg:SWI48 (match_dup 1)) (match_dup 1)))]
18498 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
18499 "blsi\t{%1, %0|%0, %1}"
18500 [(set_attr "type" "bitmanip")
18501 (set_attr "btver2_decode" "double")
18502 (set_attr "mode" "<MODE>")])
18504 (define_insn "*bmi_blsi_<mode>_ccno"
18505 [(set (reg FLAGS_REG)
18508 (neg:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
18511 (clobber (match_scratch:SWI48 0 "=r"))]
18512 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
18513 "blsi\t{%1, %0|%0, %1}"
18514 [(set_attr "type" "bitmanip")
18515 (set_attr "btver2_decode" "double")
18516 (set_attr "mode" "<MODE>")])
18518 (define_insn "*bmi_blsmsk_<mode>"
18519 [(set (match_operand:SWI48 0 "register_operand" "=r")
18522 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18525 (clobber (reg:CC FLAGS_REG))]
18527 "blsmsk\t{%1, %0|%0, %1}"
18528 [(set_attr "type" "bitmanip")
18529 (set_attr "btver2_decode" "double")
18530 (set_attr "mode" "<MODE>")])
18532 (define_insn "*bmi_blsr_<mode>"
18533 [(set (match_operand:SWI48 0 "register_operand" "=r")
18536 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18539 (clobber (reg:CC FLAGS_REG))]
18541 "blsr\t{%1, %0|%0, %1}"
18542 [(set_attr "type" "bitmanip")
18543 (set_attr "btver2_decode" "double")
18544 (set_attr "mode" "<MODE>")])
18546 (define_insn "*bmi_blsr_<mode>_cmp"
18547 [(set (reg:CCZ FLAGS_REG)
18551 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18555 (set (match_operand:SWI48 0 "register_operand" "=r")
18562 "blsr\t{%1, %0|%0, %1}"
18563 [(set_attr "type" "bitmanip")
18564 (set_attr "btver2_decode" "double")
18565 (set_attr "mode" "<MODE>")])
18567 (define_insn "*bmi_blsr_<mode>_ccz"
18568 [(set (reg:CCZ FLAGS_REG)
18572 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18576 (clobber (match_scratch:SWI48 0 "=r"))]
18578 "blsr\t{%1, %0|%0, %1}"
18579 [(set_attr "type" "bitmanip")
18580 (set_attr "btver2_decode" "double")
18581 (set_attr "mode" "<MODE>")])
18583 ;; BMI2 instructions.
18584 (define_expand "bmi2_bzhi_<mode>3"
18586 [(set (match_operand:SWI48 0 "register_operand")
18587 (if_then_else:SWI48
18588 (ne:QI (and:SWI48 (match_operand:SWI48 2 "register_operand")
18591 (zero_extract:SWI48
18592 (match_operand:SWI48 1 "nonimmediate_operand")
18593 (umin:SWI48 (and:SWI48 (match_dup 2) (const_int 255))
18597 (clobber (reg:CC FLAGS_REG))])]
18599 "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
18601 (define_insn "*bmi2_bzhi_<mode>3"
18602 [(set (match_operand:SWI48 0 "register_operand" "=r")
18603 (if_then_else:SWI48
18604 (ne:QI (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
18607 (zero_extract:SWI48
18608 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18609 (umin:SWI48 (and:SWI48 (match_dup 2) (const_int 255))
18610 (match_operand:SWI48 3 "const_int_operand"))
18613 (clobber (reg:CC FLAGS_REG))]
18614 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
18615 "bzhi\t{%2, %1, %0|%0, %1, %2}"
18616 [(set_attr "type" "bitmanip")
18617 (set_attr "prefix" "vex")
18618 (set_attr "mode" "<MODE>")])
18620 (define_insn "*bmi2_bzhi_<mode>3_1"
18621 [(set (match_operand:SWI48 0 "register_operand" "=r")
18622 (if_then_else:SWI48
18623 (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0))
18624 (zero_extract:SWI48
18625 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18626 (umin:SWI48 (zero_extend:SWI48 (match_dup 2))
18627 (match_operand:SWI48 3 "const_int_operand"))
18630 (clobber (reg:CC FLAGS_REG))]
18631 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
18632 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
18633 [(set_attr "type" "bitmanip")
18634 (set_attr "prefix" "vex")
18635 (set_attr "mode" "<MODE>")])
18637 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
18638 [(set (reg:CCZ FLAGS_REG)
18640 (if_then_else:SWI48
18641 (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0))
18642 (zero_extract:SWI48
18643 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18644 (umin:SWI48 (zero_extend:SWI48 (match_dup 2))
18645 (match_operand:SWI48 3 "const_int_operand"))
18649 (clobber (match_scratch:SWI48 0 "=r"))]
18650 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
18651 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
18652 [(set_attr "type" "bitmanip")
18653 (set_attr "prefix" "vex")
18654 (set_attr "mode" "<MODE>")])
18656 (define_insn "*bmi2_bzhi_<mode>3_2"
18657 [(set (match_operand:SWI48 0 "register_operand" "=r")
18660 (ashift:SWI48 (const_int 1)
18661 (match_operand:QI 2 "register_operand" "r"))
18663 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18664 (clobber (reg:CC FLAGS_REG))]
18666 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
18667 [(set_attr "type" "bitmanip")
18668 (set_attr "prefix" "vex")
18669 (set_attr "mode" "<MODE>")])
18671 (define_insn "*bmi2_bzhi_<mode>3_3"
18672 [(set (match_operand:SWI48 0 "register_operand" "=r")
18675 (ashift:SWI48 (const_int -1)
18676 (match_operand:QI 2 "register_operand" "r")))
18677 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18678 (clobber (reg:CC FLAGS_REG))]
18680 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
18681 [(set_attr "type" "bitmanip")
18682 (set_attr "prefix" "vex")
18683 (set_attr "mode" "<MODE>")])
18685 (define_insn "*bmi2_bzhi_zero_extendsidi_4"
18686 [(set (match_operand:DI 0 "register_operand" "=r")
18690 (ashift:SI (const_int 1)
18691 (match_operand:QI 2 "register_operand" "r"))
18693 (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18694 (clobber (reg:CC FLAGS_REG))]
18695 "TARGET_64BIT && TARGET_BMI2"
18696 "bzhi\t{%q2, %q1, %q0|%q0, %q1, %q2}"
18697 [(set_attr "type" "bitmanip")
18698 (set_attr "prefix" "vex")
18699 (set_attr "mode" "DI")])
18701 (define_insn "*bmi2_bzhi_zero_extendsidi_5"
18702 [(set (match_operand:DI 0 "register_operand" "=r")
18706 (ashift:SI (const_int 1)
18707 (match_operand:QI 2 "register_operand" "r"))
18709 (match_operand:DI 1 "nonimmediate_operand" "rm")))
18710 (clobber (reg:CC FLAGS_REG))]
18711 "TARGET_64BIT && TARGET_BMI2"
18712 "bzhi\t{%q2, %q1, %q0|%q0, %q1, %q2}"
18713 [(set_attr "type" "bitmanip")
18714 (set_attr "prefix" "vex")
18715 (set_attr "mode" "DI")])
18717 (define_insn "bmi2_pdep_<mode>3"
18718 [(set (match_operand:SWI48 0 "register_operand" "=r")
18719 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
18720 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
18723 "pdep\t{%2, %1, %0|%0, %1, %2}"
18724 [(set_attr "type" "bitmanip")
18725 (set_attr "prefix" "vex")
18726 (set_attr "mode" "<MODE>")])
18728 (define_insn "bmi2_pext_<mode>3"
18729 [(set (match_operand:SWI48 0 "register_operand" "=r")
18730 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
18731 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
18734 "pext\t{%2, %1, %0|%0, %1, %2}"
18735 [(set_attr "type" "bitmanip")
18736 (set_attr "prefix" "vex")
18737 (set_attr "mode" "<MODE>")])
18739 ;; TBM instructions.
18740 (define_insn "@tbm_bextri_<mode>"
18741 [(set (match_operand:SWI48 0 "register_operand" "=r")
18742 (zero_extract:SWI48
18743 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18744 (match_operand 2 "const_0_to_255_operand")
18745 (match_operand 3 "const_0_to_255_operand")))
18746 (clobber (reg:CC FLAGS_REG))]
18749 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
18750 return "bextr\t{%2, %1, %0|%0, %1, %2}";
18752 [(set_attr "type" "bitmanip")
18753 (set_attr "mode" "<MODE>")])
18755 (define_insn "*tbm_blcfill_<mode>"
18756 [(set (match_operand:SWI48 0 "register_operand" "=r")
18759 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18762 (clobber (reg:CC FLAGS_REG))]
18764 "blcfill\t{%1, %0|%0, %1}"
18765 [(set_attr "type" "bitmanip")
18766 (set_attr "mode" "<MODE>")])
18768 (define_insn "*tbm_blci_<mode>"
18769 [(set (match_operand:SWI48 0 "register_operand" "=r")
18773 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18776 (clobber (reg:CC FLAGS_REG))]
18778 "blci\t{%1, %0|%0, %1}"
18779 [(set_attr "type" "bitmanip")
18780 (set_attr "mode" "<MODE>")])
18782 (define_insn "*tbm_blcic_<mode>"
18783 [(set (match_operand:SWI48 0 "register_operand" "=r")
18786 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18790 (clobber (reg:CC FLAGS_REG))]
18792 "blcic\t{%1, %0|%0, %1}"
18793 [(set_attr "type" "bitmanip")
18794 (set_attr "mode" "<MODE>")])
18796 (define_insn "*tbm_blcmsk_<mode>"
18797 [(set (match_operand:SWI48 0 "register_operand" "=r")
18800 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18803 (clobber (reg:CC FLAGS_REG))]
18805 "blcmsk\t{%1, %0|%0, %1}"
18806 [(set_attr "type" "bitmanip")
18807 (set_attr "mode" "<MODE>")])
18809 (define_insn "*tbm_blcs_<mode>"
18810 [(set (match_operand:SWI48 0 "register_operand" "=r")
18813 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18816 (clobber (reg:CC FLAGS_REG))]
18818 "blcs\t{%1, %0|%0, %1}"
18819 [(set_attr "type" "bitmanip")
18820 (set_attr "mode" "<MODE>")])
18822 (define_insn "*tbm_blsfill_<mode>"
18823 [(set (match_operand:SWI48 0 "register_operand" "=r")
18826 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18829 (clobber (reg:CC FLAGS_REG))]
18831 "blsfill\t{%1, %0|%0, %1}"
18832 [(set_attr "type" "bitmanip")
18833 (set_attr "mode" "<MODE>")])
18835 (define_insn "*tbm_blsic_<mode>"
18836 [(set (match_operand:SWI48 0 "register_operand" "=r")
18839 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18843 (clobber (reg:CC FLAGS_REG))]
18845 "blsic\t{%1, %0|%0, %1}"
18846 [(set_attr "type" "bitmanip")
18847 (set_attr "mode" "<MODE>")])
18849 (define_insn "*tbm_t1mskc_<mode>"
18850 [(set (match_operand:SWI48 0 "register_operand" "=r")
18853 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18857 (clobber (reg:CC FLAGS_REG))]
18859 "t1mskc\t{%1, %0|%0, %1}"
18860 [(set_attr "type" "bitmanip")
18861 (set_attr "mode" "<MODE>")])
18863 (define_insn "*tbm_tzmsk_<mode>"
18864 [(set (match_operand:SWI48 0 "register_operand" "=r")
18867 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18871 (clobber (reg:CC FLAGS_REG))]
18873 "tzmsk\t{%1, %0|%0, %1}"
18874 [(set_attr "type" "bitmanip")
18875 (set_attr "mode" "<MODE>")])
18877 (define_insn_and_split "popcount<mode>2"
18878 [(set (match_operand:SWI48 0 "register_operand" "=r")
18880 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18881 (clobber (reg:CC FLAGS_REG))]
18885 return "popcnt\t{%1, %0|%0, %1}";
18887 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
18890 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18891 && optimize_function_for_speed_p (cfun)
18892 && !reg_mentioned_p (operands[0], operands[1])"
18894 [(set (match_dup 0)
18895 (popcount:SWI48 (match_dup 1)))
18896 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18897 (clobber (reg:CC FLAGS_REG))])]
18898 "ix86_expand_clear (operands[0]);"
18899 [(set_attr "prefix_rep" "1")
18900 (set_attr "type" "bitmanip")
18901 (set_attr "mode" "<MODE>")])
18903 ; False dependency happens when destination is only updated by tzcnt,
18904 ; lzcnt or popcnt. There is no false dependency when destination is
18905 ; also used in source.
18906 (define_insn "*popcount<mode>2_falsedep"
18907 [(set (match_operand:SWI48 0 "register_operand" "=r")
18909 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18910 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18911 UNSPEC_INSN_FALSE_DEP)
18912 (clobber (reg:CC FLAGS_REG))]
18916 return "popcnt\t{%1, %0|%0, %1}";
18918 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
18921 [(set_attr "prefix_rep" "1")
18922 (set_attr "type" "bitmanip")
18923 (set_attr "mode" "<MODE>")])
18925 (define_insn_and_split "*popcountsi2_zext"
18926 [(set (match_operand:DI 0 "register_operand" "=r")
18930 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
18932 (clobber (reg:CC FLAGS_REG))]
18933 "TARGET_POPCNT && TARGET_64BIT"
18936 return "popcnt\t{%1, %k0|%k0, %1}";
18938 return "popcnt{l}\t{%1, %k0|%k0, %1}";
18941 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18942 && optimize_function_for_speed_p (cfun)
18943 && !reg_mentioned_p (operands[0], operands[1])"
18945 [(set (match_dup 0)
18946 (and:DI (subreg:DI (popcount:SI (match_dup 1)) 0) (const_int 63)))
18947 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18948 (clobber (reg:CC FLAGS_REG))])]
18949 "ix86_expand_clear (operands[0]);"
18950 [(set_attr "prefix_rep" "1")
18951 (set_attr "type" "bitmanip")
18952 (set_attr "mode" "SI")])
18954 ; False dependency happens when destination is only updated by tzcnt,
18955 ; lzcnt or popcnt. There is no false dependency when destination is
18956 ; also used in source.
18957 (define_insn "*popcountsi2_zext_falsedep"
18958 [(set (match_operand:DI 0 "register_operand" "=r")
18962 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
18964 (unspec [(match_operand:DI 2 "register_operand" "0")]
18965 UNSPEC_INSN_FALSE_DEP)
18966 (clobber (reg:CC FLAGS_REG))]
18967 "TARGET_POPCNT && TARGET_64BIT"
18970 return "popcnt\t{%1, %k0|%k0, %1}";
18972 return "popcnt{l}\t{%1, %k0|%k0, %1}";
18975 [(set_attr "prefix_rep" "1")
18976 (set_attr "type" "bitmanip")
18977 (set_attr "mode" "SI")])
18979 (define_insn_and_split "*popcountsi2_zext_2"
18980 [(set (match_operand:DI 0 "register_operand" "=r")
18982 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18983 (clobber (reg:CC FLAGS_REG))]
18984 "TARGET_POPCNT && TARGET_64BIT"
18987 return "popcnt\t{%1, %k0|%k0, %1}";
18989 return "popcnt{l}\t{%1, %k0|%k0, %1}";
18992 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18993 && optimize_function_for_speed_p (cfun)
18994 && !reg_mentioned_p (operands[0], operands[1])"
18996 [(set (match_dup 0)
18997 (zero_extend:DI (popcount:SI (match_dup 1))))
18998 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18999 (clobber (reg:CC FLAGS_REG))])]
19000 "ix86_expand_clear (operands[0]);"
19001 [(set_attr "prefix_rep" "1")
19002 (set_attr "type" "bitmanip")
19003 (set_attr "mode" "SI")])
19005 ; False dependency happens when destination is only updated by tzcnt,
19006 ; lzcnt or popcnt. There is no false dependency when destination is
19007 ; also used in source.
19008 (define_insn "*popcountsi2_zext_2_falsedep"
19009 [(set (match_operand:DI 0 "register_operand" "=r")
19011 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
19012 (unspec [(match_operand:DI 2 "register_operand" "0")]
19013 UNSPEC_INSN_FALSE_DEP)
19014 (clobber (reg:CC FLAGS_REG))]
19015 "TARGET_POPCNT && TARGET_64BIT"
19018 return "popcnt\t{%1, %k0|%k0, %1}";
19020 return "popcnt{l}\t{%1, %k0|%k0, %1}";
19023 [(set_attr "prefix_rep" "1")
19024 (set_attr "type" "bitmanip")
19025 (set_attr "mode" "SI")])
19027 (define_insn_and_split "*popcounthi2_1"
19028 [(set (match_operand:SI 0 "register_operand")
19030 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
19031 (clobber (reg:CC FLAGS_REG))]
19033 && ix86_pre_reload_split ()"
19038 rtx tmp = gen_reg_rtx (HImode);
19040 emit_insn (gen_popcounthi2 (tmp, operands[1]));
19041 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
19045 (define_insn_and_split "*popcounthi2_2"
19046 [(set (match_operand:SI 0 "register_operand")
19048 (popcount:HI (match_operand:HI 1 "nonimmediate_operand"))))
19049 (clobber (reg:CC FLAGS_REG))]
19051 && ix86_pre_reload_split ()"
19056 rtx tmp = gen_reg_rtx (HImode);
19058 emit_insn (gen_popcounthi2 (tmp, operands[1]));
19059 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
19063 (define_insn "popcounthi2"
19064 [(set (match_operand:HI 0 "register_operand" "=r")
19066 (match_operand:HI 1 "nonimmediate_operand" "rm")))
19067 (clobber (reg:CC FLAGS_REG))]
19071 return "popcnt\t{%1, %0|%0, %1}";
19073 return "popcnt{w}\t{%1, %0|%0, %1}";
19076 [(set_attr "prefix_rep" "1")
19077 (set_attr "type" "bitmanip")
19078 (set_attr "mode" "HI")])
19080 (define_expand "bswapdi2"
19081 [(set (match_operand:DI 0 "register_operand")
19082 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
19086 operands[1] = force_reg (DImode, operands[1]);
19089 (define_expand "bswapsi2"
19090 [(set (match_operand:SI 0 "register_operand")
19091 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
19096 else if (TARGET_BSWAP)
19097 operands[1] = force_reg (SImode, operands[1]);
19100 rtx x = operands[0];
19102 emit_move_insn (x, operands[1]);
19103 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
19104 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
19105 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
19110 (define_insn "*bswap<mode>2_movbe"
19111 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
19112 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
19114 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
19117 movbe{<imodesuffix>}\t{%1, %0|%0, %1}
19118 movbe{<imodesuffix>}\t{%1, %0|%0, %1}"
19119 [(set_attr "type" "bitmanip,imov,imov")
19120 (set_attr "modrm" "0,1,1")
19121 (set_attr "prefix_0f" "*,1,1")
19122 (set_attr "prefix_extra" "*,1,1")
19123 (set_attr "mode" "<MODE>")])
19125 (define_insn "*bswap<mode>2"
19126 [(set (match_operand:SWI48 0 "register_operand" "=r")
19127 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
19130 [(set_attr "type" "bitmanip")
19131 (set_attr "modrm" "0")
19132 (set_attr "mode" "<MODE>")])
19134 (define_expand "bswaphi2"
19135 [(set (match_operand:HI 0 "register_operand")
19136 (bswap:HI (match_operand:HI 1 "nonimmediate_operand")))]
19139 (define_insn "*bswaphi2_movbe"
19140 [(set (match_operand:HI 0 "nonimmediate_operand" "=Q,r,m")
19141 (bswap:HI (match_operand:HI 1 "nonimmediate_operand" "0,m,r")))]
19143 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
19145 xchg{b}\t{%h0, %b0|%b0, %h0}
19146 movbe{w}\t{%1, %0|%0, %1}
19147 movbe{w}\t{%1, %0|%0, %1}"
19148 [(set_attr "type" "imov")
19149 (set_attr "modrm" "*,1,1")
19150 (set_attr "prefix_0f" "*,1,1")
19151 (set_attr "prefix_extra" "*,1,1")
19152 (set_attr "pent_pair" "np,*,*")
19153 (set_attr "athlon_decode" "vector,*,*")
19154 (set_attr "amdfam10_decode" "double,*,*")
19155 (set_attr "bdver1_decode" "double,*,*")
19156 (set_attr "mode" "QI,HI,HI")])
19159 [(set (match_operand:HI 0 "general_reg_operand")
19160 (bswap:HI (match_dup 0)))]
19162 && !(TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))
19163 && peep2_regno_dead_p (0, FLAGS_REG)"
19164 [(parallel [(set (match_dup 0) (rotate:HI (match_dup 0) (const_int 8)))
19165 (clobber (reg:CC FLAGS_REG))])])
19167 (define_insn "bswaphi_lowpart"
19168 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
19169 (bswap:HI (match_dup 0)))
19170 (clobber (reg:CC FLAGS_REG))]
19173 xchg{b}\t{%h0, %b0|%b0, %h0}
19174 rol{w}\t{$8, %0|%0, 8}"
19175 [(set (attr "preferred_for_size")
19176 (cond [(eq_attr "alternative" "0")
19177 (symbol_ref "true")]
19178 (symbol_ref "false")))
19179 (set (attr "preferred_for_speed")
19180 (cond [(eq_attr "alternative" "0")
19181 (symbol_ref "TARGET_USE_XCHGB")]
19182 (symbol_ref "!TARGET_USE_XCHGB")))
19183 (set_attr "length" "2,4")
19184 (set_attr "mode" "QI,HI")])
19186 (define_expand "paritydi2"
19187 [(set (match_operand:DI 0 "register_operand")
19188 (parity:DI (match_operand:DI 1 "register_operand")))]
19191 rtx scratch = gen_reg_rtx (QImode);
19192 rtx hipart1 = gen_reg_rtx (SImode);
19193 rtx lopart1 = gen_reg_rtx (SImode);
19194 rtx xor1 = gen_reg_rtx (SImode);
19195 rtx shift2 = gen_reg_rtx (SImode);
19196 rtx hipart2 = gen_reg_rtx (HImode);
19197 rtx lopart2 = gen_reg_rtx (HImode);
19198 rtx xor2 = gen_reg_rtx (HImode);
19202 rtx shift1 = gen_reg_rtx (DImode);
19203 emit_insn (gen_lshrdi3 (shift1, operands[1], GEN_INT (32)));
19204 emit_move_insn (hipart1, gen_lowpart (SImode, shift1));
19207 emit_move_insn (hipart1, gen_highpart (SImode, operands[1]));
19209 emit_move_insn (lopart1, gen_lowpart (SImode, operands[1]));
19210 emit_insn (gen_xorsi3 (xor1, hipart1, lopart1));
19212 emit_insn (gen_lshrsi3 (shift2, xor1, GEN_INT (16)));
19213 emit_move_insn (hipart2, gen_lowpart (HImode, shift2));
19214 emit_move_insn (lopart2, gen_lowpart (HImode, xor1));
19215 emit_insn (gen_xorhi3 (xor2, hipart2, lopart2));
19217 emit_insn (gen_parityhi2_cmp (xor2));
19219 ix86_expand_setcc (scratch, ORDERED,
19220 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19223 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
19226 rtx tmp = gen_reg_rtx (SImode);
19228 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
19229 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
19234 (define_expand "paritysi2"
19235 [(set (match_operand:SI 0 "register_operand")
19236 (parity:SI (match_operand:SI 1 "register_operand")))]
19239 rtx scratch = gen_reg_rtx (QImode);
19240 rtx shift = gen_reg_rtx (SImode);
19241 rtx hipart = gen_reg_rtx (HImode);
19242 rtx lopart = gen_reg_rtx (HImode);
19243 rtx tmp = gen_reg_rtx (HImode);
19245 emit_insn (gen_lshrsi3 (shift, operands[1], GEN_INT (16)));
19246 emit_move_insn (hipart, gen_lowpart (HImode, shift));
19247 emit_move_insn (lopart, gen_lowpart (HImode, operands[1]));
19248 emit_insn (gen_xorhi3 (tmp, hipart, lopart));
19250 emit_insn (gen_parityhi2_cmp (tmp));
19252 ix86_expand_setcc (scratch, ORDERED,
19253 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19255 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
19259 (define_expand "parityhi2"
19260 [(set (match_operand:HI 0 "register_operand")
19261 (parity:HI (match_operand:HI 1 "register_operand")))]
19264 rtx scratch = gen_reg_rtx (QImode);
19266 emit_insn (gen_parityhi2_cmp (operands[1]));
19268 ix86_expand_setcc (scratch, ORDERED,
19269 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19271 emit_insn (gen_zero_extendqihi2 (operands[0], scratch));
19275 (define_expand "parityqi2"
19276 [(set (match_operand:QI 0 "register_operand")
19277 (parity:QI (match_operand:QI 1 "register_operand")))]
19280 emit_insn (gen_parityqi2_cmp (operands[1]));
19282 ix86_expand_setcc (operands[0], ORDERED,
19283 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19287 (define_insn "parityhi2_cmp"
19288 [(set (reg:CC FLAGS_REG)
19289 (unspec:CC [(match_operand:HI 0 "register_operand" "+Q")]
19291 (clobber (match_dup 0))]
19293 "xor{b}\t{%h0, %b0|%b0, %h0}"
19294 [(set_attr "length" "2")
19295 (set_attr "mode" "QI")])
19297 (define_insn "parityqi2_cmp"
19298 [(set (reg:CC FLAGS_REG)
19299 (unspec:CC [(match_operand:QI 0 "register_operand" "q")]
19303 [(set_attr "mode" "QI")])
19305 ;; Replace zero_extend:HI followed by parityhi2_cmp with parityqi2_cmp
19307 [(set (match_operand:HI 0 "register_operand")
19308 (zero_extend:HI (match_operand:QI 1 "general_reg_operand")))
19309 (parallel [(set (reg:CC FLAGS_REG)
19310 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
19311 (clobber (match_dup 0))])]
19313 [(set (reg:CC FLAGS_REG)
19314 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))])
19316 ;; Eliminate QImode popcount&1 using parity flag
19318 [(set (match_operand:SI 0 "register_operand")
19319 (zero_extend:SI (match_operand:QI 1 "general_reg_operand")))
19320 (parallel [(set (match_operand:SI 2 "register_operand")
19321 (popcount:SI (match_dup 0)))
19322 (clobber (reg:CC FLAGS_REG))])
19323 (set (reg:CCZ FLAGS_REG)
19324 (compare:CCZ (and:QI (match_operand:QI 3 "register_operand")
19327 (set (pc) (if_then_else (match_operator 4 "bt_comparison_operator"
19328 [(reg:CCZ FLAGS_REG)
19330 (label_ref (match_operand 5))
19332 "REGNO (operands[2]) == REGNO (operands[3])
19333 && peep2_reg_dead_p (3, operands[0])
19334 && peep2_reg_dead_p (3, operands[2])
19335 && peep2_regno_dead_p (4, FLAGS_REG)"
19336 [(set (reg:CC FLAGS_REG)
19337 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
19338 (set (pc) (if_then_else (match_op_dup 4 [(reg:CC FLAGS_REG)
19340 (label_ref (match_dup 5))
19343 operands[4] = shallow_copy_rtx (operands[4]);
19344 PUT_CODE (operands[4], GET_CODE (operands[4]) == EQ ? UNORDERED : ORDERED);
19347 ;; Eliminate HImode popcount&1 using parity flag
19349 [(match_scratch:HI 0 "Q")
19350 (parallel [(set (match_operand:HI 1 "register_operand")
19352 (match_operand:HI 2 "nonimmediate_operand")))
19353 (clobber (reg:CC FLAGS_REG))])
19354 (set (match_operand 3 "register_operand")
19355 (zero_extend (match_dup 1)))
19356 (set (reg:CCZ FLAGS_REG)
19357 (compare:CCZ (and:QI (match_operand:QI 4 "register_operand")
19360 (set (pc) (if_then_else (match_operator 5 "bt_comparison_operator"
19361 [(reg:CCZ FLAGS_REG)
19363 (label_ref (match_operand 6))
19365 "REGNO (operands[3]) == REGNO (operands[4])
19366 && peep2_reg_dead_p (3, operands[1])
19367 && peep2_reg_dead_p (3, operands[3])
19368 && peep2_regno_dead_p (4, FLAGS_REG)"
19369 [(set (match_dup 0) (match_dup 2))
19370 (parallel [(set (reg:CC FLAGS_REG)
19371 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
19372 (clobber (match_dup 0))])
19373 (set (pc) (if_then_else (match_op_dup 5 [(reg:CC FLAGS_REG)
19375 (label_ref (match_dup 6))
19378 operands[5] = shallow_copy_rtx (operands[5]);
19379 PUT_CODE (operands[5], GET_CODE (operands[5]) == EQ ? UNORDERED : ORDERED);
19382 ;; Eliminate HImode popcount&1 using parity flag (variant 2)
19384 [(match_scratch:HI 0 "Q")
19385 (parallel [(set (match_operand:HI 1 "register_operand")
19387 (match_operand:HI 2 "nonimmediate_operand")))
19388 (clobber (reg:CC FLAGS_REG))])
19389 (set (reg:CCZ FLAGS_REG)
19390 (compare:CCZ (and:QI (match_operand:QI 3 "register_operand")
19393 (set (pc) (if_then_else (match_operator 4 "bt_comparison_operator"
19394 [(reg:CCZ FLAGS_REG)
19396 (label_ref (match_operand 5))
19398 "REGNO (operands[1]) == REGNO (operands[3])
19399 && peep2_reg_dead_p (2, operands[1])
19400 && peep2_reg_dead_p (2, operands[3])
19401 && peep2_regno_dead_p (3, FLAGS_REG)"
19402 [(set (match_dup 0) (match_dup 2))
19403 (parallel [(set (reg:CC FLAGS_REG)
19404 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
19405 (clobber (match_dup 0))])
19406 (set (pc) (if_then_else (match_op_dup 4 [(reg:CC FLAGS_REG)
19408 (label_ref (match_dup 5))
19411 operands[4] = shallow_copy_rtx (operands[4]);
19412 PUT_CODE (operands[4], GET_CODE (operands[4]) == EQ ? UNORDERED : ORDERED);
19416 ;; Thread-local storage patterns for ELF.
19418 ;; Note that these code sequences must appear exactly as shown
19419 ;; in order to allow linker relaxation.
19421 (define_insn "*tls_global_dynamic_32_gnu"
19422 [(set (match_operand:SI 0 "register_operand" "=a")
19424 [(match_operand:SI 1 "register_operand" "Yb")
19425 (match_operand 2 "tls_symbolic_operand")
19426 (match_operand 3 "constant_call_address_operand" "Bz")
19429 (clobber (match_scratch:SI 4 "=d"))
19430 (clobber (match_scratch:SI 5 "=c"))
19431 (clobber (reg:CC FLAGS_REG))]
19432 "!TARGET_64BIT && TARGET_GNU_TLS"
19434 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19436 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
19439 ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
19440 if (TARGET_SUN_TLS)
19441 #ifdef HAVE_AS_IX86_TLSGDPLT
19442 return "call\t%a2@tlsgdplt";
19444 return "call\t%p3@plt";
19446 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19447 return "call\t%P3";
19448 return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
19450 [(set_attr "type" "multi")
19451 (set_attr "length" "12")])
19453 (define_expand "tls_global_dynamic_32"
19455 [(set (match_operand:SI 0 "register_operand")
19456 (unspec:SI [(match_operand:SI 2 "register_operand")
19457 (match_operand 1 "tls_symbolic_operand")
19458 (match_operand 3 "constant_call_address_operand")
19461 (clobber (scratch:SI))
19462 (clobber (scratch:SI))
19463 (clobber (reg:CC FLAGS_REG))])]
19465 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
19467 (define_insn "*tls_global_dynamic_64_<mode>"
19468 [(set (match_operand:P 0 "register_operand" "=a")
19470 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
19471 (match_operand 3)))
19472 (unspec:P [(match_operand 1 "tls_symbolic_operand")
19478 /* The .loc directive has effect for 'the immediately following assembly
19479 instruction'. So for a sequence:
19483 the 'immediately following assembly instruction' is insn1.
19484 We want to emit an insn prefix here, but if we use .byte (as shown in
19485 'ELF Handling For Thread-Local Storage'), a preceding .loc will point
19486 inside the insn sequence, rather than to the start. After relaxation
19487 of the sequence by the linker, the .loc might point inside an insn.
19488 Use data16 prefix instead, which doesn't have this problem. */
19489 fputs ("\tdata16", asm_out_file);
19491 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
19492 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19493 fputs (ASM_SHORT "0x6666\n", asm_out_file);
19495 fputs (ASM_BYTE "0x66\n", asm_out_file);
19496 fputs ("\trex64\n", asm_out_file);
19497 if (TARGET_SUN_TLS)
19498 return "call\t%p2@plt";
19499 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19500 return "call\t%P2";
19501 return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
19503 [(set_attr "type" "multi")
19504 (set (attr "length")
19505 (symbol_ref "TARGET_X32 ? 15 : 16"))])
19507 (define_insn "*tls_global_dynamic_64_largepic"
19508 [(set (match_operand:DI 0 "register_operand" "=a")
19510 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
19511 (match_operand:DI 3 "immediate_operand" "i")))
19512 (match_operand 4)))
19513 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
19516 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
19517 && GET_CODE (operands[3]) == CONST
19518 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
19519 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
19522 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
19523 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
19524 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
19525 return "call\t{*%%rax|rax}";
19527 [(set_attr "type" "multi")
19528 (set_attr "length" "22")])
19530 (define_expand "@tls_global_dynamic_64_<mode>"
19532 [(set (match_operand:P 0 "register_operand")
19534 (mem:QI (match_operand 2))
19536 (unspec:P [(match_operand 1 "tls_symbolic_operand")
19540 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
19542 (define_insn "*tls_local_dynamic_base_32_gnu"
19543 [(set (match_operand:SI 0 "register_operand" "=a")
19545 [(match_operand:SI 1 "register_operand" "Yb")
19546 (match_operand 2 "constant_call_address_operand" "Bz")
19548 UNSPEC_TLS_LD_BASE))
19549 (clobber (match_scratch:SI 3 "=d"))
19550 (clobber (match_scratch:SI 4 "=c"))
19551 (clobber (reg:CC FLAGS_REG))]
19552 "!TARGET_64BIT && TARGET_GNU_TLS"
19555 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
19556 if (TARGET_SUN_TLS)
19558 if (HAVE_AS_IX86_TLSLDMPLT)
19559 return "call\t%&@tlsldmplt";
19561 return "call\t%p2@plt";
19563 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19564 return "call\t%P2";
19565 return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
19567 [(set_attr "type" "multi")
19568 (set_attr "length" "11")])
19570 (define_expand "tls_local_dynamic_base_32"
19572 [(set (match_operand:SI 0 "register_operand")
19574 [(match_operand:SI 1 "register_operand")
19575 (match_operand 2 "constant_call_address_operand")
19577 UNSPEC_TLS_LD_BASE))
19578 (clobber (scratch:SI))
19579 (clobber (scratch:SI))
19580 (clobber (reg:CC FLAGS_REG))])]
19582 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
19584 (define_insn "*tls_local_dynamic_base_64_<mode>"
19585 [(set (match_operand:P 0 "register_operand" "=a")
19587 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
19588 (match_operand 2)))
19589 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
19593 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
19594 if (TARGET_SUN_TLS)
19595 return "call\t%p1@plt";
19596 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19597 return "call\t%P1";
19598 return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
19600 [(set_attr "type" "multi")
19601 (set_attr "length" "12")])
19603 (define_insn "*tls_local_dynamic_base_64_largepic"
19604 [(set (match_operand:DI 0 "register_operand" "=a")
19606 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
19607 (match_operand:DI 2 "immediate_operand" "i")))
19608 (match_operand 3)))
19609 (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
19610 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
19611 && GET_CODE (operands[2]) == CONST
19612 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
19613 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
19616 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
19617 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
19618 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
19619 return "call\t{*%%rax|rax}";
19621 [(set_attr "type" "multi")
19622 (set_attr "length" "22")])
19624 (define_expand "@tls_local_dynamic_base_64_<mode>"
19626 [(set (match_operand:P 0 "register_operand")
19628 (mem:QI (match_operand 1))
19630 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
19632 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
19634 ;; Local dynamic of a single variable is a lose. Show combine how
19635 ;; to convert that back to global dynamic.
19637 (define_insn_and_split "*tls_local_dynamic_32_once"
19638 [(set (match_operand:SI 0 "register_operand" "=a")
19640 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
19641 (match_operand 2 "constant_call_address_operand" "Bz")
19643 UNSPEC_TLS_LD_BASE)
19644 (const:SI (unspec:SI
19645 [(match_operand 3 "tls_symbolic_operand")]
19647 (clobber (match_scratch:SI 4 "=d"))
19648 (clobber (match_scratch:SI 5 "=c"))
19649 (clobber (reg:CC FLAGS_REG))]
19654 [(set (match_dup 0)
19655 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
19658 (clobber (match_dup 4))
19659 (clobber (match_dup 5))
19660 (clobber (reg:CC FLAGS_REG))])])
19662 ;; Load and add the thread base pointer from %<tp_seg>:0.
19663 (define_expand "get_thread_pointer<mode>"
19664 [(set (match_operand:PTR 0 "register_operand")
19665 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
19668 /* targetm is not visible in the scope of the condition. */
19669 if (!targetm.have_tls)
19670 error ("%<__builtin_thread_pointer%> is not supported on this target");
19673 (define_insn_and_split "*load_tp_<mode>"
19674 [(set (match_operand:PTR 0 "register_operand" "=r")
19675 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
19679 [(set (match_dup 0)
19682 addr_space_t as = DEFAULT_TLS_SEG_REG;
19684 operands[1] = gen_const_mem (<MODE>mode, const0_rtx);
19685 set_mem_addr_space (operands[1], as);
19688 (define_insn_and_split "*load_tp_x32_zext"
19689 [(set (match_operand:DI 0 "register_operand" "=r")
19691 (unspec:SI [(const_int 0)] UNSPEC_TP)))]
19695 [(set (match_dup 0)
19696 (zero_extend:DI (match_dup 1)))]
19698 addr_space_t as = DEFAULT_TLS_SEG_REG;
19700 operands[1] = gen_const_mem (SImode, const0_rtx);
19701 set_mem_addr_space (operands[1], as);
19704 (define_insn_and_split "*add_tp_<mode>"
19705 [(set (match_operand:PTR 0 "register_operand" "=r")
19707 (unspec:PTR [(const_int 0)] UNSPEC_TP)
19708 (match_operand:PTR 1 "register_operand" "0")))
19709 (clobber (reg:CC FLAGS_REG))]
19714 [(set (match_dup 0)
19715 (plus:PTR (match_dup 1) (match_dup 2)))
19716 (clobber (reg:CC FLAGS_REG))])]
19718 addr_space_t as = DEFAULT_TLS_SEG_REG;
19720 operands[2] = gen_const_mem (<MODE>mode, const0_rtx);
19721 set_mem_addr_space (operands[2], as);
19724 (define_insn_and_split "*add_tp_x32_zext"
19725 [(set (match_operand:DI 0 "register_operand" "=r")
19727 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
19728 (match_operand:SI 1 "register_operand" "0"))))
19729 (clobber (reg:CC FLAGS_REG))]
19734 [(set (match_dup 0)
19736 (plus:SI (match_dup 1) (match_dup 2))))
19737 (clobber (reg:CC FLAGS_REG))])]
19739 addr_space_t as = DEFAULT_TLS_SEG_REG;
19741 operands[2] = gen_const_mem (SImode, const0_rtx);
19742 set_mem_addr_space (operands[2], as);
19745 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
19746 ;; %rax as destination of the initial executable code sequence.
19747 (define_insn "tls_initial_exec_64_sun"
19748 [(set (match_operand:DI 0 "register_operand" "=a")
19750 [(match_operand 1 "tls_symbolic_operand")]
19751 UNSPEC_TLS_IE_SUN))
19752 (clobber (reg:CC FLAGS_REG))]
19753 "TARGET_64BIT && TARGET_SUN_TLS"
19756 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
19757 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
19759 [(set_attr "type" "multi")])
19761 ;; GNU2 TLS patterns can be split.
19763 (define_expand "tls_dynamic_gnu2_32"
19764 [(set (match_dup 3)
19765 (plus:SI (match_operand:SI 2 "register_operand")
19767 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
19770 [(set (match_operand:SI 0 "register_operand")
19771 (unspec:SI [(match_dup 1) (match_dup 3)
19772 (match_dup 2) (reg:SI SP_REG)]
19774 (clobber (reg:CC FLAGS_REG))])]
19775 "!TARGET_64BIT && TARGET_GNU2_TLS"
19777 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
19778 ix86_tls_descriptor_calls_expanded_in_cfun = true;
19781 (define_insn "*tls_dynamic_gnu2_lea_32"
19782 [(set (match_operand:SI 0 "register_operand" "=r")
19783 (plus:SI (match_operand:SI 1 "register_operand" "b")
19785 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
19786 UNSPEC_TLSDESC))))]
19787 "!TARGET_64BIT && TARGET_GNU2_TLS"
19788 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
19789 [(set_attr "type" "lea")
19790 (set_attr "mode" "SI")
19791 (set_attr "length" "6")
19792 (set_attr "length_address" "4")])
19794 (define_insn "*tls_dynamic_gnu2_call_32"
19795 [(set (match_operand:SI 0 "register_operand" "=a")
19796 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
19797 (match_operand:SI 2 "register_operand" "0")
19798 ;; we have to make sure %ebx still points to the GOT
19799 (match_operand:SI 3 "register_operand" "b")
19802 (clobber (reg:CC FLAGS_REG))]
19803 "!TARGET_64BIT && TARGET_GNU2_TLS"
19804 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
19805 [(set_attr "type" "call")
19806 (set_attr "length" "2")
19807 (set_attr "length_address" "0")])
19809 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
19810 [(set (match_operand:SI 0 "register_operand" "=&a")
19812 (unspec:SI [(match_operand 3 "tls_modbase_operand")
19813 (match_operand:SI 4)
19814 (match_operand:SI 2 "register_operand" "b")
19817 (const:SI (unspec:SI
19818 [(match_operand 1 "tls_symbolic_operand")]
19820 (clobber (reg:CC FLAGS_REG))]
19821 "!TARGET_64BIT && TARGET_GNU2_TLS"
19824 [(set (match_dup 0) (match_dup 5))]
19826 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
19827 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
19830 (define_expand "@tls_dynamic_gnu2_64_<mode>"
19831 [(set (match_dup 2)
19832 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")]
19835 [(set (match_operand:PTR 0 "register_operand")
19836 (unspec:PTR [(match_dup 1) (match_dup 2) (reg:PTR SP_REG)]
19838 (clobber (reg:CC FLAGS_REG))])]
19839 "TARGET_64BIT && TARGET_GNU2_TLS"
19841 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (ptr_mode) : operands[0];
19842 ix86_tls_descriptor_calls_expanded_in_cfun = true;
19845 (define_insn "*tls_dynamic_gnu2_lea_64_<mode>"
19846 [(set (match_operand:PTR 0 "register_operand" "=r")
19847 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")]
19849 "TARGET_64BIT && TARGET_GNU2_TLS"
19850 "lea%z0\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
19851 [(set_attr "type" "lea")
19852 (set_attr "mode" "<MODE>")
19853 (set_attr "length" "7")
19854 (set_attr "length_address" "4")])
19856 (define_insn "*tls_dynamic_gnu2_call_64_<mode>"
19857 [(set (match_operand:PTR 0 "register_operand" "=a")
19858 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")
19859 (match_operand:PTR 2 "register_operand" "0")
19862 (clobber (reg:CC FLAGS_REG))]
19863 "TARGET_64BIT && TARGET_GNU2_TLS"
19864 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
19865 [(set_attr "type" "call")
19866 (set_attr "length" "2")
19867 (set_attr "length_address" "0")])
19869 (define_insn_and_split "*tls_dynamic_gnu2_combine_64_<mode>"
19870 [(set (match_operand:PTR 0 "register_operand" "=&a")
19872 (unspec:PTR [(match_operand 2 "tls_modbase_operand")
19873 (match_operand:PTR 3)
19876 (const:PTR (unspec:PTR
19877 [(match_operand 1 "tls_symbolic_operand")]
19879 (clobber (reg:CC FLAGS_REG))]
19880 "TARGET_64BIT && TARGET_GNU2_TLS"
19883 [(set (match_dup 0) (match_dup 4))]
19885 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (ptr_mode) : operands[0];
19886 emit_insn (gen_tls_dynamic_gnu2_64 (ptr_mode, operands[4], operands[1]));
19890 [(match_operand 0 "tls_address_pattern")]
19891 "TARGET_TLS_DIRECT_SEG_REFS"
19893 "operands[0] = ix86_rewrite_tls_address (operands[0]);")
19896 ;; These patterns match the binary 387 instructions for addM3, subM3,
19897 ;; mulM3 and divM3. There are three patterns for each of DFmode and
19898 ;; SFmode. The first is the normal insn, the second the same insn but
19899 ;; with one operand a conversion, and the third the same insn but with
19900 ;; the other operand a conversion. The conversion may be SFmode or
19901 ;; SImode if the target mode DFmode, but only SImode if the target mode
19904 ;; Gcc is slightly more smart about handling normal two address instructions
19905 ;; so use special patterns for add and mull.
19907 (define_insn "*fop_xf_comm_i387"
19908 [(set (match_operand:XF 0 "register_operand" "=f")
19909 (match_operator:XF 3 "binary_fp_operator"
19910 [(match_operand:XF 1 "register_operand" "%0")
19911 (match_operand:XF 2 "register_operand" "f")]))]
19913 && COMMUTATIVE_ARITH_P (operands[3])"
19914 "* return output_387_binary_op (insn, operands);"
19915 [(set (attr "type")
19916 (if_then_else (match_operand:XF 3 "mult_operator")
19917 (const_string "fmul")
19918 (const_string "fop")))
19919 (set_attr "mode" "XF")])
19921 (define_insn "*fop_<mode>_comm"
19922 [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
19923 (match_operator:MODEF 3 "binary_fp_operator"
19924 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
19925 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
19926 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
19927 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
19928 && COMMUTATIVE_ARITH_P (operands[3])
19929 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
19930 "* return output_387_binary_op (insn, operands);"
19931 [(set (attr "type")
19932 (if_then_else (eq_attr "alternative" "1,2")
19933 (if_then_else (match_operand:MODEF 3 "mult_operator")
19934 (const_string "ssemul")
19935 (const_string "sseadd"))
19936 (if_then_else (match_operand:MODEF 3 "mult_operator")
19937 (const_string "fmul")
19938 (const_string "fop"))))
19939 (set_attr "isa" "*,noavx,avx")
19940 (set_attr "prefix" "orig,orig,vex")
19941 (set_attr "mode" "<MODE>")
19942 (set (attr "enabled")
19944 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
19946 (eq_attr "alternative" "0")
19947 (symbol_ref "TARGET_MIX_SSE_I387
19948 && X87_ENABLE_ARITH (<MODE>mode)")
19949 (const_string "*"))
19951 (eq_attr "alternative" "0")
19952 (symbol_ref "true")
19953 (symbol_ref "false"))))])
19955 (define_insn "*<insn>hf"
19956 [(set (match_operand:HF 0 "register_operand" "=v")
19957 (plusminusmultdiv:HF
19958 (match_operand:HF 1 "nonimmediate_operand" "<comm>v")
19959 (match_operand:HF 2 "nonimmediate_operand" "vm")))]
19961 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
19962 "v<insn>sh\t{%2, %1, %0|%0, %1, %2}"
19963 [(set_attr "prefix" "evex")
19964 (set_attr "mode" "HF")])
19966 (define_insn "*rcpsf2_sse"
19967 [(set (match_operand:SF 0 "register_operand" "=x,x,x")
19968 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m")]
19970 "TARGET_SSE && TARGET_SSE_MATH"
19972 %vrcpss\t{%d1, %0|%0, %d1}
19973 %vrcpss\t{%d1, %0|%0, %d1}
19974 %vrcpss\t{%1, %d0|%d0, %1}"
19975 [(set_attr "type" "sse")
19976 (set_attr "atom_sse_attr" "rcp")
19977 (set_attr "btver2_sse_attr" "rcp")
19978 (set_attr "prefix" "maybe_vex")
19979 (set_attr "mode" "SF")
19980 (set_attr "avx_partial_xmm_update" "false,false,true")
19981 (set (attr "preferred_for_speed")
19982 (cond [(match_test "TARGET_AVX")
19983 (symbol_ref "true")
19984 (eq_attr "alternative" "1,2")
19985 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
19987 (symbol_ref "true")))])
19989 (define_insn "rcphf2"
19990 [(set (match_operand:HF 0 "register_operand" "=v,v")
19991 (unspec:HF [(match_operand:HF 1 "nonimmediate_operand" "v,m")]
19993 "TARGET_AVX512FP16"
19995 vrcpsh\t{%d1, %0|%0, %d1}
19996 vrcpsh\t{%1, %d0|%d0, %1}"
19997 [(set_attr "type" "sse")
19998 (set_attr "prefix" "evex")
19999 (set_attr "mode" "HF")
20000 (set_attr "avx_partial_xmm_update" "false,true")])
20002 (define_insn "*fop_xf_1_i387"
20003 [(set (match_operand:XF 0 "register_operand" "=f,f")
20004 (match_operator:XF 3 "binary_fp_operator"
20005 [(match_operand:XF 1 "register_operand" "0,f")
20006 (match_operand:XF 2 "register_operand" "f,0")]))]
20008 && !COMMUTATIVE_ARITH_P (operands[3])"
20009 "* return output_387_binary_op (insn, operands);"
20010 [(set (attr "type")
20011 (if_then_else (match_operand:XF 3 "div_operator")
20012 (const_string "fdiv")
20013 (const_string "fop")))
20014 (set_attr "mode" "XF")])
20016 (define_insn "*fop_<mode>_1"
20017 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
20018 (match_operator:MODEF 3 "binary_fp_operator"
20019 [(match_operand:MODEF 1
20020 "x87nonimm_ssenomem_operand" "0,fm,0,v")
20021 (match_operand:MODEF 2
20022 "nonimmediate_operand" "fm,0,xm,vm")]))]
20023 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20024 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
20025 && !COMMUTATIVE_ARITH_P (operands[3])
20026 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
20027 "* return output_387_binary_op (insn, operands);"
20028 [(set (attr "type")
20029 (if_then_else (eq_attr "alternative" "2,3")
20030 (if_then_else (match_operand:MODEF 3 "div_operator")
20031 (const_string "ssediv")
20032 (const_string "sseadd"))
20033 (if_then_else (match_operand:MODEF 3 "div_operator")
20034 (const_string "fdiv")
20035 (const_string "fop"))))
20036 (set_attr "isa" "*,*,noavx,avx")
20037 (set_attr "prefix" "orig,orig,orig,vex")
20038 (set_attr "mode" "<MODE>")
20039 (set (attr "enabled")
20041 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
20043 (eq_attr "alternative" "0,1")
20044 (symbol_ref "TARGET_MIX_SSE_I387
20045 && X87_ENABLE_ARITH (<MODE>mode)")
20046 (const_string "*"))
20048 (eq_attr "alternative" "0,1")
20049 (symbol_ref "true")
20050 (symbol_ref "false"))))])
20052 (define_insn "*fop_<X87MODEF:mode>_2_i387"
20053 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
20054 (match_operator:X87MODEF 3 "binary_fp_operator"
20056 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
20057 (match_operand:X87MODEF 2 "register_operand" "0")]))]
20058 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
20059 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
20060 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
20061 || optimize_function_for_size_p (cfun))"
20062 "* return output_387_binary_op (insn, operands);"
20063 [(set (attr "type")
20064 (cond [(match_operand:X87MODEF 3 "mult_operator")
20065 (const_string "fmul")
20066 (match_operand:X87MODEF 3 "div_operator")
20067 (const_string "fdiv")
20069 (const_string "fop")))
20070 (set_attr "fp_int_src" "true")
20071 (set_attr "mode" "<SWI24:MODE>")])
20073 (define_insn "*fop_<X87MODEF:mode>_3_i387"
20074 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
20075 (match_operator:X87MODEF 3 "binary_fp_operator"
20076 [(match_operand:X87MODEF 1 "register_operand" "0")
20078 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
20079 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
20080 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
20081 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
20082 || optimize_function_for_size_p (cfun))"
20083 "* return output_387_binary_op (insn, operands);"
20084 [(set (attr "type")
20085 (cond [(match_operand:X87MODEF 3 "mult_operator")
20086 (const_string "fmul")
20087 (match_operand:X87MODEF 3 "div_operator")
20088 (const_string "fdiv")
20090 (const_string "fop")))
20091 (set_attr "fp_int_src" "true")
20092 (set_attr "mode" "<SWI24:MODE>")])
20094 (define_insn "*fop_xf_4_i387"
20095 [(set (match_operand:XF 0 "register_operand" "=f,f")
20096 (match_operator:XF 3 "binary_fp_operator"
20098 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
20099 (match_operand:XF 2 "register_operand" "0,f")]))]
20101 "* return output_387_binary_op (insn, operands);"
20102 [(set (attr "type")
20103 (cond [(match_operand:XF 3 "mult_operator")
20104 (const_string "fmul")
20105 (match_operand:XF 3 "div_operator")
20106 (const_string "fdiv")
20108 (const_string "fop")))
20109 (set_attr "mode" "<MODE>")])
20111 (define_insn "*fop_df_4_i387"
20112 [(set (match_operand:DF 0 "register_operand" "=f,f")
20113 (match_operator:DF 3 "binary_fp_operator"
20115 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
20116 (match_operand:DF 2 "register_operand" "0,f")]))]
20117 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
20118 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
20119 "* return output_387_binary_op (insn, operands);"
20120 [(set (attr "type")
20121 (cond [(match_operand:DF 3 "mult_operator")
20122 (const_string "fmul")
20123 (match_operand:DF 3 "div_operator")
20124 (const_string "fdiv")
20126 (const_string "fop")))
20127 (set_attr "mode" "SF")])
20129 (define_insn "*fop_xf_5_i387"
20130 [(set (match_operand:XF 0 "register_operand" "=f,f")
20131 (match_operator:XF 3 "binary_fp_operator"
20132 [(match_operand:XF 1 "register_operand" "0,f")
20134 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
20136 "* return output_387_binary_op (insn, operands);"
20137 [(set (attr "type")
20138 (cond [(match_operand:XF 3 "mult_operator")
20139 (const_string "fmul")
20140 (match_operand:XF 3 "div_operator")
20141 (const_string "fdiv")
20143 (const_string "fop")))
20144 (set_attr "mode" "<MODE>")])
20146 (define_insn "*fop_df_5_i387"
20147 [(set (match_operand:DF 0 "register_operand" "=f,f")
20148 (match_operator:DF 3 "binary_fp_operator"
20149 [(match_operand:DF 1 "register_operand" "0,f")
20151 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
20152 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
20153 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
20154 "* return output_387_binary_op (insn, operands);"
20155 [(set (attr "type")
20156 (cond [(match_operand:DF 3 "mult_operator")
20157 (const_string "fmul")
20158 (match_operand:DF 3 "div_operator")
20159 (const_string "fdiv")
20161 (const_string "fop")))
20162 (set_attr "mode" "SF")])
20164 (define_insn "*fop_xf_6_i387"
20165 [(set (match_operand:XF 0 "register_operand" "=f,f")
20166 (match_operator:XF 3 "binary_fp_operator"
20168 (match_operand:MODEF 1 "register_operand" "0,f"))
20170 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
20172 "* return output_387_binary_op (insn, operands);"
20173 [(set (attr "type")
20174 (cond [(match_operand:XF 3 "mult_operator")
20175 (const_string "fmul")
20176 (match_operand:XF 3 "div_operator")
20177 (const_string "fdiv")
20179 (const_string "fop")))
20180 (set_attr "mode" "<MODE>")])
20182 (define_insn "*fop_df_6_i387"
20183 [(set (match_operand:DF 0 "register_operand" "=f,f")
20184 (match_operator:DF 3 "binary_fp_operator"
20186 (match_operand:SF 1 "register_operand" "0,f"))
20188 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
20189 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
20190 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
20191 "* return output_387_binary_op (insn, operands);"
20192 [(set (attr "type")
20193 (cond [(match_operand:DF 3 "mult_operator")
20194 (const_string "fmul")
20195 (match_operand:DF 3 "div_operator")
20196 (const_string "fdiv")
20198 (const_string "fop")))
20199 (set_attr "mode" "SF")])
20201 ;; FPU special functions.
20203 ;; This pattern implements a no-op XFmode truncation for
20204 ;; all fancy i386 XFmode math functions.
20206 (define_insn "truncxf<mode>2_i387_noop_unspec"
20207 [(set (match_operand:MODEF 0 "nonimmediate_operand" "=mf")
20208 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
20209 UNSPEC_TRUNC_NOOP))]
20210 "TARGET_USE_FANCY_MATH_387"
20211 "* return output_387_reg_move (insn, operands);"
20212 [(set_attr "type" "fmov")
20213 (set_attr "mode" "<MODE>")])
20215 (define_insn "sqrtxf2"
20216 [(set (match_operand:XF 0 "register_operand" "=f")
20217 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
20218 "TARGET_USE_FANCY_MATH_387"
20220 [(set_attr "type" "fpspc")
20221 (set_attr "mode" "XF")
20222 (set_attr "athlon_decode" "direct")
20223 (set_attr "amdfam10_decode" "direct")
20224 (set_attr "bdver1_decode" "direct")])
20226 (define_insn "*rsqrtsf2_sse"
20227 [(set (match_operand:SF 0 "register_operand" "=x,x,x")
20228 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m")]
20230 "TARGET_SSE && TARGET_SSE_MATH"
20232 %vrsqrtss\t{%d1, %0|%0, %d1}
20233 %vrsqrtss\t{%d1, %0|%0, %d1}
20234 %vrsqrtss\t{%1, %d0|%d0, %1}"
20235 [(set_attr "type" "sse")
20236 (set_attr "atom_sse_attr" "rcp")
20237 (set_attr "btver2_sse_attr" "rcp")
20238 (set_attr "prefix" "maybe_vex")
20239 (set_attr "mode" "SF")
20240 (set_attr "avx_partial_xmm_update" "false,false,true")
20241 (set (attr "preferred_for_speed")
20242 (cond [(match_test "TARGET_AVX")
20243 (symbol_ref "true")
20244 (eq_attr "alternative" "1,2")
20245 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
20247 (symbol_ref "true")))])
20249 (define_expand "rsqrtsf2"
20250 [(set (match_operand:SF 0 "register_operand")
20251 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
20253 "TARGET_SSE && TARGET_SSE_MATH"
20255 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
20259 (define_insn "rsqrthf2"
20260 [(set (match_operand:HF 0 "register_operand" "=v,v")
20261 (unspec:HF [(match_operand:HF 1 "nonimmediate_operand" "v,m")]
20263 "TARGET_AVX512FP16"
20265 vrsqrtsh\t{%d1, %0|%0, %d1}
20266 vrsqrtsh\t{%1, %d0|%d0, %1}"
20267 [(set_attr "type" "sse")
20268 (set_attr "prefix" "evex")
20269 (set_attr "avx_partial_xmm_update" "false,true")
20270 (set_attr "mode" "HF")])
20272 (define_insn "sqrthf2"
20273 [(set (match_operand:HF 0 "register_operand" "=v,v")
20275 (match_operand:HF 1 "nonimmediate_operand" "v,m")))]
20276 "TARGET_AVX512FP16"
20278 vsqrtsh\t{%d1, %0|%0, %d1}
20279 vsqrtsh\t{%1, %d0|%d0, %1}"
20280 [(set_attr "type" "sse")
20281 (set_attr "prefix" "evex")
20282 (set_attr "avx_partial_xmm_update" "false,true")
20283 (set_attr "mode" "HF")])
20285 (define_insn "*sqrt<mode>2_sse"
20286 [(set (match_operand:MODEF 0 "register_operand" "=v,v,v")
20288 (match_operand:MODEF 1 "nonimmediate_operand" "0,v,m")))]
20289 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20291 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
20292 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
20293 %vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
20294 [(set_attr "type" "sse")
20295 (set_attr "atom_sse_attr" "sqrt")
20296 (set_attr "btver2_sse_attr" "sqrt")
20297 (set_attr "prefix" "maybe_vex")
20298 (set_attr "avx_partial_xmm_update" "false,false,true")
20299 (set_attr "mode" "<MODE>")
20300 (set (attr "preferred_for_speed")
20301 (cond [(match_test "TARGET_AVX")
20302 (symbol_ref "true")
20303 (eq_attr "alternative" "1,2")
20304 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
20306 (symbol_ref "true")))])
20308 (define_expand "sqrt<mode>2"
20309 [(set (match_operand:MODEF 0 "register_operand")
20311 (match_operand:MODEF 1 "nonimmediate_operand")))]
20312 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
20313 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
20315 if (<MODE>mode == SFmode
20316 && TARGET_SSE && TARGET_SSE_MATH
20317 && TARGET_RECIP_SQRT
20318 && !optimize_function_for_size_p (cfun)
20319 && flag_finite_math_only && !flag_trapping_math
20320 && flag_unsafe_math_optimizations)
20322 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
20326 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
20328 rtx op0 = gen_reg_rtx (XFmode);
20329 rtx op1 = gen_reg_rtx (XFmode);
20331 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20332 emit_insn (gen_sqrtxf2 (op0, op1));
20333 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
20338 (define_expand "hypot<mode>3"
20339 [(use (match_operand:MODEF 0 "register_operand"))
20340 (use (match_operand:MODEF 1 "general_operand"))
20341 (use (match_operand:MODEF 2 "general_operand"))]
20342 "TARGET_USE_FANCY_MATH_387
20343 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20344 || TARGET_MIX_SSE_I387)
20345 && flag_finite_math_only
20346 && flag_unsafe_math_optimizations"
20348 rtx op0 = gen_reg_rtx (XFmode);
20349 rtx op1 = gen_reg_rtx (XFmode);
20350 rtx op2 = gen_reg_rtx (XFmode);
20352 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20353 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20355 emit_insn (gen_mulxf3 (op1, op1, op1));
20356 emit_insn (gen_mulxf3 (op2, op2, op2));
20357 emit_insn (gen_addxf3 (op0, op2, op1));
20358 emit_insn (gen_sqrtxf2 (op0, op0));
20360 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20364 (define_insn "x86_fnstsw_1"
20365 [(set (match_operand:HI 0 "register_operand" "=a")
20366 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
20369 [(set_attr "length" "2")
20370 (set_attr "mode" "SI")
20371 (set_attr "unit" "i387")])
20373 (define_insn "fpremxf4_i387"
20374 [(set (match_operand:XF 0 "register_operand" "=f")
20375 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
20376 (match_operand:XF 3 "register_operand" "1")]
20378 (set (match_operand:XF 1 "register_operand" "=f")
20379 (unspec:XF [(match_dup 2) (match_dup 3)]
20381 (set (reg:CCFP FPSR_REG)
20382 (unspec:CCFP [(match_dup 2) (match_dup 3)]
20384 "TARGET_USE_FANCY_MATH_387"
20386 [(set_attr "type" "fpspc")
20387 (set_attr "znver1_decode" "vector")
20388 (set_attr "mode" "XF")])
20390 (define_expand "fmodxf3"
20391 [(use (match_operand:XF 0 "register_operand"))
20392 (use (match_operand:XF 1 "general_operand"))
20393 (use (match_operand:XF 2 "general_operand"))]
20394 "TARGET_USE_FANCY_MATH_387"
20396 rtx_code_label *label = gen_label_rtx ();
20398 rtx op1 = gen_reg_rtx (XFmode);
20399 rtx op2 = gen_reg_rtx (XFmode);
20401 emit_move_insn (op2, operands[2]);
20402 emit_move_insn (op1, operands[1]);
20404 emit_label (label);
20405 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
20406 ix86_emit_fp_unordered_jump (label);
20407 LABEL_NUSES (label) = 1;
20409 emit_move_insn (operands[0], op1);
20413 (define_expand "fmod<mode>3"
20414 [(use (match_operand:MODEF 0 "register_operand"))
20415 (use (match_operand:MODEF 1 "general_operand"))
20416 (use (match_operand:MODEF 2 "general_operand"))]
20417 "TARGET_USE_FANCY_MATH_387"
20419 rtx (*gen_truncxf) (rtx, rtx);
20421 rtx_code_label *label = gen_label_rtx ();
20423 rtx op1 = gen_reg_rtx (XFmode);
20424 rtx op2 = gen_reg_rtx (XFmode);
20426 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20427 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20429 emit_label (label);
20430 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
20431 ix86_emit_fp_unordered_jump (label);
20432 LABEL_NUSES (label) = 1;
20434 /* Truncate the result properly for strict SSE math. */
20435 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
20436 && !TARGET_MIX_SSE_I387)
20437 gen_truncxf = gen_truncxf<mode>2;
20439 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
20441 emit_insn (gen_truncxf (operands[0], op1));
20445 (define_insn "fprem1xf4_i387"
20446 [(set (match_operand:XF 0 "register_operand" "=f")
20447 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
20448 (match_operand:XF 3 "register_operand" "1")]
20450 (set (match_operand:XF 1 "register_operand" "=f")
20451 (unspec:XF [(match_dup 2) (match_dup 3)]
20453 (set (reg:CCFP FPSR_REG)
20454 (unspec:CCFP [(match_dup 2) (match_dup 3)]
20456 "TARGET_USE_FANCY_MATH_387"
20458 [(set_attr "type" "fpspc")
20459 (set_attr "znver1_decode" "vector")
20460 (set_attr "mode" "XF")])
20462 (define_expand "remainderxf3"
20463 [(use (match_operand:XF 0 "register_operand"))
20464 (use (match_operand:XF 1 "general_operand"))
20465 (use (match_operand:XF 2 "general_operand"))]
20466 "TARGET_USE_FANCY_MATH_387"
20468 rtx_code_label *label = gen_label_rtx ();
20470 rtx op1 = gen_reg_rtx (XFmode);
20471 rtx op2 = gen_reg_rtx (XFmode);
20473 emit_move_insn (op2, operands[2]);
20474 emit_move_insn (op1, operands[1]);
20476 emit_label (label);
20477 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
20478 ix86_emit_fp_unordered_jump (label);
20479 LABEL_NUSES (label) = 1;
20481 emit_move_insn (operands[0], op1);
20485 (define_expand "remainder<mode>3"
20486 [(use (match_operand:MODEF 0 "register_operand"))
20487 (use (match_operand:MODEF 1 "general_operand"))
20488 (use (match_operand:MODEF 2 "general_operand"))]
20489 "TARGET_USE_FANCY_MATH_387"
20491 rtx (*gen_truncxf) (rtx, rtx);
20493 rtx_code_label *label = gen_label_rtx ();
20495 rtx op1 = gen_reg_rtx (XFmode);
20496 rtx op2 = gen_reg_rtx (XFmode);
20498 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20499 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20501 emit_label (label);
20503 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
20504 ix86_emit_fp_unordered_jump (label);
20505 LABEL_NUSES (label) = 1;
20507 /* Truncate the result properly for strict SSE math. */
20508 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
20509 && !TARGET_MIX_SSE_I387)
20510 gen_truncxf = gen_truncxf<mode>2;
20512 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
20514 emit_insn (gen_truncxf (operands[0], op1));
20518 (define_int_iterator SINCOS
20522 (define_int_attr sincos
20523 [(UNSPEC_SIN "sin")
20524 (UNSPEC_COS "cos")])
20526 (define_insn "<sincos>xf2"
20527 [(set (match_operand:XF 0 "register_operand" "=f")
20528 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
20530 "TARGET_USE_FANCY_MATH_387
20531 && flag_unsafe_math_optimizations"
20533 [(set_attr "type" "fpspc")
20534 (set_attr "znver1_decode" "vector")
20535 (set_attr "mode" "XF")])
20537 (define_expand "<sincos><mode>2"
20538 [(set (match_operand:MODEF 0 "register_operand")
20539 (unspec:MODEF [(match_operand:MODEF 1 "general_operand")]
20541 "TARGET_USE_FANCY_MATH_387
20542 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20543 || TARGET_MIX_SSE_I387)
20544 && flag_unsafe_math_optimizations"
20546 rtx op0 = gen_reg_rtx (XFmode);
20547 rtx op1 = gen_reg_rtx (XFmode);
20549 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20550 emit_insn (gen_<sincos>xf2 (op0, op1));
20551 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20555 (define_insn "sincosxf3"
20556 [(set (match_operand:XF 0 "register_operand" "=f")
20557 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
20558 UNSPEC_SINCOS_COS))
20559 (set (match_operand:XF 1 "register_operand" "=f")
20560 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
20561 "TARGET_USE_FANCY_MATH_387
20562 && flag_unsafe_math_optimizations"
20564 [(set_attr "type" "fpspc")
20565 (set_attr "znver1_decode" "vector")
20566 (set_attr "mode" "XF")])
20568 (define_expand "sincos<mode>3"
20569 [(use (match_operand:MODEF 0 "register_operand"))
20570 (use (match_operand:MODEF 1 "register_operand"))
20571 (use (match_operand:MODEF 2 "general_operand"))]
20572 "TARGET_USE_FANCY_MATH_387
20573 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20574 || TARGET_MIX_SSE_I387)
20575 && flag_unsafe_math_optimizations"
20577 rtx op0 = gen_reg_rtx (XFmode);
20578 rtx op1 = gen_reg_rtx (XFmode);
20579 rtx op2 = gen_reg_rtx (XFmode);
20581 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20582 emit_insn (gen_sincosxf3 (op0, op1, op2));
20583 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20584 emit_insn (gen_truncxf<mode>2 (operands[1], op1));
20588 (define_insn "fptanxf4_i387"
20589 [(set (match_operand:SF 0 "register_operand" "=f")
20590 (match_operand:SF 3 "const1_operand"))
20591 (set (match_operand:XF 1 "register_operand" "=f")
20592 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
20594 "TARGET_USE_FANCY_MATH_387
20595 && flag_unsafe_math_optimizations"
20597 [(set_attr "type" "fpspc")
20598 (set_attr "znver1_decode" "vector")
20599 (set_attr "mode" "XF")])
20601 (define_expand "tanxf2"
20602 [(use (match_operand:XF 0 "register_operand"))
20603 (use (match_operand:XF 1 "register_operand"))]
20604 "TARGET_USE_FANCY_MATH_387
20605 && flag_unsafe_math_optimizations"
20607 rtx one = gen_reg_rtx (SFmode);
20608 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1],
20609 CONST1_RTX (SFmode)));
20613 (define_expand "tan<mode>2"
20614 [(use (match_operand:MODEF 0 "register_operand"))
20615 (use (match_operand:MODEF 1 "general_operand"))]
20616 "TARGET_USE_FANCY_MATH_387
20617 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20618 || TARGET_MIX_SSE_I387)
20619 && flag_unsafe_math_optimizations"
20621 rtx op0 = gen_reg_rtx (XFmode);
20622 rtx op1 = gen_reg_rtx (XFmode);
20624 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20625 emit_insn (gen_tanxf2 (op0, op1));
20626 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20630 (define_insn "atan2xf3"
20631 [(set (match_operand:XF 0 "register_operand" "=f")
20632 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
20633 (match_operand:XF 1 "register_operand" "f")]
20635 (clobber (match_scratch:XF 3 "=1"))]
20636 "TARGET_USE_FANCY_MATH_387
20637 && flag_unsafe_math_optimizations"
20639 [(set_attr "type" "fpspc")
20640 (set_attr "znver1_decode" "vector")
20641 (set_attr "mode" "XF")])
20643 (define_expand "atan2<mode>3"
20644 [(use (match_operand:MODEF 0 "register_operand"))
20645 (use (match_operand:MODEF 1 "general_operand"))
20646 (use (match_operand:MODEF 2 "general_operand"))]
20647 "TARGET_USE_FANCY_MATH_387
20648 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20649 || TARGET_MIX_SSE_I387)
20650 && flag_unsafe_math_optimizations"
20652 rtx op0 = gen_reg_rtx (XFmode);
20653 rtx op1 = gen_reg_rtx (XFmode);
20654 rtx op2 = gen_reg_rtx (XFmode);
20656 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20657 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20659 emit_insn (gen_atan2xf3 (op0, op1, op2));
20660 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20664 (define_expand "atanxf2"
20665 [(parallel [(set (match_operand:XF 0 "register_operand")
20666 (unspec:XF [(match_dup 2)
20667 (match_operand:XF 1 "register_operand")]
20669 (clobber (scratch:XF))])]
20670 "TARGET_USE_FANCY_MATH_387
20671 && flag_unsafe_math_optimizations"
20672 "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
20674 (define_expand "atan<mode>2"
20675 [(use (match_operand:MODEF 0 "register_operand"))
20676 (use (match_operand:MODEF 1 "general_operand"))]
20677 "TARGET_USE_FANCY_MATH_387
20678 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20679 || TARGET_MIX_SSE_I387)
20680 && flag_unsafe_math_optimizations"
20682 rtx op0 = gen_reg_rtx (XFmode);
20683 rtx op1 = gen_reg_rtx (XFmode);
20685 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20686 emit_insn (gen_atanxf2 (op0, op1));
20687 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20691 (define_expand "asinxf2"
20692 [(set (match_dup 2)
20693 (mult:XF (match_operand:XF 1 "register_operand")
20695 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
20696 (set (match_dup 5) (sqrt:XF (match_dup 4)))
20697 (parallel [(set (match_operand:XF 0 "register_operand")
20698 (unspec:XF [(match_dup 5) (match_dup 1)]
20700 (clobber (scratch:XF))])]
20701 "TARGET_USE_FANCY_MATH_387
20702 && flag_unsafe_math_optimizations"
20706 for (i = 2; i < 6; i++)
20707 operands[i] = gen_reg_rtx (XFmode);
20709 emit_move_insn (operands[3], CONST1_RTX (XFmode));
20712 (define_expand "asin<mode>2"
20713 [(use (match_operand:MODEF 0 "register_operand"))
20714 (use (match_operand:MODEF 1 "general_operand"))]
20715 "TARGET_USE_FANCY_MATH_387
20716 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20717 || TARGET_MIX_SSE_I387)
20718 && flag_unsafe_math_optimizations"
20720 rtx op0 = gen_reg_rtx (XFmode);
20721 rtx op1 = gen_reg_rtx (XFmode);
20723 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20724 emit_insn (gen_asinxf2 (op0, op1));
20725 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20729 (define_expand "acosxf2"
20730 [(set (match_dup 2)
20731 (mult:XF (match_operand:XF 1 "register_operand")
20733 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
20734 (set (match_dup 5) (sqrt:XF (match_dup 4)))
20735 (parallel [(set (match_operand:XF 0 "register_operand")
20736 (unspec:XF [(match_dup 1) (match_dup 5)]
20738 (clobber (scratch:XF))])]
20739 "TARGET_USE_FANCY_MATH_387
20740 && flag_unsafe_math_optimizations"
20744 for (i = 2; i < 6; i++)
20745 operands[i] = gen_reg_rtx (XFmode);
20747 emit_move_insn (operands[3], CONST1_RTX (XFmode));
20750 (define_expand "acos<mode>2"
20751 [(use (match_operand:MODEF 0 "register_operand"))
20752 (use (match_operand:MODEF 1 "general_operand"))]
20753 "TARGET_USE_FANCY_MATH_387
20754 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20755 || TARGET_MIX_SSE_I387)
20756 && flag_unsafe_math_optimizations"
20758 rtx op0 = gen_reg_rtx (XFmode);
20759 rtx op1 = gen_reg_rtx (XFmode);
20761 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20762 emit_insn (gen_acosxf2 (op0, op1));
20763 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20767 (define_expand "sinhxf2"
20768 [(use (match_operand:XF 0 "register_operand"))
20769 (use (match_operand:XF 1 "register_operand"))]
20770 "TARGET_USE_FANCY_MATH_387
20771 && flag_finite_math_only
20772 && flag_unsafe_math_optimizations"
20774 ix86_emit_i387_sinh (operands[0], operands[1]);
20778 (define_expand "sinh<mode>2"
20779 [(use (match_operand:MODEF 0 "register_operand"))
20780 (use (match_operand:MODEF 1 "general_operand"))]
20781 "TARGET_USE_FANCY_MATH_387
20782 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20783 || TARGET_MIX_SSE_I387)
20784 && flag_finite_math_only
20785 && flag_unsafe_math_optimizations"
20787 rtx op0 = gen_reg_rtx (XFmode);
20788 rtx op1 = gen_reg_rtx (XFmode);
20790 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20791 emit_insn (gen_sinhxf2 (op0, op1));
20792 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20796 (define_expand "coshxf2"
20797 [(use (match_operand:XF 0 "register_operand"))
20798 (use (match_operand:XF 1 "register_operand"))]
20799 "TARGET_USE_FANCY_MATH_387
20800 && flag_unsafe_math_optimizations"
20802 ix86_emit_i387_cosh (operands[0], operands[1]);
20806 (define_expand "cosh<mode>2"
20807 [(use (match_operand:MODEF 0 "register_operand"))
20808 (use (match_operand:MODEF 1 "general_operand"))]
20809 "TARGET_USE_FANCY_MATH_387
20810 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20811 || TARGET_MIX_SSE_I387)
20812 && flag_unsafe_math_optimizations"
20814 rtx op0 = gen_reg_rtx (XFmode);
20815 rtx op1 = gen_reg_rtx (XFmode);
20817 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20818 emit_insn (gen_coshxf2 (op0, op1));
20819 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20823 (define_expand "tanhxf2"
20824 [(use (match_operand:XF 0 "register_operand"))
20825 (use (match_operand:XF 1 "register_operand"))]
20826 "TARGET_USE_FANCY_MATH_387
20827 && flag_unsafe_math_optimizations"
20829 ix86_emit_i387_tanh (operands[0], operands[1]);
20833 (define_expand "tanh<mode>2"
20834 [(use (match_operand:MODEF 0 "register_operand"))
20835 (use (match_operand:MODEF 1 "general_operand"))]
20836 "TARGET_USE_FANCY_MATH_387
20837 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20838 || TARGET_MIX_SSE_I387)
20839 && flag_unsafe_math_optimizations"
20841 rtx op0 = gen_reg_rtx (XFmode);
20842 rtx op1 = gen_reg_rtx (XFmode);
20844 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20845 emit_insn (gen_tanhxf2 (op0, op1));
20846 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20850 (define_expand "asinhxf2"
20851 [(use (match_operand:XF 0 "register_operand"))
20852 (use (match_operand:XF 1 "register_operand"))]
20853 "TARGET_USE_FANCY_MATH_387
20854 && flag_finite_math_only
20855 && flag_unsafe_math_optimizations"
20857 ix86_emit_i387_asinh (operands[0], operands[1]);
20861 (define_expand "asinh<mode>2"
20862 [(use (match_operand:MODEF 0 "register_operand"))
20863 (use (match_operand:MODEF 1 "general_operand"))]
20864 "TARGET_USE_FANCY_MATH_387
20865 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20866 || TARGET_MIX_SSE_I387)
20867 && flag_finite_math_only
20868 && flag_unsafe_math_optimizations"
20870 rtx op0 = gen_reg_rtx (XFmode);
20871 rtx op1 = gen_reg_rtx (XFmode);
20873 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20874 emit_insn (gen_asinhxf2 (op0, op1));
20875 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20879 (define_expand "acoshxf2"
20880 [(use (match_operand:XF 0 "register_operand"))
20881 (use (match_operand:XF 1 "register_operand"))]
20882 "TARGET_USE_FANCY_MATH_387
20883 && flag_unsafe_math_optimizations"
20885 ix86_emit_i387_acosh (operands[0], operands[1]);
20889 (define_expand "acosh<mode>2"
20890 [(use (match_operand:MODEF 0 "register_operand"))
20891 (use (match_operand:MODEF 1 "general_operand"))]
20892 "TARGET_USE_FANCY_MATH_387
20893 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20894 || TARGET_MIX_SSE_I387)
20895 && flag_unsafe_math_optimizations"
20897 rtx op0 = gen_reg_rtx (XFmode);
20898 rtx op1 = gen_reg_rtx (XFmode);
20900 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20901 emit_insn (gen_acoshxf2 (op0, op1));
20902 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20906 (define_expand "atanhxf2"
20907 [(use (match_operand:XF 0 "register_operand"))
20908 (use (match_operand:XF 1 "register_operand"))]
20909 "TARGET_USE_FANCY_MATH_387
20910 && flag_unsafe_math_optimizations"
20912 ix86_emit_i387_atanh (operands[0], operands[1]);
20916 (define_expand "atanh<mode>2"
20917 [(use (match_operand:MODEF 0 "register_operand"))
20918 (use (match_operand:MODEF 1 "general_operand"))]
20919 "TARGET_USE_FANCY_MATH_387
20920 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20921 || TARGET_MIX_SSE_I387)
20922 && flag_unsafe_math_optimizations"
20924 rtx op0 = gen_reg_rtx (XFmode);
20925 rtx op1 = gen_reg_rtx (XFmode);
20927 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20928 emit_insn (gen_atanhxf2 (op0, op1));
20929 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20933 (define_insn "fyl2xxf3_i387"
20934 [(set (match_operand:XF 0 "register_operand" "=f")
20935 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
20936 (match_operand:XF 2 "register_operand" "f")]
20938 (clobber (match_scratch:XF 3 "=2"))]
20939 "TARGET_USE_FANCY_MATH_387
20940 && flag_unsafe_math_optimizations"
20942 [(set_attr "type" "fpspc")
20943 (set_attr "znver1_decode" "vector")
20944 (set_attr "mode" "XF")])
20946 (define_expand "logxf2"
20947 [(parallel [(set (match_operand:XF 0 "register_operand")
20948 (unspec:XF [(match_operand:XF 1 "register_operand")
20949 (match_dup 2)] UNSPEC_FYL2X))
20950 (clobber (scratch:XF))])]
20951 "TARGET_USE_FANCY_MATH_387
20952 && flag_unsafe_math_optimizations"
20955 = force_reg (XFmode, standard_80387_constant_rtx (4)); /* fldln2 */
20958 (define_expand "log<mode>2"
20959 [(use (match_operand:MODEF 0 "register_operand"))
20960 (use (match_operand:MODEF 1 "general_operand"))]
20961 "TARGET_USE_FANCY_MATH_387
20962 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20963 || TARGET_MIX_SSE_I387)
20964 && flag_unsafe_math_optimizations"
20966 rtx op0 = gen_reg_rtx (XFmode);
20967 rtx op1 = gen_reg_rtx (XFmode);
20969 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20970 emit_insn (gen_logxf2 (op0, op1));
20971 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20975 (define_expand "log10xf2"
20976 [(parallel [(set (match_operand:XF 0 "register_operand")
20977 (unspec:XF [(match_operand:XF 1 "register_operand")
20978 (match_dup 2)] UNSPEC_FYL2X))
20979 (clobber (scratch:XF))])]
20980 "TARGET_USE_FANCY_MATH_387
20981 && flag_unsafe_math_optimizations"
20984 = force_reg (XFmode, standard_80387_constant_rtx (3)); /* fldlg2 */
20987 (define_expand "log10<mode>2"
20988 [(use (match_operand:MODEF 0 "register_operand"))
20989 (use (match_operand:MODEF 1 "general_operand"))]
20990 "TARGET_USE_FANCY_MATH_387
20991 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20992 || TARGET_MIX_SSE_I387)
20993 && flag_unsafe_math_optimizations"
20995 rtx op0 = gen_reg_rtx (XFmode);
20996 rtx op1 = gen_reg_rtx (XFmode);
20998 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20999 emit_insn (gen_log10xf2 (op0, op1));
21000 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21004 (define_expand "log2xf2"
21005 [(parallel [(set (match_operand:XF 0 "register_operand")
21006 (unspec:XF [(match_operand:XF 1 "register_operand")
21007 (match_dup 2)] UNSPEC_FYL2X))
21008 (clobber (scratch:XF))])]
21009 "TARGET_USE_FANCY_MATH_387
21010 && flag_unsafe_math_optimizations"
21011 "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
21013 (define_expand "log2<mode>2"
21014 [(use (match_operand:MODEF 0 "register_operand"))
21015 (use (match_operand:MODEF 1 "general_operand"))]
21016 "TARGET_USE_FANCY_MATH_387
21017 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21018 || TARGET_MIX_SSE_I387)
21019 && flag_unsafe_math_optimizations"
21021 rtx op0 = gen_reg_rtx (XFmode);
21022 rtx op1 = gen_reg_rtx (XFmode);
21024 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21025 emit_insn (gen_log2xf2 (op0, op1));
21026 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21030 (define_insn "fyl2xp1xf3_i387"
21031 [(set (match_operand:XF 0 "register_operand" "=f")
21032 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
21033 (match_operand:XF 2 "register_operand" "f")]
21035 (clobber (match_scratch:XF 3 "=2"))]
21036 "TARGET_USE_FANCY_MATH_387
21037 && flag_unsafe_math_optimizations"
21039 [(set_attr "type" "fpspc")
21040 (set_attr "znver1_decode" "vector")
21041 (set_attr "mode" "XF")])
21043 (define_expand "log1pxf2"
21044 [(use (match_operand:XF 0 "register_operand"))
21045 (use (match_operand:XF 1 "register_operand"))]
21046 "TARGET_USE_FANCY_MATH_387
21047 && flag_unsafe_math_optimizations"
21049 ix86_emit_i387_log1p (operands[0], operands[1]);
21053 (define_expand "log1p<mode>2"
21054 [(use (match_operand:MODEF 0 "register_operand"))
21055 (use (match_operand:MODEF 1 "general_operand"))]
21056 "TARGET_USE_FANCY_MATH_387
21057 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21058 || TARGET_MIX_SSE_I387)
21059 && flag_unsafe_math_optimizations"
21061 rtx op0 = gen_reg_rtx (XFmode);
21062 rtx op1 = gen_reg_rtx (XFmode);
21064 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21065 emit_insn (gen_log1pxf2 (op0, op1));
21066 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21070 (define_insn "fxtractxf3_i387"
21071 [(set (match_operand:XF 0 "register_operand" "=f")
21072 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
21073 UNSPEC_XTRACT_FRACT))
21074 (set (match_operand:XF 1 "register_operand" "=f")
21075 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
21076 "TARGET_USE_FANCY_MATH_387
21077 && flag_unsafe_math_optimizations"
21079 [(set_attr "type" "fpspc")
21080 (set_attr "znver1_decode" "vector")
21081 (set_attr "mode" "XF")])
21083 (define_expand "logbxf2"
21084 [(parallel [(set (match_dup 2)
21085 (unspec:XF [(match_operand:XF 1 "register_operand")]
21086 UNSPEC_XTRACT_FRACT))
21087 (set (match_operand:XF 0 "register_operand")
21088 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
21089 "TARGET_USE_FANCY_MATH_387
21090 && flag_unsafe_math_optimizations"
21091 "operands[2] = gen_reg_rtx (XFmode);")
21093 (define_expand "logb<mode>2"
21094 [(use (match_operand:MODEF 0 "register_operand"))
21095 (use (match_operand:MODEF 1 "general_operand"))]
21096 "TARGET_USE_FANCY_MATH_387
21097 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21098 || TARGET_MIX_SSE_I387)
21099 && flag_unsafe_math_optimizations"
21101 rtx op0 = gen_reg_rtx (XFmode);
21102 rtx op1 = gen_reg_rtx (XFmode);
21104 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21105 emit_insn (gen_logbxf2 (op0, op1));
21106 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
21110 (define_expand "ilogbxf2"
21111 [(use (match_operand:SI 0 "register_operand"))
21112 (use (match_operand:XF 1 "register_operand"))]
21113 "TARGET_USE_FANCY_MATH_387
21114 && flag_unsafe_math_optimizations"
21118 if (optimize_insn_for_size_p ())
21121 op0 = gen_reg_rtx (XFmode);
21122 op1 = gen_reg_rtx (XFmode);
21124 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
21125 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
21129 (define_expand "ilogb<mode>2"
21130 [(use (match_operand:SI 0 "register_operand"))
21131 (use (match_operand:MODEF 1 "general_operand"))]
21132 "TARGET_USE_FANCY_MATH_387
21133 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21134 || TARGET_MIX_SSE_I387)
21135 && flag_unsafe_math_optimizations"
21139 if (optimize_insn_for_size_p ())
21142 op0 = gen_reg_rtx (XFmode);
21143 op1 = gen_reg_rtx (XFmode);
21144 op2 = gen_reg_rtx (XFmode);
21146 emit_insn (gen_extend<mode>xf2 (op2, operands[1]));
21147 emit_insn (gen_fxtractxf3_i387 (op0, op1, op2));
21148 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
21152 (define_insn "*f2xm1xf2_i387"
21153 [(set (match_operand:XF 0 "register_operand" "=f")
21154 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
21156 "TARGET_USE_FANCY_MATH_387
21157 && flag_unsafe_math_optimizations"
21159 [(set_attr "type" "fpspc")
21160 (set_attr "znver1_decode" "vector")
21161 (set_attr "mode" "XF")])
21163 (define_insn "fscalexf4_i387"
21164 [(set (match_operand:XF 0 "register_operand" "=f")
21165 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
21166 (match_operand:XF 3 "register_operand" "1")]
21167 UNSPEC_FSCALE_FRACT))
21168 (set (match_operand:XF 1 "register_operand" "=f")
21169 (unspec:XF [(match_dup 2) (match_dup 3)]
21170 UNSPEC_FSCALE_EXP))]
21171 "TARGET_USE_FANCY_MATH_387
21172 && flag_unsafe_math_optimizations"
21174 [(set_attr "type" "fpspc")
21175 (set_attr "znver1_decode" "vector")
21176 (set_attr "mode" "XF")])
21178 (define_expand "expNcorexf3"
21179 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
21180 (match_operand:XF 2 "register_operand")))
21181 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
21182 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
21183 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
21184 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
21185 (parallel [(set (match_operand:XF 0 "register_operand")
21186 (unspec:XF [(match_dup 8) (match_dup 4)]
21187 UNSPEC_FSCALE_FRACT))
21189 (unspec:XF [(match_dup 8) (match_dup 4)]
21190 UNSPEC_FSCALE_EXP))])]
21191 "TARGET_USE_FANCY_MATH_387
21192 && flag_unsafe_math_optimizations"
21196 for (i = 3; i < 10; i++)
21197 operands[i] = gen_reg_rtx (XFmode);
21199 emit_move_insn (operands[7], CONST1_RTX (XFmode));
21202 (define_expand "expxf2"
21203 [(use (match_operand:XF 0 "register_operand"))
21204 (use (match_operand:XF 1 "register_operand"))]
21205 "TARGET_USE_FANCY_MATH_387
21206 && flag_unsafe_math_optimizations"
21208 rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (5)); /* fldl2e */
21210 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
21214 (define_expand "exp<mode>2"
21215 [(use (match_operand:MODEF 0 "register_operand"))
21216 (use (match_operand:MODEF 1 "general_operand"))]
21217 "TARGET_USE_FANCY_MATH_387
21218 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21219 || TARGET_MIX_SSE_I387)
21220 && flag_unsafe_math_optimizations"
21222 rtx op0 = gen_reg_rtx (XFmode);
21223 rtx op1 = gen_reg_rtx (XFmode);
21225 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21226 emit_insn (gen_expxf2 (op0, op1));
21227 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21231 (define_expand "exp10xf2"
21232 [(use (match_operand:XF 0 "register_operand"))
21233 (use (match_operand:XF 1 "register_operand"))]
21234 "TARGET_USE_FANCY_MATH_387
21235 && flag_unsafe_math_optimizations"
21237 rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (6)); /* fldl2t */
21239 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
21243 (define_expand "exp10<mode>2"
21244 [(use (match_operand:MODEF 0 "register_operand"))
21245 (use (match_operand:MODEF 1 "general_operand"))]
21246 "TARGET_USE_FANCY_MATH_387
21247 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21248 || TARGET_MIX_SSE_I387)
21249 && flag_unsafe_math_optimizations"
21251 rtx op0 = gen_reg_rtx (XFmode);
21252 rtx op1 = gen_reg_rtx (XFmode);
21254 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21255 emit_insn (gen_exp10xf2 (op0, op1));
21256 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21260 (define_expand "exp2xf2"
21261 [(use (match_operand:XF 0 "register_operand"))
21262 (use (match_operand:XF 1 "register_operand"))]
21263 "TARGET_USE_FANCY_MATH_387
21264 && flag_unsafe_math_optimizations"
21266 rtx op2 = force_reg (XFmode, CONST1_RTX (XFmode));
21268 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
21272 (define_expand "exp2<mode>2"
21273 [(use (match_operand:MODEF 0 "register_operand"))
21274 (use (match_operand:MODEF 1 "general_operand"))]
21275 "TARGET_USE_FANCY_MATH_387
21276 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21277 || TARGET_MIX_SSE_I387)
21278 && flag_unsafe_math_optimizations"
21280 rtx op0 = gen_reg_rtx (XFmode);
21281 rtx op1 = gen_reg_rtx (XFmode);
21283 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21284 emit_insn (gen_exp2xf2 (op0, op1));
21285 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21289 (define_expand "expm1xf2"
21290 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
21292 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
21293 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
21294 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
21295 (parallel [(set (match_dup 7)
21296 (unspec:XF [(match_dup 6) (match_dup 4)]
21297 UNSPEC_FSCALE_FRACT))
21299 (unspec:XF [(match_dup 6) (match_dup 4)]
21300 UNSPEC_FSCALE_EXP))])
21301 (parallel [(set (match_dup 10)
21302 (unspec:XF [(match_dup 9) (match_dup 8)]
21303 UNSPEC_FSCALE_FRACT))
21304 (set (match_dup 11)
21305 (unspec:XF [(match_dup 9) (match_dup 8)]
21306 UNSPEC_FSCALE_EXP))])
21307 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
21308 (set (match_operand:XF 0 "register_operand")
21309 (plus:XF (match_dup 12) (match_dup 7)))]
21310 "TARGET_USE_FANCY_MATH_387
21311 && flag_unsafe_math_optimizations"
21315 for (i = 2; i < 13; i++)
21316 operands[i] = gen_reg_rtx (XFmode);
21318 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
21319 emit_move_insn (operands[9], CONST1_RTX (XFmode));
21322 (define_expand "expm1<mode>2"
21323 [(use (match_operand:MODEF 0 "register_operand"))
21324 (use (match_operand:MODEF 1 "general_operand"))]
21325 "TARGET_USE_FANCY_MATH_387
21326 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21327 || TARGET_MIX_SSE_I387)
21328 && flag_unsafe_math_optimizations"
21330 rtx op0 = gen_reg_rtx (XFmode);
21331 rtx op1 = gen_reg_rtx (XFmode);
21333 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21334 emit_insn (gen_expm1xf2 (op0, op1));
21335 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21339 (define_insn "avx512f_scalef<mode>2"
21340 [(set (match_operand:MODEF 0 "register_operand" "=v")
21342 [(match_operand:MODEF 1 "register_operand" "v")
21343 (match_operand:MODEF 2 "nonimmediate_operand" "vm")]
21346 "vscalef<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
21347 [(set_attr "prefix" "evex")
21348 (set_attr "mode" "<MODE>")])
21350 (define_expand "ldexpxf3"
21351 [(match_operand:XF 0 "register_operand")
21352 (match_operand:XF 1 "register_operand")
21353 (match_operand:SI 2 "register_operand")]
21354 "TARGET_USE_FANCY_MATH_387
21355 && flag_unsafe_math_optimizations"
21357 rtx tmp1 = gen_reg_rtx (XFmode);
21358 rtx tmp2 = gen_reg_rtx (XFmode);
21360 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
21361 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
21362 operands[1], tmp1));
21366 (define_expand "ldexp<mode>3"
21367 [(use (match_operand:MODEF 0 "register_operand"))
21368 (use (match_operand:MODEF 1 "general_operand"))
21369 (use (match_operand:SI 2 "register_operand"))]
21370 "((TARGET_USE_FANCY_MATH_387
21371 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21372 || TARGET_MIX_SSE_I387))
21373 || (TARGET_AVX512F && TARGET_SSE_MATH))
21374 && flag_unsafe_math_optimizations"
21376 /* Prefer avx512f version. */
21377 if (TARGET_AVX512F && TARGET_SSE_MATH)
21379 rtx op2 = gen_reg_rtx (<MODE>mode);
21380 operands[1] = force_reg (<MODE>mode, operands[1]);
21382 emit_insn (gen_floatsi<mode>2 (op2, operands[2]));
21383 emit_insn (gen_avx512f_scalef<mode>2 (operands[0], operands[1], op2));
21387 rtx op0 = gen_reg_rtx (XFmode);
21388 rtx op1 = gen_reg_rtx (XFmode);
21390 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21391 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
21392 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21397 (define_expand "scalbxf3"
21398 [(parallel [(set (match_operand:XF 0 " register_operand")
21399 (unspec:XF [(match_operand:XF 1 "register_operand")
21400 (match_operand:XF 2 "register_operand")]
21401 UNSPEC_FSCALE_FRACT))
21403 (unspec:XF [(match_dup 1) (match_dup 2)]
21404 UNSPEC_FSCALE_EXP))])]
21405 "TARGET_USE_FANCY_MATH_387
21406 && flag_unsafe_math_optimizations"
21407 "operands[3] = gen_reg_rtx (XFmode);")
21409 (define_expand "scalb<mode>3"
21410 [(use (match_operand:MODEF 0 "register_operand"))
21411 (use (match_operand:MODEF 1 "general_operand"))
21412 (use (match_operand:MODEF 2 "general_operand"))]
21413 "TARGET_USE_FANCY_MATH_387
21414 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21415 || TARGET_MIX_SSE_I387)
21416 && flag_unsafe_math_optimizations"
21418 rtx op0 = gen_reg_rtx (XFmode);
21419 rtx op1 = gen_reg_rtx (XFmode);
21420 rtx op2 = gen_reg_rtx (XFmode);
21422 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21423 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
21424 emit_insn (gen_scalbxf3 (op0, op1, op2));
21425 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21429 (define_expand "significandxf2"
21430 [(parallel [(set (match_operand:XF 0 "register_operand")
21431 (unspec:XF [(match_operand:XF 1 "register_operand")]
21432 UNSPEC_XTRACT_FRACT))
21434 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
21435 "TARGET_USE_FANCY_MATH_387
21436 && flag_unsafe_math_optimizations"
21437 "operands[2] = gen_reg_rtx (XFmode);")
21439 (define_expand "significand<mode>2"
21440 [(use (match_operand:MODEF 0 "register_operand"))
21441 (use (match_operand:MODEF 1 "general_operand"))]
21442 "TARGET_USE_FANCY_MATH_387
21443 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21444 || TARGET_MIX_SSE_I387)
21445 && flag_unsafe_math_optimizations"
21447 rtx op0 = gen_reg_rtx (XFmode);
21448 rtx op1 = gen_reg_rtx (XFmode);
21450 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21451 emit_insn (gen_significandxf2 (op0, op1));
21452 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21457 (define_insn "sse4_1_round<mode>2"
21458 [(set (match_operand:MODEFH 0 "register_operand" "=x,x,x,v,v")
21460 [(match_operand:MODEFH 1 "nonimmediate_operand" "0,x,m,v,m")
21461 (match_operand:SI 2 "const_0_to_15_operand")]
21465 %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
21466 %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
21467 %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
21468 vrndscale<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
21469 vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
21470 [(set_attr "type" "ssecvt")
21471 (set_attr "prefix_extra" "1,1,1,*,*")
21472 (set_attr "length_immediate" "*,*,*,1,1")
21473 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,evex,evex")
21474 (set_attr "isa" "noavx512f,noavx512f,noavx512f,avx512f,avx512f")
21475 (set_attr "avx_partial_xmm_update" "false,false,true,false,true")
21476 (set_attr "mode" "<MODE>")
21477 (set (attr "preferred_for_speed")
21478 (cond [(match_test "TARGET_AVX")
21479 (symbol_ref "true")
21480 (eq_attr "alternative" "1,2")
21481 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
21483 (symbol_ref "true")))])
21485 (define_insn "rintxf2"
21486 [(set (match_operand:XF 0 "register_operand" "=f")
21487 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
21489 "TARGET_USE_FANCY_MATH_387"
21491 [(set_attr "type" "fpspc")
21492 (set_attr "znver1_decode" "vector")
21493 (set_attr "mode" "XF")])
21495 (define_expand "rinthf2"
21496 [(match_operand:HF 0 "register_operand")
21497 (match_operand:HF 1 "nonimmediate_operand")]
21498 "TARGET_AVX512FP16"
21500 emit_insn (gen_sse4_1_roundhf2 (operands[0],
21502 GEN_INT (ROUND_MXCSR)));
21506 (define_expand "rint<mode>2"
21507 [(use (match_operand:MODEF 0 "register_operand"))
21508 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
21509 "TARGET_USE_FANCY_MATH_387
21510 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
21512 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21515 emit_insn (gen_sse4_1_round<mode>2
21516 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
21518 ix86_expand_rint (operands[0], operands[1]);
21522 rtx op0 = gen_reg_rtx (XFmode);
21523 rtx op1 = gen_reg_rtx (XFmode);
21525 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21526 emit_insn (gen_rintxf2 (op0, op1));
21527 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
21532 (define_expand "nearbyintxf2"
21533 [(set (match_operand:XF 0 "register_operand")
21534 (unspec:XF [(match_operand:XF 1 "register_operand")]
21536 "TARGET_USE_FANCY_MATH_387
21537 && !flag_trapping_math")
21539 (define_expand "nearbyinthf2"
21540 [(match_operand:HF 0 "register_operand")
21541 (match_operand:HF 1 "nonimmediate_operand")]
21542 "TARGET_AVX512FP16"
21544 emit_insn (gen_sse4_1_roundhf2 (operands[0],
21546 GEN_INT (ROUND_MXCSR | ROUND_NO_EXC)));
21550 (define_expand "nearbyint<mode>2"
21551 [(use (match_operand:MODEF 0 "register_operand"))
21552 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
21553 "(TARGET_USE_FANCY_MATH_387
21554 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21555 || TARGET_MIX_SSE_I387)
21556 && !flag_trapping_math)
21557 || (TARGET_SSE4_1 && TARGET_SSE_MATH)"
21559 if (TARGET_SSE4_1 && TARGET_SSE_MATH)
21560 emit_insn (gen_sse4_1_round<mode>2
21561 (operands[0], operands[1], GEN_INT (ROUND_MXCSR
21565 rtx op0 = gen_reg_rtx (XFmode);
21566 rtx op1 = gen_reg_rtx (XFmode);
21568 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21569 emit_insn (gen_nearbyintxf2 (op0, op1));
21570 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
21575 (define_expand "round<mode>2"
21576 [(match_operand:X87MODEF 0 "register_operand")
21577 (match_operand:X87MODEF 1 "nonimmediate_operand")]
21578 "(TARGET_USE_FANCY_MATH_387
21579 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21580 || TARGET_MIX_SSE_I387)
21581 && flag_unsafe_math_optimizations
21582 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
21583 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
21584 && !flag_trapping_math && !flag_rounding_math)"
21586 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
21587 && !flag_trapping_math && !flag_rounding_math)
21591 operands[1] = force_reg (<MODE>mode, operands[1]);
21592 ix86_expand_round_sse4 (operands[0], operands[1]);
21594 else if (TARGET_64BIT || (<MODE>mode != DFmode))
21595 ix86_expand_round (operands[0], operands[1]);
21597 ix86_expand_rounddf_32 (operands[0], operands[1]);
21601 operands[1] = force_reg (<MODE>mode, operands[1]);
21602 ix86_emit_i387_round (operands[0], operands[1]);
21607 (define_insn "lrintxfdi2"
21608 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
21609 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
21611 (clobber (match_scratch:XF 2 "=&f"))]
21612 "TARGET_USE_FANCY_MATH_387"
21613 "* return output_fix_trunc (insn, operands, false);"
21614 [(set_attr "type" "fpspc")
21615 (set_attr "mode" "DI")])
21617 (define_insn "lrintxf<mode>2"
21618 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
21619 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
21621 "TARGET_USE_FANCY_MATH_387"
21622 "* return output_fix_trunc (insn, operands, false);"
21623 [(set_attr "type" "fpspc")
21624 (set_attr "mode" "<MODE>")])
21626 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
21627 [(set (match_operand:SWI48 0 "register_operand")
21628 (unspec:SWI48 [(match_operand:MODEF 1 "nonimmediate_operand")]
21629 UNSPEC_FIX_NOTRUNC))]
21630 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
21632 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
21633 [(match_operand:SWI248x 0 "nonimmediate_operand")
21634 (match_operand:X87MODEF 1 "register_operand")]
21635 "(TARGET_USE_FANCY_MATH_387
21636 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
21637 || TARGET_MIX_SSE_I387)
21638 && flag_unsafe_math_optimizations)
21639 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
21640 && <SWI248x:MODE>mode != HImode
21641 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
21642 && !flag_trapping_math && !flag_rounding_math)"
21644 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
21645 && <SWI248x:MODE>mode != HImode
21646 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
21647 && !flag_trapping_math && !flag_rounding_math)
21648 ix86_expand_lround (operands[0], operands[1]);
21650 ix86_emit_i387_round (operands[0], operands[1]);
21654 (define_int_iterator FRNDINT_ROUNDING
21655 [UNSPEC_FRNDINT_ROUNDEVEN
21656 UNSPEC_FRNDINT_FLOOR
21657 UNSPEC_FRNDINT_CEIL
21658 UNSPEC_FRNDINT_TRUNC])
21660 (define_int_iterator FIST_ROUNDING
21664 ;; Base name for define_insn
21665 (define_int_attr rounding_insn
21666 [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven")
21667 (UNSPEC_FRNDINT_FLOOR "floor")
21668 (UNSPEC_FRNDINT_CEIL "ceil")
21669 (UNSPEC_FRNDINT_TRUNC "btrunc")
21670 (UNSPEC_FIST_FLOOR "floor")
21671 (UNSPEC_FIST_CEIL "ceil")])
21673 (define_int_attr rounding
21674 [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven")
21675 (UNSPEC_FRNDINT_FLOOR "floor")
21676 (UNSPEC_FRNDINT_CEIL "ceil")
21677 (UNSPEC_FRNDINT_TRUNC "trunc")
21678 (UNSPEC_FIST_FLOOR "floor")
21679 (UNSPEC_FIST_CEIL "ceil")])
21681 (define_int_attr ROUNDING
21682 [(UNSPEC_FRNDINT_ROUNDEVEN "ROUNDEVEN")
21683 (UNSPEC_FRNDINT_FLOOR "FLOOR")
21684 (UNSPEC_FRNDINT_CEIL "CEIL")
21685 (UNSPEC_FRNDINT_TRUNC "TRUNC")
21686 (UNSPEC_FIST_FLOOR "FLOOR")
21687 (UNSPEC_FIST_CEIL "CEIL")])
21689 ;; Rounding mode control word calculation could clobber FLAGS_REG.
21690 (define_insn_and_split "frndintxf2_<rounding>"
21691 [(set (match_operand:XF 0 "register_operand")
21692 (unspec:XF [(match_operand:XF 1 "register_operand")]
21694 (clobber (reg:CC FLAGS_REG))]
21695 "TARGET_USE_FANCY_MATH_387
21696 && (flag_fp_int_builtin_inexact || !flag_trapping_math)
21697 && ix86_pre_reload_split ()"
21702 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
21704 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
21705 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
21707 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
21708 operands[2], operands[3]));
21711 [(set_attr "type" "frndint")
21712 (set_attr "i387_cw" "<rounding>")
21713 (set_attr "mode" "XF")])
21715 (define_insn "frndintxf2_<rounding>_i387"
21716 [(set (match_operand:XF 0 "register_operand" "=f")
21717 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
21719 (use (match_operand:HI 2 "memory_operand" "m"))
21720 (use (match_operand:HI 3 "memory_operand" "m"))]
21721 "TARGET_USE_FANCY_MATH_387
21722 && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
21723 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
21724 [(set_attr "type" "frndint")
21725 (set_attr "i387_cw" "<rounding>")
21726 (set_attr "mode" "XF")])
21728 (define_expand "<rounding_insn>xf2"
21729 [(parallel [(set (match_operand:XF 0 "register_operand")
21730 (unspec:XF [(match_operand:XF 1 "register_operand")]
21732 (clobber (reg:CC FLAGS_REG))])]
21733 "TARGET_USE_FANCY_MATH_387
21734 && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
21736 (define_expand "<rounding_insn>hf2"
21737 [(parallel [(set (match_operand:HF 0 "register_operand")
21738 (unspec:HF [(match_operand:HF 1 "register_operand")]
21740 (clobber (reg:CC FLAGS_REG))])]
21741 "TARGET_AVX512FP16"
21743 emit_insn (gen_sse4_1_roundhf2 (operands[0], operands[1],
21744 GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
21748 (define_expand "<rounding_insn><mode>2"
21749 [(parallel [(set (match_operand:MODEF 0 "register_operand")
21750 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
21752 (clobber (reg:CC FLAGS_REG))])]
21753 "(TARGET_USE_FANCY_MATH_387
21754 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21755 || TARGET_MIX_SSE_I387)
21756 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
21757 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
21759 || (ROUND_<ROUNDING> != ROUND_ROUNDEVEN
21760 && (flag_fp_int_builtin_inexact || !flag_trapping_math))))"
21762 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
21764 || (ROUND_<ROUNDING> != ROUND_ROUNDEVEN
21765 && (flag_fp_int_builtin_inexact || !flag_trapping_math))))
21768 emit_insn (gen_sse4_1_round<mode>2
21769 (operands[0], operands[1],
21770 GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
21771 else if (TARGET_64BIT || (<MODE>mode != DFmode))
21773 if (ROUND_<ROUNDING> == ROUND_FLOOR)
21774 ix86_expand_floorceil (operands[0], operands[1], true);
21775 else if (ROUND_<ROUNDING> == ROUND_CEIL)
21776 ix86_expand_floorceil (operands[0], operands[1], false);
21777 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
21778 ix86_expand_trunc (operands[0], operands[1]);
21780 gcc_unreachable ();
21784 if (ROUND_<ROUNDING> == ROUND_FLOOR)
21785 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
21786 else if (ROUND_<ROUNDING> == ROUND_CEIL)
21787 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
21788 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
21789 ix86_expand_truncdf_32 (operands[0], operands[1]);
21791 gcc_unreachable ();
21796 rtx op0 = gen_reg_rtx (XFmode);
21797 rtx op1 = gen_reg_rtx (XFmode);
21799 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21800 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
21801 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
21806 ;; Rounding mode control word calculation could clobber FLAGS_REG.
21807 (define_insn_and_split "*fist<mode>2_<rounding>_1"
21808 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
21809 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
21811 (clobber (reg:CC FLAGS_REG))]
21812 "TARGET_USE_FANCY_MATH_387
21813 && flag_unsafe_math_optimizations
21814 && ix86_pre_reload_split ()"
21819 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
21821 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
21822 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
21824 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
21825 operands[2], operands[3]));
21828 [(set_attr "type" "fistp")
21829 (set_attr "i387_cw" "<rounding>")
21830 (set_attr "mode" "<MODE>")])
21832 (define_insn "fistdi2_<rounding>"
21833 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
21834 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
21836 (use (match_operand:HI 2 "memory_operand" "m"))
21837 (use (match_operand:HI 3 "memory_operand" "m"))
21838 (clobber (match_scratch:XF 4 "=&f"))]
21839 "TARGET_USE_FANCY_MATH_387
21840 && flag_unsafe_math_optimizations"
21841 "* return output_fix_trunc (insn, operands, false);"
21842 [(set_attr "type" "fistp")
21843 (set_attr "i387_cw" "<rounding>")
21844 (set_attr "mode" "DI")])
21846 (define_insn "fist<mode>2_<rounding>"
21847 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
21848 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
21850 (use (match_operand:HI 2 "memory_operand" "m"))
21851 (use (match_operand:HI 3 "memory_operand" "m"))]
21852 "TARGET_USE_FANCY_MATH_387
21853 && flag_unsafe_math_optimizations"
21854 "* return output_fix_trunc (insn, operands, false);"
21855 [(set_attr "type" "fistp")
21856 (set_attr "i387_cw" "<rounding>")
21857 (set_attr "mode" "<MODE>")])
21859 (define_expand "l<rounding_insn>xf<mode>2"
21860 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
21861 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
21863 (clobber (reg:CC FLAGS_REG))])]
21864 "TARGET_USE_FANCY_MATH_387
21865 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
21866 && flag_unsafe_math_optimizations")
21868 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
21869 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
21870 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
21872 (clobber (reg:CC FLAGS_REG))])]
21873 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
21874 && (TARGET_SSE4_1 || !flag_trapping_math)"
21878 rtx tmp = gen_reg_rtx (<MODEF:MODE>mode);
21880 emit_insn (gen_sse4_1_round<MODEF:mode>2
21881 (tmp, operands[1], GEN_INT (ROUND_<ROUNDING>
21883 emit_insn (gen_fix_trunc<MODEF:mode><SWI48:mode>2
21884 (operands[0], tmp));
21886 else if (ROUND_<ROUNDING> == ROUND_FLOOR)
21887 ix86_expand_lfloorceil (operands[0], operands[1], true);
21888 else if (ROUND_<ROUNDING> == ROUND_CEIL)
21889 ix86_expand_lfloorceil (operands[0], operands[1], false);
21891 gcc_unreachable ();
21896 (define_insn "fxam<mode>2_i387"
21897 [(set (match_operand:HI 0 "register_operand" "=a")
21899 [(match_operand:X87MODEF 1 "register_operand" "f")]
21901 "TARGET_USE_FANCY_MATH_387"
21902 "fxam\n\tfnstsw\t%0"
21903 [(set_attr "type" "multi")
21904 (set_attr "length" "4")
21905 (set_attr "unit" "i387")
21906 (set_attr "mode" "<MODE>")])
21908 (define_expand "signbittf2"
21909 [(use (match_operand:SI 0 "register_operand"))
21910 (use (match_operand:TF 1 "register_operand"))]
21915 rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
21916 rtx scratch = gen_reg_rtx (QImode);
21918 emit_insn (gen_ptesttf2 (operands[1], mask));
21919 ix86_expand_setcc (scratch, NE,
21920 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
21922 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
21926 emit_insn (gen_sse_movmskps (operands[0],
21927 gen_lowpart (V4SFmode, operands[1])));
21928 emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8)));
21933 (define_expand "signbitxf2"
21934 [(use (match_operand:SI 0 "register_operand"))
21935 (use (match_operand:XF 1 "register_operand"))]
21936 "TARGET_USE_FANCY_MATH_387"
21938 rtx scratch = gen_reg_rtx (HImode);
21940 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
21941 emit_insn (gen_andsi3 (operands[0],
21942 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
21946 (define_insn "movmsk_df"
21947 [(set (match_operand:SI 0 "register_operand" "=r")
21949 [(match_operand:DF 1 "register_operand" "x")]
21951 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
21952 "%vmovmskpd\t{%1, %0|%0, %1}"
21953 [(set_attr "type" "ssemov")
21954 (set_attr "prefix" "maybe_vex")
21955 (set_attr "mode" "DF")])
21957 ;; Use movmskpd in SSE mode to avoid store forwarding stall
21958 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
21959 (define_expand "signbitdf2"
21960 [(use (match_operand:SI 0 "register_operand"))
21961 (use (match_operand:DF 1 "register_operand"))]
21962 "TARGET_USE_FANCY_MATH_387
21963 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
21965 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
21967 emit_insn (gen_movmsk_df (operands[0], operands[1]));
21968 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
21972 rtx scratch = gen_reg_rtx (HImode);
21974 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
21975 emit_insn (gen_andsi3 (operands[0],
21976 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
21981 (define_expand "signbitsf2"
21982 [(use (match_operand:SI 0 "register_operand"))
21983 (use (match_operand:SF 1 "register_operand"))]
21984 "TARGET_USE_FANCY_MATH_387
21985 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
21987 rtx scratch = gen_reg_rtx (HImode);
21989 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
21990 emit_insn (gen_andsi3 (operands[0],
21991 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
21995 ;; Block operation instructions
21998 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
22001 [(set_attr "length" "1")
22002 (set_attr "length_immediate" "0")
22003 (set_attr "modrm" "0")])
22005 (define_expand "cpymem<mode>"
22006 [(use (match_operand:BLK 0 "memory_operand"))
22007 (use (match_operand:BLK 1 "memory_operand"))
22008 (use (match_operand:SWI48 2 "nonmemory_operand"))
22009 (use (match_operand:SWI48 3 "const_int_operand"))
22010 (use (match_operand:SI 4 "const_int_operand"))
22011 (use (match_operand:SI 5 "const_int_operand"))
22012 (use (match_operand:SI 6 ""))
22013 (use (match_operand:SI 7 ""))
22014 (use (match_operand:SI 8 ""))]
22017 if (ix86_expand_set_or_cpymem (operands[0], operands[1],
22018 operands[2], NULL, operands[3],
22019 operands[4], operands[5],
22020 operands[6], operands[7],
22021 operands[8], false))
22027 ;; Most CPUs don't like single string operations
22028 ;; Handle this case here to simplify previous expander.
22030 (define_expand "strmov"
22031 [(set (match_dup 4) (match_operand 3 "memory_operand"))
22032 (set (match_operand 1 "memory_operand") (match_dup 4))
22033 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
22034 (clobber (reg:CC FLAGS_REG))])
22035 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
22036 (clobber (reg:CC FLAGS_REG))])]
22039 /* Can't use this for non-default address spaces. */
22040 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
22043 int piece_size = GET_MODE_SIZE (GET_MODE (operands[1]));
22045 /* If .md ever supports :P for Pmode, these can be directly
22046 in the pattern above. */
22047 operands[5] = plus_constant (Pmode, operands[0], piece_size);
22048 operands[6] = plus_constant (Pmode, operands[2], piece_size);
22050 /* Can't use this if the user has appropriated esi or edi. */
22051 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
22052 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
22054 emit_insn (gen_strmov_singleop (operands[0], operands[1],
22055 operands[2], operands[3],
22056 operands[5], operands[6]));
22060 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
22063 (define_expand "strmov_singleop"
22064 [(parallel [(set (match_operand 1 "memory_operand")
22065 (match_operand 3 "memory_operand"))
22066 (set (match_operand 0 "register_operand")
22068 (set (match_operand 2 "register_operand")
22069 (match_operand 5))])]
22073 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22076 (define_insn "*strmovdi_rex_1"
22077 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
22078 (mem:DI (match_operand:P 3 "register_operand" "1")))
22079 (set (match_operand:P 0 "register_operand" "=D")
22080 (plus:P (match_dup 2)
22082 (set (match_operand:P 1 "register_operand" "=S")
22083 (plus:P (match_dup 3)
22086 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22087 && ix86_check_no_addr_space (insn)"
22089 [(set_attr "type" "str")
22090 (set_attr "memory" "both")
22091 (set_attr "mode" "DI")])
22093 (define_insn "*strmovsi_1"
22094 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
22095 (mem:SI (match_operand:P 3 "register_operand" "1")))
22096 (set (match_operand:P 0 "register_operand" "=D")
22097 (plus:P (match_dup 2)
22099 (set (match_operand:P 1 "register_operand" "=S")
22100 (plus:P (match_dup 3)
22102 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22103 && ix86_check_no_addr_space (insn)"
22105 [(set_attr "type" "str")
22106 (set_attr "memory" "both")
22107 (set_attr "mode" "SI")])
22109 (define_insn "*strmovhi_1"
22110 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
22111 (mem:HI (match_operand:P 3 "register_operand" "1")))
22112 (set (match_operand:P 0 "register_operand" "=D")
22113 (plus:P (match_dup 2)
22115 (set (match_operand:P 1 "register_operand" "=S")
22116 (plus:P (match_dup 3)
22118 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22119 && ix86_check_no_addr_space (insn)"
22121 [(set_attr "type" "str")
22122 (set_attr "memory" "both")
22123 (set_attr "mode" "HI")])
22125 (define_insn "*strmovqi_1"
22126 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
22127 (mem:QI (match_operand:P 3 "register_operand" "1")))
22128 (set (match_operand:P 0 "register_operand" "=D")
22129 (plus:P (match_dup 2)
22131 (set (match_operand:P 1 "register_operand" "=S")
22132 (plus:P (match_dup 3)
22134 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22135 && ix86_check_no_addr_space (insn)"
22137 [(set_attr "type" "str")
22138 (set_attr "memory" "both")
22139 (set (attr "prefix_rex")
22141 (match_test "<P:MODE>mode == DImode")
22143 (const_string "*")))
22144 (set_attr "mode" "QI")])
22146 (define_expand "rep_mov"
22147 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
22148 (set (match_operand 0 "register_operand")
22150 (set (match_operand 2 "register_operand")
22152 (set (match_operand 1 "memory_operand")
22153 (match_operand 3 "memory_operand"))
22154 (use (match_dup 4))])]
22158 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22161 (define_insn "*rep_movdi_rex64"
22162 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
22163 (set (match_operand:P 0 "register_operand" "=D")
22164 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
22166 (match_operand:P 3 "register_operand" "0")))
22167 (set (match_operand:P 1 "register_operand" "=S")
22168 (plus:P (ashift:P (match_dup 5) (const_int 3))
22169 (match_operand:P 4 "register_operand" "1")))
22170 (set (mem:BLK (match_dup 3))
22171 (mem:BLK (match_dup 4)))
22172 (use (match_dup 5))]
22174 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22175 && ix86_check_no_addr_space (insn)"
22177 [(set_attr "type" "str")
22178 (set_attr "prefix_rep" "1")
22179 (set_attr "memory" "both")
22180 (set_attr "mode" "DI")])
22182 (define_insn "*rep_movsi"
22183 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
22184 (set (match_operand:P 0 "register_operand" "=D")
22185 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
22187 (match_operand:P 3 "register_operand" "0")))
22188 (set (match_operand:P 1 "register_operand" "=S")
22189 (plus:P (ashift:P (match_dup 5) (const_int 2))
22190 (match_operand:P 4 "register_operand" "1")))
22191 (set (mem:BLK (match_dup 3))
22192 (mem:BLK (match_dup 4)))
22193 (use (match_dup 5))]
22194 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22195 && ix86_check_no_addr_space (insn)"
22196 "%^rep{%;} movs{l|d}"
22197 [(set_attr "type" "str")
22198 (set_attr "prefix_rep" "1")
22199 (set_attr "memory" "both")
22200 (set_attr "mode" "SI")])
22202 (define_insn "*rep_movqi"
22203 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
22204 (set (match_operand:P 0 "register_operand" "=D")
22205 (plus:P (match_operand:P 3 "register_operand" "0")
22206 (match_operand:P 5 "register_operand" "2")))
22207 (set (match_operand:P 1 "register_operand" "=S")
22208 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
22209 (set (mem:BLK (match_dup 3))
22210 (mem:BLK (match_dup 4)))
22211 (use (match_dup 5))]
22212 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22213 && ix86_check_no_addr_space (insn)"
22215 [(set_attr "type" "str")
22216 (set_attr "prefix_rep" "1")
22217 (set_attr "memory" "both")
22218 (set_attr "mode" "QI")])
22220 (define_expand "setmem<mode>"
22221 [(use (match_operand:BLK 0 "memory_operand"))
22222 (use (match_operand:SWI48 1 "nonmemory_operand"))
22223 (use (match_operand:QI 2 "nonmemory_operand"))
22224 (use (match_operand 3 "const_int_operand"))
22225 (use (match_operand:SI 4 "const_int_operand"))
22226 (use (match_operand:SI 5 "const_int_operand"))
22227 (use (match_operand:SI 6 ""))
22228 (use (match_operand:SI 7 ""))
22229 (use (match_operand:SI 8 ""))]
22232 if (ix86_expand_set_or_cpymem (operands[0], NULL,
22233 operands[1], operands[2],
22234 operands[3], operands[4],
22235 operands[5], operands[6],
22236 operands[7], operands[8], true))
22242 ;; Most CPUs don't like single string operations
22243 ;; Handle this case here to simplify previous expander.
22245 (define_expand "strset"
22246 [(set (match_operand 1 "memory_operand")
22247 (match_operand 2 "register_operand"))
22248 (parallel [(set (match_operand 0 "register_operand")
22250 (clobber (reg:CC FLAGS_REG))])]
22253 /* Can't use this for non-default address spaces. */
22254 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
22257 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
22258 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
22260 /* If .md ever supports :P for Pmode, this can be directly
22261 in the pattern above. */
22262 operands[3] = plus_constant (Pmode, operands[0],
22263 GET_MODE_SIZE (GET_MODE (operands[2])));
22265 /* Can't use this if the user has appropriated eax or edi. */
22266 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
22267 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
22269 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
22275 (define_expand "strset_singleop"
22276 [(parallel [(set (match_operand 1 "memory_operand")
22277 (match_operand 2 "register_operand"))
22278 (set (match_operand 0 "register_operand")
22280 (unspec [(const_int 0)] UNSPEC_STOS)])]
22284 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22287 (define_insn "*strsetdi_rex_1"
22288 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
22289 (match_operand:DI 2 "register_operand" "a"))
22290 (set (match_operand:P 0 "register_operand" "=D")
22291 (plus:P (match_dup 1)
22293 (unspec [(const_int 0)] UNSPEC_STOS)]
22295 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22296 && ix86_check_no_addr_space (insn)"
22298 [(set_attr "type" "str")
22299 (set_attr "memory" "store")
22300 (set_attr "mode" "DI")])
22302 (define_insn "*strsetsi_1"
22303 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
22304 (match_operand:SI 2 "register_operand" "a"))
22305 (set (match_operand:P 0 "register_operand" "=D")
22306 (plus:P (match_dup 1)
22308 (unspec [(const_int 0)] UNSPEC_STOS)]
22309 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22310 && ix86_check_no_addr_space (insn)"
22312 [(set_attr "type" "str")
22313 (set_attr "memory" "store")
22314 (set_attr "mode" "SI")])
22316 (define_insn "*strsethi_1"
22317 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
22318 (match_operand:HI 2 "register_operand" "a"))
22319 (set (match_operand:P 0 "register_operand" "=D")
22320 (plus:P (match_dup 1)
22322 (unspec [(const_int 0)] UNSPEC_STOS)]
22323 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22324 && ix86_check_no_addr_space (insn)"
22326 [(set_attr "type" "str")
22327 (set_attr "memory" "store")
22328 (set_attr "mode" "HI")])
22330 (define_insn "*strsetqi_1"
22331 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
22332 (match_operand:QI 2 "register_operand" "a"))
22333 (set (match_operand:P 0 "register_operand" "=D")
22334 (plus:P (match_dup 1)
22336 (unspec [(const_int 0)] UNSPEC_STOS)]
22337 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22338 && ix86_check_no_addr_space (insn)"
22340 [(set_attr "type" "str")
22341 (set_attr "memory" "store")
22342 (set (attr "prefix_rex")
22344 (match_test "<P:MODE>mode == DImode")
22346 (const_string "*")))
22347 (set_attr "mode" "QI")])
22349 (define_expand "rep_stos"
22350 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
22351 (set (match_operand 0 "register_operand")
22353 (set (match_operand 2 "memory_operand") (const_int 0))
22354 (use (match_operand 3 "register_operand"))
22355 (use (match_dup 1))])]
22359 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22362 (define_insn "*rep_stosdi_rex64"
22363 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
22364 (set (match_operand:P 0 "register_operand" "=D")
22365 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
22367 (match_operand:P 3 "register_operand" "0")))
22368 (set (mem:BLK (match_dup 3))
22370 (use (match_operand:DI 2 "register_operand" "a"))
22371 (use (match_dup 4))]
22373 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
22374 && ix86_check_no_addr_space (insn)"
22376 [(set_attr "type" "str")
22377 (set_attr "prefix_rep" "1")
22378 (set_attr "memory" "store")
22379 (set_attr "mode" "DI")])
22381 (define_insn "*rep_stossi"
22382 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
22383 (set (match_operand:P 0 "register_operand" "=D")
22384 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
22386 (match_operand:P 3 "register_operand" "0")))
22387 (set (mem:BLK (match_dup 3))
22389 (use (match_operand:SI 2 "register_operand" "a"))
22390 (use (match_dup 4))]
22391 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
22392 && ix86_check_no_addr_space (insn)"
22393 "%^rep{%;} stos{l|d}"
22394 [(set_attr "type" "str")
22395 (set_attr "prefix_rep" "1")
22396 (set_attr "memory" "store")
22397 (set_attr "mode" "SI")])
22399 (define_insn "*rep_stosqi"
22400 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
22401 (set (match_operand:P 0 "register_operand" "=D")
22402 (plus:P (match_operand:P 3 "register_operand" "0")
22403 (match_operand:P 4 "register_operand" "1")))
22404 (set (mem:BLK (match_dup 3))
22406 (use (match_operand:QI 2 "register_operand" "a"))
22407 (use (match_dup 4))]
22408 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
22409 && ix86_check_no_addr_space (insn)"
22411 [(set_attr "type" "str")
22412 (set_attr "prefix_rep" "1")
22413 (set_attr "memory" "store")
22414 (set (attr "prefix_rex")
22416 (match_test "<P:MODE>mode == DImode")
22418 (const_string "*")))
22419 (set_attr "mode" "QI")])
22421 (define_expand "cmpmemsi"
22422 [(set (match_operand:SI 0 "register_operand" "")
22423 (compare:SI (match_operand:BLK 1 "memory_operand" "")
22424 (match_operand:BLK 2 "memory_operand" "") ) )
22425 (use (match_operand 3 "general_operand"))
22426 (use (match_operand 4 "immediate_operand"))]
22429 if (ix86_expand_cmpstrn_or_cmpmem (operands[0], operands[1],
22430 operands[2], operands[3],
22431 operands[4], false))
22437 (define_expand "cmpstrnsi"
22438 [(set (match_operand:SI 0 "register_operand")
22439 (compare:SI (match_operand:BLK 1 "general_operand")
22440 (match_operand:BLK 2 "general_operand")))
22441 (use (match_operand 3 "general_operand"))
22442 (use (match_operand 4 "immediate_operand"))]
22445 if (ix86_expand_cmpstrn_or_cmpmem (operands[0], operands[1],
22446 operands[2], operands[3],
22447 operands[4], true))
22453 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
22455 (define_expand "cmpintqi"
22456 [(set (match_dup 1)
22457 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
22459 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
22460 (parallel [(set (match_operand:QI 0 "register_operand")
22461 (minus:QI (match_dup 1)
22463 (clobber (reg:CC FLAGS_REG))])]
22466 operands[1] = gen_reg_rtx (QImode);
22467 operands[2] = gen_reg_rtx (QImode);
22470 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
22471 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
22473 (define_expand "cmpstrnqi_nz_1"
22474 [(parallel [(set (reg:CC FLAGS_REG)
22475 (compare:CC (match_operand 4 "memory_operand")
22476 (match_operand 5 "memory_operand")))
22477 (use (match_operand 2 "register_operand"))
22478 (use (match_operand:SI 3 "immediate_operand"))
22479 (clobber (match_operand 0 "register_operand"))
22480 (clobber (match_operand 1 "register_operand"))
22481 (clobber (match_dup 2))])]
22485 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22488 (define_insn "*cmpstrnqi_nz_1"
22489 [(set (reg:CC FLAGS_REG)
22490 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
22491 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
22492 (use (match_operand:P 6 "register_operand" "2"))
22493 (use (match_operand:SI 3 "immediate_operand" "i"))
22494 (clobber (match_operand:P 0 "register_operand" "=S"))
22495 (clobber (match_operand:P 1 "register_operand" "=D"))
22496 (clobber (match_operand:P 2 "register_operand" "=c"))]
22497 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22498 && ix86_check_no_addr_space (insn)"
22500 [(set_attr "type" "str")
22501 (set_attr "mode" "QI")
22502 (set (attr "prefix_rex")
22504 (match_test "<P:MODE>mode == DImode")
22506 (const_string "*")))
22507 (set_attr "prefix_rep" "1")])
22509 ;; The same, but the count is not known to not be zero.
22511 (define_expand "cmpstrnqi_1"
22512 [(parallel [(set (reg:CC FLAGS_REG)
22513 (if_then_else:CC (ne (match_operand 2 "register_operand")
22515 (compare:CC (match_operand 4 "memory_operand")
22516 (match_operand 5 "memory_operand"))
22518 (use (match_operand:SI 3 "immediate_operand"))
22519 (use (reg:CC FLAGS_REG))
22520 (clobber (match_operand 0 "register_operand"))
22521 (clobber (match_operand 1 "register_operand"))
22522 (clobber (match_dup 2))])]
22526 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22529 (define_insn "*cmpstrnqi_1"
22530 [(set (reg:CC FLAGS_REG)
22531 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
22533 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
22534 (mem:BLK (match_operand:P 5 "register_operand" "1")))
22536 (use (match_operand:SI 3 "immediate_operand" "i"))
22537 (use (reg:CC FLAGS_REG))
22538 (clobber (match_operand:P 0 "register_operand" "=S"))
22539 (clobber (match_operand:P 1 "register_operand" "=D"))
22540 (clobber (match_operand:P 2 "register_operand" "=c"))]
22541 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22542 && ix86_check_no_addr_space (insn)"
22544 [(set_attr "type" "str")
22545 (set_attr "mode" "QI")
22546 (set (attr "prefix_rex")
22548 (match_test "<P:MODE>mode == DImode")
22550 (const_string "*")))
22551 (set_attr "prefix_rep" "1")])
22553 (define_expand "strlen<mode>"
22554 [(set (match_operand:P 0 "register_operand")
22555 (unspec:P [(match_operand:BLK 1 "general_operand")
22556 (match_operand:QI 2 "immediate_operand")
22557 (match_operand 3 "immediate_operand")]
22561 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
22567 (define_expand "strlenqi_1"
22568 [(parallel [(set (match_operand 0 "register_operand")
22570 (clobber (match_operand 1 "register_operand"))
22571 (clobber (reg:CC FLAGS_REG))])]
22575 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22578 (define_insn "*strlenqi_1"
22579 [(set (match_operand:P 0 "register_operand" "=&c")
22580 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
22581 (match_operand:QI 2 "register_operand" "a")
22582 (match_operand:P 3 "immediate_operand" "i")
22583 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
22584 (clobber (match_operand:P 1 "register_operand" "=D"))
22585 (clobber (reg:CC FLAGS_REG))]
22586 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
22587 && ix86_check_no_addr_space (insn)"
22588 "%^repnz{%;} scasb"
22589 [(set_attr "type" "str")
22590 (set_attr "mode" "QI")
22591 (set (attr "prefix_rex")
22593 (match_test "<P:MODE>mode == DImode")
22595 (const_string "*")))
22596 (set_attr "prefix_rep" "1")])
22598 ;; Peephole optimizations to clean up after cmpstrn*. This should be
22599 ;; handled in combine, but it is not currently up to the task.
22600 ;; When used for their truth value, the cmpstrn* expanders generate
22609 ;; The intermediate three instructions are unnecessary.
22611 ;; This one handles cmpstrn*_nz_1...
22614 (set (reg:CC FLAGS_REG)
22615 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
22616 (mem:BLK (match_operand 5 "register_operand"))))
22617 (use (match_operand 6 "register_operand"))
22618 (use (match_operand:SI 3 "immediate_operand"))
22619 (clobber (match_operand 0 "register_operand"))
22620 (clobber (match_operand 1 "register_operand"))
22621 (clobber (match_operand 2 "register_operand"))])
22622 (set (match_operand:QI 7 "register_operand")
22623 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
22624 (set (match_operand:QI 8 "register_operand")
22625 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
22626 (set (reg FLAGS_REG)
22627 (compare (match_dup 7) (match_dup 8)))
22629 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
22631 (set (reg:CC FLAGS_REG)
22632 (compare:CC (mem:BLK (match_dup 4))
22633 (mem:BLK (match_dup 5))))
22634 (use (match_dup 6))
22635 (use (match_dup 3))
22636 (clobber (match_dup 0))
22637 (clobber (match_dup 1))
22638 (clobber (match_dup 2))])])
22640 ;; ...and this one handles cmpstrn*_1.
22643 (set (reg:CC FLAGS_REG)
22644 (if_then_else:CC (ne (match_operand 6 "register_operand")
22646 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
22647 (mem:BLK (match_operand 5 "register_operand")))
22649 (use (match_operand:SI 3 "immediate_operand"))
22650 (use (reg:CC FLAGS_REG))
22651 (clobber (match_operand 0 "register_operand"))
22652 (clobber (match_operand 1 "register_operand"))
22653 (clobber (match_operand 2 "register_operand"))])
22654 (set (match_operand:QI 7 "register_operand")
22655 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
22656 (set (match_operand:QI 8 "register_operand")
22657 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
22658 (set (reg FLAGS_REG)
22659 (compare (match_dup 7) (match_dup 8)))
22661 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
22663 (set (reg:CC FLAGS_REG)
22664 (if_then_else:CC (ne (match_dup 6)
22666 (compare:CC (mem:BLK (match_dup 4))
22667 (mem:BLK (match_dup 5)))
22669 (use (match_dup 3))
22670 (use (reg:CC FLAGS_REG))
22671 (clobber (match_dup 0))
22672 (clobber (match_dup 1))
22673 (clobber (match_dup 2))])])
22675 ;; Conditional move instructions.
22677 (define_expand "mov<mode>cc"
22678 [(set (match_operand:SWIM 0 "register_operand")
22679 (if_then_else:SWIM (match_operand 1 "comparison_operator")
22680 (match_operand:SWIM 2 "<general_operand>")
22681 (match_operand:SWIM 3 "<general_operand>")))]
22683 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
22685 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
22686 ;; the register first winds up with `sbbl $0,reg', which is also weird.
22687 ;; So just document what we're doing explicitly.
22689 (define_expand "x86_mov<mode>cc_0_m1"
22691 [(set (match_operand:SWI48 0 "register_operand")
22692 (if_then_else:SWI48
22693 (match_operator:SWI48 2 "ix86_carry_flag_operator"
22694 [(match_operand 1 "flags_reg_operand")
22698 (clobber (reg:CC FLAGS_REG))])])
22700 (define_insn "*x86_mov<mode>cc_0_m1"
22701 [(set (match_operand:SWI48 0 "register_operand" "=r")
22702 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
22703 [(reg FLAGS_REG) (const_int 0)])
22706 (clobber (reg:CC FLAGS_REG))]
22708 "sbb{<imodesuffix>}\t%0, %0"
22709 [(set_attr "type" "alu1")
22710 (set_attr "use_carry" "1")
22711 (set_attr "pent_pair" "pu")
22712 (set_attr "mode" "<MODE>")
22713 (set_attr "length_immediate" "0")])
22715 (define_insn "*x86_mov<mode>cc_0_m1_se"
22716 [(set (match_operand:SWI48 0 "register_operand" "=r")
22717 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
22718 [(reg FLAGS_REG) (const_int 0)])
22721 (clobber (reg:CC FLAGS_REG))]
22723 "sbb{<imodesuffix>}\t%0, %0"
22724 [(set_attr "type" "alu1")
22725 (set_attr "use_carry" "1")
22726 (set_attr "pent_pair" "pu")
22727 (set_attr "mode" "<MODE>")
22728 (set_attr "length_immediate" "0")])
22730 (define_insn "*x86_mov<mode>cc_0_m1_neg"
22731 [(set (match_operand:SWI 0 "register_operand" "=<r>")
22732 (neg:SWI (match_operator 1 "ix86_carry_flag_operator"
22733 [(reg FLAGS_REG) (const_int 0)])))
22734 (clobber (reg:CC FLAGS_REG))]
22736 "sbb{<imodesuffix>}\t%0, %0"
22737 [(set_attr "type" "alu1")
22738 (set_attr "use_carry" "1")
22739 (set_attr "pent_pair" "pu")
22740 (set_attr "mode" "<MODE>")
22741 (set_attr "length_immediate" "0")])
22743 (define_expand "x86_mov<mode>cc_0_m1_neg"
22745 [(set (match_operand:SWI48 0 "register_operand")
22746 (neg:SWI48 (ltu:SWI48 (reg:CCC FLAGS_REG) (const_int 0))))
22747 (clobber (reg:CC FLAGS_REG))])])
22750 [(set (match_operand:SWI48 0 "register_operand")
22753 (match_operand 1 "int_nonimmediate_operand")
22754 (match_operand 2 "const_int_operand"))))]
22755 "x86_64_immediate_operand (operands[2], VOIDmode)
22756 && INTVAL (operands[2]) != -1
22757 && INTVAL (operands[2]) != 2147483647"
22758 [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
22760 (neg:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))))]
22761 "operands[2] = GEN_INT (INTVAL (operands[2]) + 1);")
22764 [(set (match_operand:SWI 0 "register_operand")
22767 (match_operand 1 "int_nonimmediate_operand")
22770 [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (const_int 1)))
22772 (neg:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))))])
22775 [(set (match_operand:SWI 0 "register_operand")
22778 (match_operand 1 "int_nonimmediate_operand")
22781 [(set (reg:CCC FLAGS_REG)
22782 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
22784 (neg:SWI (ltu:SWI (reg:CCC FLAGS_REG) (const_int 0))))])
22786 (define_insn "*mov<mode>cc_noc"
22787 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
22788 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
22789 [(reg FLAGS_REG) (const_int 0)])
22790 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
22791 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
22792 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
22794 cmov%O2%C1\t{%2, %0|%0, %2}
22795 cmov%O2%c1\t{%3, %0|%0, %3}"
22796 [(set_attr "type" "icmov")
22797 (set_attr "mode" "<MODE>")])
22799 (define_insn "*movsicc_noc_zext"
22800 [(set (match_operand:DI 0 "register_operand" "=r,r")
22801 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
22802 [(reg FLAGS_REG) (const_int 0)])
22804 (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
22806 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
22808 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
22810 cmov%O2%C1\t{%2, %k0|%k0, %2}
22811 cmov%O2%c1\t{%3, %k0|%k0, %3}"
22812 [(set_attr "type" "icmov")
22813 (set_attr "mode" "SI")])
22815 (define_insn "*movsicc_noc_zext_1"
22816 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r")
22818 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
22819 [(reg FLAGS_REG) (const_int 0)])
22820 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
22821 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
22823 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
22825 cmov%O2%C1\t{%2, %k0|%k0, %2}
22826 cmov%O2%c1\t{%3, %k0|%k0, %3}"
22827 [(set_attr "type" "icmov")
22828 (set_attr "mode" "SI")])
22831 ;; Don't do conditional moves with memory inputs. This splitter helps
22832 ;; register starved x86_32 by forcing inputs into registers before reload.
22834 [(set (match_operand:SWI248 0 "register_operand")
22835 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
22836 [(reg FLAGS_REG) (const_int 0)])
22837 (match_operand:SWI248 2 "nonimmediate_operand")
22838 (match_operand:SWI248 3 "nonimmediate_operand")))]
22839 "!TARGET_64BIT && TARGET_CMOVE
22840 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
22841 && (MEM_P (operands[2]) || MEM_P (operands[3]))
22842 && can_create_pseudo_p ()
22843 && optimize_insn_for_speed_p ()"
22844 [(set (match_dup 0)
22845 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
22847 operands[2] = force_reg (<MODE>mode, operands[2]);
22848 operands[3] = force_reg (<MODE>mode, operands[3]);
22851 (define_insn "*movqicc_noc"
22852 [(set (match_operand:QI 0 "register_operand" "=r,r")
22853 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
22854 [(reg FLAGS_REG) (const_int 0)])
22855 (match_operand:QI 2 "register_operand" "r,0")
22856 (match_operand:QI 3 "register_operand" "0,r")))]
22857 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
22859 [(set_attr "type" "icmov")
22860 (set_attr "mode" "QI")])
22863 [(set (match_operand:SWI12 0 "register_operand")
22864 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
22865 [(reg FLAGS_REG) (const_int 0)])
22866 (match_operand:SWI12 2 "register_operand")
22867 (match_operand:SWI12 3 "register_operand")))]
22868 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
22869 && reload_completed"
22870 [(set (match_dup 0)
22871 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
22873 operands[0] = gen_lowpart (SImode, operands[0]);
22874 operands[2] = gen_lowpart (SImode, operands[2]);
22875 operands[3] = gen_lowpart (SImode, operands[3]);
22878 ;; Don't do conditional moves with memory inputs
22880 [(match_scratch:SWI248 4 "r")
22881 (set (match_operand:SWI248 0 "register_operand")
22882 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
22883 [(reg FLAGS_REG) (const_int 0)])
22884 (match_operand:SWI248 2 "nonimmediate_operand")
22885 (match_operand:SWI248 3 "nonimmediate_operand")))]
22886 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
22887 && (MEM_P (operands[2]) || MEM_P (operands[3]))
22888 && optimize_insn_for_speed_p ()"
22889 [(set (match_dup 4) (match_dup 5))
22891 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
22893 if (MEM_P (operands[2]))
22895 operands[5] = operands[2];
22896 operands[2] = operands[4];
22898 else if (MEM_P (operands[3]))
22900 operands[5] = operands[3];
22901 operands[3] = operands[4];
22904 gcc_unreachable ();
22908 [(match_scratch:SI 4 "r")
22909 (set (match_operand:DI 0 "register_operand")
22910 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
22911 [(reg FLAGS_REG) (const_int 0)])
22913 (match_operand:SI 2 "nonimmediate_operand"))
22915 (match_operand:SI 3 "nonimmediate_operand"))))]
22917 && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
22918 && (MEM_P (operands[2]) || MEM_P (operands[3]))
22919 && optimize_insn_for_speed_p ()"
22920 [(set (match_dup 4) (match_dup 5))
22922 (if_then_else:DI (match_dup 1)
22923 (zero_extend:DI (match_dup 2))
22924 (zero_extend:DI (match_dup 3))))]
22926 if (MEM_P (operands[2]))
22928 operands[5] = operands[2];
22929 operands[2] = operands[4];
22931 else if (MEM_P (operands[3]))
22933 operands[5] = operands[3];
22934 operands[3] = operands[4];
22937 gcc_unreachable ();
22940 ;; Eliminate a reg-reg mov by inverting the condition of a cmov (#1).
22941 ;; mov r0,r1; dec r0; mov r2,r3; cmov r0,r2 -> dec r1; mov r0,r3; cmov r0, r1
22943 [(set (match_operand:SWI248 0 "general_reg_operand")
22944 (match_operand:SWI248 1 "general_reg_operand"))
22945 (parallel [(set (reg FLAGS_REG) (match_operand 5))
22946 (set (match_dup 0) (match_operand:SWI248 6))])
22947 (set (match_operand:SWI248 2 "general_reg_operand")
22948 (match_operand:SWI248 3 "general_gr_operand"))
22950 (if_then_else:SWI248 (match_operator 4 "ix86_comparison_operator"
22951 [(reg FLAGS_REG) (const_int 0)])
22955 && REGNO (operands[2]) != REGNO (operands[0])
22956 && REGNO (operands[2]) != REGNO (operands[1])
22957 && peep2_reg_dead_p (1, operands[1])
22958 && peep2_reg_dead_p (4, operands[2])
22959 && !reg_overlap_mentioned_p (operands[0], operands[3])"
22960 [(parallel [(set (match_dup 7) (match_dup 8))
22961 (set (match_dup 1) (match_dup 9))])
22962 (set (match_dup 0) (match_dup 3))
22963 (set (match_dup 0) (if_then_else:SWI248 (match_dup 4)
22967 operands[7] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
22969 = ix86_replace_reg_with_reg (operands[5], operands[0], operands[1]);
22971 = ix86_replace_reg_with_reg (operands[6], operands[0], operands[1]);
22974 ;; Eliminate a reg-reg mov by inverting the condition of a cmov (#2).
22975 ;; mov r2,r3; mov r0,r1; dec r0; cmov r0,r2 -> dec r1; mov r0,r3; cmov r0, r1
22977 [(set (match_operand:SWI248 2 "general_reg_operand")
22978 (match_operand:SWI248 3 "general_gr_operand"))
22979 (set (match_operand:SWI248 0 "general_reg_operand")
22980 (match_operand:SWI248 1 "general_reg_operand"))
22981 (parallel [(set (reg FLAGS_REG) (match_operand 5))
22982 (set (match_dup 0) (match_operand:SWI248 6))])
22984 (if_then_else:SWI248 (match_operator 4 "ix86_comparison_operator"
22985 [(reg FLAGS_REG) (const_int 0)])
22989 && REGNO (operands[2]) != REGNO (operands[0])
22990 && REGNO (operands[2]) != REGNO (operands[1])
22991 && peep2_reg_dead_p (2, operands[1])
22992 && peep2_reg_dead_p (4, operands[2])
22993 && !reg_overlap_mentioned_p (operands[0], operands[3])
22994 && !reg_mentioned_p (operands[2], operands[6])"
22995 [(parallel [(set (match_dup 7) (match_dup 8))
22996 (set (match_dup 1) (match_dup 9))])
22997 (set (match_dup 0) (match_dup 3))
22998 (set (match_dup 0) (if_then_else:SWI248 (match_dup 4)
23002 operands[7] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (2)), 0, 0));
23004 = ix86_replace_reg_with_reg (operands[5], operands[0], operands[1]);
23006 = ix86_replace_reg_with_reg (operands[6], operands[0], operands[1]);
23009 (define_insn "movhf_mask"
23010 [(set (match_operand:HF 0 "nonimmediate_operand" "=v,m,v")
23012 [(match_operand:HF 1 "nonimmediate_operand" "m,v,v")
23013 (match_operand:HF 2 "nonimm_or_0_operand" "0C,0C,0C")
23014 (match_operand:QI 3 "register_operand" "Yk,Yk,Yk")]
23015 UNSPEC_MOVCC_MASK))]
23016 "TARGET_AVX512FP16"
23018 vmovsh\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}
23019 vmovsh\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}
23020 vmovsh\t{%d1, %0%{%3%}%N2|%0%{%3%}%N2, %d1}"
23021 [(set_attr "type" "ssemov")
23022 (set_attr "prefix" "evex")
23023 (set_attr "mode" "HF")])
23025 (define_expand "movhfcc"
23026 [(set (match_operand:HF 0 "register_operand")
23028 (match_operand 1 "comparison_operator")
23029 (match_operand:HF 2 "register_operand")
23030 (match_operand:HF 3 "register_operand")))]
23031 "TARGET_AVX512FP16"
23032 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
23034 (define_expand "mov<mode>cc"
23035 [(set (match_operand:X87MODEF 0 "register_operand")
23036 (if_then_else:X87MODEF
23037 (match_operand 1 "comparison_operator")
23038 (match_operand:X87MODEF 2 "register_operand")
23039 (match_operand:X87MODEF 3 "register_operand")))]
23040 "(TARGET_80387 && TARGET_CMOVE)
23041 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
23042 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
23044 (define_insn "*movxfcc_1"
23045 [(set (match_operand:XF 0 "register_operand" "=f,f")
23046 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
23047 [(reg FLAGS_REG) (const_int 0)])
23048 (match_operand:XF 2 "register_operand" "f,0")
23049 (match_operand:XF 3 "register_operand" "0,f")))]
23050 "TARGET_80387 && TARGET_CMOVE"
23052 fcmov%F1\t{%2, %0|%0, %2}
23053 fcmov%f1\t{%3, %0|%0, %3}"
23054 [(set_attr "type" "fcmov")
23055 (set_attr "mode" "XF")])
23057 (define_insn "*movdfcc_1"
23058 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
23059 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
23060 [(reg FLAGS_REG) (const_int 0)])
23061 (match_operand:DF 2 "nonimmediate_operand"
23063 (match_operand:DF 3 "nonimmediate_operand"
23064 "0 ,f,0 ,rm,0, rm")))]
23065 "TARGET_80387 && TARGET_CMOVE
23066 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23068 fcmov%F1\t{%2, %0|%0, %2}
23069 fcmov%f1\t{%3, %0|%0, %3}
23072 cmov%O2%C1\t{%2, %0|%0, %2}
23073 cmov%O2%c1\t{%3, %0|%0, %3}"
23074 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
23075 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
23076 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
23079 [(set (match_operand:DF 0 "general_reg_operand")
23080 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
23081 [(reg FLAGS_REG) (const_int 0)])
23082 (match_operand:DF 2 "nonimmediate_operand")
23083 (match_operand:DF 3 "nonimmediate_operand")))]
23084 "!TARGET_64BIT && reload_completed"
23085 [(set (match_dup 2)
23086 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
23088 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
23090 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
23091 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
23094 (define_insn "*movsfcc_1_387"
23095 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
23096 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
23097 [(reg FLAGS_REG) (const_int 0)])
23098 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
23099 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
23100 "TARGET_80387 && TARGET_CMOVE
23101 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23103 fcmov%F1\t{%2, %0|%0, %2}
23104 fcmov%f1\t{%3, %0|%0, %3}
23105 cmov%O2%C1\t{%2, %0|%0, %2}
23106 cmov%O2%c1\t{%3, %0|%0, %3}"
23107 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
23108 (set_attr "mode" "SF,SF,SI,SI")])
23110 ;; Don't do conditional moves with memory inputs. This splitter helps
23111 ;; register starved x86_32 by forcing inputs into registers before reload.
23113 [(set (match_operand:MODEF 0 "register_operand")
23114 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
23115 [(reg FLAGS_REG) (const_int 0)])
23116 (match_operand:MODEF 2 "nonimmediate_operand")
23117 (match_operand:MODEF 3 "nonimmediate_operand")))]
23118 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
23119 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23120 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23121 && can_create_pseudo_p ()
23122 && optimize_insn_for_speed_p ()"
23123 [(set (match_dup 0)
23124 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
23126 operands[2] = force_reg (<MODE>mode, operands[2]);
23127 operands[3] = force_reg (<MODE>mode, operands[3]);
23130 ;; Don't do conditional moves with memory inputs
23132 [(match_scratch:MODEF 4 "r")
23133 (set (match_operand:MODEF 0 "general_reg_operand")
23134 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
23135 [(reg FLAGS_REG) (const_int 0)])
23136 (match_operand:MODEF 2 "nonimmediate_operand")
23137 (match_operand:MODEF 3 "nonimmediate_operand")))]
23138 "(<MODE>mode != DFmode || TARGET_64BIT)
23139 && TARGET_80387 && TARGET_CMOVE
23140 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23141 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23142 && optimize_insn_for_speed_p ()"
23143 [(set (match_dup 4) (match_dup 5))
23145 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
23147 if (MEM_P (operands[2]))
23149 operands[5] = operands[2];
23150 operands[2] = operands[4];
23152 else if (MEM_P (operands[3]))
23154 operands[5] = operands[3];
23155 operands[3] = operands[4];
23158 gcc_unreachable ();
23161 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
23162 ;; the scalar versions to have only XMM registers as operands.
23164 ;; XOP conditional move
23165 (define_insn "*xop_pcmov_<mode>"
23166 [(set (match_operand:MODEF 0 "register_operand" "=x")
23167 (if_then_else:MODEF
23168 (match_operand:MODEF 1 "register_operand" "x")
23169 (match_operand:MODEF 2 "register_operand" "x")
23170 (match_operand:MODEF 3 "register_operand" "x")))]
23172 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
23173 [(set_attr "type" "sse4arg")])
23175 ;; These versions of the min/max patterns are intentionally ignorant of
23176 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
23177 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
23178 ;; are undefined in this condition, we're certain this is correct.
23180 (define_insn "<code><mode>3"
23181 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
23183 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
23184 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
23185 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
23187 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
23188 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
23189 [(set_attr "isa" "noavx,avx")
23190 (set_attr "prefix" "orig,vex")
23191 (set_attr "type" "sseadd")
23192 (set_attr "mode" "<MODE>")])
23194 (define_insn "<code>hf3"
23195 [(set (match_operand:HF 0 "register_operand" "=v")
23197 (match_operand:HF 1 "nonimmediate_operand" "%v")
23198 (match_operand:HF 2 "nonimmediate_operand" "vm")))]
23199 "TARGET_AVX512FP16"
23200 "v<maxmin_float>sh\t{%2, %1, %0|%0, %1, %2}"
23201 [(set_attr "prefix" "evex")
23202 (set_attr "type" "sseadd")
23203 (set_attr "mode" "HF")])
23205 ;; These versions of the min/max patterns implement exactly the operations
23206 ;; min = (op1 < op2 ? op1 : op2)
23207 ;; max = (!(op1 < op2) ? op1 : op2)
23208 ;; Their operands are not commutative, and thus they may be used in the
23209 ;; presence of -0.0 and NaN.
23211 (define_insn "*ieee_s<ieee_maxmin>hf3"
23212 [(set (match_operand:HF 0 "register_operand" "=v")
23214 [(match_operand:HF 1 "register_operand" "v")
23215 (match_operand:HF 2 "nonimmediate_operand" "vm")]
23217 "TARGET_AVX512FP16"
23218 "v<ieee_maxmin>sh\t{%2, %1, %0|%0, %1, %2}"
23219 [(set_attr "prefix" "evex")
23220 (set_attr "type" "sseadd")
23221 (set_attr "mode" "HF")])
23223 (define_insn "*ieee_s<ieee_maxmin><mode>3"
23224 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
23226 [(match_operand:MODEF 1 "register_operand" "0,v")
23227 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
23229 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
23231 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
23232 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
23233 [(set_attr "isa" "noavx,avx")
23234 (set_attr "prefix" "orig,maybe_evex")
23235 (set_attr "type" "sseadd")
23236 (set_attr "mode" "<MODE>")])
23238 ;; Operands order in min/max instruction matters for signed zero and NANs.
23239 (define_insn_and_split "*ieee_max<mode>3_1"
23240 [(set (match_operand:MODEF 0 "register_operand")
23242 [(match_operand:MODEF 1 "register_operand")
23243 (match_operand:MODEF 2 "register_operand")
23245 (match_operand:MODEF 3 "register_operand")
23246 (match_operand:MODEF 4 "register_operand"))]
23248 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
23249 && (rtx_equal_p (operands[1], operands[3])
23250 && rtx_equal_p (operands[2], operands[4]))
23251 && ix86_pre_reload_split ()"
23254 [(set (match_dup 0)
23258 UNSPEC_IEEE_MAX))])
23260 (define_insn_and_split "*ieee_min<mode>3_1"
23261 [(set (match_operand:MODEF 0 "register_operand")
23263 [(match_operand:MODEF 1 "register_operand")
23264 (match_operand:MODEF 2 "register_operand")
23266 (match_operand:MODEF 3 "register_operand")
23267 (match_operand:MODEF 4 "register_operand"))]
23269 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
23270 && (rtx_equal_p (operands[1], operands[4])
23271 && rtx_equal_p (operands[2], operands[3]))
23272 && ix86_pre_reload_split ()"
23275 [(set (match_dup 0)
23279 UNSPEC_IEEE_MIN))])
23281 ;; Make two stack loads independent:
23283 ;; fld %st(0) -> fld bb
23284 ;; fmul bb fmul %st(1), %st
23286 ;; Actually we only match the last two instructions for simplicity.
23289 [(set (match_operand 0 "fp_register_operand")
23290 (match_operand 1 "fp_register_operand"))
23292 (match_operator 2 "binary_fp_operator"
23294 (match_operand 3 "memory_operand")]))]
23295 "REGNO (operands[0]) != REGNO (operands[1])"
23296 [(set (match_dup 0) (match_dup 3))
23299 [(match_dup 5) (match_dup 4)]))]
23301 operands[4] = operands[0];
23302 operands[5] = operands[1];
23304 /* The % modifier is not operational anymore in peephole2's, so we have to
23305 swap the operands manually in the case of addition and multiplication. */
23306 if (COMMUTATIVE_ARITH_P (operands[2]))
23307 std::swap (operands[4], operands[5]);
23311 [(set (match_operand 0 "fp_register_operand")
23312 (match_operand 1 "fp_register_operand"))
23314 (match_operator 2 "binary_fp_operator"
23315 [(match_operand 3 "memory_operand")
23317 "REGNO (operands[0]) != REGNO (operands[1])"
23318 [(set (match_dup 0) (match_dup 3))
23321 [(match_dup 4) (match_dup 5)]))]
23323 operands[4] = operands[0];
23324 operands[5] = operands[1];
23326 /* The % modifier is not operational anymore in peephole2's, so we have to
23327 swap the operands manually in the case of addition and multiplication. */
23328 if (COMMUTATIVE_ARITH_P (operands[2]))
23329 std::swap (operands[4], operands[5]);
23332 ;; Conditional addition patterns
23333 (define_expand "add<mode>cc"
23334 [(match_operand:SWI 0 "register_operand")
23335 (match_operand 1 "ordered_comparison_operator")
23336 (match_operand:SWI 2 "register_operand")
23337 (match_operand:SWI 3 "const_int_operand")]
23339 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
23341 ;; min/max patterns
23343 (define_code_attr maxmin_rel
23344 [(smax "GE") (smin "LE") (umax "GEU") (umin "LEU")])
23346 (define_expand "<code><mode>3"
23348 [(set (match_operand:SDWIM 0 "register_operand")
23350 (match_operand:SDWIM 1 "register_operand")
23351 (match_operand:SDWIM 2 "general_operand")))
23352 (clobber (reg:CC FLAGS_REG))])]
23354 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)")
23356 (define_insn_and_split "*<code><dwi>3_doubleword"
23357 [(set (match_operand:<DWI> 0 "register_operand")
23359 (match_operand:<DWI> 1 "register_operand")
23360 (match_operand:<DWI> 2 "general_operand")))
23361 (clobber (reg:CC FLAGS_REG))]
23363 && ix86_pre_reload_split ()"
23366 [(set (match_dup 0)
23367 (if_then_else:DWIH (match_dup 6)
23371 (if_then_else:DWIH (match_dup 6)
23375 operands[2] = force_reg (<DWI>mode, operands[2]);
23377 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
23379 rtx cmplo[2] = { operands[1], operands[2] };
23380 rtx cmphi[2] = { operands[4], operands[5] };
23382 enum rtx_code code = <maxmin_rel>;
23387 std::swap (cmplo[0], cmplo[1]);
23388 std::swap (cmphi[0], cmphi[1]);
23389 code = swap_condition (code);
23394 bool uns = (code == GEU);
23395 rtx (*sbb_insn) (machine_mode, rtx, rtx, rtx)
23396 = uns ? gen_sub3_carry_ccc : gen_sub3_carry_ccgz;
23398 emit_insn (gen_cmp_1 (<MODE>mode, cmplo[0], cmplo[1]));
23400 rtx tmp = gen_rtx_SCRATCH (<MODE>mode);
23401 emit_insn (sbb_insn (<MODE>mode, tmp, cmphi[0], cmphi[1]));
23403 rtx flags = gen_rtx_REG (uns ? CCCmode : CCGZmode, FLAGS_REG);
23404 operands[6] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
23410 gcc_unreachable ();
23414 (define_insn_and_split "*<code><mode>3_1"
23415 [(set (match_operand:SWI 0 "register_operand")
23417 (match_operand:SWI 1 "register_operand")
23418 (match_operand:SWI 2 "general_operand")))
23419 (clobber (reg:CC FLAGS_REG))]
23421 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
23422 && ix86_pre_reload_split ()"
23425 [(set (match_dup 0)
23426 (if_then_else:SWI (match_dup 3)
23430 machine_mode mode = <MODE>mode;
23431 rtx cmp_op = operands[2];
23433 operands[2] = force_reg (mode, cmp_op);
23435 enum rtx_code code = <maxmin_rel>;
23437 if (cmp_op == const1_rtx)
23439 /* Convert smax (x, 1) into (x > 0 ? x : 1).
23440 Convert umax (x, 1) into (x != 0 ? x : 1).
23441 Convert ?min (x, 1) into (x <= 0 ? x : 1). */
23442 cmp_op = const0_rtx;
23445 else if (code == GEU)
23448 /* Convert smin (x, -1) into (x < 0 ? x : -1). */
23449 else if (cmp_op == constm1_rtx && code == LE)
23451 cmp_op = const0_rtx;
23454 /* Convert smax (x, -1) into (x >= 0 ? x : -1). */
23455 else if (cmp_op == constm1_rtx && code == GE)
23456 cmp_op = const0_rtx;
23457 else if (cmp_op != const0_rtx)
23458 cmp_op = operands[2];
23460 machine_mode cmpmode = SELECT_CC_MODE (code, operands[1], cmp_op);
23461 rtx flags = gen_rtx_REG (cmpmode, FLAGS_REG);
23463 rtx tmp = gen_rtx_COMPARE (cmpmode, operands[1], cmp_op);
23464 emit_insn (gen_rtx_SET (flags, tmp));
23466 operands[3] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
23469 ;; Avoid clearing a register between a flags setting comparison and its use,
23470 ;; i.e. prefer "xorl %eax,%eax; test/cmp" over "test/cmp; movl $0, %eax".
23472 [(set (reg FLAGS_REG) (match_operand 0))
23473 (set (match_operand:SWI 1 "general_reg_operand") (const_int 0))]
23474 "peep2_regno_dead_p (0, FLAGS_REG)
23475 && !reg_overlap_mentioned_p (operands[1], operands[0])"
23476 [(set (match_dup 2) (match_dup 0))]
23478 operands[2] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
23479 ix86_expand_clear (operands[1]);
23482 ;; When optimizing for size, zeroing memory should use a register.
23484 [(match_scratch:SWI48 0 "r")
23485 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
23486 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))
23487 (set (match_operand:SWI48 3 "memory_operand") (const_int 0))
23488 (set (match_operand:SWI48 4 "memory_operand") (const_int 0))]
23489 "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
23492 ix86_expand_clear (operands[0]);
23493 emit_move_insn (operands[1], operands[0]);
23494 emit_move_insn (operands[2], operands[0]);
23495 emit_move_insn (operands[3], operands[0]);
23496 ix86_last_zero_store_uid
23497 = INSN_UID (emit_move_insn (operands[4], operands[0]));
23502 [(match_scratch:SWI48 0 "r")
23503 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
23504 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))]
23505 "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
23508 ix86_expand_clear (operands[0]);
23509 emit_move_insn (operands[1], operands[0]);
23510 ix86_last_zero_store_uid
23511 = INSN_UID (emit_move_insn (operands[2], operands[0]));
23516 [(match_scratch:SWI48 0 "r")
23517 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))]
23518 "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
23521 ix86_expand_clear (operands[0]);
23522 ix86_last_zero_store_uid
23523 = INSN_UID (emit_move_insn (operands[1], operands[0]));
23528 [(set (match_operand:SWI48 5 "memory_operand")
23529 (match_operand:SWI48 0 "general_reg_operand"))
23530 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
23531 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))
23532 (set (match_operand:SWI48 3 "memory_operand") (const_int 0))
23533 (set (match_operand:SWI48 4 "memory_operand") (const_int 0))]
23534 "optimize_insn_for_size_p ()
23535 && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
23538 emit_move_insn (operands[5], operands[0]);
23539 emit_move_insn (operands[1], operands[0]);
23540 emit_move_insn (operands[2], operands[0]);
23541 emit_move_insn (operands[3], operands[0]);
23542 ix86_last_zero_store_uid
23543 = INSN_UID (emit_move_insn (operands[4], operands[0]));
23548 [(set (match_operand:SWI48 3 "memory_operand")
23549 (match_operand:SWI48 0 "general_reg_operand"))
23550 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
23551 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))]
23552 "optimize_insn_for_size_p ()
23553 && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
23556 emit_move_insn (operands[3], operands[0]);
23557 emit_move_insn (operands[1], operands[0]);
23558 ix86_last_zero_store_uid
23559 = INSN_UID (emit_move_insn (operands[2], operands[0]));
23564 [(set (match_operand:SWI48 2 "memory_operand")
23565 (match_operand:SWI48 0 "general_reg_operand"))
23566 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))]
23567 "optimize_insn_for_size_p ()
23568 && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
23571 emit_move_insn (operands[2], operands[0]);
23572 ix86_last_zero_store_uid
23573 = INSN_UID (emit_move_insn (operands[1], operands[0]));
23577 ;; Reload dislikes loading constants directly into class_likely_spilled
23578 ;; hard registers. Try to tidy things up here.
23580 [(set (match_operand:SWI 0 "general_reg_operand")
23581 (match_operand:SWI 1 "x86_64_general_operand"))
23582 (set (match_operand:SWI 2 "general_reg_operand")
23584 "peep2_reg_dead_p (2, operands[0])"
23585 [(set (match_dup 2) (match_dup 1))])
23587 ;; Misc patterns (?)
23589 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
23590 ;; Otherwise there will be nothing to keep
23592 ;; [(set (reg ebp) (reg esp))]
23593 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
23594 ;; (clobber (eflags)]
23595 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
23597 ;; in proper program order.
23599 (define_insn "@pro_epilogue_adjust_stack_add_<mode>"
23600 [(set (match_operand:P 0 "register_operand" "=r,r")
23601 (plus:P (match_operand:P 1 "register_operand" "0,r")
23602 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
23603 (clobber (reg:CC FLAGS_REG))
23604 (clobber (mem:BLK (scratch)))]
23607 switch (get_attr_type (insn))
23610 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
23613 gcc_assert (rtx_equal_p (operands[0], operands[1]));
23614 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
23615 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
23617 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
23620 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
23621 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
23624 [(set (attr "type")
23625 (cond [(and (eq_attr "alternative" "0")
23626 (not (match_test "TARGET_OPT_AGU")))
23627 (const_string "alu")
23628 (match_operand:<MODE> 2 "const0_operand")
23629 (const_string "imov")
23631 (const_string "lea")))
23632 (set (attr "length_immediate")
23633 (cond [(eq_attr "type" "imov")
23635 (and (eq_attr "type" "alu")
23636 (match_operand 2 "const128_operand"))
23639 (const_string "*")))
23640 (set_attr "mode" "<MODE>")])
23642 (define_insn "@pro_epilogue_adjust_stack_sub_<mode>"
23643 [(set (match_operand:P 0 "register_operand" "=r")
23644 (minus:P (match_operand:P 1 "register_operand" "0")
23645 (match_operand:P 2 "register_operand" "r")))
23646 (clobber (reg:CC FLAGS_REG))
23647 (clobber (mem:BLK (scratch)))]
23649 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
23650 [(set_attr "type" "alu")
23651 (set_attr "mode" "<MODE>")])
23653 (define_insn "@allocate_stack_worker_probe_<mode>"
23654 [(set (match_operand:P 0 "register_operand" "=a")
23655 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
23656 UNSPECV_STACK_PROBE))
23657 (clobber (reg:CC FLAGS_REG))]
23658 "ix86_target_stack_probe ()"
23659 "call\t___chkstk_ms"
23660 [(set_attr "type" "multi")
23661 (set_attr "length" "5")])
23663 (define_expand "allocate_stack"
23664 [(match_operand 0 "register_operand")
23665 (match_operand 1 "general_operand")]
23666 "ix86_target_stack_probe ()"
23670 #ifndef CHECK_STACK_LIMIT
23671 #define CHECK_STACK_LIMIT 0
23674 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
23675 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
23679 x = copy_to_mode_reg (Pmode, operands[1]);
23681 emit_insn (gen_allocate_stack_worker_probe (Pmode, x, x));
23684 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
23685 stack_pointer_rtx, 0, OPTAB_DIRECT);
23687 if (x != stack_pointer_rtx)
23688 emit_move_insn (stack_pointer_rtx, x);
23690 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
23694 (define_expand "probe_stack"
23695 [(match_operand 0 "memory_operand")]
23698 emit_insn (gen_probe_stack_1
23699 (word_mode, operands[0], const0_rtx));
23703 ;; Use OR for stack probes, this is shorter.
23704 (define_insn "@probe_stack_1_<mode>"
23705 [(set (match_operand:W 0 "memory_operand" "=m")
23706 (unspec:W [(match_operand:W 1 "const0_operand")]
23707 UNSPEC_PROBE_STACK))
23708 (clobber (reg:CC FLAGS_REG))]
23710 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
23711 [(set_attr "type" "alu1")
23712 (set_attr "mode" "<MODE>")
23713 (set_attr "length_immediate" "1")])
23715 (define_insn "@adjust_stack_and_probe_<mode>"
23716 [(set (match_operand:P 0 "register_operand" "=r")
23717 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
23718 UNSPECV_PROBE_STACK_RANGE))
23719 (set (reg:P SP_REG)
23720 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand")))
23721 (clobber (reg:CC FLAGS_REG))
23722 (clobber (mem:BLK (scratch)))]
23724 "* return output_adjust_stack_and_probe (operands[0]);"
23725 [(set_attr "type" "multi")])
23727 (define_insn "@probe_stack_range_<mode>"
23728 [(set (match_operand:P 0 "register_operand" "=r")
23729 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
23730 (match_operand:P 2 "const_int_operand")]
23731 UNSPECV_PROBE_STACK_RANGE))
23732 (clobber (reg:CC FLAGS_REG))]
23734 "* return output_probe_stack_range (operands[0], operands[2]);"
23735 [(set_attr "type" "multi")])
23737 (define_expand "builtin_setjmp_receiver"
23738 [(label_ref (match_operand 0))]
23739 "!TARGET_64BIT && flag_pic"
23745 rtx_code_label *label_rtx = gen_label_rtx ();
23746 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
23747 xops[0] = xops[1] = pic_offset_table_rtx;
23748 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
23749 ix86_expand_binary_operator (MINUS, SImode, xops);
23753 emit_insn (gen_set_got (pic_offset_table_rtx));
23757 (define_expand "save_stack_nonlocal"
23758 [(set (match_operand 0 "memory_operand")
23759 (match_operand 1 "register_operand"))]
23764 if (flag_cf_protection & CF_RETURN)
23766 /* Copy shadow stack pointer to the first slot
23767 and stack pointer to the second slot. */
23768 rtx ssp_slot = adjust_address (operands[0], word_mode, 0);
23769 stack_slot = adjust_address (operands[0], Pmode, UNITS_PER_WORD);
23771 rtx reg_ssp = force_reg (word_mode, const0_rtx);
23772 emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
23773 emit_move_insn (ssp_slot, reg_ssp);
23776 stack_slot = adjust_address (operands[0], Pmode, 0);
23777 emit_move_insn (stack_slot, operands[1]);
23781 (define_expand "restore_stack_nonlocal"
23782 [(set (match_operand 0 "register_operand" "")
23783 (match_operand 1 "memory_operand" ""))]
23788 if (flag_cf_protection & CF_RETURN)
23790 /* Restore shadow stack pointer from the first slot
23791 and stack pointer from the second slot. */
23792 rtx ssp_slot = adjust_address (operands[1], word_mode, 0);
23793 stack_slot = adjust_address (operands[1], Pmode, UNITS_PER_WORD);
23795 /* Get the current shadow stack pointer. The code below will check if
23796 SHSTK feature is enabled. If it is not enabled the RDSSP instruction
23798 rtx reg_ssp = force_reg (word_mode, const0_rtx);
23799 emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
23801 /* Compare through subtraction the saved and the current ssp
23802 to decide if ssp has to be adjusted. */
23803 reg_ssp = expand_simple_binop (word_mode, MINUS,
23805 reg_ssp, 1, OPTAB_DIRECT);
23807 /* Compare and jump over adjustment code. */
23808 rtx noadj_label = gen_label_rtx ();
23809 emit_cmp_and_jump_insns (reg_ssp, const0_rtx, EQ, NULL_RTX,
23810 word_mode, 1, noadj_label);
23812 /* Compute the number of frames to adjust. */
23813 rtx reg_adj = gen_lowpart (ptr_mode, reg_ssp);
23814 rtx reg_adj_neg = expand_simple_unop (ptr_mode, NEG, reg_adj,
23817 reg_adj = expand_simple_binop (ptr_mode, LSHIFTRT, reg_adj_neg,
23818 GEN_INT (exact_log2 (UNITS_PER_WORD)),
23819 reg_adj, 1, OPTAB_DIRECT);
23821 /* Check if number of frames <= 255 so no loop is needed. */
23822 rtx inc_label = gen_label_rtx ();
23823 emit_cmp_and_jump_insns (reg_adj, GEN_INT (255), LEU, NULL_RTX,
23824 ptr_mode, 1, inc_label);
23826 /* Adjust the ssp in a loop. */
23827 rtx loop_label = gen_label_rtx ();
23828 emit_label (loop_label);
23829 LABEL_NUSES (loop_label) = 1;
23831 rtx reg_255 = force_reg (word_mode, GEN_INT (255));
23832 emit_insn (gen_incssp (word_mode, reg_255));
23834 reg_adj = expand_simple_binop (ptr_mode, MINUS,
23835 reg_adj, GEN_INT (255),
23836 reg_adj, 1, OPTAB_DIRECT);
23838 /* Compare and jump to the loop label. */
23839 emit_cmp_and_jump_insns (reg_adj, GEN_INT (255), GTU, NULL_RTX,
23840 ptr_mode, 1, loop_label);
23842 emit_label (inc_label);
23843 LABEL_NUSES (inc_label) = 1;
23845 emit_insn (gen_incssp (word_mode, reg_ssp));
23847 emit_label (noadj_label);
23848 LABEL_NUSES (noadj_label) = 1;
23851 stack_slot = adjust_address (operands[1], Pmode, 0);
23852 emit_move_insn (operands[0], stack_slot);
23857 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
23858 ;; Do not split instructions with mask registers.
23860 [(set (match_operand 0 "general_reg_operand")
23861 (match_operator 3 "promotable_binary_operator"
23862 [(match_operand 1 "general_reg_operand")
23863 (match_operand 2 "aligned_operand")]))
23864 (clobber (reg:CC FLAGS_REG))]
23865 "! TARGET_PARTIAL_REG_STALL && reload_completed
23866 && ((GET_MODE (operands[0]) == HImode
23867 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
23868 /* ??? next two lines just !satisfies_constraint_K (...) */
23869 || !CONST_INT_P (operands[2])
23870 || satisfies_constraint_K (operands[2])))
23871 || (GET_MODE (operands[0]) == QImode
23872 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
23873 [(parallel [(set (match_dup 0)
23874 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
23875 (clobber (reg:CC FLAGS_REG))])]
23877 operands[0] = gen_lowpart (SImode, operands[0]);
23878 operands[1] = gen_lowpart (SImode, operands[1]);
23879 if (GET_CODE (operands[3]) != ASHIFT)
23880 operands[2] = gen_lowpart (SImode, operands[2]);
23881 operands[3] = shallow_copy_rtx (operands[3]);
23882 PUT_MODE (operands[3], SImode);
23885 ; Promote the QImode tests, as i386 has encoding of the AND
23886 ; instruction with 32-bit sign-extended immediate and thus the
23887 ; instruction size is unchanged, except in the %eax case for
23888 ; which it is increased by one byte, hence the ! optimize_size.
23890 [(set (match_operand 0 "flags_reg_operand")
23891 (match_operator 2 "compare_operator"
23892 [(and (match_operand 3 "aligned_operand")
23893 (match_operand 4 "const_int_operand"))
23895 (set (match_operand 1 "register_operand")
23896 (and (match_dup 3) (match_dup 4)))]
23897 "! TARGET_PARTIAL_REG_STALL && reload_completed
23898 && optimize_insn_for_speed_p ()
23899 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
23900 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
23901 /* Ensure that the operand will remain sign-extended immediate. */
23902 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
23903 [(parallel [(set (match_dup 0)
23904 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
23907 (and:SI (match_dup 3) (match_dup 4)))])]
23910 = gen_int_mode (INTVAL (operands[4])
23911 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
23912 operands[1] = gen_lowpart (SImode, operands[1]);
23913 operands[3] = gen_lowpart (SImode, operands[3]);
23916 ; Don't promote the QImode tests, as i386 doesn't have encoding of
23917 ; the TEST instruction with 32-bit sign-extended immediate and thus
23918 ; the instruction size would at least double, which is not what we
23919 ; want even with ! optimize_size.
23921 [(set (match_operand 0 "flags_reg_operand")
23922 (match_operator 1 "compare_operator"
23923 [(and (match_operand:HI 2 "aligned_operand")
23924 (match_operand:HI 3 "const_int_operand"))
23926 "! TARGET_PARTIAL_REG_STALL && reload_completed
23927 && ! TARGET_FAST_PREFIX
23928 && optimize_insn_for_speed_p ()
23929 /* Ensure that the operand will remain sign-extended immediate. */
23930 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
23931 [(set (match_dup 0)
23932 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
23936 = gen_int_mode (INTVAL (operands[3])
23937 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
23938 operands[2] = gen_lowpart (SImode, operands[2]);
23942 [(set (match_operand 0 "register_operand")
23943 (neg (match_operand 1 "register_operand")))
23944 (clobber (reg:CC FLAGS_REG))]
23945 "! TARGET_PARTIAL_REG_STALL && reload_completed
23946 && (GET_MODE (operands[0]) == HImode
23947 || (GET_MODE (operands[0]) == QImode
23948 && (TARGET_PROMOTE_QImode
23949 || optimize_insn_for_size_p ())))"
23950 [(parallel [(set (match_dup 0)
23951 (neg:SI (match_dup 1)))
23952 (clobber (reg:CC FLAGS_REG))])]
23954 operands[0] = gen_lowpart (SImode, operands[0]);
23955 operands[1] = gen_lowpart (SImode, operands[1]);
23958 ;; Do not split instructions with mask regs.
23960 [(set (match_operand 0 "general_reg_operand")
23961 (not (match_operand 1 "general_reg_operand")))]
23962 "! TARGET_PARTIAL_REG_STALL && reload_completed
23963 && (GET_MODE (operands[0]) == HImode
23964 || (GET_MODE (operands[0]) == QImode
23965 && (TARGET_PROMOTE_QImode
23966 || optimize_insn_for_size_p ())))"
23967 [(set (match_dup 0)
23968 (not:SI (match_dup 1)))]
23970 operands[0] = gen_lowpart (SImode, operands[0]);
23971 operands[1] = gen_lowpart (SImode, operands[1]);
23974 ;; RTL Peephole optimizations, run before sched2. These primarily look to
23975 ;; transform a complex memory operation into two memory to register operations.
23977 ;; Don't push memory operands
23979 [(set (match_operand:SWI 0 "push_operand")
23980 (match_operand:SWI 1 "memory_operand"))
23981 (match_scratch:SWI 2 "<r>")]
23982 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
23983 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
23984 [(set (match_dup 2) (match_dup 1))
23985 (set (match_dup 0) (match_dup 2))])
23987 ;; We need to handle SFmode only, because DFmode and XFmode are split to
23990 [(set (match_operand:SF 0 "push_operand")
23991 (match_operand:SF 1 "memory_operand"))
23992 (match_scratch:SF 2 "r")]
23993 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
23994 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
23995 [(set (match_dup 2) (match_dup 1))
23996 (set (match_dup 0) (match_dup 2))])
23998 ;; Don't move an immediate directly to memory when the instruction
23999 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
24001 [(match_scratch:SWI124 1 "<r>")
24002 (set (match_operand:SWI124 0 "memory_operand")
24004 "optimize_insn_for_speed_p ()
24005 && ((<MODE>mode == HImode
24006 && TARGET_LCP_STALL)
24007 || (!TARGET_USE_MOV0
24008 && TARGET_SPLIT_LONG_MOVES
24009 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
24010 && peep2_regno_dead_p (0, FLAGS_REG)"
24011 [(parallel [(set (match_dup 2) (const_int 0))
24012 (clobber (reg:CC FLAGS_REG))])
24013 (set (match_dup 0) (match_dup 1))]
24014 "operands[2] = gen_lowpart (SImode, operands[1]);")
24017 [(match_scratch:SWI124 2 "<r>")
24018 (set (match_operand:SWI124 0 "memory_operand")
24019 (match_operand:SWI124 1 "immediate_operand"))]
24020 "optimize_insn_for_speed_p ()
24021 && ((<MODE>mode == HImode
24022 && TARGET_LCP_STALL)
24023 || (TARGET_SPLIT_LONG_MOVES
24024 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
24025 [(set (match_dup 2) (match_dup 1))
24026 (set (match_dup 0) (match_dup 2))])
24028 ;; Don't compare memory with zero, load and use a test instead.
24030 [(set (match_operand 0 "flags_reg_operand")
24031 (match_operator 1 "compare_operator"
24032 [(match_operand:SI 2 "memory_operand")
24034 (match_scratch:SI 3 "r")]
24035 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
24036 [(set (match_dup 3) (match_dup 2))
24037 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
24039 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
24040 ;; Don't split NOTs with a displacement operand, because resulting XOR
24041 ;; will not be pairable anyway.
24043 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
24044 ;; represented using a modRM byte. The XOR replacement is long decoded,
24045 ;; so this split helps here as well.
24047 ;; Note: Can't do this as a regular split because we can't get proper
24048 ;; lifetime information then.
24051 [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
24052 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
24053 "optimize_insn_for_speed_p ()
24054 && ((TARGET_NOT_UNPAIRABLE
24055 && (!MEM_P (operands[0])
24056 || !memory_displacement_operand (operands[0], <MODE>mode)))
24057 || (TARGET_NOT_VECTORMODE
24058 && long_memory_operand (operands[0], <MODE>mode)))
24059 && peep2_regno_dead_p (0, FLAGS_REG)"
24060 [(parallel [(set (match_dup 0)
24061 (xor:SWI124 (match_dup 1) (const_int -1)))
24062 (clobber (reg:CC FLAGS_REG))])])
24064 ;; Non pairable "test imm, reg" instructions can be translated to
24065 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
24066 ;; byte opcode instead of two, have a short form for byte operands),
24067 ;; so do it for other CPUs as well. Given that the value was dead,
24068 ;; this should not create any new dependencies. Pass on the sub-word
24069 ;; versions if we're concerned about partial register stalls.
24072 [(set (match_operand 0 "flags_reg_operand")
24073 (match_operator 1 "compare_operator"
24074 [(and:SI (match_operand:SI 2 "register_operand")
24075 (match_operand:SI 3 "immediate_operand"))
24077 "ix86_match_ccmode (insn, CCNOmode)
24078 && (REGNO (operands[2]) != AX_REG
24079 || satisfies_constraint_K (operands[3]))
24080 && peep2_reg_dead_p (1, operands[2])"
24082 [(set (match_dup 0)
24083 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
24086 (and:SI (match_dup 2) (match_dup 3)))])])
24088 ;; We don't need to handle HImode case, because it will be promoted to SImode
24089 ;; on ! TARGET_PARTIAL_REG_STALL
24092 [(set (match_operand 0 "flags_reg_operand")
24093 (match_operator 1 "compare_operator"
24094 [(and:QI (match_operand:QI 2 "register_operand")
24095 (match_operand:QI 3 "immediate_operand"))
24097 "! TARGET_PARTIAL_REG_STALL
24098 && ix86_match_ccmode (insn, CCNOmode)
24099 && REGNO (operands[2]) != AX_REG
24100 && peep2_reg_dead_p (1, operands[2])"
24102 [(set (match_dup 0)
24103 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
24106 (and:QI (match_dup 2) (match_dup 3)))])])
24109 [(set (match_operand 0 "flags_reg_operand")
24110 (match_operator 1 "compare_operator"
24113 (match_operator:SWI248 4 "extract_operator"
24114 [(match_operand 2 "int248_register_operand")
24117 (match_operand 3 "const_int_operand"))
24119 "! TARGET_PARTIAL_REG_STALL
24120 && ix86_match_ccmode (insn, CCNOmode)
24121 && REGNO (operands[2]) != AX_REG
24122 && peep2_reg_dead_p (1, operands[2])"
24124 [(set (match_dup 0)
24128 (match_op_dup 4 [(match_dup 2)
24133 (set (zero_extract:SWI248 (match_dup 2)
24139 (match_op_dup 4 [(match_dup 2)
24142 (match_dup 3)) 0))])])
24144 ;; Don't do logical operations with memory inputs.
24146 [(match_scratch:SWI 2 "<r>")
24147 (parallel [(set (match_operand:SWI 0 "register_operand")
24148 (match_operator:SWI 3 "arith_or_logical_operator"
24150 (match_operand:SWI 1 "memory_operand")]))
24151 (clobber (reg:CC FLAGS_REG))])]
24152 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
24153 [(set (match_dup 2) (match_dup 1))
24154 (parallel [(set (match_dup 0)
24155 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
24156 (clobber (reg:CC FLAGS_REG))])])
24159 [(match_scratch:SWI 2 "<r>")
24160 (parallel [(set (match_operand:SWI 0 "register_operand")
24161 (match_operator:SWI 3 "arith_or_logical_operator"
24162 [(match_operand:SWI 1 "memory_operand")
24164 (clobber (reg:CC FLAGS_REG))])]
24165 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
24166 [(set (match_dup 2) (match_dup 1))
24167 (parallel [(set (match_dup 0)
24168 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
24169 (clobber (reg:CC FLAGS_REG))])])
24171 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when
24172 ;; the memory address refers to the destination of the load!
24175 [(set (match_operand:SWI 0 "general_reg_operand")
24176 (match_operand:SWI 1 "general_reg_operand"))
24177 (parallel [(set (match_dup 0)
24178 (match_operator:SWI 3 "commutative_operator"
24180 (match_operand:SWI 2 "memory_operand")]))
24181 (clobber (reg:CC FLAGS_REG))])]
24182 "REGNO (operands[0]) != REGNO (operands[1])
24183 && (<MODE>mode != QImode
24184 || any_QIreg_operand (operands[1], QImode))"
24185 [(set (match_dup 0) (match_dup 4))
24186 (parallel [(set (match_dup 0)
24187 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
24188 (clobber (reg:CC FLAGS_REG))])]
24191 = ix86_replace_reg_with_reg (operands[2], operands[0], operands[1]);
24195 [(set (match_operand 0 "mmx_reg_operand")
24196 (match_operand 1 "mmx_reg_operand"))
24198 (match_operator 3 "commutative_operator"
24200 (match_operand 2 "memory_operand")]))]
24201 "REGNO (operands[0]) != REGNO (operands[1])"
24202 [(set (match_dup 0) (match_dup 2))
24204 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
24207 [(set (match_operand 0 "sse_reg_operand")
24208 (match_operand 1 "sse_reg_operand"))
24210 (match_operator 3 "commutative_operator"
24212 (match_operand 2 "memory_operand")]))]
24213 "REGNO (operands[0]) != REGNO (operands[1])
24214 /* Punt if operands[1] is %[xy]mm16+ and AVX512BW is not enabled,
24215 as EVEX encoded vpadd[bw], vpmullw, vpmin[su][bw] and vpmax[su][bw]
24216 instructions require AVX512BW and AVX512VL, but with the original
24217 instructions it might require just AVX512VL.
24218 AVX512VL is implied from TARGET_HARD_REGNO_MODE_OK. */
24219 && (!EXT_REX_SSE_REGNO_P (REGNO (operands[1]))
24221 || GET_MODE_SIZE (GET_MODE_INNER (GET_MODE (operands[0]))) > 2
24222 || logic_operator (operands[3], VOIDmode))"
24223 [(set (match_dup 0) (match_dup 2))
24225 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
24227 ; Don't do logical operations with memory outputs
24229 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
24230 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
24231 ; the same decoder scheduling characteristics as the original.
24234 [(match_scratch:SWI 2 "<r>")
24235 (parallel [(set (match_operand:SWI 0 "memory_operand")
24236 (match_operator:SWI 3 "arith_or_logical_operator"
24238 (match_operand:SWI 1 "<nonmemory_operand>")]))
24239 (clobber (reg:CC FLAGS_REG))])]
24240 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
24241 [(set (match_dup 2) (match_dup 0))
24242 (parallel [(set (match_dup 2)
24243 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
24244 (clobber (reg:CC FLAGS_REG))])
24245 (set (match_dup 0) (match_dup 2))])
24248 [(match_scratch:SWI 2 "<r>")
24249 (parallel [(set (match_operand:SWI 0 "memory_operand")
24250 (match_operator:SWI 3 "arith_or_logical_operator"
24251 [(match_operand:SWI 1 "<nonmemory_operand>")
24253 (clobber (reg:CC FLAGS_REG))])]
24254 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
24255 [(set (match_dup 2) (match_dup 0))
24256 (parallel [(set (match_dup 2)
24257 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
24258 (clobber (reg:CC FLAGS_REG))])
24259 (set (match_dup 0) (match_dup 2))])
24261 ;; Attempt to use arith or logical operations with memory outputs with
24262 ;; setting of flags.
24264 [(set (match_operand:SWI 0 "register_operand")
24265 (match_operand:SWI 1 "memory_operand"))
24266 (parallel [(set (match_dup 0)
24267 (match_operator:SWI 3 "plusminuslogic_operator"
24269 (match_operand:SWI 2 "<nonmemory_operand>")]))
24270 (clobber (reg:CC FLAGS_REG))])
24271 (set (match_dup 1) (match_dup 0))
24272 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
24273 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24274 && peep2_reg_dead_p (4, operands[0])
24275 && !reg_overlap_mentioned_p (operands[0], operands[1])
24276 && !reg_overlap_mentioned_p (operands[0], operands[2])
24277 && (<MODE>mode != QImode
24278 || immediate_operand (operands[2], QImode)
24279 || any_QIreg_operand (operands[2], QImode))
24280 && ix86_match_ccmode (peep2_next_insn (3),
24281 (GET_CODE (operands[3]) == PLUS
24282 || GET_CODE (operands[3]) == MINUS)
24283 ? CCGOCmode : CCNOmode)"
24284 [(parallel [(set (match_dup 4) (match_dup 6))
24285 (set (match_dup 1) (match_dup 5))])]
24287 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
24289 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
24290 copy_rtx (operands[1]),
24293 = gen_rtx_COMPARE (GET_MODE (operands[4]),
24294 copy_rtx (operands[5]),
24298 ;; Likewise for cmpelim optimized pattern.
24300 [(set (match_operand:SWI 0 "register_operand")
24301 (match_operand:SWI 1 "memory_operand"))
24302 (parallel [(set (reg FLAGS_REG)
24303 (compare (match_operator:SWI 3 "plusminuslogic_operator"
24305 (match_operand:SWI 2 "<nonmemory_operand>")])
24307 (set (match_dup 0) (match_dup 3))])
24308 (set (match_dup 1) (match_dup 0))]
24309 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24310 && peep2_reg_dead_p (3, operands[0])
24311 && !reg_overlap_mentioned_p (operands[0], operands[1])
24312 && !reg_overlap_mentioned_p (operands[0], operands[2])
24313 && ix86_match_ccmode (peep2_next_insn (1),
24314 (GET_CODE (operands[3]) == PLUS
24315 || GET_CODE (operands[3]) == MINUS)
24316 ? CCGOCmode : CCNOmode)"
24317 [(parallel [(set (match_dup 4) (match_dup 6))
24318 (set (match_dup 1) (match_dup 5))])]
24320 operands[4] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
24322 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
24323 copy_rtx (operands[1]), operands[2]);
24325 = gen_rtx_COMPARE (GET_MODE (operands[4]), copy_rtx (operands[5]),
24329 ;; Likewise for instances where we have a lea pattern.
24331 [(set (match_operand:SWI 0 "register_operand")
24332 (match_operand:SWI 1 "memory_operand"))
24333 (set (match_operand:<LEAMODE> 3 "register_operand")
24334 (plus:<LEAMODE> (match_operand:<LEAMODE> 4 "register_operand")
24335 (match_operand:<LEAMODE> 2 "<nonmemory_operand>")))
24336 (set (match_dup 1) (match_operand:SWI 5 "register_operand"))
24337 (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
24338 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24339 && REGNO (operands[4]) == REGNO (operands[0])
24340 && REGNO (operands[5]) == REGNO (operands[3])
24341 && peep2_reg_dead_p (4, operands[3])
24342 && ((REGNO (operands[0]) == REGNO (operands[3]))
24343 || peep2_reg_dead_p (2, operands[0]))
24344 && !reg_overlap_mentioned_p (operands[0], operands[1])
24345 && !reg_overlap_mentioned_p (operands[3], operands[1])
24346 && !reg_overlap_mentioned_p (operands[0], operands[2])
24347 && (<MODE>mode != QImode
24348 || immediate_operand (operands[2], QImode)
24349 || any_QIreg_operand (operands[2], QImode))
24350 && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
24351 [(parallel [(set (match_dup 6) (match_dup 8))
24352 (set (match_dup 1) (match_dup 7))])]
24354 operands[6] = SET_DEST (PATTERN (peep2_next_insn (3)));
24356 = gen_rtx_PLUS (<MODE>mode,
24357 copy_rtx (operands[1]),
24358 gen_lowpart (<MODE>mode, operands[2]));
24360 = gen_rtx_COMPARE (GET_MODE (operands[6]),
24361 copy_rtx (operands[7]),
24366 [(parallel [(set (match_operand:SWI 0 "register_operand")
24367 (match_operator:SWI 2 "plusminuslogic_operator"
24369 (match_operand:SWI 1 "memory_operand")]))
24370 (clobber (reg:CC FLAGS_REG))])
24371 (set (match_dup 1) (match_dup 0))
24372 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
24373 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24374 && COMMUTATIVE_ARITH_P (operands[2])
24375 && peep2_reg_dead_p (3, operands[0])
24376 && !reg_overlap_mentioned_p (operands[0], operands[1])
24377 && ix86_match_ccmode (peep2_next_insn (2),
24378 GET_CODE (operands[2]) == PLUS
24379 ? CCGOCmode : CCNOmode)"
24380 [(parallel [(set (match_dup 3) (match_dup 5))
24381 (set (match_dup 1) (match_dup 4))])]
24383 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
24385 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
24386 copy_rtx (operands[1]),
24389 = gen_rtx_COMPARE (GET_MODE (operands[3]),
24390 copy_rtx (operands[4]),
24394 ;; Likewise for cmpelim optimized pattern.
24396 [(parallel [(set (reg FLAGS_REG)
24397 (compare (match_operator:SWI 2 "plusminuslogic_operator"
24398 [(match_operand:SWI 0 "register_operand")
24399 (match_operand:SWI 1 "memory_operand")])
24401 (set (match_dup 0) (match_dup 2))])
24402 (set (match_dup 1) (match_dup 0))]
24403 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24404 && COMMUTATIVE_ARITH_P (operands[2])
24405 && peep2_reg_dead_p (2, operands[0])
24406 && !reg_overlap_mentioned_p (operands[0], operands[1])
24407 && ix86_match_ccmode (peep2_next_insn (0),
24408 GET_CODE (operands[2]) == PLUS
24409 ? CCGOCmode : CCNOmode)"
24410 [(parallel [(set (match_dup 3) (match_dup 5))
24411 (set (match_dup 1) (match_dup 4))])]
24413 operands[3] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (0)), 0, 0));
24415 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
24416 copy_rtx (operands[1]), operands[0]);
24418 = gen_rtx_COMPARE (GET_MODE (operands[3]), copy_rtx (operands[4]),
24423 [(set (match_operand:SWI12 0 "register_operand")
24424 (match_operand:SWI12 1 "memory_operand"))
24425 (parallel [(set (match_operand:SI 4 "register_operand")
24426 (match_operator:SI 3 "plusminuslogic_operator"
24428 (match_operand:SI 2 "nonmemory_operand")]))
24429 (clobber (reg:CC FLAGS_REG))])
24430 (set (match_dup 1) (match_dup 0))
24431 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
24432 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24433 && REGNO (operands[0]) == REGNO (operands[4])
24434 && peep2_reg_dead_p (4, operands[0])
24435 && (<MODE>mode != QImode
24436 || immediate_operand (operands[2], SImode)
24437 || any_QIreg_operand (operands[2], SImode))
24438 && !reg_overlap_mentioned_p (operands[0], operands[1])
24439 && !reg_overlap_mentioned_p (operands[0], operands[2])
24440 && ix86_match_ccmode (peep2_next_insn (3),
24441 (GET_CODE (operands[3]) == PLUS
24442 || GET_CODE (operands[3]) == MINUS)
24443 ? CCGOCmode : CCNOmode)"
24444 [(parallel [(set (match_dup 5) (match_dup 7))
24445 (set (match_dup 1) (match_dup 6))])]
24447 operands[5] = SET_DEST (PATTERN (peep2_next_insn (3)));
24449 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
24450 copy_rtx (operands[1]),
24451 gen_lowpart (<MODE>mode, operands[2]));
24453 = gen_rtx_COMPARE (GET_MODE (operands[5]),
24454 copy_rtx (operands[6]),
24458 ;; peephole2 comes before regcprop, so deal also with a case that
24459 ;; would be cleaned up by regcprop.
24461 [(set (match_operand:SWI 0 "register_operand")
24462 (match_operand:SWI 1 "memory_operand"))
24463 (parallel [(set (match_dup 0)
24464 (match_operator:SWI 3 "plusminuslogic_operator"
24466 (match_operand:SWI 2 "<nonmemory_operand>")]))
24467 (clobber (reg:CC FLAGS_REG))])
24468 (set (match_operand:SWI 4 "register_operand") (match_dup 0))
24469 (set (match_dup 1) (match_dup 4))
24470 (set (reg FLAGS_REG) (compare (match_dup 4) (const_int 0)))]
24471 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24472 && peep2_reg_dead_p (3, operands[0])
24473 && peep2_reg_dead_p (5, operands[4])
24474 && !reg_overlap_mentioned_p (operands[0], operands[1])
24475 && !reg_overlap_mentioned_p (operands[0], operands[2])
24476 && !reg_overlap_mentioned_p (operands[4], operands[1])
24477 && (<MODE>mode != QImode
24478 || immediate_operand (operands[2], QImode)
24479 || any_QIreg_operand (operands[2], QImode))
24480 && ix86_match_ccmode (peep2_next_insn (4),
24481 (GET_CODE (operands[3]) == PLUS
24482 || GET_CODE (operands[3]) == MINUS)
24483 ? CCGOCmode : CCNOmode)"
24484 [(parallel [(set (match_dup 5) (match_dup 7))
24485 (set (match_dup 1) (match_dup 6))])]
24487 operands[5] = SET_DEST (PATTERN (peep2_next_insn (4)));
24489 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
24490 copy_rtx (operands[1]),
24493 = gen_rtx_COMPARE (GET_MODE (operands[5]),
24494 copy_rtx (operands[6]),
24499 [(set (match_operand:SWI12 0 "register_operand")
24500 (match_operand:SWI12 1 "memory_operand"))
24501 (parallel [(set (match_operand:SI 4 "register_operand")
24502 (match_operator:SI 3 "plusminuslogic_operator"
24504 (match_operand:SI 2 "nonmemory_operand")]))
24505 (clobber (reg:CC FLAGS_REG))])
24506 (set (match_operand:SWI12 5 "register_operand") (match_dup 0))
24507 (set (match_dup 1) (match_dup 5))
24508 (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
24509 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24510 && REGNO (operands[0]) == REGNO (operands[4])
24511 && peep2_reg_dead_p (3, operands[0])
24512 && peep2_reg_dead_p (5, operands[5])
24513 && (<MODE>mode != QImode
24514 || immediate_operand (operands[2], SImode)
24515 || any_QIreg_operand (operands[2], SImode))
24516 && !reg_overlap_mentioned_p (operands[0], operands[1])
24517 && !reg_overlap_mentioned_p (operands[0], operands[2])
24518 && !reg_overlap_mentioned_p (operands[5], operands[1])
24519 && ix86_match_ccmode (peep2_next_insn (4),
24520 (GET_CODE (operands[3]) == PLUS
24521 || GET_CODE (operands[3]) == MINUS)
24522 ? CCGOCmode : CCNOmode)"
24523 [(parallel [(set (match_dup 6) (match_dup 8))
24524 (set (match_dup 1) (match_dup 7))])]
24526 operands[6] = SET_DEST (PATTERN (peep2_next_insn (4)));
24528 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
24529 copy_rtx (operands[1]),
24530 gen_lowpart (<MODE>mode, operands[2]));
24532 = gen_rtx_COMPARE (GET_MODE (operands[6]),
24533 copy_rtx (operands[7]),
24537 ;; Likewise for cmpelim optimized pattern.
24539 [(set (match_operand:SWI 0 "register_operand")
24540 (match_operand:SWI 1 "memory_operand"))
24541 (parallel [(set (reg FLAGS_REG)
24542 (compare (match_operator:SWI 3 "plusminuslogic_operator"
24544 (match_operand:SWI 2 "<nonmemory_operand>")])
24546 (set (match_dup 0) (match_dup 3))])
24547 (set (match_operand:SWI 4 "register_operand") (match_dup 0))
24548 (set (match_dup 1) (match_dup 4))]
24549 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24550 && peep2_reg_dead_p (3, operands[0])
24551 && peep2_reg_dead_p (4, operands[4])
24552 && !reg_overlap_mentioned_p (operands[0], operands[1])
24553 && !reg_overlap_mentioned_p (operands[0], operands[2])
24554 && !reg_overlap_mentioned_p (operands[4], operands[1])
24555 && ix86_match_ccmode (peep2_next_insn (1),
24556 (GET_CODE (operands[3]) == PLUS
24557 || GET_CODE (operands[3]) == MINUS)
24558 ? CCGOCmode : CCNOmode)"
24559 [(parallel [(set (match_dup 5) (match_dup 7))
24560 (set (match_dup 1) (match_dup 6))])]
24562 operands[5] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
24564 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
24565 copy_rtx (operands[1]), operands[2]);
24567 = gen_rtx_COMPARE (GET_MODE (operands[5]), copy_rtx (operands[6]),
24571 ;; Special cases for xor, where (x ^= y) != 0 is (misoptimized)
24572 ;; into x = z; x ^= y; x != z
24574 [(set (match_operand:SWI 0 "register_operand")
24575 (match_operand:SWI 1 "memory_operand"))
24576 (set (match_operand:SWI 3 "register_operand") (match_dup 0))
24577 (parallel [(set (match_operand:SWI 4 "register_operand")
24578 (xor:SWI (match_dup 4)
24579 (match_operand:SWI 2 "<nonmemory_operand>")))
24580 (clobber (reg:CC FLAGS_REG))])
24581 (set (match_dup 1) (match_dup 4))
24582 (set (reg:CCZ FLAGS_REG)
24583 (compare:CCZ (match_operand:SWI 5 "register_operand")
24584 (match_operand:SWI 6 "<nonmemory_operand>")))]
24585 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24586 && (REGNO (operands[4]) == REGNO (operands[0])
24587 || REGNO (operands[4]) == REGNO (operands[3]))
24588 && (rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
24589 ? 3 : 0], operands[5])
24590 ? rtx_equal_p (operands[2], operands[6])
24591 : rtx_equal_p (operands[2], operands[5])
24592 && rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
24593 ? 3 : 0], operands[6]))
24594 && peep2_reg_dead_p (4, operands[4])
24595 && peep2_reg_dead_p (5, operands[REGNO (operands[4]) == REGNO (operands[0])
24597 && !reg_overlap_mentioned_p (operands[0], operands[1])
24598 && !reg_overlap_mentioned_p (operands[0], operands[2])
24599 && !reg_overlap_mentioned_p (operands[3], operands[0])
24600 && !reg_overlap_mentioned_p (operands[3], operands[1])
24601 && !reg_overlap_mentioned_p (operands[3], operands[2])
24602 && (<MODE>mode != QImode
24603 || immediate_operand (operands[2], QImode)
24604 || any_QIreg_operand (operands[2], QImode))"
24605 [(parallel [(set (match_dup 7) (match_dup 9))
24606 (set (match_dup 1) (match_dup 8))])]
24608 operands[7] = SET_DEST (PATTERN (peep2_next_insn (4)));
24609 operands[8] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
24612 = gen_rtx_COMPARE (GET_MODE (operands[7]),
24613 copy_rtx (operands[8]),
24618 [(set (match_operand:SWI12 0 "register_operand")
24619 (match_operand:SWI12 1 "memory_operand"))
24620 (set (match_operand:SWI12 3 "register_operand") (match_dup 0))
24621 (parallel [(set (match_operand:SI 4 "register_operand")
24622 (xor:SI (match_dup 4)
24623 (match_operand:SI 2 "<nonmemory_operand>")))
24624 (clobber (reg:CC FLAGS_REG))])
24625 (set (match_dup 1) (match_operand:SWI12 5 "register_operand"))
24626 (set (reg:CCZ FLAGS_REG)
24627 (compare:CCZ (match_operand:SWI12 6 "register_operand")
24628 (match_operand:SWI12 7 "<nonmemory_operand>")))]
24629 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24630 && (REGNO (operands[5]) == REGNO (operands[0])
24631 || REGNO (operands[5]) == REGNO (operands[3]))
24632 && REGNO (operands[5]) == REGNO (operands[4])
24633 && (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
24634 ? 3 : 0], operands[6])
24635 ? (REG_P (operands[2])
24636 ? REG_P (operands[7]) && REGNO (operands[2]) == REGNO (operands[7])
24637 : rtx_equal_p (operands[2], operands[7]))
24638 : (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
24639 ? 3 : 0], operands[7])
24640 && REG_P (operands[2])
24641 && REGNO (operands[2]) == REGNO (operands[6])))
24642 && peep2_reg_dead_p (4, operands[5])
24643 && peep2_reg_dead_p (5, operands[REGNO (operands[5]) == REGNO (operands[0])
24645 && !reg_overlap_mentioned_p (operands[0], operands[1])
24646 && !reg_overlap_mentioned_p (operands[0], operands[2])
24647 && !reg_overlap_mentioned_p (operands[3], operands[0])
24648 && !reg_overlap_mentioned_p (operands[3], operands[1])
24649 && !reg_overlap_mentioned_p (operands[3], operands[2])
24650 && (<MODE>mode != QImode
24651 || immediate_operand (operands[2], SImode)
24652 || any_QIreg_operand (operands[2], SImode))"
24653 [(parallel [(set (match_dup 8) (match_dup 10))
24654 (set (match_dup 1) (match_dup 9))])]
24656 operands[8] = SET_DEST (PATTERN (peep2_next_insn (4)));
24657 operands[9] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
24658 gen_lowpart (<MODE>mode, operands[2]));
24660 = gen_rtx_COMPARE (GET_MODE (operands[8]),
24661 copy_rtx (operands[9]),
24665 ;; Attempt to optimize away memory stores of values the memory already
24666 ;; has. See PR79593.
24668 [(set (match_operand 0 "register_operand")
24669 (match_operand 1 "memory_operand"))
24670 (set (match_operand 2 "memory_operand") (match_dup 0))]
24671 "!MEM_VOLATILE_P (operands[1])
24672 && !MEM_VOLATILE_P (operands[2])
24673 && rtx_equal_p (operands[1], operands[2])
24674 && !reg_overlap_mentioned_p (operands[0], operands[2])"
24675 [(set (match_dup 0) (match_dup 1))])
24677 ;; Attempt to always use XOR for zeroing registers (including FP modes).
24679 [(set (match_operand 0 "general_reg_operand")
24680 (match_operand 1 "const0_operand"))]
24681 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
24682 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
24683 && peep2_regno_dead_p (0, FLAGS_REG)"
24684 [(parallel [(set (match_dup 0) (const_int 0))
24685 (clobber (reg:CC FLAGS_REG))])]
24686 "operands[0] = gen_lowpart (word_mode, operands[0]);")
24689 [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
24691 "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
24692 && peep2_regno_dead_p (0, FLAGS_REG)"
24693 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
24694 (clobber (reg:CC FLAGS_REG))])])
24696 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
24698 [(set (match_operand:SWI248 0 "general_reg_operand")
24700 "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
24701 && peep2_regno_dead_p (0, FLAGS_REG)"
24702 [(parallel [(set (match_dup 0) (const_int -1))
24703 (clobber (reg:CC FLAGS_REG))])]
24705 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
24706 operands[0] = gen_lowpart (SImode, operands[0]);
24709 ;; Attempt to convert simple lea to add/shift.
24710 ;; These can be created by move expanders.
24711 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
24712 ;; relevant lea instructions were already split.
24715 [(set (match_operand:SWI48 0 "register_operand")
24716 (plus:SWI48 (match_dup 0)
24717 (match_operand:SWI48 1 "<nonmemory_operand>")))]
24719 && peep2_regno_dead_p (0, FLAGS_REG)"
24720 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
24721 (clobber (reg:CC FLAGS_REG))])])
24724 [(set (match_operand:SWI48 0 "register_operand")
24725 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
24728 && peep2_regno_dead_p (0, FLAGS_REG)"
24729 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
24730 (clobber (reg:CC FLAGS_REG))])])
24733 [(set (match_operand:DI 0 "register_operand")
24735 (plus:SI (match_operand:SI 1 "register_operand")
24736 (match_operand:SI 2 "nonmemory_operand"))))]
24737 "TARGET_64BIT && !TARGET_OPT_AGU
24738 && REGNO (operands[0]) == REGNO (operands[1])
24739 && peep2_regno_dead_p (0, FLAGS_REG)"
24740 [(parallel [(set (match_dup 0)
24741 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
24742 (clobber (reg:CC FLAGS_REG))])])
24745 [(set (match_operand:DI 0 "register_operand")
24747 (plus:SI (match_operand:SI 1 "nonmemory_operand")
24748 (match_operand:SI 2 "register_operand"))))]
24749 "TARGET_64BIT && !TARGET_OPT_AGU
24750 && REGNO (operands[0]) == REGNO (operands[2])
24751 && peep2_regno_dead_p (0, FLAGS_REG)"
24752 [(parallel [(set (match_dup 0)
24753 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
24754 (clobber (reg:CC FLAGS_REG))])])
24757 [(set (match_operand:SWI48 0 "register_operand")
24758 (mult:SWI48 (match_dup 0)
24759 (match_operand:SWI48 1 "const_int_operand")))]
24760 "pow2p_hwi (INTVAL (operands[1]))
24761 && peep2_regno_dead_p (0, FLAGS_REG)"
24762 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
24763 (clobber (reg:CC FLAGS_REG))])]
24764 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
24767 [(set (match_operand:DI 0 "register_operand")
24769 (mult:SI (match_operand:SI 1 "register_operand")
24770 (match_operand:SI 2 "const_int_operand"))))]
24772 && pow2p_hwi (INTVAL (operands[2]))
24773 && REGNO (operands[0]) == REGNO (operands[1])
24774 && peep2_regno_dead_p (0, FLAGS_REG)"
24775 [(parallel [(set (match_dup 0)
24776 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
24777 (clobber (reg:CC FLAGS_REG))])]
24778 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
24780 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
24781 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
24782 ;; On many CPUs it is also faster, since special hardware to avoid esp
24783 ;; dependencies is present.
24785 ;; While some of these conversions may be done using splitters, we use
24786 ;; peepholes in order to allow combine_stack_adjustments pass to see
24787 ;; nonobfuscated RTL.
24789 ;; Convert prologue esp subtractions to push.
24790 ;; We need register to push. In order to keep verify_flow_info happy we have
24792 ;; - use scratch and clobber it in order to avoid dependencies
24793 ;; - use already live register
24794 ;; We can't use the second way right now, since there is no reliable way how to
24795 ;; verify that given register is live. First choice will also most likely in
24796 ;; fewer dependencies. On the place of esp adjustments it is very likely that
24797 ;; call clobbered registers are dead. We may want to use base pointer as an
24798 ;; alternative when no register is available later.
24801 [(match_scratch:W 1 "r")
24802 (parallel [(set (reg:P SP_REG)
24803 (plus:P (reg:P SP_REG)
24804 (match_operand:P 0 "const_int_operand")))
24805 (clobber (reg:CC FLAGS_REG))
24806 (clobber (mem:BLK (scratch)))])]
24807 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
24808 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
24809 && !ix86_red_zone_used"
24810 [(clobber (match_dup 1))
24811 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
24812 (clobber (mem:BLK (scratch)))])])
24815 [(match_scratch:W 1 "r")
24816 (parallel [(set (reg:P SP_REG)
24817 (plus:P (reg:P SP_REG)
24818 (match_operand:P 0 "const_int_operand")))
24819 (clobber (reg:CC FLAGS_REG))
24820 (clobber (mem:BLK (scratch)))])]
24821 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
24822 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
24823 && !ix86_red_zone_used"
24824 [(clobber (match_dup 1))
24825 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
24826 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
24827 (clobber (mem:BLK (scratch)))])])
24829 ;; Convert esp subtractions to push.
24831 [(match_scratch:W 1 "r")
24832 (parallel [(set (reg:P SP_REG)
24833 (plus:P (reg:P SP_REG)
24834 (match_operand:P 0 "const_int_operand")))
24835 (clobber (reg:CC FLAGS_REG))])]
24836 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
24837 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
24838 && !ix86_red_zone_used"
24839 [(clobber (match_dup 1))
24840 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
24843 [(match_scratch:W 1 "r")
24844 (parallel [(set (reg:P SP_REG)
24845 (plus:P (reg:P SP_REG)
24846 (match_operand:P 0 "const_int_operand")))
24847 (clobber (reg:CC FLAGS_REG))])]
24848 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
24849 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
24850 && !ix86_red_zone_used"
24851 [(clobber (match_dup 1))
24852 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
24853 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
24855 ;; Convert epilogue deallocator to pop.
24857 [(match_scratch:W 1 "r")
24858 (parallel [(set (reg:P SP_REG)
24859 (plus:P (reg:P SP_REG)
24860 (match_operand:P 0 "const_int_operand")))
24861 (clobber (reg:CC FLAGS_REG))
24862 (clobber (mem:BLK (scratch)))])]
24863 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
24864 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
24865 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
24866 (clobber (mem:BLK (scratch)))])])
24868 ;; Two pops case is tricky, since pop causes dependency
24869 ;; on destination register. We use two registers if available.
24871 [(match_scratch:W 1 "r")
24872 (match_scratch:W 2 "r")
24873 (parallel [(set (reg:P SP_REG)
24874 (plus:P (reg:P SP_REG)
24875 (match_operand:P 0 "const_int_operand")))
24876 (clobber (reg:CC FLAGS_REG))
24877 (clobber (mem:BLK (scratch)))])]
24878 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
24879 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
24880 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
24881 (clobber (mem:BLK (scratch)))])
24882 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
24885 [(match_scratch:W 1 "r")
24886 (parallel [(set (reg:P SP_REG)
24887 (plus:P (reg:P SP_REG)
24888 (match_operand:P 0 "const_int_operand")))
24889 (clobber (reg:CC FLAGS_REG))
24890 (clobber (mem:BLK (scratch)))])]
24891 "optimize_insn_for_size_p ()
24892 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
24893 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
24894 (clobber (mem:BLK (scratch)))])
24895 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
24897 ;; Convert esp additions to pop.
24899 [(match_scratch:W 1 "r")
24900 (parallel [(set (reg:P SP_REG)
24901 (plus:P (reg:P SP_REG)
24902 (match_operand:P 0 "const_int_operand")))
24903 (clobber (reg:CC FLAGS_REG))])]
24904 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
24905 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
24907 ;; Two pops case is tricky, since pop causes dependency
24908 ;; on destination register. We use two registers if available.
24910 [(match_scratch:W 1 "r")
24911 (match_scratch:W 2 "r")
24912 (parallel [(set (reg:P SP_REG)
24913 (plus:P (reg:P SP_REG)
24914 (match_operand:P 0 "const_int_operand")))
24915 (clobber (reg:CC FLAGS_REG))])]
24916 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
24917 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
24918 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
24921 [(match_scratch:W 1 "r")
24922 (parallel [(set (reg:P SP_REG)
24923 (plus:P (reg:P SP_REG)
24924 (match_operand:P 0 "const_int_operand")))
24925 (clobber (reg:CC FLAGS_REG))])]
24926 "optimize_insn_for_size_p ()
24927 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
24928 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
24929 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
24931 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
24932 ;; required and register dies. Similarly for 128 to -128.
24934 [(set (match_operand 0 "flags_reg_operand")
24935 (match_operator 1 "compare_operator"
24936 [(match_operand 2 "register_operand")
24937 (match_operand 3 "const_int_operand")]))]
24938 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
24939 && incdec_operand (operands[3], GET_MODE (operands[3])))
24940 || (!TARGET_FUSE_CMP_AND_BRANCH
24941 && INTVAL (operands[3]) == 128))
24942 && ix86_match_ccmode (insn, CCGCmode)
24943 && peep2_reg_dead_p (1, operands[2])"
24944 [(parallel [(set (match_dup 0)
24945 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
24946 (clobber (match_dup 2))])])
24948 ;; Convert imul by three, five and nine into lea
24951 [(set (match_operand:SWI48 0 "register_operand")
24952 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
24953 (match_operand:SWI48 2 "const359_operand")))
24954 (clobber (reg:CC FLAGS_REG))])]
24955 "!TARGET_PARTIAL_REG_STALL
24956 || <MODE>mode == SImode
24957 || optimize_function_for_size_p (cfun)"
24958 [(set (match_dup 0)
24959 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
24961 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
24965 [(set (match_operand:SWI48 0 "register_operand")
24966 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
24967 (match_operand:SWI48 2 "const359_operand")))
24968 (clobber (reg:CC FLAGS_REG))])]
24969 "optimize_insn_for_speed_p ()
24970 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
24971 [(set (match_dup 0) (match_dup 1))
24973 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
24975 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
24977 ;; imul $32bit_imm, mem, reg is vector decoded, while
24978 ;; imul $32bit_imm, reg, reg is direct decoded.
24980 [(match_scratch:SWI48 3 "r")
24981 (parallel [(set (match_operand:SWI48 0 "register_operand")
24982 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
24983 (match_operand:SWI48 2 "immediate_operand")))
24984 (clobber (reg:CC FLAGS_REG))])]
24985 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
24986 && !satisfies_constraint_K (operands[2])"
24987 [(set (match_dup 3) (match_dup 1))
24988 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
24989 (clobber (reg:CC FLAGS_REG))])])
24992 [(match_scratch:SI 3 "r")
24993 (parallel [(set (match_operand:DI 0 "register_operand")
24995 (mult:SI (match_operand:SI 1 "memory_operand")
24996 (match_operand:SI 2 "immediate_operand"))))
24997 (clobber (reg:CC FLAGS_REG))])]
24999 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
25000 && !satisfies_constraint_K (operands[2])"
25001 [(set (match_dup 3) (match_dup 1))
25002 (parallel [(set (match_dup 0)
25003 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
25004 (clobber (reg:CC FLAGS_REG))])])
25006 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
25007 ;; Convert it into imul reg, reg
25008 ;; It would be better to force assembler to encode instruction using long
25009 ;; immediate, but there is apparently no way to do so.
25011 [(parallel [(set (match_operand:SWI248 0 "register_operand")
25013 (match_operand:SWI248 1 "nonimmediate_operand")
25014 (match_operand:SWI248 2 "const_int_operand")))
25015 (clobber (reg:CC FLAGS_REG))])
25016 (match_scratch:SWI248 3 "r")]
25017 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
25018 && satisfies_constraint_K (operands[2])"
25019 [(set (match_dup 3) (match_dup 2))
25020 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
25021 (clobber (reg:CC FLAGS_REG))])]
25023 if (!rtx_equal_p (operands[0], operands[1]))
25024 emit_move_insn (operands[0], operands[1]);
25027 ;; After splitting up read-modify operations, array accesses with memory
25028 ;; operands might end up in form:
25030 ;; movl 4(%esp), %edx
25032 ;; instead of pre-splitting:
25034 ;; addl 4(%esp), %eax
25036 ;; movl 4(%esp), %edx
25037 ;; leal (%edx,%eax,4), %eax
25040 [(match_scratch:W 5 "r")
25041 (parallel [(set (match_operand 0 "register_operand")
25042 (ashift (match_operand 1 "register_operand")
25043 (match_operand 2 "const_int_operand")))
25044 (clobber (reg:CC FLAGS_REG))])
25045 (parallel [(set (match_operand 3 "register_operand")
25046 (plus (match_dup 0)
25047 (match_operand 4 "x86_64_general_operand")))
25048 (clobber (reg:CC FLAGS_REG))])]
25049 "IN_RANGE (INTVAL (operands[2]), 1, 3)
25050 /* Validate MODE for lea. */
25051 && ((!TARGET_PARTIAL_REG_STALL
25052 && (GET_MODE (operands[0]) == QImode
25053 || GET_MODE (operands[0]) == HImode))
25054 || GET_MODE (operands[0]) == SImode
25055 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
25056 && (rtx_equal_p (operands[0], operands[3])
25057 || peep2_reg_dead_p (2, operands[0]))
25058 /* We reorder load and the shift. */
25059 && !reg_overlap_mentioned_p (operands[0], operands[4])"
25060 [(set (match_dup 5) (match_dup 4))
25061 (set (match_dup 0) (match_dup 1))]
25063 machine_mode op1mode = GET_MODE (operands[1]);
25064 machine_mode mode = op1mode == DImode ? DImode : SImode;
25065 int scale = 1 << INTVAL (operands[2]);
25066 rtx index = gen_lowpart (word_mode, operands[1]);
25067 rtx base = gen_lowpart (word_mode, operands[5]);
25068 rtx dest = gen_lowpart (mode, operands[3]);
25070 operands[1] = gen_rtx_PLUS (word_mode, base,
25071 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
25072 if (mode != word_mode)
25073 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
25075 operands[5] = base;
25076 if (op1mode != word_mode)
25077 operands[5] = gen_lowpart (op1mode, operands[5]);
25079 operands[0] = dest;
25082 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
25083 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
25084 ;; caught for use by garbage collectors and the like. Using an insn that
25085 ;; maps to SIGILL makes it more likely the program will rightfully die.
25086 ;; Keeping with tradition, "6" is in honor of #UD.
25087 (define_insn "trap"
25088 [(trap_if (const_int 1) (const_int 6))]
25091 #ifdef HAVE_AS_IX86_UD2
25094 return ASM_SHORT "0x0b0f";
25097 [(set_attr "length" "2")])
25100 [(unspec_volatile [(const_int 0)] UNSPECV_UD2)]
25103 #ifdef HAVE_AS_IX86_UD2
25106 return ASM_SHORT "0x0b0f";
25109 [(set_attr "length" "2")])
25111 (define_expand "prefetch"
25112 [(prefetch (match_operand 0 "address_operand")
25113 (match_operand:SI 1 "const_int_operand")
25114 (match_operand:SI 2 "const_int_operand"))]
25115 "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
25117 bool write = operands[1] != const0_rtx;
25118 int locality = INTVAL (operands[2]);
25120 gcc_assert (IN_RANGE (locality, 0, 3));
25122 /* Use 3dNOW prefetch in case we are asking for write prefetch not
25123 supported by SSE counterpart (non-SSE2 athlon machines) or the
25124 SSE prefetch is not available (K6 machines). Otherwise use SSE
25125 prefetch as it allows specifying of locality. */
25129 if (TARGET_PREFETCHWT1)
25130 operands[2] = GEN_INT (MAX (locality, 2));
25131 else if (TARGET_PRFCHW)
25132 operands[2] = GEN_INT (3);
25133 else if (TARGET_3DNOW && !TARGET_SSE2)
25134 operands[2] = GEN_INT (3);
25135 else if (TARGET_PREFETCH_SSE)
25136 operands[1] = const0_rtx;
25139 gcc_assert (TARGET_3DNOW);
25140 operands[2] = GEN_INT (3);
25145 if (TARGET_PREFETCH_SSE)
25149 gcc_assert (TARGET_3DNOW);
25150 operands[2] = GEN_INT (3);
25155 (define_insn "*prefetch_sse"
25156 [(prefetch (match_operand 0 "address_operand" "p")
25158 (match_operand:SI 1 "const_int_operand"))]
25159 "TARGET_PREFETCH_SSE"
25161 static const char * const patterns[4] = {
25162 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
25165 int locality = INTVAL (operands[1]);
25166 gcc_assert (IN_RANGE (locality, 0, 3));
25168 return patterns[locality];
25170 [(set_attr "type" "sse")
25171 (set_attr "atom_sse_attr" "prefetch")
25172 (set (attr "length_address")
25173 (symbol_ref "memory_address_length (operands[0], false)"))
25174 (set_attr "memory" "none")])
25176 (define_insn "*prefetch_3dnow"
25177 [(prefetch (match_operand 0 "address_operand" "p")
25178 (match_operand:SI 1 "const_int_operand")
25180 "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1"
25182 if (operands[1] == const0_rtx)
25183 return "prefetch\t%a0";
25185 return "prefetchw\t%a0";
25187 [(set_attr "type" "mmx")
25188 (set (attr "length_address")
25189 (symbol_ref "memory_address_length (operands[0], false)"))
25190 (set_attr "memory" "none")])
25192 (define_insn "*prefetch_prefetchwt1"
25193 [(prefetch (match_operand 0 "address_operand" "p")
25196 "TARGET_PREFETCHWT1"
25197 "prefetchwt1\t%a0";
25198 [(set_attr "type" "sse")
25199 (set (attr "length_address")
25200 (symbol_ref "memory_address_length (operands[0], false)"))
25201 (set_attr "memory" "none")])
25203 (define_insn "prefetchi"
25204 [(unspec_volatile [(match_operand 0 "local_func_symbolic_operand" "p")
25205 (match_operand:SI 1 "const_int_operand")]
25206 UNSPECV_PREFETCHI)]
25207 "TARGET_PREFETCHI && TARGET_64BIT"
25209 static const char * const patterns[2] = {
25210 "prefetchit1\t%0", "prefetchit0\t%0"
25213 int locality = INTVAL (operands[1]);
25214 gcc_assert (IN_RANGE (locality, 2, 3));
25216 return patterns[locality - 2];
25218 [(set_attr "type" "sse")
25219 (set (attr "length_address")
25220 (symbol_ref "memory_address_length (operands[0], false)"))
25221 (set_attr "memory" "none")])
25223 (define_expand "stack_protect_set"
25224 [(match_operand 0 "memory_operand")
25225 (match_operand 1 "memory_operand")]
25228 emit_insn (gen_stack_protect_set_1
25229 (ptr_mode, operands[0], operands[1]));
25233 (define_insn "@stack_protect_set_1_<mode>"
25234 [(set (match_operand:PTR 0 "memory_operand" "=m")
25235 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
25237 (set (match_scratch:PTR 2 "=&r") (const_int 0))
25238 (clobber (reg:CC FLAGS_REG))]
25241 output_asm_insn ("mov{<imodesuffix>}\t{%1, %2|%2, %1}", operands);
25242 output_asm_insn ("mov{<imodesuffix>}\t{%2, %0|%0, %2}", operands);
25243 return "xor{l}\t%k2, %k2";
25245 [(set_attr "type" "multi")])
25247 ;; Patterns and peephole2s to optimize stack_protect_set_1_<mode>
25248 ;; immediately followed by *mov{s,d}i_internal to the same register,
25249 ;; where we can avoid the xor{l} above. We don't split this, so that
25250 ;; scheduling or anything else doesn't separate the *stack_protect_set*
25251 ;; pattern from the set of the register that overwrites the register
25252 ;; with a new value.
25253 (define_insn "*stack_protect_set_2_<mode>"
25254 [(set (match_operand:PTR 0 "memory_operand" "=m")
25255 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
25257 (set (match_operand:SI 1 "register_operand" "=&r")
25258 (match_operand:SI 2 "general_operand" "g"))
25259 (clobber (reg:CC FLAGS_REG))]
25261 && !reg_overlap_mentioned_p (operands[1], operands[2])"
25263 output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
25264 output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
25265 if (pic_32bit_operand (operands[2], SImode)
25266 || ix86_use_lea_for_mov (insn, operands + 1))
25267 return "lea{l}\t{%E2, %1|%1, %E2}";
25269 return "mov{l}\t{%2, %1|%1, %2}";
25271 [(set_attr "type" "multi")
25272 (set_attr "length" "24")])
25275 [(parallel [(set (match_operand:PTR 0 "memory_operand")
25276 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
25278 (set (match_operand:PTR 2 "general_reg_operand") (const_int 0))
25279 (clobber (reg:CC FLAGS_REG))])
25280 (set (match_operand:SI 3 "general_reg_operand")
25281 (match_operand:SI 4))]
25282 "REGNO (operands[2]) == REGNO (operands[3])
25283 && general_operand (operands[4], SImode)
25284 && (general_reg_operand (operands[4], SImode)
25285 || memory_operand (operands[4], SImode)
25286 || immediate_operand (operands[4], SImode))
25287 && !reg_overlap_mentioned_p (operands[3], operands[4])"
25288 [(parallel [(set (match_dup 0)
25289 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
25290 (set (match_dup 3) (match_dup 4))
25291 (clobber (reg:CC FLAGS_REG))])])
25293 (define_insn "*stack_protect_set_3"
25294 [(set (match_operand:DI 0 "memory_operand" "=m,m,m")
25295 (unspec:DI [(match_operand:DI 3 "memory_operand" "m,m,m")]
25297 (set (match_operand:DI 1 "register_operand" "=&r,r,r")
25298 (match_operand:DI 2 "general_operand" "Z,rem,i"))
25299 (clobber (reg:CC FLAGS_REG))]
25301 && reload_completed
25302 && !reg_overlap_mentioned_p (operands[1], operands[2])"
25304 output_asm_insn ("mov{q}\t{%3, %1|%1, %3}", operands);
25305 output_asm_insn ("mov{q}\t{%1, %0|%0, %1}", operands);
25306 if (pic_32bit_operand (operands[2], DImode))
25307 return "lea{q}\t{%E2, %1|%1, %E2}";
25308 else if (which_alternative == 0)
25309 return "mov{l}\t{%k2, %k1|%k1, %k2}";
25310 else if (which_alternative == 2)
25311 return "movabs{q}\t{%2, %1|%1, %2}";
25312 else if (ix86_use_lea_for_mov (insn, operands + 1))
25313 return "lea{q}\t{%E2, %1|%1, %E2}";
25315 return "mov{q}\t{%2, %1|%1, %2}";
25317 [(set_attr "type" "multi")
25318 (set_attr "length" "24")])
25321 [(parallel [(set (match_operand:DI 0 "memory_operand")
25322 (unspec:DI [(match_operand:DI 1 "memory_operand")]
25324 (set (match_operand:DI 2 "general_reg_operand") (const_int 0))
25325 (clobber (reg:CC FLAGS_REG))])
25326 (set (match_dup 2) (match_operand:DI 3))]
25328 && general_operand (operands[3], DImode)
25329 && (general_reg_operand (operands[3], DImode)
25330 || memory_operand (operands[3], DImode)
25331 || x86_64_zext_immediate_operand (operands[3], DImode)
25332 || x86_64_immediate_operand (operands[3], DImode)
25333 || (CONSTANT_P (operands[3])
25334 && (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[3]))))
25335 && !reg_overlap_mentioned_p (operands[2], operands[3])"
25336 [(parallel [(set (match_dup 0)
25337 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
25338 (set (match_dup 2) (match_dup 3))
25339 (clobber (reg:CC FLAGS_REG))])])
25341 (define_expand "stack_protect_test"
25342 [(match_operand 0 "memory_operand")
25343 (match_operand 1 "memory_operand")
25347 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
25349 emit_insn (gen_stack_protect_test_1
25350 (ptr_mode, flags, operands[0], operands[1]));
25352 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
25353 flags, const0_rtx, operands[2]));
25357 (define_insn "@stack_protect_test_1_<mode>"
25358 [(set (match_operand:CCZ 0 "flags_reg_operand")
25359 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
25360 (match_operand:PTR 2 "memory_operand" "m")]
25362 (clobber (match_scratch:PTR 3 "=&r"))]
25365 output_asm_insn ("mov{<imodesuffix>}\t{%1, %3|%3, %1}", operands);
25366 return "sub{<imodesuffix>}\t{%2, %3|%3, %2}";
25368 [(set_attr "type" "multi")])
25370 (define_insn "sse4_2_crc32<mode>"
25371 [(set (match_operand:SI 0 "register_operand" "=r")
25373 [(match_operand:SI 1 "register_operand" "0")
25374 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
25377 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
25378 [(set_attr "type" "sselog1")
25379 (set_attr "prefix_rep" "1")
25380 (set_attr "prefix_extra" "1")
25381 (set (attr "prefix_data16")
25382 (if_then_else (match_operand:HI 2)
25384 (const_string "*")))
25385 (set (attr "prefix_rex")
25386 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
25388 (const_string "*")))
25389 (set_attr "mode" "SI")])
25391 (define_insn "sse4_2_crc32di"
25392 [(set (match_operand:DI 0 "register_operand" "=r")
25395 [(match_operand:SI 1 "register_operand" "0")
25396 (match_operand:DI 2 "nonimmediate_operand" "rm")]
25398 "TARGET_64BIT && TARGET_CRC32"
25399 "crc32{q}\t{%2, %0|%0, %2}"
25400 [(set_attr "type" "sselog1")
25401 (set_attr "prefix_rep" "1")
25402 (set_attr "prefix_extra" "1")
25403 (set_attr "mode" "DI")])
25405 (define_insn "rdpmc"
25406 [(set (match_operand:DI 0 "register_operand" "=A")
25407 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
25411 [(set_attr "type" "other")
25412 (set_attr "length" "2")])
25414 (define_insn "rdpmc_rex64"
25415 [(set (match_operand:DI 0 "register_operand" "=a")
25416 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
25418 (set (match_operand:DI 1 "register_operand" "=d")
25419 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
25422 [(set_attr "type" "other")
25423 (set_attr "length" "2")])
25425 (define_insn "rdtsc"
25426 [(set (match_operand:DI 0 "register_operand" "=A")
25427 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
25430 [(set_attr "type" "other")
25431 (set_attr "length" "2")])
25433 (define_insn "rdtsc_rex64"
25434 [(set (match_operand:DI 0 "register_operand" "=a")
25435 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
25436 (set (match_operand:DI 1 "register_operand" "=d")
25437 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
25440 [(set_attr "type" "other")
25441 (set_attr "length" "2")])
25443 (define_insn "rdtscp"
25444 [(set (match_operand:DI 0 "register_operand" "=A")
25445 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
25446 (set (match_operand:SI 1 "register_operand" "=c")
25447 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
25450 [(set_attr "type" "other")
25451 (set_attr "length" "3")])
25453 (define_insn "rdtscp_rex64"
25454 [(set (match_operand:DI 0 "register_operand" "=a")
25455 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
25456 (set (match_operand:DI 1 "register_operand" "=d")
25457 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
25458 (set (match_operand:SI 2 "register_operand" "=c")
25459 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
25462 [(set_attr "type" "other")
25463 (set_attr "length" "3")])
25465 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25467 ;; FXSR, XSAVE and XSAVEOPT instructions
25469 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25471 (define_insn "fxsave"
25472 [(set (match_operand:BLK 0 "memory_operand" "=m")
25473 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
25476 [(set_attr "type" "other")
25477 (set_attr "memory" "store")
25478 (set (attr "length")
25479 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25481 (define_insn "fxsave64"
25482 [(set (match_operand:BLK 0 "memory_operand" "=m")
25483 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
25484 "TARGET_64BIT && TARGET_FXSR"
25486 [(set_attr "type" "other")
25487 (set_attr "memory" "store")
25488 (set (attr "length")
25489 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
25491 (define_insn "fxrstor"
25492 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
25496 [(set_attr "type" "other")
25497 (set_attr "memory" "load")
25498 (set (attr "length")
25499 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25501 (define_insn "fxrstor64"
25502 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
25503 UNSPECV_FXRSTOR64)]
25504 "TARGET_64BIT && TARGET_FXSR"
25506 [(set_attr "type" "other")
25507 (set_attr "memory" "load")
25508 (set (attr "length")
25509 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
25511 (define_int_iterator ANY_XSAVE
25513 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
25514 (UNSPECV_XSAVEC "TARGET_XSAVEC")
25515 (UNSPECV_XSAVES "TARGET_XSAVES")])
25517 (define_int_iterator ANY_XSAVE64
25519 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
25520 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
25521 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
25523 (define_int_attr xsave
25524 [(UNSPECV_XSAVE "xsave")
25525 (UNSPECV_XSAVE64 "xsave64")
25526 (UNSPECV_XSAVEOPT "xsaveopt")
25527 (UNSPECV_XSAVEOPT64 "xsaveopt64")
25528 (UNSPECV_XSAVEC "xsavec")
25529 (UNSPECV_XSAVEC64 "xsavec64")
25530 (UNSPECV_XSAVES "xsaves")
25531 (UNSPECV_XSAVES64 "xsaves64")])
25533 (define_int_iterator ANY_XRSTOR
25535 (UNSPECV_XRSTORS "TARGET_XSAVES")])
25537 (define_int_iterator ANY_XRSTOR64
25539 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
25541 (define_int_attr xrstor
25542 [(UNSPECV_XRSTOR "xrstor")
25543 (UNSPECV_XRSTOR64 "xrstor")
25544 (UNSPECV_XRSTORS "xrstors")
25545 (UNSPECV_XRSTORS64 "xrstors")])
25547 (define_insn "<xsave>"
25548 [(set (match_operand:BLK 0 "memory_operand" "=m")
25549 (unspec_volatile:BLK
25550 [(match_operand:DI 1 "register_operand" "A")]
25552 "!TARGET_64BIT && TARGET_XSAVE"
25554 [(set_attr "type" "other")
25555 (set_attr "memory" "store")
25556 (set (attr "length")
25557 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25559 (define_insn "<xsave>_rex64"
25560 [(set (match_operand:BLK 0 "memory_operand" "=m")
25561 (unspec_volatile:BLK
25562 [(match_operand:SI 1 "register_operand" "a")
25563 (match_operand:SI 2 "register_operand" "d")]
25565 "TARGET_64BIT && TARGET_XSAVE"
25567 [(set_attr "type" "other")
25568 (set_attr "memory" "store")
25569 (set (attr "length")
25570 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25572 (define_insn "<xsave>"
25573 [(set (match_operand:BLK 0 "memory_operand" "=m")
25574 (unspec_volatile:BLK
25575 [(match_operand:SI 1 "register_operand" "a")
25576 (match_operand:SI 2 "register_operand" "d")]
25578 "TARGET_64BIT && TARGET_XSAVE"
25580 [(set_attr "type" "other")
25581 (set_attr "memory" "store")
25582 (set (attr "length")
25583 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
25585 (define_insn "<xrstor>"
25586 [(unspec_volatile:BLK
25587 [(match_operand:BLK 0 "memory_operand" "m")
25588 (match_operand:DI 1 "register_operand" "A")]
25590 "!TARGET_64BIT && TARGET_XSAVE"
25592 [(set_attr "type" "other")
25593 (set_attr "memory" "load")
25594 (set (attr "length")
25595 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25597 (define_insn "<xrstor>_rex64"
25598 [(unspec_volatile:BLK
25599 [(match_operand:BLK 0 "memory_operand" "m")
25600 (match_operand:SI 1 "register_operand" "a")
25601 (match_operand:SI 2 "register_operand" "d")]
25603 "TARGET_64BIT && TARGET_XSAVE"
25605 [(set_attr "type" "other")
25606 (set_attr "memory" "load")
25607 (set (attr "length")
25608 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25610 (define_insn "<xrstor>64"
25611 [(unspec_volatile:BLK
25612 [(match_operand:BLK 0 "memory_operand" "m")
25613 (match_operand:SI 1 "register_operand" "a")
25614 (match_operand:SI 2 "register_operand" "d")]
25616 "TARGET_64BIT && TARGET_XSAVE"
25618 [(set_attr "type" "other")
25619 (set_attr "memory" "load")
25620 (set (attr "length")
25621 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
25623 (define_insn "xsetbv"
25624 [(unspec_volatile:SI
25625 [(match_operand:SI 0 "register_operand" "c")
25626 (match_operand:DI 1 "register_operand" "A")]
25628 "!TARGET_64BIT && TARGET_XSAVE"
25630 [(set_attr "type" "other")])
25632 (define_insn "xsetbv_rex64"
25633 [(unspec_volatile:SI
25634 [(match_operand:SI 0 "register_operand" "c")
25635 (match_operand:SI 1 "register_operand" "a")
25636 (match_operand:SI 2 "register_operand" "d")]
25638 "TARGET_64BIT && TARGET_XSAVE"
25640 [(set_attr "type" "other")])
25642 (define_insn "xgetbv"
25643 [(set (match_operand:DI 0 "register_operand" "=A")
25644 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
25646 "!TARGET_64BIT && TARGET_XSAVE"
25648 [(set_attr "type" "other")])
25650 (define_insn "xgetbv_rex64"
25651 [(set (match_operand:DI 0 "register_operand" "=a")
25652 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
25654 (set (match_operand:DI 1 "register_operand" "=d")
25655 (unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))]
25656 "TARGET_64BIT && TARGET_XSAVE"
25658 [(set_attr "type" "other")])
25660 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25662 ;; Floating-point instructions for atomic compound assignments
25664 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25666 ; Clobber all floating-point registers on environment save and restore
25667 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
25668 (define_insn "fnstenv"
25669 [(set (match_operand:BLK 0 "memory_operand" "=m")
25670 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
25671 (clobber (reg:XF ST0_REG))
25672 (clobber (reg:XF ST1_REG))
25673 (clobber (reg:XF ST2_REG))
25674 (clobber (reg:XF ST3_REG))
25675 (clobber (reg:XF ST4_REG))
25676 (clobber (reg:XF ST5_REG))
25677 (clobber (reg:XF ST6_REG))
25678 (clobber (reg:XF ST7_REG))]
25681 [(set_attr "type" "other")
25682 (set_attr "memory" "store")
25683 (set (attr "length")
25684 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
25686 (define_insn "fldenv"
25687 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
25689 (clobber (reg:XF ST0_REG))
25690 (clobber (reg:XF ST1_REG))
25691 (clobber (reg:XF ST2_REG))
25692 (clobber (reg:XF ST3_REG))
25693 (clobber (reg:XF ST4_REG))
25694 (clobber (reg:XF ST5_REG))
25695 (clobber (reg:XF ST6_REG))
25696 (clobber (reg:XF ST7_REG))]
25699 [(set_attr "type" "other")
25700 (set_attr "memory" "load")
25701 (set (attr "length")
25702 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
25704 (define_insn "fnstsw"
25705 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
25706 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
25709 [(set_attr "type" "other,other")
25710 (set_attr "memory" "none,store")
25711 (set (attr "length")
25712 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
25714 (define_insn "fnclex"
25715 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
25718 [(set_attr "type" "other")
25719 (set_attr "memory" "none")
25720 (set_attr "length" "2")])
25722 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25724 ;; LWP instructions
25726 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25728 (define_insn "@lwp_llwpcb<mode>"
25729 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
25730 UNSPECV_LLWP_INTRINSIC)]
25733 [(set_attr "type" "lwp")
25734 (set_attr "mode" "<MODE>")
25735 (set_attr "length" "5")])
25737 (define_insn "@lwp_slwpcb<mode>"
25738 [(set (match_operand:P 0 "register_operand" "=r")
25739 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
25742 [(set_attr "type" "lwp")
25743 (set_attr "mode" "<MODE>")
25744 (set_attr "length" "5")])
25746 (define_insn "@lwp_lwpval<mode>"
25747 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
25748 (match_operand:SI 1 "nonimmediate_operand" "rm")
25749 (match_operand:SI 2 "const_int_operand")]
25750 UNSPECV_LWPVAL_INTRINSIC)]
25752 "lwpval\t{%2, %1, %0|%0, %1, %2}"
25753 [(set_attr "type" "lwp")
25754 (set_attr "mode" "<MODE>")
25755 (set (attr "length")
25756 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
25758 (define_insn "@lwp_lwpins<mode>"
25759 [(set (reg:CCC FLAGS_REG)
25760 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
25761 (match_operand:SI 1 "nonimmediate_operand" "rm")
25762 (match_operand:SI 2 "const_int_operand")]
25763 UNSPECV_LWPINS_INTRINSIC))]
25765 "lwpins\t{%2, %1, %0|%0, %1, %2}"
25766 [(set_attr "type" "lwp")
25767 (set_attr "mode" "<MODE>")
25768 (set (attr "length")
25769 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
25771 (define_int_iterator RDFSGSBASE
25775 (define_int_iterator WRFSGSBASE
25779 (define_int_attr fsgs
25780 [(UNSPECV_RDFSBASE "fs")
25781 (UNSPECV_RDGSBASE "gs")
25782 (UNSPECV_WRFSBASE "fs")
25783 (UNSPECV_WRGSBASE "gs")])
25785 (define_insn "rd<fsgs>base<mode>"
25786 [(set (match_operand:SWI48 0 "register_operand" "=r")
25787 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
25788 "TARGET_64BIT && TARGET_FSGSBASE"
25790 [(set_attr "type" "other")
25791 (set_attr "prefix_extra" "2")])
25793 (define_insn "wr<fsgs>base<mode>"
25794 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
25796 "TARGET_64BIT && TARGET_FSGSBASE"
25798 [(set_attr "type" "other")
25799 (set_attr "prefix_extra" "2")])
25801 (define_insn "ptwrite<mode>"
25802 [(unspec_volatile [(match_operand:SWI48 0 "nonimmediate_operand" "rm")]
25806 [(set_attr "type" "other")
25807 (set_attr "prefix_extra" "2")])
25809 (define_insn "@rdrand<mode>"
25810 [(set (match_operand:SWI248 0 "register_operand" "=r")
25811 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
25812 (set (reg:CCC FLAGS_REG)
25813 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
25816 [(set_attr "type" "other")
25817 (set_attr "prefix_extra" "1")])
25819 (define_insn "@rdseed<mode>"
25820 [(set (match_operand:SWI248 0 "register_operand" "=r")
25821 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
25822 (set (reg:CCC FLAGS_REG)
25823 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
25826 [(set_attr "type" "other")
25827 (set_attr "prefix_extra" "1")])
25829 (define_expand "pause"
25830 [(set (match_dup 0)
25831 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
25834 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
25835 MEM_VOLATILE_P (operands[0]) = 1;
25838 ;; Use "rep; nop", instead of "pause", to support older assemblers.
25839 ;; They have the same encoding.
25840 (define_insn "*pause"
25841 [(set (match_operand:BLK 0)
25842 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
25845 [(set_attr "length" "2")
25846 (set_attr "memory" "unknown")])
25848 ;; CET instructions
25849 (define_insn "@rdssp<mode>"
25850 [(set (match_operand:SWI48 0 "register_operand" "=r")
25851 (unspec_volatile:SWI48 [(match_operand:SWI48 1 "register_operand" "0")]
25852 UNSPECV_NOP_RDSSP))]
25853 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
25854 "rdssp<mskmodesuffix>\t%0"
25855 [(set_attr "length" "6")
25856 (set_attr "type" "other")])
25858 (define_insn "@incssp<mode>"
25859 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
25861 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
25862 "incssp<mskmodesuffix>\t%0"
25863 [(set_attr "length" "4")
25864 (set_attr "type" "other")])
25866 (define_insn "saveprevssp"
25867 [(unspec_volatile [(const_int 0)] UNSPECV_SAVEPREVSSP)]
25870 [(set_attr "length" "5")
25871 (set_attr "type" "other")])
25873 (define_insn "rstorssp"
25874 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")]
25878 [(set_attr "length" "5")
25879 (set_attr "type" "other")])
25881 (define_insn "@wrss<mode>"
25882 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
25883 (match_operand:SWI48 1 "memory_operand" "m")]
25886 "wrss<mskmodesuffix>\t%0, %1"
25887 [(set_attr "length" "3")
25888 (set_attr "type" "other")])
25890 (define_insn "@wruss<mode>"
25891 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
25892 (match_operand:SWI48 1 "memory_operand" "m")]
25895 "wruss<mskmodesuffix>\t%0, %1"
25896 [(set_attr "length" "4")
25897 (set_attr "type" "other")])
25899 (define_insn "setssbsy"
25900 [(unspec_volatile [(const_int 0)] UNSPECV_SETSSBSY)]
25903 [(set_attr "length" "4")
25904 (set_attr "type" "other")])
25906 (define_insn "clrssbsy"
25907 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")]
25911 [(set_attr "length" "4")
25912 (set_attr "type" "other")])
25914 (define_insn "nop_endbr"
25915 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]
25916 "(flag_cf_protection & CF_BRANCH)"
25918 return TARGET_64BIT ? "endbr64" : "endbr32";
25920 [(set_attr "length" "4")
25921 (set_attr "length_immediate" "0")
25922 (set_attr "modrm" "0")])
25925 (define_expand "xbegin"
25926 [(set (match_operand:SI 0 "register_operand")
25927 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
25930 rtx_code_label *label = gen_label_rtx ();
25932 /* xbegin is emitted as jump_insn, so reload won't be able
25933 to reload its operand. Force the value into AX hard register. */
25934 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
25935 emit_move_insn (ax_reg, constm1_rtx);
25937 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
25939 emit_label (label);
25940 LABEL_NUSES (label) = 1;
25942 emit_move_insn (operands[0], ax_reg);
25947 (define_insn "xbegin_1"
25949 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
25951 (label_ref (match_operand 1))
25953 (set (match_operand:SI 0 "register_operand" "+a")
25954 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
25957 [(set_attr "type" "other")
25958 (set_attr "length" "6")])
25960 (define_insn "xend"
25961 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
25964 [(set_attr "type" "other")
25965 (set_attr "length" "3")])
25967 (define_insn "xabort"
25968 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand")]
25972 [(set_attr "type" "other")
25973 (set_attr "length" "3")])
25975 (define_expand "xtest"
25976 [(set (match_operand:QI 0 "register_operand")
25977 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
25980 emit_insn (gen_xtest_1 ());
25982 ix86_expand_setcc (operands[0], NE,
25983 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
25987 (define_insn "xtest_1"
25988 [(set (reg:CCZ FLAGS_REG)
25989 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
25992 [(set_attr "type" "other")
25993 (set_attr "length" "3")])
25995 (define_insn "clwb"
25996 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
26000 [(set_attr "type" "sse")
26001 (set_attr "atom_sse_attr" "fence")
26002 (set_attr "memory" "unknown")])
26004 (define_insn "clflushopt"
26005 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
26006 UNSPECV_CLFLUSHOPT)]
26007 "TARGET_CLFLUSHOPT"
26009 [(set_attr "type" "sse")
26010 (set_attr "atom_sse_attr" "fence")
26011 (set_attr "memory" "unknown")])
26013 ;; MONITORX and MWAITX
26014 (define_insn "mwaitx"
26015 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
26016 (match_operand:SI 1 "register_operand" "a")
26017 (match_operand:SI 2 "register_operand" "b")]
26020 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
26021 ;; Since 32bit register operands are implicitly zero extended to 64bit,
26022 ;; we only need to set up 32bit registers.
26024 [(set_attr "length" "3")])
26026 (define_insn "@monitorx_<mode>"
26027 [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
26028 (match_operand:SI 1 "register_operand" "c")
26029 (match_operand:SI 2 "register_operand" "d")]
26032 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
26033 ;; RCX and RDX are used. Since 32bit register operands are implicitly
26034 ;; zero extended to 64bit, we only need to set up 32bit registers.
26036 [(set (attr "length")
26037 (symbol_ref ("(Pmode != word_mode) + 3")))])
26040 (define_insn "@clzero_<mode>"
26041 [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
26045 [(set_attr "length" "3")
26046 (set_attr "memory" "unknown")])
26048 ;; RDPKRU and WRPKRU
26050 (define_expand "rdpkru"
26052 [(set (match_operand:SI 0 "register_operand")
26053 (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
26054 (set (match_dup 2) (const_int 0))])]
26057 operands[1] = force_reg (SImode, const0_rtx);
26058 operands[2] = gen_reg_rtx (SImode);
26061 (define_insn "*rdpkru"
26062 [(set (match_operand:SI 0 "register_operand" "=a")
26063 (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
26065 (set (match_operand:SI 1 "register_operand" "=d")
26069 [(set_attr "type" "other")])
26071 (define_expand "wrpkru"
26072 [(unspec_volatile:SI
26073 [(match_operand:SI 0 "register_operand")
26074 (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
26077 operands[1] = force_reg (SImode, const0_rtx);
26078 operands[2] = force_reg (SImode, const0_rtx);
26081 (define_insn "*wrpkru"
26082 [(unspec_volatile:SI
26083 [(match_operand:SI 0 "register_operand" "a")
26084 (match_operand:SI 1 "register_operand" "d")
26085 (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
26088 [(set_attr "type" "other")])
26090 (define_insn "rdpid"
26091 [(set (match_operand:SI 0 "register_operand" "=r")
26092 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDPID))]
26093 "!TARGET_64BIT && TARGET_RDPID"
26095 [(set_attr "type" "other")])
26097 (define_insn "rdpid_rex64"
26098 [(set (match_operand:DI 0 "register_operand" "=r")
26099 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPID))]
26100 "TARGET_64BIT && TARGET_RDPID"
26102 [(set_attr "type" "other")])
26104 ;; Intirinsics for > i486
26106 (define_insn "wbinvd"
26107 [(unspec_volatile [(const_int 0)] UNSPECV_WBINVD)]
26110 [(set_attr "type" "other")])
26112 (define_insn "wbnoinvd"
26113 [(unspec_volatile [(const_int 0)] UNSPECV_WBNOINVD)]
26116 [(set_attr "type" "other")])
26118 ;; MOVDIRI and MOVDIR64B
26120 (define_insn "movdiri<mode>"
26121 [(set (match_operand:SWI48 0 "memory_operand" "=m")
26122 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")]
26125 "movdiri\t{%1, %0|%0, %1}"
26126 [(set_attr "type" "other")])
26128 (define_insn "@movdir64b_<mode>"
26129 [(set (mem:XI (match_operand:P 0 "register_operand" "r"))
26130 (unspec:XI [(match_operand:XI 1 "memory_operand" "m")]
26131 UNSPEC_MOVDIR64B))]
26133 "movdir64b\t{%1, %0|%0, %1}"
26134 [(set_attr "type" "other")])
26137 (define_int_iterator TSXLDTRK [UNSPECV_XSUSLDTRK UNSPECV_XRESLDTRK])
26138 (define_int_attr tsxldtrk [(UNSPECV_XSUSLDTRK "xsusldtrk")
26139 (UNSPECV_XRESLDTRK "xresldtrk")])
26140 (define_insn "<tsxldtrk>"
26141 [(unspec_volatile [(const_int 0)] TSXLDTRK)]
26144 [(set_attr "type" "other")
26145 (set_attr "length" "4")])
26147 ;; ENQCMD and ENQCMDS
26149 (define_int_iterator ENQCMD [UNSPECV_ENQCMD UNSPECV_ENQCMDS])
26150 (define_int_attr enqcmd_sfx [(UNSPECV_ENQCMD "") (UNSPECV_ENQCMDS "s")])
26152 (define_insn "@enqcmd<enqcmd_sfx>_<mode>"
26153 [(set (reg:CCZ FLAGS_REG)
26154 (unspec_volatile:CCZ [(match_operand:P 0 "register_operand" "r")
26155 (match_operand:XI 1 "memory_operand" "m")]
26158 "enqcmd<enqcmd_sfx>\t{%1, %0|%0, %1}"
26159 [(set_attr "type" "other")])
26162 (define_int_iterator UINTR [UNSPECV_CLUI UNSPECV_STUI])
26163 (define_int_attr uintr [(UNSPECV_CLUI "clui") (UNSPECV_STUI "stui")])
26165 (define_insn "<uintr>"
26166 [(unspec_volatile [(const_int 0)] UINTR)]
26167 "TARGET_UINTR && TARGET_64BIT"
26169 [(set_attr "type" "other")
26170 (set_attr "length" "4")])
26172 (define_insn "testui"
26173 [(set (reg:CCC FLAGS_REG)
26174 (unspec_volatile:CCC [(const_int 0)] UNSPECV_TESTUI))]
26175 "TARGET_UINTR && TARGET_64BIT"
26177 [(set_attr "type" "other")
26178 (set_attr "length" "4")])
26180 (define_insn "senduipi"
26182 [(match_operand:DI 0 "register_operand" "r")]
26184 "TARGET_UINTR && TARGET_64BIT"
26186 [(set_attr "type" "other")
26187 (set_attr "length" "4")])
26191 (define_insn "umwait"
26192 [(set (reg:CCC FLAGS_REG)
26193 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26194 (match_operand:DI 1 "register_operand" "A")]
26196 "!TARGET_64BIT && TARGET_WAITPKG"
26198 [(set_attr "length" "3")])
26200 (define_insn "umwait_rex64"
26201 [(set (reg:CCC FLAGS_REG)
26202 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26203 (match_operand:SI 1 "register_operand" "a")
26204 (match_operand:SI 2 "register_operand" "d")]
26206 "TARGET_64BIT && TARGET_WAITPKG"
26208 [(set_attr "length" "3")])
26210 (define_insn "@umonitor_<mode>"
26211 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
26215 [(set (attr "length")
26216 (symbol_ref ("(Pmode != word_mode) + 3")))])
26218 (define_insn "tpause"
26219 [(set (reg:CCC FLAGS_REG)
26220 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26221 (match_operand:DI 1 "register_operand" "A")]
26223 "!TARGET_64BIT && TARGET_WAITPKG"
26225 [(set_attr "length" "3")])
26227 (define_insn "tpause_rex64"
26228 [(set (reg:CCC FLAGS_REG)
26229 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26230 (match_operand:SI 1 "register_operand" "a")
26231 (match_operand:SI 2 "register_operand" "d")]
26233 "TARGET_64BIT && TARGET_WAITPKG"
26235 [(set_attr "length" "3")])
26237 (define_insn "cldemote"
26238 [(unspec_volatile[(match_operand 0 "address_operand" "p")]
26242 [(set_attr "type" "other")
26243 (set_attr "memory" "unknown")])
26245 (define_insn "speculation_barrier"
26246 [(unspec_volatile [(const_int 0)] UNSPECV_SPECULATION_BARRIER)]
26249 [(set_attr "type" "other")
26250 (set_attr "length" "3")])
26252 (define_insn "serialize"
26253 [(unspec_volatile [(const_int 0)] UNSPECV_SERIALIZE)]
26256 [(set_attr "type" "other")
26257 (set_attr "length" "3")])
26259 (define_insn "patchable_area"
26260 [(unspec_volatile [(match_operand 0 "const_int_operand")
26261 (match_operand 1 "const_int_operand")]
26262 UNSPECV_PATCHABLE_AREA)]
26265 ix86_output_patchable_area (INTVAL (operands[0]),
26266 INTVAL (operands[1]) != 0);
26269 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
26270 (set_attr "length_immediate" "0")
26271 (set_attr "modrm" "0")])
26273 (define_insn "hreset"
26274 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")]
26278 [(set_attr "type" "other")
26279 (set_attr "length" "4")])
26281 ;; Spaceship optimization
26282 (define_expand "spaceship<mode>3"
26283 [(match_operand:SI 0 "register_operand")
26284 (match_operand:MODEF 1 "cmp_fp_expander_operand")
26285 (match_operand:MODEF 2 "cmp_fp_expander_operand")]
26286 "(TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
26287 && (TARGET_CMOVE || (TARGET_SAHF && TARGET_USE_SAHF))"
26289 ix86_expand_fp_spaceship (operands[0], operands[1], operands[2]);
26293 (define_expand "spaceshipxf3"
26294 [(match_operand:SI 0 "register_operand")
26295 (match_operand:XF 1 "nonmemory_operand")
26296 (match_operand:XF 2 "nonmemory_operand")]
26297 "TARGET_80387 && (TARGET_CMOVE || (TARGET_SAHF && TARGET_USE_SAHF))"
26299 ix86_expand_fp_spaceship (operands[0], operands[1], operands[2]);
26303 ;; Defined because the generic expand_builtin_issignaling for XFmode
26304 ;; only tests for sNaNs, but i387 treats also pseudo numbers as always
26306 (define_expand "issignalingxf2"
26307 [(match_operand:SI 0 "register_operand")
26308 (match_operand:XF 1 "general_operand")]
26311 rtx temp = operands[1];
26314 rtx mem = assign_stack_temp (XFmode, GET_MODE_SIZE (XFmode));
26315 emit_move_insn (mem, temp);
26318 rtx ex = adjust_address (temp, HImode, 8);
26319 rtx hi = adjust_address (temp, SImode, 4);
26320 rtx lo = adjust_address (temp, SImode, 0);
26321 rtx val = GEN_INT (HOST_WIDE_INT_M1U << 30);
26322 rtx mask = GEN_INT (0x7fff);
26323 rtx bit = GEN_INT (HOST_WIDE_INT_1U << 30);
26325 ((ex & mask) && (int) hi >= 0)
26326 || ((ex & mask) == mask && ((hi ^ bit) | ((lo | -lo) >> 31)) > val). */
26327 rtx nlo = expand_unop (SImode, neg_optab, lo, NULL_RTX, 0);
26328 lo = expand_binop (SImode, ior_optab, lo, nlo,
26329 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26330 lo = expand_shift (RSHIFT_EXPR, SImode, lo, 31, NULL_RTX, 1);
26331 temp = expand_binop (SImode, xor_optab, hi, bit,
26332 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26333 temp = expand_binop (SImode, ior_optab, temp, lo,
26334 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26335 temp = emit_store_flag_force (gen_reg_rtx (SImode), GTU, temp, val,
26337 ex = expand_binop (HImode, and_optab, ex, mask,
26338 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26339 rtx temp2 = emit_store_flag_force (gen_reg_rtx (SImode), NE,
26340 ex, const0_rtx, SImode, 1, 1);
26341 ex = emit_store_flag_force (gen_reg_rtx (SImode), EQ,
26342 ex, mask, HImode, 1, 1);
26343 temp = expand_binop (SImode, and_optab, temp, ex,
26344 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26345 rtx temp3 = emit_store_flag_force (gen_reg_rtx (SImode), GE,
26346 hi, const0_rtx, SImode, 0, 1);
26347 temp2 = expand_binop (SImode, and_optab, temp2, temp3,
26348 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26349 temp = expand_binop (SImode, ior_optab, temp, temp2,
26350 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26351 emit_move_insn (operands[0], temp);
26357 (include "sync.md")