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_and_split "*add<dwi>3_doubleword_concat_zext"
6298 [(set (match_operand:<DWI> 0 "register_operand" "=&r")
6303 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))
6304 (match_operand:QI 3 "const_int_operand"))
6306 (match_operand:DWIH 4 "nonimmediate_operand" "rm")))
6308 (match_operand:DWIH 1 "nonimmediate_operand" "rm"))))
6309 (clobber (reg:CC FLAGS_REG))]
6310 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
6312 "&& reload_completed"
6313 [(set (match_dup 0) (match_dup 4))
6314 (set (match_dup 5) (match_dup 2))
6315 (parallel [(set (reg:CCC FLAGS_REG)
6317 (plus:DWIH (match_dup 0) (match_dup 1))
6320 (plus:DWIH (match_dup 0) (match_dup 1)))])
6321 (parallel [(set (match_dup 5)
6324 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6327 (clobber (reg:CC FLAGS_REG))])]
6328 "split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[5]);")
6330 (define_insn "*add<mode>_1"
6331 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,r")
6333 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
6334 (match_operand:SWI48 2 "x86_64_general_operand" "re,BM,0,le")))
6335 (clobber (reg:CC FLAGS_REG))]
6336 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6338 switch (get_attr_type (insn))
6344 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6345 if (operands[2] == const1_rtx)
6346 return "inc{<imodesuffix>}\t%0";
6349 gcc_assert (operands[2] == constm1_rtx);
6350 return "dec{<imodesuffix>}\t%0";
6354 /* For most processors, ADD is faster than LEA. This alternative
6355 was added to use ADD as much as possible. */
6356 if (which_alternative == 2)
6357 std::swap (operands[1], operands[2]);
6359 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6360 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6361 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6363 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6367 (cond [(eq_attr "alternative" "3")
6368 (const_string "lea")
6369 (match_operand:SWI48 2 "incdec_operand")
6370 (const_string "incdec")
6372 (const_string "alu")))
6373 (set (attr "length_immediate")
6375 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6377 (const_string "*")))
6378 (set_attr "mode" "<MODE>")])
6380 ;; It may seem that nonimmediate operand is proper one for operand 1.
6381 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6382 ;; we take care in ix86_binary_operator_ok to not allow two memory
6383 ;; operands so proper swapping will be done in reload. This allow
6384 ;; patterns constructed from addsi_1 to match.
6386 (define_insn "addsi_1_zext"
6387 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6389 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
6390 (match_operand:SI 2 "x86_64_general_operand" "rBMe,0,le"))))
6391 (clobber (reg:CC FLAGS_REG))]
6392 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6394 switch (get_attr_type (insn))
6400 if (operands[2] == const1_rtx)
6401 return "inc{l}\t%k0";
6404 gcc_assert (operands[2] == constm1_rtx);
6405 return "dec{l}\t%k0";
6409 /* For most processors, ADD is faster than LEA. This alternative
6410 was added to use ADD as much as possible. */
6411 if (which_alternative == 1)
6412 std::swap (operands[1], operands[2]);
6414 if (x86_maybe_negate_const_int (&operands[2], SImode))
6415 return "sub{l}\t{%2, %k0|%k0, %2}";
6417 return "add{l}\t{%2, %k0|%k0, %2}";
6421 (cond [(eq_attr "alternative" "2")
6422 (const_string "lea")
6423 (match_operand:SI 2 "incdec_operand")
6424 (const_string "incdec")
6426 (const_string "alu")))
6427 (set (attr "length_immediate")
6429 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6431 (const_string "*")))
6432 (set_attr "mode" "SI")])
6434 (define_insn "*addhi_1"
6435 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
6436 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
6437 (match_operand:HI 2 "general_operand" "rn,m,0,ln")))
6438 (clobber (reg:CC FLAGS_REG))]
6439 "ix86_binary_operator_ok (PLUS, HImode, operands)"
6441 switch (get_attr_type (insn))
6447 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6448 if (operands[2] == const1_rtx)
6449 return "inc{w}\t%0";
6452 gcc_assert (operands[2] == constm1_rtx);
6453 return "dec{w}\t%0";
6457 /* For most processors, ADD is faster than LEA. This alternative
6458 was added to use ADD as much as possible. */
6459 if (which_alternative == 2)
6460 std::swap (operands[1], operands[2]);
6462 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6463 if (x86_maybe_negate_const_int (&operands[2], HImode))
6464 return "sub{w}\t{%2, %0|%0, %2}";
6466 return "add{w}\t{%2, %0|%0, %2}";
6470 (cond [(eq_attr "alternative" "3")
6471 (const_string "lea")
6472 (match_operand:HI 2 "incdec_operand")
6473 (const_string "incdec")
6475 (const_string "alu")))
6476 (set (attr "length_immediate")
6478 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6480 (const_string "*")))
6481 (set_attr "mode" "HI,HI,HI,SI")])
6483 (define_insn "*addqi_1"
6484 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
6485 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
6486 (match_operand:QI 2 "general_operand" "qn,m,0,rn,0,ln")))
6487 (clobber (reg:CC FLAGS_REG))]
6488 "ix86_binary_operator_ok (PLUS, QImode, operands)"
6490 bool widen = (get_attr_mode (insn) != MODE_QI);
6492 switch (get_attr_type (insn))
6498 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6499 if (operands[2] == const1_rtx)
6500 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6503 gcc_assert (operands[2] == constm1_rtx);
6504 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6508 /* For most processors, ADD is faster than LEA. These alternatives
6509 were added to use ADD as much as possible. */
6510 if (which_alternative == 2 || which_alternative == 4)
6511 std::swap (operands[1], operands[2]);
6513 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6514 if (x86_maybe_negate_const_int (&operands[2], QImode))
6517 return "sub{l}\t{%2, %k0|%k0, %2}";
6519 return "sub{b}\t{%2, %0|%0, %2}";
6522 return "add{l}\t{%k2, %k0|%k0, %k2}";
6524 return "add{b}\t{%2, %0|%0, %2}";
6528 (cond [(eq_attr "alternative" "5")
6529 (const_string "lea")
6530 (match_operand:QI 2 "incdec_operand")
6531 (const_string "incdec")
6533 (const_string "alu")))
6534 (set (attr "length_immediate")
6536 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6538 (const_string "*")))
6539 (set_attr "mode" "QI,QI,QI,SI,SI,SI")
6540 ;; Potential partial reg stall on alternatives 3 and 4.
6541 (set (attr "preferred_for_speed")
6542 (cond [(eq_attr "alternative" "3,4")
6543 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
6544 (symbol_ref "true")))])
6546 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
6547 (define_insn_and_split "*add<mode>_1_slp"
6548 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
6549 (plus:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0,!<r>")
6550 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
6551 (clobber (reg:CC FLAGS_REG))]
6552 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6554 if (which_alternative)
6557 switch (get_attr_type (insn))
6560 if (operands[2] == const1_rtx)
6561 return "inc{<imodesuffix>}\t%0";
6564 gcc_assert (operands[2] == constm1_rtx);
6565 return "dec{<imodesuffix>}\t%0";
6569 if (x86_maybe_negate_const_int (&operands[2], QImode))
6570 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6572 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6575 "&& reload_completed"
6576 [(set (strict_low_part (match_dup 0)) (match_dup 1))
6578 [(set (strict_low_part (match_dup 0))
6579 (plus:SWI12 (match_dup 0) (match_dup 2)))
6580 (clobber (reg:CC FLAGS_REG))])]
6583 (if_then_else (match_operand:QI 2 "incdec_operand")
6584 (const_string "incdec")
6585 (const_string "alu")))
6586 (set_attr "mode" "<MODE>")])
6588 ;; Split non destructive adds if we cannot use lea.
6590 [(set (match_operand:SWI48 0 "register_operand")
6591 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
6592 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
6593 (clobber (reg:CC FLAGS_REG))]
6594 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
6595 [(set (match_dup 0) (match_dup 1))
6596 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
6597 (clobber (reg:CC FLAGS_REG))])])
6599 ;; Split non destructive adds if we cannot use lea.
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))]
6607 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
6608 [(set (match_dup 3) (match_dup 1))
6609 (parallel [(set (match_dup 0)
6610 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
6611 (clobber (reg:CC FLAGS_REG))])]
6612 "operands[3] = gen_lowpart (SImode, operands[0]);")
6614 ;; Convert add to the lea pattern to avoid flags dependency.
6616 [(set (match_operand:SWI 0 "register_operand")
6617 (plus:SWI (match_operand:SWI 1 "register_operand")
6618 (match_operand:SWI 2 "<nonmemory_operand>")))
6619 (clobber (reg:CC FLAGS_REG))]
6620 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
6622 (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
6624 if (<MODE>mode != <LEAMODE>mode)
6626 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
6627 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
6628 operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
6632 ;; Convert add to the lea pattern to avoid flags dependency.
6634 [(set (match_operand:DI 0 "register_operand")
6636 (plus:SI (match_operand:SI 1 "register_operand")
6637 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
6638 (clobber (reg:CC FLAGS_REG))]
6639 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
6641 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
6643 (define_insn "*add<mode>_2"
6644 [(set (reg FLAGS_REG)
6647 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
6648 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,0"))
6650 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,<r>")
6651 (plus:SWI (match_dup 1) (match_dup 2)))]
6652 "ix86_match_ccmode (insn, CCGOCmode)
6653 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6655 switch (get_attr_type (insn))
6658 if (operands[2] == const1_rtx)
6659 return "inc{<imodesuffix>}\t%0";
6662 gcc_assert (operands[2] == constm1_rtx);
6663 return "dec{<imodesuffix>}\t%0";
6667 if (which_alternative == 2)
6668 std::swap (operands[1], operands[2]);
6670 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6671 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6672 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6674 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6678 (if_then_else (match_operand:SWI 2 "incdec_operand")
6679 (const_string "incdec")
6680 (const_string "alu")))
6681 (set (attr "length_immediate")
6683 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6685 (const_string "*")))
6686 (set_attr "mode" "<MODE>")])
6688 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6689 (define_insn "*addsi_2_zext"
6690 [(set (reg FLAGS_REG)
6692 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6693 (match_operand:SI 2 "x86_64_general_operand" "rBMe,0"))
6695 (set (match_operand:DI 0 "register_operand" "=r,r")
6696 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6697 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6698 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6700 switch (get_attr_type (insn))
6703 if (operands[2] == const1_rtx)
6704 return "inc{l}\t%k0";
6707 gcc_assert (operands[2] == constm1_rtx);
6708 return "dec{l}\t%k0";
6712 if (which_alternative == 1)
6713 std::swap (operands[1], operands[2]);
6715 if (x86_maybe_negate_const_int (&operands[2], SImode))
6716 return "sub{l}\t{%2, %k0|%k0, %2}";
6718 return "add{l}\t{%2, %k0|%k0, %2}";
6722 (if_then_else (match_operand:SI 2 "incdec_operand")
6723 (const_string "incdec")
6724 (const_string "alu")))
6725 (set (attr "length_immediate")
6727 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6729 (const_string "*")))
6730 (set_attr "mode" "SI")])
6732 (define_insn "*add<mode>_3"
6733 [(set (reg FLAGS_REG)
6735 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6736 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
6737 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6738 "ix86_match_ccmode (insn, CCZmode)
6739 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6741 switch (get_attr_type (insn))
6744 if (operands[2] == const1_rtx)
6745 return "inc{<imodesuffix>}\t%0";
6748 gcc_assert (operands[2] == constm1_rtx);
6749 return "dec{<imodesuffix>}\t%0";
6753 if (which_alternative == 1)
6754 std::swap (operands[1], operands[2]);
6756 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6757 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6758 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6760 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6764 (if_then_else (match_operand:SWI 2 "incdec_operand")
6765 (const_string "incdec")
6766 (const_string "alu")))
6767 (set (attr "length_immediate")
6769 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6771 (const_string "*")))
6772 (set_attr "mode" "<MODE>")])
6774 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6775 (define_insn "*addsi_3_zext"
6776 [(set (reg FLAGS_REG)
6778 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rBMe,0"))
6779 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
6780 (set (match_operand:DI 0 "register_operand" "=r,r")
6781 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6782 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6783 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6785 switch (get_attr_type (insn))
6788 if (operands[2] == const1_rtx)
6789 return "inc{l}\t%k0";
6792 gcc_assert (operands[2] == constm1_rtx);
6793 return "dec{l}\t%k0";
6797 if (which_alternative == 1)
6798 std::swap (operands[1], operands[2]);
6800 if (x86_maybe_negate_const_int (&operands[2], SImode))
6801 return "sub{l}\t{%2, %k0|%k0, %2}";
6803 return "add{l}\t{%2, %k0|%k0, %2}";
6807 (if_then_else (match_operand:SI 2 "incdec_operand")
6808 (const_string "incdec")
6809 (const_string "alu")))
6810 (set (attr "length_immediate")
6812 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6814 (const_string "*")))
6815 (set_attr "mode" "SI")])
6817 ; For comparisons against 1, -1 and 128, we may generate better code
6818 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6819 ; is matched then. We can't accept general immediate, because for
6820 ; case of overflows, the result is messed up.
6821 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6822 ; only for comparisons not depending on it.
6824 (define_insn "*adddi_4"
6825 [(set (reg FLAGS_REG)
6827 (match_operand:DI 1 "nonimmediate_operand" "0")
6828 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6829 (clobber (match_scratch:DI 0 "=r"))]
6831 && ix86_match_ccmode (insn, CCGCmode)"
6833 switch (get_attr_type (insn))
6836 if (operands[2] == constm1_rtx)
6837 return "inc{q}\t%0";
6840 gcc_assert (operands[2] == const1_rtx);
6841 return "dec{q}\t%0";
6845 if (x86_maybe_negate_const_int (&operands[2], DImode))
6846 return "add{q}\t{%2, %0|%0, %2}";
6848 return "sub{q}\t{%2, %0|%0, %2}";
6852 (if_then_else (match_operand:DI 2 "incdec_operand")
6853 (const_string "incdec")
6854 (const_string "alu")))
6855 (set (attr "length_immediate")
6857 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6859 (const_string "*")))
6860 (set_attr "mode" "DI")])
6862 ; For comparisons against 1, -1 and 128, we may generate better code
6863 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6864 ; is matched then. We can't accept general immediate, because for
6865 ; case of overflows, the result is messed up.
6866 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6867 ; only for comparisons not depending on it.
6869 (define_insn "*add<mode>_4"
6870 [(set (reg FLAGS_REG)
6872 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6873 (match_operand:SWI124 2 "const_int_operand")))
6874 (clobber (match_scratch:SWI124 0 "=<r>"))]
6875 "ix86_match_ccmode (insn, CCGCmode)"
6877 switch (get_attr_type (insn))
6880 if (operands[2] == constm1_rtx)
6881 return "inc{<imodesuffix>}\t%0";
6884 gcc_assert (operands[2] == const1_rtx);
6885 return "dec{<imodesuffix>}\t%0";
6889 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6890 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6892 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6896 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6897 (const_string "incdec")
6898 (const_string "alu")))
6899 (set (attr "length_immediate")
6901 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6903 (const_string "*")))
6904 (set_attr "mode" "<MODE>")])
6906 (define_insn "*add<mode>_5"
6907 [(set (reg FLAGS_REG)
6910 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6911 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6913 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6914 "ix86_match_ccmode (insn, CCGOCmode)
6915 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6917 switch (get_attr_type (insn))
6920 if (operands[2] == const1_rtx)
6921 return "inc{<imodesuffix>}\t%0";
6924 gcc_assert (operands[2] == constm1_rtx);
6925 return "dec{<imodesuffix>}\t%0";
6929 if (which_alternative == 1)
6930 std::swap (operands[1], operands[2]);
6932 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6933 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6934 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6936 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6940 (if_then_else (match_operand:SWI 2 "incdec_operand")
6941 (const_string "incdec")
6942 (const_string "alu")))
6943 (set (attr "length_immediate")
6945 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6947 (const_string "*")))
6948 (set_attr "mode" "<MODE>")])
6950 (define_insn "*addqi_ext<mode>_0"
6951 [(set (match_operand:QI 0 "nonimm_x64constmem_operand" "=QBc,m")
6954 (match_operator:SWI248 3 "extract_operator"
6955 [(match_operand 2 "int248_register_operand" "Q,Q")
6958 (match_operand:QI 1 "nonimm_x64constmem_operand" "0,0")))
6959 (clobber (reg:CC FLAGS_REG))]
6961 "add{b}\t{%h2, %0|%0, %h2}"
6962 [(set_attr "isa" "*,nox64")
6963 (set_attr "type" "alu")
6964 (set_attr "mode" "QI")])
6966 (define_expand "addqi_ext_1"
6968 [(set (zero_extract:HI (match_operand:HI 0 "register_operand")
6974 (zero_extract:HI (match_operand:HI 1 "register_operand")
6977 (match_operand:QI 2 "const_int_operand")) 0))
6978 (clobber (reg:CC FLAGS_REG))])])
6980 (define_insn "*addqi_ext<mode>_1"
6981 [(set (zero_extract:SWI248
6982 (match_operand 0 "int248_register_operand" "+Q,Q")
6988 (match_operator:SWI248 3 "extract_operator"
6989 [(match_operand 1 "int248_register_operand" "0,0")
6992 (match_operand:QI 2 "general_x64constmem_operand" "QnBc,m")) 0))
6993 (clobber (reg:CC FLAGS_REG))]
6994 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
6995 rtx_equal_p (operands[0], operands[1])"
6997 switch (get_attr_type (insn))
7000 if (operands[2] == const1_rtx)
7001 return "inc{b}\t%h0";
7004 gcc_assert (operands[2] == constm1_rtx);
7005 return "dec{b}\t%h0";
7009 return "add{b}\t{%2, %h0|%h0, %2}";
7012 [(set_attr "isa" "*,nox64")
7014 (if_then_else (match_operand:QI 2 "incdec_operand")
7015 (const_string "incdec")
7016 (const_string "alu")))
7017 (set_attr "mode" "QI")])
7019 (define_insn "*addqi_ext<mode>_2"
7020 [(set (zero_extract:SWI248
7021 (match_operand 0 "int248_register_operand" "+Q")
7027 (match_operator:SWI248 3 "extract_operator"
7028 [(match_operand 1 "int248_register_operand" "%0")
7032 (match_operator:SWI248 4 "extract_operator"
7033 [(match_operand 2 "int248_register_operand" "Q")
7035 (const_int 8)]) 0)) 0))
7036 (clobber (reg:CC FLAGS_REG))]
7037 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
7038 rtx_equal_p (operands[0], operands[1])
7039 || rtx_equal_p (operands[0], operands[2])"
7040 "add{b}\t{%h2, %h0|%h0, %h2}"
7041 [(set_attr "type" "alu")
7042 (set_attr "mode" "QI")])
7044 ;; Like DWI, but use POImode instead of OImode.
7045 (define_mode_attr DPWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI") (TI "POI")])
7047 ;; Add with jump on overflow.
7048 (define_expand "addv<mode>4"
7049 [(parallel [(set (reg:CCO FLAGS_REG)
7053 (match_operand:SWIDWI 1 "nonimmediate_operand"))
7056 (plus:SWIDWI (match_dup 1)
7057 (match_operand:SWIDWI 2
7058 "<general_hilo_operand>")))))
7059 (set (match_operand:SWIDWI 0 "register_operand")
7060 (plus:SWIDWI (match_dup 1) (match_dup 2)))])
7061 (set (pc) (if_then_else
7062 (eq (reg:CCO FLAGS_REG) (const_int 0))
7063 (label_ref (match_operand 3))
7067 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
7068 if (CONST_SCALAR_INT_P (operands[2]))
7069 operands[4] = operands[2];
7071 operands[4] = gen_rtx_SIGN_EXTEND (<DPWI>mode, operands[2]);
7074 (define_insn "*addv<mode>4"
7075 [(set (reg:CCO FLAGS_REG)
7078 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
7080 (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m")))
7082 (plus:SWI (match_dup 1) (match_dup 2)))))
7083 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7084 (plus:SWI (match_dup 1) (match_dup 2)))]
7085 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7086 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7087 [(set_attr "type" "alu")
7088 (set_attr "mode" "<MODE>")])
7090 (define_insn "addv<mode>4_1"
7091 [(set (reg:CCO FLAGS_REG)
7094 (match_operand:SWI 1 "nonimmediate_operand" "0"))
7095 (match_operand:<DWI> 3 "const_int_operand"))
7099 (match_operand:SWI 2 "x86_64_immediate_operand" "<i>")))))
7100 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
7101 (plus:SWI (match_dup 1) (match_dup 2)))]
7102 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
7103 && CONST_INT_P (operands[2])
7104 && INTVAL (operands[2]) == INTVAL (operands[3])"
7105 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7106 [(set_attr "type" "alu")
7107 (set_attr "mode" "<MODE>")
7108 (set (attr "length_immediate")
7109 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7111 (match_test "<MODE_SIZE> == 8")
7113 (const_string "<MODE_SIZE>")))])
7115 ;; Quad word integer modes as mode attribute.
7116 (define_mode_attr QPWI [(SI "TI") (DI "POI")])
7118 (define_insn_and_split "*addv<dwi>4_doubleword"
7119 [(set (reg:CCO FLAGS_REG)
7123 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0"))
7125 (match_operand:<DWI> 2 "nonimmediate_operand" "r,o")))
7127 (plus:<DWI> (match_dup 1) (match_dup 2)))))
7128 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
7129 (plus:<DWI> (match_dup 1) (match_dup 2)))]
7130 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
7132 "&& reload_completed"
7133 [(parallel [(set (reg:CCC FLAGS_REG)
7135 (plus:DWIH (match_dup 1) (match_dup 2))
7138 (plus:DWIH (match_dup 1) (match_dup 2)))])
7139 (parallel [(set (reg:CCO FLAGS_REG)
7143 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7144 (sign_extend:<DWI> (match_dup 4)))
7145 (sign_extend:<DWI> (match_dup 5)))
7149 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7155 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7159 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7162 (define_insn_and_split "*addv<dwi>4_doubleword_1"
7163 [(set (reg:CCO FLAGS_REG)
7167 (match_operand:<DWI> 1 "nonimmediate_operand" "%0"))
7168 (match_operand:<QPWI> 3 "const_scalar_int_operand" "n"))
7172 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>")))))
7173 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
7174 (plus:<DWI> (match_dup 1) (match_dup 2)))]
7175 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)
7176 && CONST_SCALAR_INT_P (operands[2])
7177 && rtx_equal_p (operands[2], operands[3])"
7179 "&& reload_completed"
7180 [(parallel [(set (reg:CCC FLAGS_REG)
7182 (plus:DWIH (match_dup 1) (match_dup 2))
7185 (plus:DWIH (match_dup 1) (match_dup 2)))])
7186 (parallel [(set (reg:CCO FLAGS_REG)
7190 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7191 (sign_extend:<DWI> (match_dup 4)))
7196 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7202 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7206 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7207 if (operands[2] == const0_rtx)
7209 emit_insn (gen_addv<mode>4_1 (operands[3], operands[4], operands[5],
7215 (define_insn "*addv<mode>4_overflow_1"
7216 [(set (reg:CCO FLAGS_REG)
7220 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7221 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7223 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")))
7225 (match_operand:SWI 2 "<general_sext_operand>" "rWe,m")))
7229 (match_operator:SWI 5 "ix86_carry_flag_operator"
7230 [(match_dup 3) (const_int 0)])
7233 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r")
7236 (match_op_dup 5 [(match_dup 3) (const_int 0)])
7239 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7240 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
7241 [(set_attr "type" "alu")
7242 (set_attr "mode" "<MODE>")])
7244 (define_insn "*addv<mode>4_overflow_2"
7245 [(set (reg:CCO FLAGS_REG)
7249 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7250 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7252 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
7253 (match_operand:<DWI> 6 "const_int_operand" "n"))
7257 (match_operator:SWI 5 "ix86_carry_flag_operator"
7258 [(match_dup 3) (const_int 0)])
7260 (match_operand:SWI 2 "x86_64_immediate_operand" "e")))))
7261 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm")
7264 (match_op_dup 5 [(match_dup 3) (const_int 0)])
7267 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
7268 && CONST_INT_P (operands[2])
7269 && INTVAL (operands[2]) == INTVAL (operands[6])"
7270 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
7271 [(set_attr "type" "alu")
7272 (set_attr "mode" "<MODE>")
7273 (set (attr "length_immediate")
7274 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7276 (const_string "4")))])
7278 (define_expand "uaddv<mode>4"
7279 [(parallel [(set (reg:CCC FLAGS_REG)
7282 (match_operand:SWIDWI 1 "nonimmediate_operand")
7283 (match_operand:SWIDWI 2 "<general_hilo_operand>"))
7285 (set (match_operand:SWIDWI 0 "register_operand")
7286 (plus:SWIDWI (match_dup 1) (match_dup 2)))])
7287 (set (pc) (if_then_else
7288 (ltu (reg:CCC FLAGS_REG) (const_int 0))
7289 (label_ref (match_operand 3))
7292 "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
7294 ;; The lea patterns for modes less than 32 bits need to be matched by
7295 ;; several insns converted to real lea by splitters.
7297 (define_insn_and_split "*lea<mode>_general_1"
7298 [(set (match_operand:SWI12 0 "register_operand" "=r")
7300 (plus:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7301 (match_operand:SWI12 2 "register_operand" "r"))
7302 (match_operand:SWI12 3 "immediate_operand" "i")))]
7303 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7305 "&& reload_completed"
7308 (plus:SI (match_dup 1) (match_dup 2))
7311 operands[0] = gen_lowpart (SImode, operands[0]);
7312 operands[1] = gen_lowpart (SImode, operands[1]);
7313 operands[2] = gen_lowpart (SImode, operands[2]);
7314 operands[3] = gen_lowpart (SImode, operands[3]);
7316 [(set_attr "type" "lea")
7317 (set_attr "mode" "SI")])
7319 (define_insn_and_split "*lea<mode>_general_2"
7320 [(set (match_operand:SWI12 0 "register_operand" "=r")
7322 (mult:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7323 (match_operand 2 "const248_operand" "n"))
7324 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
7325 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7327 "&& reload_completed"
7330 (mult:SI (match_dup 1) (match_dup 2))
7333 operands[0] = gen_lowpart (SImode, operands[0]);
7334 operands[1] = gen_lowpart (SImode, operands[1]);
7335 operands[3] = gen_lowpart (SImode, operands[3]);
7337 [(set_attr "type" "lea")
7338 (set_attr "mode" "SI")])
7340 (define_insn_and_split "*lea<mode>_general_2b"
7341 [(set (match_operand:SWI12 0 "register_operand" "=r")
7343 (ashift:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7344 (match_operand 2 "const123_operand" "n"))
7345 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
7346 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7348 "&& reload_completed"
7351 (ashift:SI (match_dup 1) (match_dup 2))
7354 operands[0] = gen_lowpart (SImode, operands[0]);
7355 operands[1] = gen_lowpart (SImode, operands[1]);
7356 operands[3] = gen_lowpart (SImode, operands[3]);
7358 [(set_attr "type" "lea")
7359 (set_attr "mode" "SI")])
7361 (define_insn_and_split "*lea<mode>_general_3"
7362 [(set (match_operand:SWI12 0 "register_operand" "=r")
7365 (mult:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7366 (match_operand 2 "const248_operand" "n"))
7367 (match_operand:SWI12 3 "register_operand" "r"))
7368 (match_operand:SWI12 4 "immediate_operand" "i")))]
7369 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7371 "&& reload_completed"
7375 (mult:SI (match_dup 1) (match_dup 2))
7379 operands[0] = gen_lowpart (SImode, operands[0]);
7380 operands[1] = gen_lowpart (SImode, operands[1]);
7381 operands[3] = gen_lowpart (SImode, operands[3]);
7382 operands[4] = gen_lowpart (SImode, operands[4]);
7384 [(set_attr "type" "lea")
7385 (set_attr "mode" "SI")])
7387 (define_insn_and_split "*lea<mode>_general_3b"
7388 [(set (match_operand:SWI12 0 "register_operand" "=r")
7391 (ashift:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7392 (match_operand 2 "const123_operand" "n"))
7393 (match_operand:SWI12 3 "register_operand" "r"))
7394 (match_operand:SWI12 4 "immediate_operand" "i")))]
7395 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7397 "&& reload_completed"
7401 (ashift:SI (match_dup 1) (match_dup 2))
7405 operands[0] = gen_lowpart (SImode, operands[0]);
7406 operands[1] = gen_lowpart (SImode, operands[1]);
7407 operands[3] = gen_lowpart (SImode, operands[3]);
7408 operands[4] = gen_lowpart (SImode, operands[4]);
7410 [(set_attr "type" "lea")
7411 (set_attr "mode" "SI")])
7413 (define_insn_and_split "*lea<mode>_general_4"
7414 [(set (match_operand:SWI12 0 "register_operand" "=r")
7417 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7418 (match_operand 2 "const_0_to_3_operand"))
7419 (match_operand 3 "const_int_operand")))]
7420 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7421 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
7422 < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
7424 "&& reload_completed"
7427 (mult:SI (match_dup 1) (match_dup 2))
7430 operands[0] = gen_lowpart (SImode, operands[0]);
7431 operands[1] = gen_lowpart (SImode, operands[1]);
7432 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
7434 [(set_attr "type" "lea")
7435 (set_attr "mode" "SI")])
7437 (define_insn_and_split "*lea<mode>_general_4"
7438 [(set (match_operand:SWI48 0 "register_operand" "=r")
7441 (match_operand:SWI48 1 "register_no_SP_operand" "l")
7442 (match_operand 2 "const_0_to_3_operand"))
7443 (match_operand 3 "const_int_operand")))]
7444 "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
7445 < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
7447 "&& reload_completed"
7450 (mult:SWI48 (match_dup 1) (match_dup 2))
7452 "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
7453 [(set_attr "type" "lea")
7454 (set_attr "mode" "<MODE>")])
7456 ;; Subtract instructions
7458 (define_expand "sub<mode>3"
7459 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
7460 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
7461 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
7463 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
7465 (define_insn_and_split "*sub<dwi>3_doubleword"
7466 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
7468 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7469 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
7470 (clobber (reg:CC FLAGS_REG))]
7471 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7473 "&& reload_completed"
7474 [(parallel [(set (reg:CC FLAGS_REG)
7475 (compare:CC (match_dup 1) (match_dup 2)))
7477 (minus:DWIH (match_dup 1) (match_dup 2)))])
7478 (parallel [(set (match_dup 3)
7482 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7484 (clobber (reg:CC FLAGS_REG))])]
7486 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7487 if (operands[2] == const0_rtx)
7489 ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
7494 (define_insn_and_split "*sub<dwi>3_doubleword_zext"
7495 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
7497 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7499 (match_operand:DWIH 2 "nonimmediate_operand" "rm,r"))))
7500 (clobber (reg:CC FLAGS_REG))]
7501 "ix86_binary_operator_ok (UNKNOWN, <DWI>mode, operands)"
7503 "&& reload_completed"
7504 [(parallel [(set (reg:CC FLAGS_REG)
7505 (compare:CC (match_dup 1) (match_dup 2)))
7507 (minus:DWIH (match_dup 1) (match_dup 2)))])
7508 (parallel [(set (match_dup 3)
7512 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7514 (clobber (reg:CC FLAGS_REG))])]
7515 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[3]);")
7517 (define_insn "*sub<mode>_1"
7518 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7520 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7521 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
7522 (clobber (reg:CC FLAGS_REG))]
7523 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7524 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7525 [(set_attr "type" "alu")
7526 (set_attr "mode" "<MODE>")])
7528 (define_insn "*subsi_1_zext"
7529 [(set (match_operand:DI 0 "register_operand" "=r")
7531 (minus:SI (match_operand:SI 1 "register_operand" "0")
7532 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
7533 (clobber (reg:CC FLAGS_REG))]
7534 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7535 "sub{l}\t{%2, %k0|%k0, %2}"
7536 [(set_attr "type" "alu")
7537 (set_attr "mode" "SI")])
7539 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
7540 (define_insn_and_split "*sub<mode>_1_slp"
7541 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
7542 (minus:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
7543 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
7544 (clobber (reg:CC FLAGS_REG))]
7545 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7547 sub{<imodesuffix>}\t{%2, %0|%0, %2}
7549 "&& reload_completed"
7550 [(set (strict_low_part (match_dup 0)) (match_dup 1))
7552 [(set (strict_low_part (match_dup 0))
7553 (minus:SWI12 (match_dup 0) (match_dup 2)))
7554 (clobber (reg:CC FLAGS_REG))])]
7556 [(set_attr "type" "alu")
7557 (set_attr "mode" "<MODE>")])
7559 (define_insn "*sub<mode>_2"
7560 [(set (reg FLAGS_REG)
7563 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7564 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
7566 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7567 (minus:SWI (match_dup 1) (match_dup 2)))]
7568 "ix86_match_ccmode (insn, CCGOCmode)
7569 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7570 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7571 [(set_attr "type" "alu")
7572 (set_attr "mode" "<MODE>")])
7574 (define_insn "*subsi_2_zext"
7575 [(set (reg FLAGS_REG)
7577 (minus:SI (match_operand:SI 1 "register_operand" "0")
7578 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
7580 (set (match_operand:DI 0 "register_operand" "=r")
7582 (minus:SI (match_dup 1)
7584 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7585 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7586 "sub{l}\t{%2, %k0|%k0, %2}"
7587 [(set_attr "type" "alu")
7588 (set_attr "mode" "SI")])
7590 (define_insn "*subqi_ext<mode>_0"
7591 [(set (match_operand:QI 0 "nonimm_x64constmem_operand" "=QBc,m")
7593 (match_operand:QI 1 "nonimm_x64constmem_operand" "0,0")
7595 (match_operator:SWI248 3 "extract_operator"
7596 [(match_operand 2 "int248_register_operand" "Q,Q")
7598 (const_int 8)]) 0)))
7599 (clobber (reg:CC FLAGS_REG))]
7601 "sub{b}\t{%h2, %0|%0, %h2}"
7602 [(set_attr "isa" "*,nox64")
7603 (set_attr "type" "alu")
7604 (set_attr "mode" "QI")])
7606 (define_insn "*subqi_ext<mode>_2"
7607 [(set (zero_extract:SWI248
7608 (match_operand 0 "int248_register_operand" "+Q")
7614 (match_operator:SWI248 3 "extract_operator"
7615 [(match_operand 1 "int248_register_operand" "0")
7619 (match_operator:SWI248 4 "extract_operator"
7620 [(match_operand 2 "int248_register_operand" "Q")
7622 (const_int 8)]) 0)) 0))
7623 (clobber (reg:CC FLAGS_REG))]
7624 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
7625 rtx_equal_p (operands[0], operands[1])"
7626 "sub{b}\t{%h2, %h0|%h0, %h2}"
7627 [(set_attr "type" "alu")
7628 (set_attr "mode" "QI")])
7630 ;; Subtract with jump on overflow.
7631 (define_expand "subv<mode>4"
7632 [(parallel [(set (reg:CCO FLAGS_REG)
7636 (match_operand:SWIDWI 1 "nonimmediate_operand"))
7639 (minus:SWIDWI (match_dup 1)
7640 (match_operand:SWIDWI 2
7641 "<general_hilo_operand>")))))
7642 (set (match_operand:SWIDWI 0 "register_operand")
7643 (minus:SWIDWI (match_dup 1) (match_dup 2)))])
7644 (set (pc) (if_then_else
7645 (eq (reg:CCO FLAGS_REG) (const_int 0))
7646 (label_ref (match_operand 3))
7650 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
7651 if (CONST_SCALAR_INT_P (operands[2]))
7652 operands[4] = operands[2];
7654 operands[4] = gen_rtx_SIGN_EXTEND (<DPWI>mode, operands[2]);
7657 (define_insn "*subv<mode>4"
7658 [(set (reg:CCO FLAGS_REG)
7659 (eq:CCO (minus:<DWI>
7661 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
7663 (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m")))
7665 (minus:SWI (match_dup 1) (match_dup 2)))))
7666 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7667 (minus:SWI (match_dup 1) (match_dup 2)))]
7668 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7669 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7670 [(set_attr "type" "alu")
7671 (set_attr "mode" "<MODE>")])
7673 (define_insn "subv<mode>4_1"
7674 [(set (reg:CCO FLAGS_REG)
7675 (eq:CCO (minus:<DWI>
7677 (match_operand:SWI 1 "nonimmediate_operand" "0"))
7678 (match_operand:<DWI> 3 "const_int_operand"))
7682 (match_operand:SWI 2 "x86_64_immediate_operand" "<i>")))))
7683 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
7684 (minus:SWI (match_dup 1) (match_dup 2)))]
7685 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7686 && CONST_INT_P (operands[2])
7687 && INTVAL (operands[2]) == INTVAL (operands[3])"
7688 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7689 [(set_attr "type" "alu")
7690 (set_attr "mode" "<MODE>")
7691 (set (attr "length_immediate")
7692 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7694 (match_test "<MODE_SIZE> == 8")
7696 (const_string "<MODE_SIZE>")))])
7698 (define_insn_and_split "*subv<dwi>4_doubleword"
7699 [(set (reg:CCO FLAGS_REG)
7703 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0"))
7705 (match_operand:<DWI> 2 "nonimmediate_operand" "r,o")))
7707 (minus:<DWI> (match_dup 1) (match_dup 2)))))
7708 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
7709 (minus:<DWI> (match_dup 1) (match_dup 2)))]
7710 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7712 "&& reload_completed"
7713 [(parallel [(set (reg:CC FLAGS_REG)
7714 (compare:CC (match_dup 1) (match_dup 2)))
7716 (minus:DWIH (match_dup 1) (match_dup 2)))])
7717 (parallel [(set (reg:CCO FLAGS_REG)
7721 (sign_extend:<DWI> (match_dup 4))
7722 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))
7723 (sign_extend:<DWI> (match_dup 5)))
7728 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7734 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7737 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7740 (define_insn_and_split "*subv<dwi>4_doubleword_1"
7741 [(set (reg:CCO FLAGS_REG)
7745 (match_operand:<DWI> 1 "nonimmediate_operand" "0"))
7746 (match_operand:<QPWI> 3 "const_scalar_int_operand"))
7750 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>")))))
7751 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
7752 (minus:<DWI> (match_dup 1) (match_dup 2)))]
7753 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7754 && CONST_SCALAR_INT_P (operands[2])
7755 && rtx_equal_p (operands[2], operands[3])"
7757 "&& reload_completed"
7758 [(parallel [(set (reg:CC FLAGS_REG)
7759 (compare:CC (match_dup 1) (match_dup 2)))
7761 (minus:DWIH (match_dup 1) (match_dup 2)))])
7762 (parallel [(set (reg:CCO FLAGS_REG)
7766 (sign_extend:<DWI> (match_dup 4))
7767 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))
7773 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7779 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7782 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7783 if (operands[2] == const0_rtx)
7785 emit_insn (gen_subv<mode>4_1 (operands[3], operands[4], operands[5],
7791 (define_insn "*subv<mode>4_overflow_1"
7792 [(set (reg:CCO FLAGS_REG)
7797 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
7798 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7799 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
7801 (match_operand:SWI 2 "<general_sext_operand>" "rWe,m")))
7806 (match_operator:SWI 5 "ix86_carry_flag_operator"
7807 [(match_dup 3) (const_int 0)]))
7809 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r")
7813 (match_op_dup 5 [(match_dup 3) (const_int 0)]))
7815 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7816 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7817 [(set_attr "type" "alu")
7818 (set_attr "mode" "<MODE>")])
7820 (define_insn "*subv<mode>4_overflow_2"
7821 [(set (reg:CCO FLAGS_REG)
7826 (match_operand:SWI 1 "nonimmediate_operand" "%0"))
7827 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7828 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
7829 (match_operand:<DWI> 6 "const_int_operand" "n"))
7834 (match_operator:SWI 5 "ix86_carry_flag_operator"
7835 [(match_dup 3) (const_int 0)]))
7836 (match_operand:SWI 2 "x86_64_immediate_operand" "e")))))
7837 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm")
7841 (match_op_dup 5 [(match_dup 3) (const_int 0)]))
7843 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7844 && CONST_INT_P (operands[2])
7845 && INTVAL (operands[2]) == INTVAL (operands[6])"
7846 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7847 [(set_attr "type" "alu")
7848 (set_attr "mode" "<MODE>")
7849 (set (attr "length_immediate")
7850 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7852 (const_string "4")))])
7854 (define_expand "usubv<mode>4"
7855 [(parallel [(set (reg:CC FLAGS_REG)
7857 (match_operand:SWI 1 "nonimmediate_operand")
7858 (match_operand:SWI 2 "<general_operand>")))
7859 (set (match_operand:SWI 0 "register_operand")
7860 (minus:SWI (match_dup 1) (match_dup 2)))])
7861 (set (pc) (if_then_else
7862 (ltu (reg:CC FLAGS_REG) (const_int 0))
7863 (label_ref (match_operand 3))
7866 "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
7868 (define_insn "*sub<mode>_3"
7869 [(set (reg FLAGS_REG)
7870 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7871 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
7872 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7873 (minus:SWI (match_dup 1) (match_dup 2)))]
7874 "ix86_match_ccmode (insn, CCmode)
7875 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7876 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7877 [(set_attr "type" "alu")
7878 (set_attr "mode" "<MODE>")])
7882 [(set (reg:CC FLAGS_REG)
7883 (compare:CC (match_operand:SWI 0 "general_reg_operand")
7884 (match_operand:SWI 1 "general_gr_operand")))
7886 (minus:SWI (match_dup 0) (match_dup 1)))])]
7887 "find_regno_note (peep2_next_insn (0), REG_UNUSED, REGNO (operands[0])) != 0"
7888 [(set (reg:CC FLAGS_REG)
7889 (compare:CC (match_dup 0) (match_dup 1)))])
7892 [(set (match_operand:SWI 0 "general_reg_operand")
7893 (match_operand:SWI 1 "memory_operand"))
7894 (parallel [(set (reg:CC FLAGS_REG)
7895 (compare:CC (match_dup 0)
7896 (match_operand:SWI 2 "memory_operand")))
7898 (minus:SWI (match_dup 0) (match_dup 2)))])
7899 (set (match_dup 1) (match_dup 0))]
7900 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
7901 && peep2_reg_dead_p (3, operands[0])
7902 && !reg_overlap_mentioned_p (operands[0], operands[1])
7903 && !reg_overlap_mentioned_p (operands[0], operands[2])"
7904 [(set (match_dup 0) (match_dup 2))
7905 (parallel [(set (reg:CC FLAGS_REG)
7906 (compare:CC (match_dup 1) (match_dup 0)))
7908 (minus:SWI (match_dup 1) (match_dup 0)))])])
7910 ;; decl %eax; cmpl $-1, %eax; jne .Lxx; can be optimized into
7911 ;; subl $1, %eax; jnc .Lxx;
7914 [(set (match_operand:SWI 0 "general_reg_operand")
7915 (plus:SWI (match_dup 0) (const_int -1)))
7916 (clobber (reg FLAGS_REG))])
7917 (set (reg:CCZ FLAGS_REG)
7918 (compare:CCZ (match_dup 0) (const_int -1)))
7920 (if_then_else (match_operator 1 "bt_comparison_operator"
7921 [(reg:CCZ FLAGS_REG) (const_int 0)])
7924 "peep2_regno_dead_p (3, FLAGS_REG)"
7926 [(set (reg:CC FLAGS_REG)
7927 (compare:CC (match_dup 0) (const_int 1)))
7929 (minus:SWI (match_dup 0) (const_int 1)))])
7931 (if_then_else (match_dup 3)
7935 rtx cc = gen_rtx_REG (CCmode, FLAGS_REG);
7936 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE
7937 ? GEU : LTU, VOIDmode, cc, const0_rtx);
7940 ;; Help combine use borrow flag to test for -1 after dec (add $-1).
7941 (define_insn_and_split "*dec_cmov<mode>"
7942 [(set (match_operand:SWI248 0 "register_operand" "=r")
7943 (if_then_else:SWI248
7944 (match_operator 1 "bt_comparison_operator"
7945 [(match_operand:SWI248 2 "register_operand" "0") (const_int 0)])
7946 (plus:SWI248 (match_dup 2) (const_int -1))
7947 (match_operand:SWI248 3 "nonimmediate_operand" "rm")))
7948 (clobber (reg:CC FLAGS_REG))]
7951 "&& reload_completed"
7952 [(parallel [(set (reg:CC FLAGS_REG)
7953 (compare:CC (match_dup 2) (const_int 1)))
7954 (set (match_dup 0) (minus:SWI248 (match_dup 2) (const_int 1)))])
7956 (if_then_else:SWI248 (match_dup 4) (match_dup 0) (match_dup 3)))]
7958 rtx cc = gen_rtx_REG (CCCmode, FLAGS_REG);
7959 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE
7960 ? GEU : LTU, VOIDmode, cc, const0_rtx);
7963 (define_insn "*subsi_3_zext"
7964 [(set (reg FLAGS_REG)
7965 (compare (match_operand:SI 1 "register_operand" "0")
7966 (match_operand:SI 2 "x86_64_general_operand" "rBMe")))
7967 (set (match_operand:DI 0 "register_operand" "=r")
7969 (minus:SI (match_dup 1)
7971 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7972 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7973 "sub{l}\t{%2, %1|%1, %2}"
7974 [(set_attr "type" "alu")
7975 (set_attr "mode" "SI")])
7977 ;; Add with carry and subtract with borrow
7979 (define_insn "@add<mode>3_carry"
7980 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7983 (match_operator:SWI 4 "ix86_carry_flag_operator"
7984 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7985 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
7986 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
7987 (clobber (reg:CC FLAGS_REG))]
7988 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7989 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
7990 [(set_attr "type" "alu")
7991 (set_attr "use_carry" "1")
7992 (set_attr "pent_pair" "pu")
7993 (set_attr "mode" "<MODE>")])
7996 [(set (match_operand:SWI 0 "general_reg_operand")
7997 (match_operand:SWI 1 "memory_operand"))
7998 (parallel [(set (match_dup 0)
8001 (match_operator:SWI 4 "ix86_carry_flag_operator"
8002 [(match_operand 3 "flags_reg_operand")
8005 (match_operand:SWI 2 "memory_operand")))
8006 (clobber (reg:CC FLAGS_REG))])
8007 (set (match_dup 1) (match_dup 0))]
8008 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8009 && peep2_reg_dead_p (3, operands[0])
8010 && !reg_overlap_mentioned_p (operands[0], operands[1])
8011 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8012 [(set (match_dup 0) (match_dup 2))
8013 (parallel [(set (match_dup 1)
8014 (plus:SWI (plus:SWI (match_op_dup 4
8015 [(match_dup 3) (const_int 0)])
8018 (clobber (reg:CC FLAGS_REG))])])
8021 [(set (match_operand:SWI 0 "general_reg_operand")
8022 (match_operand:SWI 1 "memory_operand"))
8023 (parallel [(set (match_dup 0)
8026 (match_operator:SWI 4 "ix86_carry_flag_operator"
8027 [(match_operand 3 "flags_reg_operand")
8030 (match_operand:SWI 2 "memory_operand")))
8031 (clobber (reg:CC FLAGS_REG))])
8032 (set (match_operand:SWI 5 "general_reg_operand") (match_dup 0))
8033 (set (match_dup 1) (match_dup 5))]
8034 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8035 && peep2_reg_dead_p (3, operands[0])
8036 && peep2_reg_dead_p (4, operands[5])
8037 && !reg_overlap_mentioned_p (operands[0], operands[1])
8038 && !reg_overlap_mentioned_p (operands[0], operands[2])
8039 && !reg_overlap_mentioned_p (operands[5], operands[1])"
8040 [(set (match_dup 0) (match_dup 2))
8041 (parallel [(set (match_dup 1)
8042 (plus:SWI (plus:SWI (match_op_dup 4
8043 [(match_dup 3) (const_int 0)])
8046 (clobber (reg:CC FLAGS_REG))])])
8048 (define_insn "*add<mode>3_carry_0"
8049 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8051 (match_operator:SWI 2 "ix86_carry_flag_operator"
8052 [(reg FLAGS_REG) (const_int 0)])
8053 (match_operand:SWI 1 "nonimmediate_operand" "0")))
8054 (clobber (reg:CC FLAGS_REG))]
8055 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8056 "adc{<imodesuffix>}\t{$0, %0|%0, 0}"
8057 [(set_attr "type" "alu")
8058 (set_attr "use_carry" "1")
8059 (set_attr "pent_pair" "pu")
8060 (set_attr "mode" "<MODE>")])
8062 (define_insn "*add<mode>3_carry_0r"
8063 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8065 (match_operator:SWI 2 "ix86_carry_flag_unset_operator"
8066 [(reg FLAGS_REG) (const_int 0)])
8067 (match_operand:SWI 1 "nonimmediate_operand" "0")))
8068 (clobber (reg:CC FLAGS_REG))]
8069 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8070 "sbb{<imodesuffix>}\t{$-1, %0|%0, -1}"
8071 [(set_attr "type" "alu")
8072 (set_attr "use_carry" "1")
8073 (set_attr "pent_pair" "pu")
8074 (set_attr "mode" "<MODE>")])
8076 (define_insn "*addsi3_carry_zext"
8077 [(set (match_operand:DI 0 "register_operand" "=r")
8080 (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
8081 [(reg FLAGS_REG) (const_int 0)])
8082 (match_operand:SI 1 "register_operand" "%0"))
8083 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
8084 (clobber (reg:CC FLAGS_REG))]
8085 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
8086 "adc{l}\t{%2, %k0|%k0, %2}"
8087 [(set_attr "type" "alu")
8088 (set_attr "use_carry" "1")
8089 (set_attr "pent_pair" "pu")
8090 (set_attr "mode" "SI")])
8092 (define_insn "*addsi3_carry_zext_0"
8093 [(set (match_operand:DI 0 "register_operand" "=r")
8095 (plus:SI (match_operator:SI 2 "ix86_carry_flag_operator"
8096 [(reg FLAGS_REG) (const_int 0)])
8097 (match_operand:SI 1 "register_operand" "0"))))
8098 (clobber (reg:CC FLAGS_REG))]
8100 "adc{l}\t{$0, %k0|%k0, 0}"
8101 [(set_attr "type" "alu")
8102 (set_attr "use_carry" "1")
8103 (set_attr "pent_pair" "pu")
8104 (set_attr "mode" "SI")])
8106 (define_insn "*addsi3_carry_zext_0r"
8107 [(set (match_operand:DI 0 "register_operand" "=r")
8109 (plus:SI (match_operator:SI 2 "ix86_carry_flag_unset_operator"
8110 [(reg FLAGS_REG) (const_int 0)])
8111 (match_operand:SI 1 "register_operand" "0"))))
8112 (clobber (reg:CC FLAGS_REG))]
8114 "sbb{l}\t{$-1, %k0|%k0, -1}"
8115 [(set_attr "type" "alu")
8116 (set_attr "use_carry" "1")
8117 (set_attr "pent_pair" "pu")
8118 (set_attr "mode" "SI")])
8120 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
8122 (define_insn "addcarry<mode>"
8123 [(set (reg:CCC FLAGS_REG)
8128 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8129 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8130 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0"))
8131 (match_operand:SWI48 2 "nonimmediate_operand" "r,rm")))
8133 (zero_extend:<DWI> (match_dup 2))
8134 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8135 [(match_dup 3) (const_int 0)]))))
8136 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
8137 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8138 [(match_dup 3) (const_int 0)])
8141 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
8142 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
8143 [(set_attr "type" "alu")
8144 (set_attr "use_carry" "1")
8145 (set_attr "pent_pair" "pu")
8146 (set_attr "mode" "<MODE>")])
8149 [(parallel [(set (reg:CCC FLAGS_REG)
8154 (match_operator:SWI48 4 "ix86_carry_flag_operator"
8155 [(match_operand 2 "flags_reg_operand")
8157 (match_operand:SWI48 0 "general_reg_operand"))
8158 (match_operand:SWI48 1 "memory_operand")))
8160 (zero_extend:<DWI> (match_dup 1))
8161 (match_operator:<DWI> 3 "ix86_carry_flag_operator"
8162 [(match_dup 2) (const_int 0)]))))
8164 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8165 [(match_dup 2) (const_int 0)])
8168 (set (match_dup 1) (match_dup 0))]
8169 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8170 && peep2_reg_dead_p (2, operands[0])
8171 && !reg_overlap_mentioned_p (operands[0], operands[1])"
8172 [(parallel [(set (reg:CCC FLAGS_REG)
8178 [(match_dup 2) (const_int 0)])
8182 (zero_extend:<DWI> (match_dup 0))
8184 [(match_dup 2) (const_int 0)]))))
8186 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8187 [(match_dup 2) (const_int 0)])
8192 [(set (match_operand:SWI48 0 "general_reg_operand")
8193 (match_operand:SWI48 1 "memory_operand"))
8194 (parallel [(set (reg:CCC FLAGS_REG)
8199 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8200 [(match_operand 3 "flags_reg_operand")
8203 (match_operand:SWI48 2 "memory_operand")))
8205 (zero_extend:<DWI> (match_dup 2))
8206 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8207 [(match_dup 3) (const_int 0)]))))
8209 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8210 [(match_dup 3) (const_int 0)])
8213 (set (match_dup 1) (match_dup 0))]
8214 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8215 && peep2_reg_dead_p (3, operands[0])
8216 && !reg_overlap_mentioned_p (operands[0], operands[1])
8217 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8218 [(set (match_dup 0) (match_dup 2))
8219 (parallel [(set (reg:CCC FLAGS_REG)
8225 [(match_dup 3) (const_int 0)])
8229 (zero_extend:<DWI> (match_dup 0))
8231 [(match_dup 3) (const_int 0)]))))
8233 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8234 [(match_dup 3) (const_int 0)])
8239 [(parallel [(set (reg:CCC FLAGS_REG)
8244 (match_operator:SWI48 4 "ix86_carry_flag_operator"
8245 [(match_operand 2 "flags_reg_operand")
8247 (match_operand:SWI48 0 "general_reg_operand"))
8248 (match_operand:SWI48 1 "memory_operand")))
8250 (zero_extend:<DWI> (match_dup 1))
8251 (match_operator:<DWI> 3 "ix86_carry_flag_operator"
8252 [(match_dup 2) (const_int 0)]))))
8254 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8255 [(match_dup 2) (const_int 0)])
8258 (set (match_operand:QI 5 "general_reg_operand")
8259 (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8260 (set (match_operand:SWI48 6 "general_reg_operand")
8261 (zero_extend:SWI48 (match_dup 5)))
8262 (set (match_dup 1) (match_dup 0))]
8263 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8264 && peep2_reg_dead_p (4, operands[0])
8265 && !reg_overlap_mentioned_p (operands[0], operands[1])
8266 && !reg_overlap_mentioned_p (operands[0], operands[5])
8267 && !reg_overlap_mentioned_p (operands[5], operands[1])
8268 && !reg_overlap_mentioned_p (operands[0], operands[6])
8269 && !reg_overlap_mentioned_p (operands[6], operands[1])"
8270 [(parallel [(set (reg:CCC FLAGS_REG)
8276 [(match_dup 2) (const_int 0)])
8280 (zero_extend:<DWI> (match_dup 0))
8282 [(match_dup 2) (const_int 0)]))))
8284 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8285 [(match_dup 2) (const_int 0)])
8288 (set (match_dup 5) (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8289 (set (match_dup 6) (zero_extend:SWI48 (match_dup 5)))])
8291 (define_expand "addcarry<mode>_0"
8293 [(set (reg:CCC FLAGS_REG)
8296 (match_operand:SWI48 1 "nonimmediate_operand")
8297 (match_operand:SWI48 2 "x86_64_general_operand"))
8299 (set (match_operand:SWI48 0 "nonimmediate_operand")
8300 (plus:SWI48 (match_dup 1) (match_dup 2)))])]
8301 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)")
8303 (define_insn "*addcarry<mode>_1"
8304 [(set (reg:CCC FLAGS_REG)
8309 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8310 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8311 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
8312 (match_operand:SWI48 2 "x86_64_immediate_operand" "e")))
8314 (match_operand:<DWI> 6 "const_scalar_int_operand")
8315 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8316 [(match_dup 3) (const_int 0)]))))
8317 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
8318 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8319 [(match_dup 3) (const_int 0)])
8322 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
8323 && CONST_INT_P (operands[2])
8324 /* Check that operands[6] is operands[2] zero extended from
8325 <MODE>mode to <DWI>mode. */
8326 && ((<MODE>mode == SImode || INTVAL (operands[2]) >= 0)
8327 ? (CONST_INT_P (operands[6])
8328 && UINTVAL (operands[6]) == (UINTVAL (operands[2])
8329 & GET_MODE_MASK (<MODE>mode)))
8330 : (CONST_WIDE_INT_P (operands[6])
8331 && CONST_WIDE_INT_NUNITS (operands[6]) == 2
8332 && ((unsigned HOST_WIDE_INT) CONST_WIDE_INT_ELT (operands[6], 0)
8333 == UINTVAL (operands[2]))
8334 && CONST_WIDE_INT_ELT (operands[6], 1) == 0))"
8335 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
8336 [(set_attr "type" "alu")
8337 (set_attr "use_carry" "1")
8338 (set_attr "pent_pair" "pu")
8339 (set_attr "mode" "<MODE>")
8340 (set (attr "length_immediate")
8341 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
8343 (const_string "4")))])
8345 (define_insn "@sub<mode>3_carry"
8346 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
8349 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
8350 (match_operator:SWI 4 "ix86_carry_flag_operator"
8351 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
8352 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
8353 (clobber (reg:CC FLAGS_REG))]
8354 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
8355 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8356 [(set_attr "type" "alu")
8357 (set_attr "use_carry" "1")
8358 (set_attr "pent_pair" "pu")
8359 (set_attr "mode" "<MODE>")])
8362 [(set (match_operand:SWI 0 "general_reg_operand")
8363 (match_operand:SWI 1 "memory_operand"))
8364 (parallel [(set (match_dup 0)
8368 (match_operator:SWI 4 "ix86_carry_flag_operator"
8369 [(match_operand 3 "flags_reg_operand")
8371 (match_operand:SWI 2 "memory_operand")))
8372 (clobber (reg:CC FLAGS_REG))])
8373 (set (match_dup 1) (match_dup 0))]
8374 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8375 && peep2_reg_dead_p (3, operands[0])
8376 && !reg_overlap_mentioned_p (operands[0], operands[1])
8377 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8378 [(set (match_dup 0) (match_dup 2))
8379 (parallel [(set (match_dup 1)
8380 (minus:SWI (minus:SWI (match_dup 1)
8382 [(match_dup 3) (const_int 0)]))
8384 (clobber (reg:CC FLAGS_REG))])])
8387 [(set (match_operand:SWI 0 "general_reg_operand")
8388 (match_operand:SWI 1 "memory_operand"))
8389 (parallel [(set (match_dup 0)
8393 (match_operator:SWI 4 "ix86_carry_flag_operator"
8394 [(match_operand 3 "flags_reg_operand")
8396 (match_operand:SWI 2 "memory_operand")))
8397 (clobber (reg:CC FLAGS_REG))])
8398 (set (match_operand:SWI 5 "general_reg_operand") (match_dup 0))
8399 (set (match_dup 1) (match_dup 5))]
8400 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8401 && peep2_reg_dead_p (3, operands[0])
8402 && peep2_reg_dead_p (4, operands[5])
8403 && !reg_overlap_mentioned_p (operands[0], operands[1])
8404 && !reg_overlap_mentioned_p (operands[0], operands[2])
8405 && !reg_overlap_mentioned_p (operands[5], operands[1])"
8406 [(set (match_dup 0) (match_dup 2))
8407 (parallel [(set (match_dup 1)
8408 (minus:SWI (minus:SWI (match_dup 1)
8410 [(match_dup 3) (const_int 0)]))
8412 (clobber (reg:CC FLAGS_REG))])])
8414 (define_insn "*sub<mode>3_carry_0"
8415 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8417 (match_operand:SWI 1 "nonimmediate_operand" "0")
8418 (match_operator:SWI 2 "ix86_carry_flag_operator"
8419 [(reg FLAGS_REG) (const_int 0)])))
8420 (clobber (reg:CC FLAGS_REG))]
8421 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8422 "sbb{<imodesuffix>}\t{$0, %0|%0, 0}"
8423 [(set_attr "type" "alu")
8424 (set_attr "use_carry" "1")
8425 (set_attr "pent_pair" "pu")
8426 (set_attr "mode" "<MODE>")])
8428 (define_insn "*sub<mode>3_carry_0r"
8429 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8431 (match_operand:SWI 1 "nonimmediate_operand" "0")
8432 (match_operator:SWI 2 "ix86_carry_flag_unset_operator"
8433 [(reg FLAGS_REG) (const_int 0)])))
8434 (clobber (reg:CC FLAGS_REG))]
8435 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8436 "adc{<imodesuffix>}\t{$-1, %0|%0, -1}"
8437 [(set_attr "type" "alu")
8438 (set_attr "use_carry" "1")
8439 (set_attr "pent_pair" "pu")
8440 (set_attr "mode" "<MODE>")])
8442 (define_insn "*subsi3_carry_zext"
8443 [(set (match_operand:DI 0 "register_operand" "=r")
8447 (match_operand:SI 1 "register_operand" "0")
8448 (match_operator:SI 3 "ix86_carry_flag_operator"
8449 [(reg FLAGS_REG) (const_int 0)]))
8450 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
8451 (clobber (reg:CC FLAGS_REG))]
8452 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
8453 "sbb{l}\t{%2, %k0|%k0, %2}"
8454 [(set_attr "type" "alu")
8455 (set_attr "use_carry" "1")
8456 (set_attr "pent_pair" "pu")
8457 (set_attr "mode" "SI")])
8459 (define_insn "*subsi3_carry_zext_0"
8460 [(set (match_operand:DI 0 "register_operand" "=r")
8463 (match_operand:SI 1 "register_operand" "0")
8464 (match_operator:SI 2 "ix86_carry_flag_operator"
8465 [(reg FLAGS_REG) (const_int 0)]))))
8466 (clobber (reg:CC FLAGS_REG))]
8468 "sbb{l}\t{$0, %k0|%k0, 0}"
8469 [(set_attr "type" "alu")
8470 (set_attr "use_carry" "1")
8471 (set_attr "pent_pair" "pu")
8472 (set_attr "mode" "SI")])
8474 (define_insn "*subsi3_carry_zext_0r"
8475 [(set (match_operand:DI 0 "register_operand" "=r")
8478 (match_operand:SI 1 "register_operand" "0")
8479 (match_operator:SI 2 "ix86_carry_flag_unset_operator"
8480 [(reg FLAGS_REG) (const_int 0)]))))
8481 (clobber (reg:CC FLAGS_REG))]
8483 "adc{l}\t{$-1, %k0|%k0, -1}"
8484 [(set_attr "type" "alu")
8485 (set_attr "use_carry" "1")
8486 (set_attr "pent_pair" "pu")
8487 (set_attr "mode" "SI")])
8489 (define_insn "@sub<mode>3_carry_ccc"
8490 [(set (reg:CCC FLAGS_REG)
8492 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
8494 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
8496 (match_operand:DWIH 2 "x86_64_sext_operand" "rmWe")))))
8497 (clobber (match_scratch:DWIH 0 "=r"))]
8499 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8500 [(set_attr "type" "alu")
8501 (set_attr "mode" "<MODE>")])
8503 (define_insn "*sub<mode>3_carry_ccc_1"
8504 [(set (reg:CCC FLAGS_REG)
8506 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
8508 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
8509 (match_operand:<DWI> 2 "x86_64_dwzext_immediate_operand" "Wf"))))
8510 (clobber (match_scratch:DWIH 0 "=r"))]
8513 operands[3] = simplify_subreg (<MODE>mode, operands[2], <DWI>mode, 0);
8514 return "sbb{<imodesuffix>}\t{%3, %0|%0, %3}";
8516 [(set_attr "type" "alu")
8517 (set_attr "mode" "<MODE>")])
8519 ;; The sign flag is set from the
8520 ;; (compare (match_dup 1) (plus:DWIH (ltu:DWIH ...) (match_dup 2)))
8521 ;; result, the overflow flag likewise, but the overflow flag is also
8522 ;; set if the (plus:DWIH (ltu:DWIH ...) (match_dup 2)) overflows.
8523 (define_insn "@sub<mode>3_carry_ccgz"
8524 [(set (reg:CCGZ FLAGS_REG)
8525 (unspec:CCGZ [(match_operand:DWIH 1 "register_operand" "0")
8526 (match_operand:DWIH 2 "x86_64_general_operand" "rBMe")
8527 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))]
8529 (clobber (match_scratch:DWIH 0 "=r"))]
8531 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8532 [(set_attr "type" "alu")
8533 (set_attr "mode" "<MODE>")])
8535 (define_insn "subborrow<mode>"
8536 [(set (reg:CCC FLAGS_REG)
8539 (match_operand:SWI48 1 "nonimmediate_operand" "0,0"))
8541 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8542 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8544 (match_operand:SWI48 2 "nonimmediate_operand" "r,rm")))))
8545 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
8546 (minus:SWI48 (minus:SWI48
8548 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8549 [(match_dup 3) (const_int 0)]))
8551 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
8552 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8553 [(set_attr "type" "alu")
8554 (set_attr "use_carry" "1")
8555 (set_attr "pent_pair" "pu")
8556 (set_attr "mode" "<MODE>")])
8559 [(set (match_operand:SWI48 0 "general_reg_operand")
8560 (match_operand:SWI48 1 "memory_operand"))
8561 (parallel [(set (reg:CCC FLAGS_REG)
8563 (zero_extend:<DWI> (match_dup 0))
8565 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8566 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8568 (match_operand:SWI48 2 "memory_operand")))))
8573 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8574 [(match_dup 3) (const_int 0)]))
8576 (set (match_dup 1) (match_dup 0))]
8577 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8578 && peep2_reg_dead_p (3, operands[0])
8579 && !reg_overlap_mentioned_p (operands[0], operands[1])
8580 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8581 [(set (match_dup 0) (match_dup 2))
8582 (parallel [(set (reg:CCC FLAGS_REG)
8584 (zero_extend:<DWI> (match_dup 1))
8585 (plus:<DWI> (match_op_dup 4
8586 [(match_dup 3) (const_int 0)])
8587 (zero_extend:<DWI> (match_dup 0)))))
8589 (minus:SWI48 (minus:SWI48 (match_dup 1)
8591 [(match_dup 3) (const_int 0)]))
8595 [(set (match_operand:SWI48 6 "general_reg_operand")
8596 (match_operand:SWI48 7 "memory_operand"))
8597 (set (match_operand:SWI48 8 "general_reg_operand")
8598 (match_operand:SWI48 9 "memory_operand"))
8599 (parallel [(set (reg:CCC FLAGS_REG)
8602 (match_operand:SWI48 0 "general_reg_operand"))
8604 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8605 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8607 (match_operand:SWI48 2 "general_reg_operand")))))
8612 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8613 [(match_dup 3) (const_int 0)]))
8615 (set (match_operand:SWI48 1 "memory_operand") (match_dup 0))]
8616 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8617 && peep2_reg_dead_p (4, operands[0])
8618 && peep2_reg_dead_p (3, operands[2])
8619 && !reg_overlap_mentioned_p (operands[0], operands[1])
8620 && !reg_overlap_mentioned_p (operands[2], operands[1])
8621 && !reg_overlap_mentioned_p (operands[6], operands[9])
8622 && (rtx_equal_p (operands[6], operands[0])
8623 ? (rtx_equal_p (operands[7], operands[1])
8624 && rtx_equal_p (operands[8], operands[2]))
8625 : (rtx_equal_p (operands[8], operands[0])
8626 && rtx_equal_p (operands[9], operands[1])
8627 && rtx_equal_p (operands[6], operands[2])))"
8628 [(set (match_dup 0) (match_dup 9))
8629 (parallel [(set (reg:CCC FLAGS_REG)
8631 (zero_extend:<DWI> (match_dup 1))
8632 (plus:<DWI> (match_op_dup 4
8633 [(match_dup 3) (const_int 0)])
8634 (zero_extend:<DWI> (match_dup 0)))))
8636 (minus:SWI48 (minus:SWI48 (match_dup 1)
8638 [(match_dup 3) (const_int 0)]))
8641 if (!rtx_equal_p (operands[6], operands[0]))
8642 operands[9] = operands[7];
8646 [(set (match_operand:SWI48 6 "general_reg_operand")
8647 (match_operand:SWI48 7 "memory_operand"))
8648 (set (match_operand:SWI48 8 "general_reg_operand")
8649 (match_operand:SWI48 9 "memory_operand"))
8650 (parallel [(set (reg:CCC FLAGS_REG)
8653 (match_operand:SWI48 0 "general_reg_operand"))
8655 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8656 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8658 (match_operand:SWI48 2 "general_reg_operand")))))
8663 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8664 [(match_dup 3) (const_int 0)]))
8666 (set (match_operand:QI 10 "general_reg_operand")
8667 (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8668 (set (match_operand:SWI48 11 "general_reg_operand")
8669 (zero_extend:SWI48 (match_dup 10)))
8670 (set (match_operand:SWI48 1 "memory_operand") (match_dup 0))]
8671 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8672 && peep2_reg_dead_p (6, operands[0])
8673 && peep2_reg_dead_p (3, operands[2])
8674 && !reg_overlap_mentioned_p (operands[0], operands[1])
8675 && !reg_overlap_mentioned_p (operands[2], operands[1])
8676 && !reg_overlap_mentioned_p (operands[6], operands[9])
8677 && !reg_overlap_mentioned_p (operands[0], operands[10])
8678 && !reg_overlap_mentioned_p (operands[10], operands[1])
8679 && !reg_overlap_mentioned_p (operands[0], operands[11])
8680 && !reg_overlap_mentioned_p (operands[11], operands[1])
8681 && (rtx_equal_p (operands[6], operands[0])
8682 ? (rtx_equal_p (operands[7], operands[1])
8683 && rtx_equal_p (operands[8], operands[2]))
8684 : (rtx_equal_p (operands[8], operands[0])
8685 && rtx_equal_p (operands[9], operands[1])
8686 && rtx_equal_p (operands[6], operands[2])))"
8687 [(set (match_dup 0) (match_dup 9))
8688 (parallel [(set (reg:CCC FLAGS_REG)
8690 (zero_extend:<DWI> (match_dup 1))
8691 (plus:<DWI> (match_op_dup 4
8692 [(match_dup 3) (const_int 0)])
8693 (zero_extend:<DWI> (match_dup 0)))))
8695 (minus:SWI48 (minus:SWI48 (match_dup 1)
8697 [(match_dup 3) (const_int 0)]))
8699 (set (match_dup 10) (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8700 (set (match_dup 11) (zero_extend:SWI48 (match_dup 10)))]
8702 if (!rtx_equal_p (operands[6], operands[0]))
8703 operands[9] = operands[7];
8706 (define_expand "subborrow<mode>_0"
8708 [(set (reg:CC FLAGS_REG)
8710 (match_operand:SWI48 1 "nonimmediate_operand")
8711 (match_operand:SWI48 2 "<general_operand>")))
8712 (set (match_operand:SWI48 0 "register_operand")
8713 (minus:SWI48 (match_dup 1) (match_dup 2)))])]
8714 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)")
8716 (define_expand "uaddc<mode>5"
8717 [(match_operand:SWI48 0 "register_operand")
8718 (match_operand:SWI48 1 "register_operand")
8719 (match_operand:SWI48 2 "register_operand")
8720 (match_operand:SWI48 3 "register_operand")
8721 (match_operand:SWI48 4 "nonmemory_operand")]
8724 rtx cf = gen_rtx_REG (CCCmode, FLAGS_REG), pat, pat2;
8725 if (operands[4] == const0_rtx)
8726 emit_insn (gen_addcarry<mode>_0 (operands[0], operands[2], operands[3]));
8729 ix86_expand_carry (operands[4]);
8730 pat = gen_rtx_LTU (<DWI>mode, cf, const0_rtx);
8731 pat2 = gen_rtx_LTU (<MODE>mode, cf, const0_rtx);
8732 emit_insn (gen_addcarry<mode> (operands[0], operands[2], operands[3],
8735 rtx cc = gen_reg_rtx (QImode);
8736 pat = gen_rtx_LTU (QImode, cf, const0_rtx);
8737 emit_insn (gen_rtx_SET (cc, pat));
8738 emit_insn (gen_zero_extendqi<mode>2 (operands[1], cc));
8742 (define_expand "usubc<mode>5"
8743 [(match_operand:SWI48 0 "register_operand")
8744 (match_operand:SWI48 1 "register_operand")
8745 (match_operand:SWI48 2 "register_operand")
8746 (match_operand:SWI48 3 "register_operand")
8747 (match_operand:SWI48 4 "nonmemory_operand")]
8751 if (operands[4] == const0_rtx)
8753 cf = gen_rtx_REG (CCmode, FLAGS_REG);
8754 emit_insn (gen_subborrow<mode>_0 (operands[0], operands[2],
8759 cf = gen_rtx_REG (CCCmode, FLAGS_REG);
8760 ix86_expand_carry (operands[4]);
8761 pat = gen_rtx_LTU (<DWI>mode, cf, const0_rtx);
8762 pat2 = gen_rtx_LTU (<MODE>mode, cf, const0_rtx);
8763 emit_insn (gen_subborrow<mode> (operands[0], operands[2], operands[3],
8766 rtx cc = gen_reg_rtx (QImode);
8767 pat = gen_rtx_LTU (QImode, cf, const0_rtx);
8768 emit_insn (gen_rtx_SET (cc, pat));
8769 emit_insn (gen_zero_extendqi<mode>2 (operands[1], cc));
8773 (define_mode_iterator CC_CCC [CC CCC])
8775 ;; Pre-reload splitter to optimize
8776 ;; *setcc_qi followed by *addqi3_cconly_overflow_1 with the same QI
8777 ;; operand and no intervening flags modifications into nothing.
8778 (define_insn_and_split "*setcc_qi_addqi3_cconly_overflow_1_<mode>"
8779 [(set (reg:CCC FLAGS_REG)
8780 (compare:CCC (neg:QI (geu:QI (reg:CC_CCC FLAGS_REG) (const_int 0)))
8781 (ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))))]
8782 "ix86_pre_reload_split ()"
8786 "emit_note (NOTE_INSN_DELETED); DONE;")
8788 ;; Set the carry flag from the carry flag.
8789 (define_insn_and_split "*setccc"
8790 [(set (reg:CCC FLAGS_REG)
8791 (reg:CCC FLAGS_REG))]
8792 "ix86_pre_reload_split ()"
8796 "emit_note (NOTE_INSN_DELETED); DONE;")
8798 ;; Set the carry flag from the carry flag.
8799 (define_insn_and_split "*setcc_qi_negqi_ccc_1_<mode>"
8800 [(set (reg:CCC FLAGS_REG)
8801 (ltu:CCC (reg:CC_CCC FLAGS_REG) (const_int 0)))]
8802 "ix86_pre_reload_split ()"
8806 "emit_note (NOTE_INSN_DELETED); DONE;")
8808 ;; Set the carry flag from the carry flag.
8809 (define_insn_and_split "*setcc_qi_negqi_ccc_2_<mode>"
8810 [(set (reg:CCC FLAGS_REG)
8811 (unspec:CCC [(ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))
8812 (const_int 0)] UNSPEC_CC_NE))]
8813 "ix86_pre_reload_split ()"
8817 "emit_note (NOTE_INSN_DELETED); DONE;")
8819 ;; Overflow setting add instructions
8821 (define_expand "addqi3_cconly_overflow"
8823 [(set (reg:CCC FLAGS_REG)
8826 (match_operand:QI 0 "nonimmediate_operand")
8827 (match_operand:QI 1 "general_operand"))
8829 (clobber (scratch:QI))])]
8830 "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
8832 (define_insn "*add<mode>3_cconly_overflow_1"
8833 [(set (reg:CCC FLAGS_REG)
8836 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8837 (match_operand:SWI 2 "<general_operand>" "<g>"))
8839 (clobber (match_scratch:SWI 0 "=<r>"))]
8840 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8841 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
8842 [(set_attr "type" "alu")
8843 (set_attr "mode" "<MODE>")])
8845 (define_insn "*add<mode>3_cc_overflow_1"
8846 [(set (reg:CCC FLAGS_REG)
8849 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8850 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
8852 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
8853 (plus:SWI (match_dup 1) (match_dup 2)))]
8854 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
8855 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
8856 [(set_attr "type" "alu")
8857 (set_attr "mode" "<MODE>")])
8860 [(parallel [(set (reg:CCC FLAGS_REG)
8862 (plus:SWI (match_operand:SWI 0 "general_reg_operand")
8863 (match_operand:SWI 1 "memory_operand"))
8865 (set (match_dup 0) (plus:SWI (match_dup 0) (match_dup 1)))])
8866 (set (match_dup 1) (match_dup 0))]
8867 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8868 && peep2_reg_dead_p (2, operands[0])
8869 && !reg_overlap_mentioned_p (operands[0], operands[1])"
8870 [(parallel [(set (reg:CCC FLAGS_REG)
8872 (plus:SWI (match_dup 1) (match_dup 0))
8874 (set (match_dup 1) (plus:SWI (match_dup 1) (match_dup 0)))])])
8877 [(set (match_operand:SWI 0 "general_reg_operand")
8878 (match_operand:SWI 1 "memory_operand"))
8879 (parallel [(set (reg:CCC FLAGS_REG)
8881 (plus:SWI (match_dup 0)
8882 (match_operand:SWI 2 "memory_operand"))
8884 (set (match_dup 0) (plus:SWI (match_dup 0) (match_dup 2)))])
8885 (set (match_dup 1) (match_dup 0))]
8886 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8887 && peep2_reg_dead_p (3, operands[0])
8888 && !reg_overlap_mentioned_p (operands[0], operands[1])
8889 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8890 [(set (match_dup 0) (match_dup 2))
8891 (parallel [(set (reg:CCC FLAGS_REG)
8893 (plus:SWI (match_dup 1) (match_dup 0))
8895 (set (match_dup 1) (plus:SWI (match_dup 1) (match_dup 0)))])])
8897 (define_insn "*addsi3_zext_cc_overflow_1"
8898 [(set (reg:CCC FLAGS_REG)
8901 (match_operand:SI 1 "nonimmediate_operand" "%0")
8902 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
8904 (set (match_operand:DI 0 "register_operand" "=r")
8905 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8906 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
8907 "add{l}\t{%2, %k0|%k0, %2}"
8908 [(set_attr "type" "alu")
8909 (set_attr "mode" "SI")])
8911 (define_insn "*add<mode>3_cconly_overflow_2"
8912 [(set (reg:CCC FLAGS_REG)
8915 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8916 (match_operand:SWI 2 "<general_operand>" "<g>"))
8918 (clobber (match_scratch:SWI 0 "=<r>"))]
8919 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8920 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
8921 [(set_attr "type" "alu")
8922 (set_attr "mode" "<MODE>")])
8924 (define_insn "*add<mode>3_cc_overflow_2"
8925 [(set (reg:CCC FLAGS_REG)
8928 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8929 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
8931 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
8932 (plus:SWI (match_dup 1) (match_dup 2)))]
8933 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
8934 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
8935 [(set_attr "type" "alu")
8936 (set_attr "mode" "<MODE>")])
8938 (define_insn "*addsi3_zext_cc_overflow_2"
8939 [(set (reg:CCC FLAGS_REG)
8942 (match_operand:SI 1 "nonimmediate_operand" "%0")
8943 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
8945 (set (match_operand:DI 0 "register_operand" "=r")
8946 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8947 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
8948 "add{l}\t{%2, %k0|%k0, %2}"
8949 [(set_attr "type" "alu")
8950 (set_attr "mode" "SI")])
8952 (define_insn_and_split "*add<dwi>3_doubleword_cc_overflow_1"
8953 [(set (reg:CCC FLAGS_REG)
8956 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
8957 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o"))
8959 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
8960 (plus:<DWI> (match_dup 1) (match_dup 2)))]
8961 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
8963 "&& reload_completed"
8964 [(parallel [(set (reg:CCC FLAGS_REG)
8966 (plus:DWIH (match_dup 1) (match_dup 2))
8969 (plus:DWIH (match_dup 1) (match_dup 2)))])
8970 (parallel [(set (reg:CCC FLAGS_REG)
8975 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8980 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))))
8983 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8987 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
8988 if (operands[2] == const0_rtx)
8990 emit_insn (gen_addcarry<mode>_0 (operands[3], operands[4], operands[5]));
8993 if (CONST_INT_P (operands[5]))
8994 operands[6] = simplify_unary_operation (ZERO_EXTEND, <DWI>mode,
8995 operands[5], <MODE>mode);
8997 operands[6] = gen_rtx_ZERO_EXTEND (<DWI>mode, operands[5]);
9000 ;; x == 0 with zero flag test can be done also as x < 1U with carry flag
9001 ;; test, where the latter is preferrable if we have some carry consuming
9003 ;; For x != 0, we need to use x < 1U with negation of carry, i.e.
9005 (define_insn_and_split "*add<mode>3_eq"
9006 [(set (match_operand:SWI 0 "nonimmediate_operand")
9009 (eq:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0))
9010 (match_operand:SWI 1 "nonimmediate_operand"))
9011 (match_operand:SWI 2 "<general_operand>")))
9012 (clobber (reg:CC FLAGS_REG))]
9013 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
9014 && ix86_pre_reload_split ()"
9017 [(set (reg:CC FLAGS_REG)
9018 (compare:CC (match_dup 3) (const_int 1)))
9019 (parallel [(set (match_dup 0)
9021 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9024 (clobber (reg:CC FLAGS_REG))])])
9026 (define_insn_and_split "*add<mode>3_ne"
9027 [(set (match_operand:SWI 0 "nonimmediate_operand")
9030 (ne:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0))
9031 (match_operand:SWI 1 "nonimmediate_operand"))
9032 (match_operand:SWI 2 "<immediate_operand>")))
9033 (clobber (reg:CC FLAGS_REG))]
9034 "CONST_INT_P (operands[2])
9035 && (<MODE>mode != DImode
9036 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
9037 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
9038 && ix86_pre_reload_split ()"
9041 [(set (reg:CC FLAGS_REG)
9042 (compare:CC (match_dup 3) (const_int 1)))
9043 (parallel [(set (match_dup 0)
9045 (minus:SWI (match_dup 1)
9046 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9048 (clobber (reg:CC FLAGS_REG))])]
9050 operands[2] = gen_int_mode (~INTVAL (operands[2]),
9051 <MODE>mode == DImode ? SImode : <MODE>mode);
9054 (define_insn_and_split "*add<mode>3_eq_0"
9055 [(set (match_operand:SWI 0 "nonimmediate_operand")
9057 (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))
9058 (match_operand:SWI 1 "<general_operand>")))
9059 (clobber (reg:CC FLAGS_REG))]
9060 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)
9061 && ix86_pre_reload_split ()"
9064 [(set (reg:CC FLAGS_REG)
9065 (compare:CC (match_dup 2) (const_int 1)))
9066 (parallel [(set (match_dup 0)
9067 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9069 (clobber (reg:CC FLAGS_REG))])]
9071 if (!nonimmediate_operand (operands[1], <MODE>mode))
9072 operands[1] = force_reg (<MODE>mode, operands[1]);
9075 (define_insn_and_split "*add<mode>3_ne_0"
9076 [(set (match_operand:SWI 0 "nonimmediate_operand")
9078 (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))
9079 (match_operand:SWI 1 "<general_operand>")))
9080 (clobber (reg:CC FLAGS_REG))]
9081 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)
9082 && ix86_pre_reload_split ()"
9085 [(set (reg:CC FLAGS_REG)
9086 (compare:CC (match_dup 2) (const_int 1)))
9087 (parallel [(set (match_dup 0)
9088 (minus:SWI (minus:SWI
9090 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9092 (clobber (reg:CC FLAGS_REG))])]
9094 if (!nonimmediate_operand (operands[1], <MODE>mode))
9095 operands[1] = force_reg (<MODE>mode, operands[1]);
9098 (define_insn_and_split "*sub<mode>3_eq"
9099 [(set (match_operand:SWI 0 "nonimmediate_operand")
9102 (match_operand:SWI 1 "nonimmediate_operand")
9103 (eq:SWI (match_operand 3 "int_nonimmediate_operand")
9105 (match_operand:SWI 2 "<general_operand>")))
9106 (clobber (reg:CC FLAGS_REG))]
9107 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
9108 && ix86_pre_reload_split ()"
9111 [(set (reg:CC FLAGS_REG)
9112 (compare:CC (match_dup 3) (const_int 1)))
9113 (parallel [(set (match_dup 0)
9115 (minus:SWI (match_dup 1)
9116 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9118 (clobber (reg:CC FLAGS_REG))])])
9120 (define_insn_and_split "*sub<mode>3_ne"
9121 [(set (match_operand:SWI 0 "nonimmediate_operand")
9124 (match_operand:SWI 1 "nonimmediate_operand")
9125 (ne:SWI (match_operand 3 "int_nonimmediate_operand")
9127 (match_operand:SWI 2 "<immediate_operand>")))
9128 (clobber (reg:CC FLAGS_REG))]
9129 "CONST_INT_P (operands[2])
9130 && (<MODE>mode != DImode
9131 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
9132 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
9133 && ix86_pre_reload_split ()"
9136 [(set (reg:CC FLAGS_REG)
9137 (compare:CC (match_dup 3) (const_int 1)))
9138 (parallel [(set (match_dup 0)
9140 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9143 (clobber (reg:CC FLAGS_REG))])]
9145 operands[2] = gen_int_mode (INTVAL (operands[2]) - 1,
9146 <MODE>mode == DImode ? SImode : <MODE>mode);
9149 (define_insn_and_split "*sub<mode>3_eq_1"
9150 [(set (match_operand:SWI 0 "nonimmediate_operand")
9153 (match_operand:SWI 1 "nonimmediate_operand")
9154 (eq:SWI (match_operand 3 "int_nonimmediate_operand")
9156 (match_operand:SWI 2 "<immediate_operand>")))
9157 (clobber (reg:CC FLAGS_REG))]
9158 "CONST_INT_P (operands[2])
9159 && (<MODE>mode != DImode
9160 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
9161 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
9162 && ix86_pre_reload_split ()"
9165 [(set (reg:CC FLAGS_REG)
9166 (compare:CC (match_dup 3) (const_int 1)))
9167 (parallel [(set (match_dup 0)
9169 (minus:SWI (match_dup 1)
9170 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9172 (clobber (reg:CC FLAGS_REG))])]
9174 operands[2] = gen_int_mode (-INTVAL (operands[2]),
9175 <MODE>mode == DImode ? SImode : <MODE>mode);
9178 (define_insn_and_split "*sub<mode>3_eq_0"
9179 [(set (match_operand:SWI 0 "nonimmediate_operand")
9181 (match_operand:SWI 1 "<general_operand>")
9182 (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))))
9183 (clobber (reg:CC FLAGS_REG))]
9184 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)
9185 && ix86_pre_reload_split ()"
9188 [(set (reg:CC FLAGS_REG)
9189 (compare:CC (match_dup 2) (const_int 1)))
9190 (parallel [(set (match_dup 0)
9191 (minus:SWI (match_dup 1)
9192 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))))
9193 (clobber (reg:CC FLAGS_REG))])]
9195 if (!nonimmediate_operand (operands[1], <MODE>mode))
9196 operands[1] = force_reg (<MODE>mode, operands[1]);
9199 (define_insn_and_split "*sub<mode>3_ne_0"
9200 [(set (match_operand:SWI 0 "nonimmediate_operand")
9202 (match_operand:SWI 1 "<general_operand>")
9203 (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))))
9204 (clobber (reg:CC FLAGS_REG))]
9205 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)
9206 && ix86_pre_reload_split ()"
9209 [(set (reg:CC FLAGS_REG)
9210 (compare:CC (match_dup 2) (const_int 1)))
9211 (parallel [(set (match_dup 0)
9213 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9216 (clobber (reg:CC FLAGS_REG))])]
9218 if (!nonimmediate_operand (operands[1], <MODE>mode))
9219 operands[1] = force_reg (<MODE>mode, operands[1]);
9222 ;; The patterns that match these are at the end of this file.
9224 (define_expand "<insn>xf3"
9225 [(set (match_operand:XF 0 "register_operand")
9227 (match_operand:XF 1 "register_operand")
9228 (match_operand:XF 2 "register_operand")))]
9231 (define_expand "<insn>hf3"
9232 [(set (match_operand:HF 0 "register_operand")
9234 (match_operand:HF 1 "register_operand")
9235 (match_operand:HF 2 "nonimmediate_operand")))]
9236 "TARGET_AVX512FP16")
9238 (define_expand "<insn><mode>3"
9239 [(set (match_operand:MODEF 0 "register_operand")
9241 (match_operand:MODEF 1 "register_operand")
9242 (match_operand:MODEF 2 "nonimmediate_operand")))]
9243 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
9244 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
9246 ;; Multiply instructions
9248 (define_expand "mul<mode>3"
9249 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
9251 (match_operand:SWIM248 1 "register_operand")
9252 (match_operand:SWIM248 2 "<general_operand>")))
9253 (clobber (reg:CC FLAGS_REG))])])
9255 (define_expand "mulqi3"
9256 [(parallel [(set (match_operand:QI 0 "register_operand")
9258 (match_operand:QI 1 "register_operand")
9259 (match_operand:QI 2 "nonimmediate_operand")))
9260 (clobber (reg:CC FLAGS_REG))])]
9261 "TARGET_QIMODE_MATH")
9264 ;; IMUL reg32/64, reg32/64, imm8 Direct
9265 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
9266 ;; IMUL reg32/64, reg32/64, imm32 Direct
9267 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
9268 ;; IMUL reg32/64, reg32/64 Direct
9269 ;; IMUL reg32/64, mem32/64 Direct
9271 ;; On BDVER1, all above IMULs use DirectPath
9274 ;; IMUL reg16, reg16, imm8 VectorPath
9275 ;; IMUL reg16, mem16, imm8 VectorPath
9276 ;; IMUL reg16, reg16, imm16 VectorPath
9277 ;; IMUL reg16, mem16, imm16 VectorPath
9278 ;; IMUL reg16, reg16 Direct
9279 ;; IMUL reg16, mem16 Direct
9281 ;; On BDVER1, all HI MULs use DoublePath
9283 (define_insn "*mul<mode>3_1"
9284 [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
9286 (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
9287 (match_operand:SWIM248 2 "<general_operand>" "K,<i>,<m>r")))
9288 (clobber (reg:CC FLAGS_REG))]
9289 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9291 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9292 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9293 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
9294 [(set_attr "type" "imul")
9295 (set_attr "prefix_0f" "0,0,1")
9296 (set (attr "athlon_decode")
9297 (cond [(eq_attr "cpu" "athlon")
9298 (const_string "vector")
9299 (eq_attr "alternative" "1")
9300 (const_string "vector")
9301 (and (eq_attr "alternative" "2")
9302 (ior (match_test "<MODE>mode == HImode")
9303 (match_operand 1 "memory_operand")))
9304 (const_string "vector")]
9305 (const_string "direct")))
9306 (set (attr "amdfam10_decode")
9307 (cond [(and (eq_attr "alternative" "0,1")
9308 (ior (match_test "<MODE>mode == HImode")
9309 (match_operand 1 "memory_operand")))
9310 (const_string "vector")]
9311 (const_string "direct")))
9312 (set (attr "bdver1_decode")
9314 (match_test "<MODE>mode == HImode")
9315 (const_string "double")
9316 (const_string "direct")))
9317 (set_attr "mode" "<MODE>")])
9319 (define_insn "*mulsi3_1_zext"
9320 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9322 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
9323 (match_operand:SI 2 "x86_64_general_operand" "K,e,BMr"))))
9324 (clobber (reg:CC FLAGS_REG))]
9326 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9328 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
9329 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
9330 imul{l}\t{%2, %k0|%k0, %2}"
9331 [(set_attr "type" "imul")
9332 (set_attr "prefix_0f" "0,0,1")
9333 (set (attr "athlon_decode")
9334 (cond [(eq_attr "cpu" "athlon")
9335 (const_string "vector")
9336 (eq_attr "alternative" "1")
9337 (const_string "vector")
9338 (and (eq_attr "alternative" "2")
9339 (match_operand 1 "memory_operand"))
9340 (const_string "vector")]
9341 (const_string "direct")))
9342 (set (attr "amdfam10_decode")
9343 (cond [(and (eq_attr "alternative" "0,1")
9344 (match_operand 1 "memory_operand"))
9345 (const_string "vector")]
9346 (const_string "direct")))
9347 (set_attr "bdver1_decode" "direct")
9348 (set_attr "mode" "SI")])
9350 ;;On AMDFAM10 and BDVER1
9354 (define_insn "*mulqi3_1"
9355 [(set (match_operand:QI 0 "register_operand" "=a")
9356 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9357 (match_operand:QI 2 "nonimmediate_operand" "qm")))
9358 (clobber (reg:CC FLAGS_REG))]
9360 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9362 [(set_attr "type" "imul")
9363 (set_attr "length_immediate" "0")
9364 (set (attr "athlon_decode")
9365 (if_then_else (eq_attr "cpu" "athlon")
9366 (const_string "vector")
9367 (const_string "direct")))
9368 (set_attr "amdfam10_decode" "direct")
9369 (set_attr "bdver1_decode" "direct")
9370 (set_attr "mode" "QI")])
9372 ;; Multiply with jump on overflow.
9373 (define_expand "mulv<mode>4"
9374 [(parallel [(set (reg:CCO FLAGS_REG)
9377 (match_operand:SWI248 1 "register_operand"))
9380 (mult:SWI248 (match_dup 1)
9381 (match_operand:SWI248 2
9382 "<general_operand>")))))
9383 (set (match_operand:SWI248 0 "register_operand")
9384 (mult:SWI248 (match_dup 1) (match_dup 2)))])
9385 (set (pc) (if_then_else
9386 (eq (reg:CCO FLAGS_REG) (const_int 0))
9387 (label_ref (match_operand 3))
9391 if (CONST_INT_P (operands[2]))
9392 operands[4] = operands[2];
9394 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
9397 (define_insn "*mulv<mode>4"
9398 [(set (reg:CCO FLAGS_REG)
9401 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
9403 (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
9405 (mult:SWI48 (match_dup 1) (match_dup 2)))))
9406 (set (match_operand:SWI48 0 "register_operand" "=r,r")
9407 (mult:SWI48 (match_dup 1) (match_dup 2)))]
9408 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9410 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9411 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
9412 [(set_attr "type" "imul")
9413 (set_attr "prefix_0f" "0,1")
9414 (set (attr "athlon_decode")
9415 (cond [(eq_attr "cpu" "athlon")
9416 (const_string "vector")
9417 (eq_attr "alternative" "0")
9418 (const_string "vector")
9419 (and (eq_attr "alternative" "1")
9420 (match_operand 1 "memory_operand"))
9421 (const_string "vector")]
9422 (const_string "direct")))
9423 (set (attr "amdfam10_decode")
9424 (cond [(and (eq_attr "alternative" "1")
9425 (match_operand 1 "memory_operand"))
9426 (const_string "vector")]
9427 (const_string "direct")))
9428 (set_attr "bdver1_decode" "direct")
9429 (set_attr "mode" "<MODE>")])
9431 (define_insn "*mulvhi4"
9432 [(set (reg:CCO FLAGS_REG)
9435 (match_operand:HI 1 "nonimmediate_operand" "%0"))
9437 (match_operand:HI 2 "nonimmediate_operand" "mr")))
9439 (mult:HI (match_dup 1) (match_dup 2)))))
9440 (set (match_operand:HI 0 "register_operand" "=r")
9441 (mult:HI (match_dup 1) (match_dup 2)))]
9442 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9443 "imul{w}\t{%2, %0|%0, %2}"
9444 [(set_attr "type" "imul")
9445 (set_attr "prefix_0f" "1")
9446 (set_attr "athlon_decode" "vector")
9447 (set_attr "amdfam10_decode" "direct")
9448 (set_attr "bdver1_decode" "double")
9449 (set_attr "mode" "HI")])
9451 (define_insn "*mulv<mode>4_1"
9452 [(set (reg:CCO FLAGS_REG)
9455 (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
9456 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
9458 (mult:SWI248 (match_dup 1)
9459 (match_operand:SWI248 2
9460 "<immediate_operand>" "K,<i>")))))
9461 (set (match_operand:SWI248 0 "register_operand" "=r,r")
9462 (mult:SWI248 (match_dup 1) (match_dup 2)))]
9463 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
9464 && CONST_INT_P (operands[2])
9465 && INTVAL (operands[2]) == INTVAL (operands[3])"
9466 "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
9467 [(set_attr "type" "imul")
9468 (set (attr "prefix_0f")
9470 (match_test "<MODE>mode == HImode")
9472 (const_string "*")))
9473 (set (attr "athlon_decode")
9474 (cond [(eq_attr "cpu" "athlon")
9475 (const_string "vector")
9476 (eq_attr "alternative" "1")
9477 (const_string "vector")]
9478 (const_string "direct")))
9479 (set (attr "amdfam10_decode")
9480 (cond [(ior (match_test "<MODE>mode == HImode")
9481 (match_operand 1 "memory_operand"))
9482 (const_string "vector")]
9483 (const_string "direct")))
9484 (set (attr "bdver1_decode")
9486 (match_test "<MODE>mode == HImode")
9487 (const_string "double")
9488 (const_string "direct")))
9489 (set_attr "mode" "<MODE>")
9490 (set (attr "length_immediate")
9491 (cond [(eq_attr "alternative" "0")
9493 (match_test "<MODE_SIZE> == 8")
9495 (const_string "<MODE_SIZE>")))])
9497 (define_expand "umulv<mode>4"
9498 [(parallel [(set (reg:CCO FLAGS_REG)
9501 (match_operand:SWI248 1
9502 "nonimmediate_operand"))
9504 (match_operand:SWI248 2
9505 "nonimmediate_operand")))
9507 (mult:SWI248 (match_dup 1) (match_dup 2)))))
9508 (set (match_operand:SWI248 0 "register_operand")
9509 (mult:SWI248 (match_dup 1) (match_dup 2)))
9510 (clobber (scratch:SWI248))])
9511 (set (pc) (if_then_else
9512 (eq (reg:CCO FLAGS_REG) (const_int 0))
9513 (label_ref (match_operand 3))
9517 if (MEM_P (operands[1]) && MEM_P (operands[2]))
9518 operands[1] = force_reg (<MODE>mode, operands[1]);
9521 (define_insn "*umulv<mode>4"
9522 [(set (reg:CCO FLAGS_REG)
9525 (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
9527 (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
9529 (mult:SWI248 (match_dup 1) (match_dup 2)))))
9530 (set (match_operand:SWI248 0 "register_operand" "=a")
9531 (mult:SWI248 (match_dup 1) (match_dup 2)))
9532 (clobber (match_scratch:SWI248 3 "=d"))]
9533 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9534 "mul{<imodesuffix>}\t%2"
9535 [(set_attr "type" "imul")
9536 (set_attr "length_immediate" "0")
9537 (set (attr "athlon_decode")
9538 (if_then_else (eq_attr "cpu" "athlon")
9539 (const_string "vector")
9540 (const_string "double")))
9541 (set_attr "amdfam10_decode" "double")
9542 (set_attr "bdver1_decode" "direct")
9543 (set_attr "mode" "<MODE>")])
9545 (define_expand "<u>mulvqi4"
9546 [(parallel [(set (reg:CCO FLAGS_REG)
9549 (match_operand:QI 1 "nonimmediate_operand"))
9551 (match_operand:QI 2 "nonimmediate_operand")))
9553 (mult:QI (match_dup 1) (match_dup 2)))))
9554 (set (match_operand:QI 0 "register_operand")
9555 (mult:QI (match_dup 1) (match_dup 2)))])
9556 (set (pc) (if_then_else
9557 (eq (reg:CCO FLAGS_REG) (const_int 0))
9558 (label_ref (match_operand 3))
9560 "TARGET_QIMODE_MATH"
9562 if (MEM_P (operands[1]) && MEM_P (operands[2]))
9563 operands[1] = force_reg (QImode, operands[1]);
9566 (define_insn "*<u>mulvqi4"
9567 [(set (reg:CCO FLAGS_REG)
9570 (match_operand:QI 1 "nonimmediate_operand" "%0"))
9572 (match_operand:QI 2 "nonimmediate_operand" "qm")))
9574 (mult:QI (match_dup 1) (match_dup 2)))))
9575 (set (match_operand:QI 0 "register_operand" "=a")
9576 (mult:QI (match_dup 1) (match_dup 2)))]
9578 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9579 "<sgnprefix>mul{b}\t%2"
9580 [(set_attr "type" "imul")
9581 (set_attr "length_immediate" "0")
9582 (set (attr "athlon_decode")
9583 (if_then_else (eq_attr "cpu" "athlon")
9584 (const_string "vector")
9585 (const_string "direct")))
9586 (set_attr "amdfam10_decode" "direct")
9587 (set_attr "bdver1_decode" "direct")
9588 (set_attr "mode" "QI")])
9590 (define_expand "<u>mul<mode><dwi>3"
9591 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
9594 (match_operand:DWIH 1 "nonimmediate_operand"))
9596 (match_operand:DWIH 2 "register_operand"))))
9597 (clobber (reg:CC FLAGS_REG))])])
9599 (define_expand "<u>mulqihi3"
9600 [(parallel [(set (match_operand:HI 0 "register_operand")
9603 (match_operand:QI 1 "nonimmediate_operand"))
9605 (match_operand:QI 2 "register_operand"))))
9606 (clobber (reg:CC FLAGS_REG))])]
9607 "TARGET_QIMODE_MATH")
9609 (define_insn "*bmi2_umul<mode><dwi>3_1"
9610 [(set (match_operand:DWIH 0 "register_operand" "=r")
9612 (match_operand:DWIH 2 "nonimmediate_operand" "%d")
9613 (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
9614 (set (match_operand:DWIH 1 "register_operand" "=r")
9617 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
9618 (zero_extend:<DWI> (match_dup 3)))
9619 (match_operand:QI 4 "const_int_operand"))))]
9620 "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
9621 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
9622 "mulx\t{%3, %0, %1|%1, %0, %3}"
9623 [(set_attr "type" "imulx")
9624 (set_attr "prefix" "vex")
9625 (set_attr "mode" "<MODE>")])
9627 (define_insn "*umul<mode><dwi>3_1"
9628 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
9631 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
9633 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
9634 (clobber (reg:CC FLAGS_REG))]
9635 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9638 mul{<imodesuffix>}\t%2"
9639 [(set_attr "isa" "bmi2,*")
9640 (set_attr "type" "imulx,imul")
9641 (set_attr "length_immediate" "*,0")
9642 (set (attr "athlon_decode")
9643 (cond [(eq_attr "alternative" "1")
9644 (if_then_else (eq_attr "cpu" "athlon")
9645 (const_string "vector")
9646 (const_string "double"))]
9647 (const_string "*")))
9648 (set_attr "amdfam10_decode" "*,double")
9649 (set_attr "bdver1_decode" "*,direct")
9650 (set_attr "prefix" "vex,orig")
9651 (set_attr "mode" "<MODE>")])
9653 ;; Convert mul to the mulx pattern to avoid flags dependency.
9655 [(set (match_operand:<DWI> 0 "register_operand")
9658 (match_operand:DWIH 1 "register_operand"))
9660 (match_operand:DWIH 2 "nonimmediate_operand"))))
9661 (clobber (reg:CC FLAGS_REG))]
9662 "TARGET_BMI2 && reload_completed
9663 && REGNO (operands[1]) == DX_REG"
9664 [(parallel [(set (match_dup 3)
9665 (mult:DWIH (match_dup 1) (match_dup 2)))
9669 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
9670 (zero_extend:<DWI> (match_dup 2)))
9673 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
9675 operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
9678 (define_insn "*mul<mode><dwi>3_1"
9679 [(set (match_operand:<DWI> 0 "register_operand" "=A")
9682 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
9684 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
9685 (clobber (reg:CC FLAGS_REG))]
9686 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9687 "imul{<imodesuffix>}\t%2"
9688 [(set_attr "type" "imul")
9689 (set_attr "length_immediate" "0")
9690 (set (attr "athlon_decode")
9691 (if_then_else (eq_attr "cpu" "athlon")
9692 (const_string "vector")
9693 (const_string "double")))
9694 (set_attr "amdfam10_decode" "double")
9695 (set_attr "bdver1_decode" "direct")
9696 (set_attr "mode" "<MODE>")])
9698 (define_insn "*<u>mulqihi3_1"
9699 [(set (match_operand:HI 0 "register_operand" "=a")
9702 (match_operand:QI 1 "nonimmediate_operand" "%0"))
9704 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
9705 (clobber (reg:CC FLAGS_REG))]
9707 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9708 "<sgnprefix>mul{b}\t%2"
9709 [(set_attr "type" "imul")
9710 (set_attr "length_immediate" "0")
9711 (set (attr "athlon_decode")
9712 (if_then_else (eq_attr "cpu" "athlon")
9713 (const_string "vector")
9714 (const_string "direct")))
9715 (set_attr "amdfam10_decode" "direct")
9716 (set_attr "bdver1_decode" "direct")
9717 (set_attr "mode" "QI")])
9719 ;; Highpart multiplication patterns
9720 (define_insn "<s>mul<mode>3_highpart"
9721 [(set (match_operand:DWIH 0 "register_operand" "=d")
9722 (any_mul_highpart:DWIH
9723 (match_operand:DWIH 1 "register_operand" "%a")
9724 (match_operand:DWIH 2 "nonimmediate_operand" "rm")))
9725 (clobber (match_scratch:DWIH 3 "=1"))
9726 (clobber (reg:CC FLAGS_REG))]
9728 "<sgnprefix>mul{<imodesuffix>}\t%2"
9729 [(set_attr "type" "imul")
9730 (set_attr "length_immediate" "0")
9731 (set (attr "athlon_decode")
9732 (if_then_else (eq_attr "cpu" "athlon")
9733 (const_string "vector")
9734 (const_string "double")))
9735 (set_attr "amdfam10_decode" "double")
9736 (set_attr "bdver1_decode" "direct")
9737 (set_attr "mode" "<MODE>")])
9739 (define_insn "*<s>mulsi3_highpart_zext"
9740 [(set (match_operand:DI 0 "register_operand" "=d")
9742 (any_mul_highpart:SI
9743 (match_operand:SI 1 "register_operand" "%a")
9744 (match_operand:SI 2 "nonimmediate_operand" "rm"))))
9745 (clobber (match_scratch:SI 3 "=1"))
9746 (clobber (reg:CC FLAGS_REG))]
9748 "<sgnprefix>mul{l}\t%2"
9749 [(set_attr "type" "imul")
9750 (set_attr "length_immediate" "0")
9751 (set (attr "athlon_decode")
9752 (if_then_else (eq_attr "cpu" "athlon")
9753 (const_string "vector")
9754 (const_string "double")))
9755 (set_attr "amdfam10_decode" "double")
9756 (set_attr "bdver1_decode" "direct")
9757 (set_attr "mode" "SI")])
9759 (define_insn "*<s>muldi3_highpart_1"
9760 [(set (match_operand:DI 0 "register_operand" "=d")
9765 (match_operand:DI 1 "nonimmediate_operand" "%a"))
9767 (match_operand:DI 2 "nonimmediate_operand" "rm")))
9769 (clobber (match_scratch:DI 3 "=1"))
9770 (clobber (reg:CC FLAGS_REG))]
9772 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9773 "<sgnprefix>mul{q}\t%2"
9774 [(set_attr "type" "imul")
9775 (set_attr "length_immediate" "0")
9776 (set (attr "athlon_decode")
9777 (if_then_else (eq_attr "cpu" "athlon")
9778 (const_string "vector")
9779 (const_string "double")))
9780 (set_attr "amdfam10_decode" "double")
9781 (set_attr "bdver1_decode" "direct")
9782 (set_attr "mode" "DI")])
9784 (define_insn "*<s>mulsi3_highpart_zext"
9785 [(set (match_operand:DI 0 "register_operand" "=d")
9786 (zero_extend:DI (truncate:SI
9788 (mult:DI (any_extend:DI
9789 (match_operand:SI 1 "nonimmediate_operand" "%a"))
9791 (match_operand:SI 2 "nonimmediate_operand" "rm")))
9793 (clobber (match_scratch:SI 3 "=1"))
9794 (clobber (reg:CC FLAGS_REG))]
9796 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9797 "<sgnprefix>mul{l}\t%2"
9798 [(set_attr "type" "imul")
9799 (set_attr "length_immediate" "0")
9800 (set (attr "athlon_decode")
9801 (if_then_else (eq_attr "cpu" "athlon")
9802 (const_string "vector")
9803 (const_string "double")))
9804 (set_attr "amdfam10_decode" "double")
9805 (set_attr "bdver1_decode" "direct")
9806 (set_attr "mode" "SI")])
9808 (define_insn "*<s>mulsi3_highpart_1"
9809 [(set (match_operand:SI 0 "register_operand" "=d")
9814 (match_operand:SI 1 "nonimmediate_operand" "%a"))
9816 (match_operand:SI 2 "nonimmediate_operand" "rm")))
9818 (clobber (match_scratch:SI 3 "=1"))
9819 (clobber (reg:CC FLAGS_REG))]
9820 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9821 "<sgnprefix>mul{l}\t%2"
9822 [(set_attr "type" "imul")
9823 (set_attr "length_immediate" "0")
9824 (set (attr "athlon_decode")
9825 (if_then_else (eq_attr "cpu" "athlon")
9826 (const_string "vector")
9827 (const_string "double")))
9828 (set_attr "amdfam10_decode" "double")
9829 (set_attr "bdver1_decode" "direct")
9830 (set_attr "mode" "SI")])
9832 ;; Highpart multiplication peephole2s to tweak register allocation.
9833 ;; mov imm,%rdx; mov %rdi,%rax; imulq %rdx -> mov imm,%rax; imulq %rdi
9835 [(set (match_operand:SWI48 0 "general_reg_operand")
9836 (match_operand:SWI48 1 "immediate_operand"))
9837 (set (match_operand:SWI48 2 "general_reg_operand")
9838 (match_operand:SWI48 3 "general_reg_operand"))
9839 (parallel [(set (match_operand:SWI48 4 "general_reg_operand")
9840 (any_mul_highpart:SWI48 (match_dup 2) (match_dup 0)))
9841 (clobber (match_dup 2))
9842 (clobber (reg:CC FLAGS_REG))])]
9843 "REGNO (operands[3]) != AX_REG
9844 && REGNO (operands[0]) != REGNO (operands[2])
9845 && REGNO (operands[0]) != REGNO (operands[3])
9846 && (REGNO (operands[0]) == REGNO (operands[4])
9847 || peep2_reg_dead_p (3, operands[0]))"
9848 [(set (match_dup 2) (match_dup 1))
9849 (parallel [(set (match_dup 4)
9850 (any_mul_highpart:SWI48 (match_dup 2) (match_dup 3)))
9851 (clobber (match_dup 2))
9852 (clobber (reg:CC FLAGS_REG))])])
9855 [(set (match_operand:SI 0 "general_reg_operand")
9856 (match_operand:SI 1 "immediate_operand"))
9857 (set (match_operand:SI 2 "general_reg_operand")
9858 (match_operand:SI 3 "general_reg_operand"))
9859 (parallel [(set (match_operand:DI 4 "general_reg_operand")
9861 (any_mul_highpart:SI (match_dup 2) (match_dup 0))))
9862 (clobber (match_dup 2))
9863 (clobber (reg:CC FLAGS_REG))])]
9865 && REGNO (operands[3]) != AX_REG
9866 && REGNO (operands[0]) != REGNO (operands[2])
9867 && REGNO (operands[2]) != REGNO (operands[3])
9868 && REGNO (operands[0]) != REGNO (operands[3])
9869 && (REGNO (operands[0]) == REGNO (operands[4])
9870 || peep2_reg_dead_p (3, operands[0]))"
9871 [(set (match_dup 2) (match_dup 1))
9872 (parallel [(set (match_dup 4)
9874 (any_mul_highpart:SI (match_dup 2) (match_dup 3))))
9875 (clobber (match_dup 2))
9876 (clobber (reg:CC FLAGS_REG))])])
9878 ;; The patterns that match these are at the end of this file.
9880 (define_expand "mulxf3"
9881 [(set (match_operand:XF 0 "register_operand")
9882 (mult:XF (match_operand:XF 1 "register_operand")
9883 (match_operand:XF 2 "register_operand")))]
9886 (define_expand "mulhf3"
9887 [(set (match_operand:HF 0 "register_operand")
9888 (mult:HF (match_operand:HF 1 "register_operand")
9889 (match_operand:HF 2 "nonimmediate_operand")))]
9890 "TARGET_AVX512FP16")
9892 (define_expand "mul<mode>3"
9893 [(set (match_operand:MODEF 0 "register_operand")
9894 (mult:MODEF (match_operand:MODEF 1 "register_operand")
9895 (match_operand:MODEF 2 "nonimmediate_operand")))]
9896 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
9897 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
9899 ;; Divide instructions
9901 ;; The patterns that match these are at the end of this file.
9903 (define_expand "divxf3"
9904 [(set (match_operand:XF 0 "register_operand")
9905 (div:XF (match_operand:XF 1 "register_operand")
9906 (match_operand:XF 2 "register_operand")))]
9909 /* There is no more precision loss than Newton-Rhapson approximation
9910 when using HFmode rcp/rsqrt, so do the transformation directly under
9911 TARGET_RECIP_DIV and fast-math. */
9912 (define_expand "divhf3"
9913 [(set (match_operand:HF 0 "register_operand")
9914 (div:HF (match_operand:HF 1 "register_operand")
9915 (match_operand:HF 2 "nonimmediate_operand")))]
9918 if (TARGET_RECIP_DIV
9919 && optimize_insn_for_speed_p ()
9920 && flag_finite_math_only && !flag_trapping_math
9921 && flag_unsafe_math_optimizations)
9923 rtx op = gen_reg_rtx (HFmode);
9924 operands[2] = force_reg (HFmode, operands[2]);
9925 emit_insn (gen_rcphf2 (op, operands[2]));
9926 emit_insn (gen_mulhf3 (operands[0], operands[1], op));
9931 (define_expand "div<mode>3"
9932 [(set (match_operand:MODEF 0 "register_operand")
9933 (div:MODEF (match_operand:MODEF 1 "register_operand")
9934 (match_operand:MODEF 2 "nonimmediate_operand")))]
9935 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
9936 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9938 if (<MODE>mode == SFmode
9939 && TARGET_SSE && TARGET_SSE_MATH
9941 && optimize_insn_for_speed_p ()
9942 && flag_finite_math_only && !flag_trapping_math
9943 && flag_unsafe_math_optimizations)
9945 ix86_emit_swdivsf (operands[0], operands[1],
9946 operands[2], SFmode);
9951 ;; Divmod instructions.
9953 (define_code_iterator any_div [div udiv])
9954 (define_code_attr paired_mod [(div "mod") (udiv "umod")])
9956 (define_expand "<u>divmod<mode>4"
9957 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
9959 (match_operand:SWIM248 1 "register_operand")
9960 (match_operand:SWIM248 2 "nonimmediate_operand")))
9961 (set (match_operand:SWIM248 3 "register_operand")
9962 (<paired_mod>:SWIM248 (match_dup 1) (match_dup 2)))
9963 (clobber (reg:CC FLAGS_REG))])])
9965 ;; Split with 8bit unsigned divide:
9966 ;; if (dividend an divisor are in [0-255])
9967 ;; use 8bit unsigned integer divide
9969 ;; use original integer divide
9971 [(set (match_operand:SWI48 0 "register_operand")
9972 (any_div:SWI48 (match_operand:SWI48 2 "register_operand")
9973 (match_operand:SWI48 3 "nonimmediate_operand")))
9974 (set (match_operand:SWI48 1 "register_operand")
9975 (<paired_mod>:SWI48 (match_dup 2) (match_dup 3)))
9976 (clobber (reg:CC FLAGS_REG))]
9977 "TARGET_USE_8BIT_IDIV
9978 && TARGET_QIMODE_MATH
9979 && can_create_pseudo_p ()
9980 && !optimize_insn_for_size_p ()"
9982 "ix86_split_idivmod (<MODE>mode, operands, <u_bool>); DONE;")
9985 [(set (match_operand:DI 0 "register_operand")
9987 (any_div:SI (match_operand:SI 2 "register_operand")
9988 (match_operand:SI 3 "nonimmediate_operand"))))
9989 (set (match_operand:SI 1 "register_operand")
9990 (<paired_mod>:SI (match_dup 2) (match_dup 3)))
9991 (clobber (reg:CC FLAGS_REG))]
9993 && TARGET_USE_8BIT_IDIV
9994 && TARGET_QIMODE_MATH
9995 && can_create_pseudo_p ()
9996 && !optimize_insn_for_size_p ()"
9998 "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
10001 [(set (match_operand:DI 1 "register_operand")
10003 (<paired_mod>:SI (match_operand:SI 2 "register_operand")
10004 (match_operand:SI 3 "nonimmediate_operand"))))
10005 (set (match_operand:SI 0 "register_operand")
10006 (any_div:SI (match_dup 2) (match_dup 3)))
10007 (clobber (reg:CC FLAGS_REG))]
10009 && TARGET_USE_8BIT_IDIV
10010 && TARGET_QIMODE_MATH
10011 && can_create_pseudo_p ()
10012 && !optimize_insn_for_size_p ()"
10014 "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
10016 (define_insn_and_split "divmod<mode>4_1"
10017 [(set (match_operand:SWI48 0 "register_operand" "=a")
10018 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
10019 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
10020 (set (match_operand:SWI48 1 "register_operand" "=&d")
10021 (mod:SWI48 (match_dup 2) (match_dup 3)))
10022 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10023 (clobber (reg:CC FLAGS_REG))]
10027 [(parallel [(set (match_dup 1)
10028 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
10029 (clobber (reg:CC FLAGS_REG))])
10030 (parallel [(set (match_dup 0)
10031 (div:SWI48 (match_dup 2) (match_dup 3)))
10033 (mod:SWI48 (match_dup 2) (match_dup 3)))
10034 (use (match_dup 1))
10035 (clobber (reg:CC FLAGS_REG))])]
10037 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
10039 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10040 operands[4] = operands[2];
10043 /* Avoid use of cltd in favor of a mov+shift. */
10044 emit_move_insn (operands[1], operands[2]);
10045 operands[4] = operands[1];
10048 [(set_attr "type" "multi")
10049 (set_attr "mode" "<MODE>")])
10051 (define_insn_and_split "udivmod<mode>4_1"
10052 [(set (match_operand:SWI48 0 "register_operand" "=a")
10053 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
10054 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
10055 (set (match_operand:SWI48 1 "register_operand" "=&d")
10056 (umod:SWI48 (match_dup 2) (match_dup 3)))
10057 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10058 (clobber (reg:CC FLAGS_REG))]
10062 [(set (match_dup 1) (const_int 0))
10063 (parallel [(set (match_dup 0)
10064 (udiv:SWI48 (match_dup 2) (match_dup 3)))
10066 (umod:SWI48 (match_dup 2) (match_dup 3)))
10067 (use (match_dup 1))
10068 (clobber (reg:CC FLAGS_REG))])]
10070 [(set_attr "type" "multi")
10071 (set_attr "mode" "<MODE>")])
10073 (define_insn_and_split "divmodsi4_zext_1"
10074 [(set (match_operand:DI 0 "register_operand" "=a")
10076 (div:SI (match_operand:SI 2 "register_operand" "0")
10077 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10078 (set (match_operand:SI 1 "register_operand" "=&d")
10079 (mod:SI (match_dup 2) (match_dup 3)))
10080 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10081 (clobber (reg:CC FLAGS_REG))]
10084 "&& reload_completed"
10085 [(parallel [(set (match_dup 1)
10086 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10087 (clobber (reg:CC FLAGS_REG))])
10088 (parallel [(set (match_dup 0)
10089 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
10091 (mod:SI (match_dup 2) (match_dup 3)))
10092 (use (match_dup 1))
10093 (clobber (reg:CC FLAGS_REG))])]
10095 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10097 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10098 operands[4] = operands[2];
10101 /* Avoid use of cltd in favor of a mov+shift. */
10102 emit_move_insn (operands[1], operands[2]);
10103 operands[4] = operands[1];
10106 [(set_attr "type" "multi")
10107 (set_attr "mode" "SI")])
10109 (define_insn_and_split "udivmodsi4_zext_1"
10110 [(set (match_operand:DI 0 "register_operand" "=a")
10112 (udiv:SI (match_operand:SI 2 "register_operand" "0")
10113 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10114 (set (match_operand:SI 1 "register_operand" "=&d")
10115 (umod:SI (match_dup 2) (match_dup 3)))
10116 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10117 (clobber (reg:CC FLAGS_REG))]
10120 "&& reload_completed"
10121 [(set (match_dup 1) (const_int 0))
10122 (parallel [(set (match_dup 0)
10123 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
10125 (umod:SI (match_dup 2) (match_dup 3)))
10126 (use (match_dup 1))
10127 (clobber (reg:CC FLAGS_REG))])]
10129 [(set_attr "type" "multi")
10130 (set_attr "mode" "SI")])
10132 (define_insn_and_split "divmodsi4_zext_2"
10133 [(set (match_operand:DI 1 "register_operand" "=&d")
10135 (mod:SI (match_operand:SI 2 "register_operand" "0")
10136 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10137 (set (match_operand:SI 0 "register_operand" "=a")
10138 (div:SI (match_dup 2) (match_dup 3)))
10139 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10140 (clobber (reg:CC FLAGS_REG))]
10143 "&& reload_completed"
10144 [(parallel [(set (match_dup 6)
10145 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10146 (clobber (reg:CC FLAGS_REG))])
10147 (parallel [(set (match_dup 1)
10148 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
10150 (div:SI (match_dup 2) (match_dup 3)))
10151 (use (match_dup 6))
10152 (clobber (reg:CC FLAGS_REG))])]
10154 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10155 operands[6] = gen_lowpart (SImode, operands[1]);
10157 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10158 operands[4] = operands[2];
10161 /* Avoid use of cltd in favor of a mov+shift. */
10162 emit_move_insn (operands[6], operands[2]);
10163 operands[4] = operands[6];
10166 [(set_attr "type" "multi")
10167 (set_attr "mode" "SI")])
10169 (define_insn_and_split "udivmodsi4_zext_2"
10170 [(set (match_operand:DI 1 "register_operand" "=&d")
10172 (umod:SI (match_operand:SI 2 "register_operand" "0")
10173 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10174 (set (match_operand:SI 0 "register_operand" "=a")
10175 (udiv:SI (match_dup 2) (match_dup 3)))
10176 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10177 (clobber (reg:CC FLAGS_REG))]
10180 "&& reload_completed"
10181 [(set (match_dup 4) (const_int 0))
10182 (parallel [(set (match_dup 1)
10183 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
10185 (udiv:SI (match_dup 2) (match_dup 3)))
10186 (use (match_dup 4))
10187 (clobber (reg:CC FLAGS_REG))])]
10188 "operands[4] = gen_lowpart (SImode, operands[1]);"
10189 [(set_attr "type" "multi")
10190 (set_attr "mode" "SI")])
10192 (define_insn_and_split "*divmod<mode>4"
10193 [(set (match_operand:SWIM248 0 "register_operand" "=a")
10194 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
10195 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
10196 (set (match_operand:SWIM248 1 "register_operand" "=&d")
10197 (mod:SWIM248 (match_dup 2) (match_dup 3)))
10198 (clobber (reg:CC FLAGS_REG))]
10202 [(parallel [(set (match_dup 1)
10203 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
10204 (clobber (reg:CC FLAGS_REG))])
10205 (parallel [(set (match_dup 0)
10206 (div:SWIM248 (match_dup 2) (match_dup 3)))
10208 (mod:SWIM248 (match_dup 2) (match_dup 3)))
10209 (use (match_dup 1))
10210 (clobber (reg:CC FLAGS_REG))])]
10212 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
10214 if (<MODE>mode != HImode
10215 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
10216 operands[4] = operands[2];
10219 /* Avoid use of cltd in favor of a mov+shift. */
10220 emit_move_insn (operands[1], operands[2]);
10221 operands[4] = operands[1];
10224 [(set_attr "type" "multi")
10225 (set_attr "mode" "<MODE>")])
10227 (define_insn_and_split "*udivmod<mode>4"
10228 [(set (match_operand:SWIM248 0 "register_operand" "=a")
10229 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
10230 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
10231 (set (match_operand:SWIM248 1 "register_operand" "=&d")
10232 (umod:SWIM248 (match_dup 2) (match_dup 3)))
10233 (clobber (reg:CC FLAGS_REG))]
10237 [(set (match_dup 1) (const_int 0))
10238 (parallel [(set (match_dup 0)
10239 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
10241 (umod:SWIM248 (match_dup 2) (match_dup 3)))
10242 (use (match_dup 1))
10243 (clobber (reg:CC FLAGS_REG))])]
10245 [(set_attr "type" "multi")
10246 (set_attr "mode" "<MODE>")])
10248 ;; Optimize division or modulo by constant power of 2, if the constant
10249 ;; materializes only after expansion.
10250 (define_insn_and_split "*udivmod<mode>4_pow2"
10251 [(set (match_operand:SWI48 0 "register_operand" "=r")
10252 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
10253 (match_operand:SWI48 3 "const_int_operand")))
10254 (set (match_operand:SWI48 1 "register_operand" "=r")
10255 (umod:SWI48 (match_dup 2) (match_dup 3)))
10256 (clobber (reg:CC FLAGS_REG))]
10257 "IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
10259 "&& reload_completed"
10260 [(set (match_dup 1) (match_dup 2))
10261 (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
10262 (clobber (reg:CC FLAGS_REG))])
10263 (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
10264 (clobber (reg:CC FLAGS_REG))])]
10266 int v = exact_log2 (UINTVAL (operands[3]));
10267 operands[4] = GEN_INT (v);
10268 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
10270 [(set_attr "type" "multi")
10271 (set_attr "mode" "<MODE>")])
10273 (define_insn_and_split "*divmodsi4_zext_1"
10274 [(set (match_operand:DI 0 "register_operand" "=a")
10276 (div:SI (match_operand:SI 2 "register_operand" "0")
10277 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10278 (set (match_operand:SI 1 "register_operand" "=&d")
10279 (mod:SI (match_dup 2) (match_dup 3)))
10280 (clobber (reg:CC FLAGS_REG))]
10283 "&& reload_completed"
10284 [(parallel [(set (match_dup 1)
10285 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10286 (clobber (reg:CC FLAGS_REG))])
10287 (parallel [(set (match_dup 0)
10288 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
10290 (mod:SI (match_dup 2) (match_dup 3)))
10291 (use (match_dup 1))
10292 (clobber (reg:CC FLAGS_REG))])]
10294 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10296 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10297 operands[4] = operands[2];
10300 /* Avoid use of cltd in favor of a mov+shift. */
10301 emit_move_insn (operands[1], operands[2]);
10302 operands[4] = operands[1];
10305 [(set_attr "type" "multi")
10306 (set_attr "mode" "SI")])
10308 (define_insn_and_split "*udivmodsi4_zext_1"
10309 [(set (match_operand:DI 0 "register_operand" "=a")
10311 (udiv:SI (match_operand:SI 2 "register_operand" "0")
10312 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10313 (set (match_operand:SI 1 "register_operand" "=&d")
10314 (umod:SI (match_dup 2) (match_dup 3)))
10315 (clobber (reg:CC FLAGS_REG))]
10318 "&& reload_completed"
10319 [(set (match_dup 1) (const_int 0))
10320 (parallel [(set (match_dup 0)
10321 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
10323 (umod:SI (match_dup 2) (match_dup 3)))
10324 (use (match_dup 1))
10325 (clobber (reg:CC FLAGS_REG))])]
10327 [(set_attr "type" "multi")
10328 (set_attr "mode" "SI")])
10330 (define_insn_and_split "*udivmodsi4_pow2_zext_1"
10331 [(set (match_operand:DI 0 "register_operand" "=r")
10333 (udiv:SI (match_operand:SI 2 "register_operand" "0")
10334 (match_operand:SI 3 "const_int_operand"))))
10335 (set (match_operand:SI 1 "register_operand" "=r")
10336 (umod:SI (match_dup 2) (match_dup 3)))
10337 (clobber (reg:CC FLAGS_REG))]
10339 && IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
10341 "&& reload_completed"
10342 [(set (match_dup 1) (match_dup 2))
10343 (parallel [(set (match_dup 0)
10344 (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4))))
10345 (clobber (reg:CC FLAGS_REG))])
10346 (parallel [(set (match_dup 1) (and:SI (match_dup 1) (match_dup 5)))
10347 (clobber (reg:CC FLAGS_REG))])]
10349 int v = exact_log2 (UINTVAL (operands[3]));
10350 operands[4] = GEN_INT (v);
10351 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
10353 [(set_attr "type" "multi")
10354 (set_attr "mode" "SI")])
10356 (define_insn_and_split "*divmodsi4_zext_2"
10357 [(set (match_operand:DI 1 "register_operand" "=&d")
10359 (mod:SI (match_operand:SI 2 "register_operand" "0")
10360 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10361 (set (match_operand:SI 0 "register_operand" "=a")
10362 (div:SI (match_dup 2) (match_dup 3)))
10363 (clobber (reg:CC FLAGS_REG))]
10366 "&& reload_completed"
10367 [(parallel [(set (match_dup 6)
10368 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10369 (clobber (reg:CC FLAGS_REG))])
10370 (parallel [(set (match_dup 1)
10371 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
10373 (div:SI (match_dup 2) (match_dup 3)))
10374 (use (match_dup 6))
10375 (clobber (reg:CC FLAGS_REG))])]
10377 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10378 operands[6] = gen_lowpart (SImode, operands[1]);
10380 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10381 operands[4] = operands[2];
10384 /* Avoid use of cltd in favor of a mov+shift. */
10385 emit_move_insn (operands[6], operands[2]);
10386 operands[4] = operands[6];
10389 [(set_attr "type" "multi")
10390 (set_attr "mode" "SI")])
10392 (define_insn_and_split "*udivmodsi4_zext_2"
10393 [(set (match_operand:DI 1 "register_operand" "=&d")
10395 (umod:SI (match_operand:SI 2 "register_operand" "0")
10396 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10397 (set (match_operand:SI 0 "register_operand" "=a")
10398 (udiv:SI (match_dup 2) (match_dup 3)))
10399 (clobber (reg:CC FLAGS_REG))]
10402 "&& reload_completed"
10403 [(set (match_dup 4) (const_int 0))
10404 (parallel [(set (match_dup 1)
10405 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
10407 (udiv:SI (match_dup 2) (match_dup 3)))
10408 (use (match_dup 4))
10409 (clobber (reg:CC FLAGS_REG))])]
10410 "operands[4] = gen_lowpart (SImode, operands[1]);"
10411 [(set_attr "type" "multi")
10412 (set_attr "mode" "SI")])
10414 (define_insn_and_split "*udivmodsi4_pow2_zext_2"
10415 [(set (match_operand:DI 1 "register_operand" "=r")
10417 (umod:SI (match_operand:SI 2 "register_operand" "0")
10418 (match_operand:SI 3 "const_int_operand"))))
10419 (set (match_operand:SI 0 "register_operand" "=r")
10420 (udiv:SI (match_dup 2) (match_dup 3)))
10421 (clobber (reg:CC FLAGS_REG))]
10423 && IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
10425 "&& reload_completed"
10426 [(set (match_dup 1) (match_dup 2))
10427 (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4)))
10428 (clobber (reg:CC FLAGS_REG))])
10429 (parallel [(set (match_dup 1)
10430 (zero_extend:DI (and:SI (match_dup 1) (match_dup 5))))
10431 (clobber (reg:CC FLAGS_REG))])]
10433 int v = exact_log2 (UINTVAL (operands[3]));
10434 operands[4] = GEN_INT (v);
10435 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
10437 [(set_attr "type" "multi")
10438 (set_attr "mode" "SI")])
10440 (define_insn "*<u>divmod<mode>4_noext"
10441 [(set (match_operand:SWIM248 0 "register_operand" "=a")
10443 (match_operand:SWIM248 2 "register_operand" "0")
10444 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
10445 (set (match_operand:SWIM248 1 "register_operand" "=d")
10446 (<paired_mod>:SWIM248 (match_dup 2) (match_dup 3)))
10447 (use (match_operand:SWIM248 4 "register_operand" "1"))
10448 (clobber (reg:CC FLAGS_REG))]
10450 "<sgnprefix>div{<imodesuffix>}\t%3"
10451 [(set_attr "type" "idiv")
10452 (set_attr "mode" "<MODE>")])
10454 (define_insn "*<u>divmodsi4_noext_zext_1"
10455 [(set (match_operand:DI 0 "register_operand" "=a")
10457 (any_div:SI (match_operand:SI 2 "register_operand" "0")
10458 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10459 (set (match_operand:SI 1 "register_operand" "=d")
10460 (<paired_mod>:SI (match_dup 2) (match_dup 3)))
10461 (use (match_operand:SI 4 "register_operand" "1"))
10462 (clobber (reg:CC FLAGS_REG))]
10464 "<sgnprefix>div{l}\t%3"
10465 [(set_attr "type" "idiv")
10466 (set_attr "mode" "SI")])
10468 (define_insn "*<u>divmodsi4_noext_zext_2"
10469 [(set (match_operand:DI 1 "register_operand" "=d")
10471 (<paired_mod>:SI (match_operand:SI 2 "register_operand" "0")
10472 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10473 (set (match_operand:SI 0 "register_operand" "=a")
10474 (any_div:SI (match_dup 2) (match_dup 3)))
10475 (use (match_operand:SI 4 "register_operand" "1"))
10476 (clobber (reg:CC FLAGS_REG))]
10478 "<sgnprefix>div{l}\t%3"
10479 [(set_attr "type" "idiv")
10480 (set_attr "mode" "SI")])
10482 ;; Avoid sign-extension (using cdq) for constant numerators.
10483 (define_insn_and_split "*divmodsi4_const"
10484 [(set (match_operand:SI 0 "register_operand" "=&a")
10485 (div:SI (match_operand:SI 2 "const_int_operand")
10486 (match_operand:SI 3 "nonimmediate_operand" "rm")))
10487 (set (match_operand:SI 1 "register_operand" "=&d")
10488 (mod:SI (match_dup 2) (match_dup 3)))
10489 (clobber (reg:CC FLAGS_REG))]
10490 "!optimize_function_for_size_p (cfun)"
10492 "&& reload_completed"
10493 [(set (match_dup 0) (match_dup 2))
10494 (set (match_dup 1) (match_dup 4))
10495 (parallel [(set (match_dup 0)
10496 (div:SI (match_dup 0) (match_dup 3)))
10498 (mod:SI (match_dup 0) (match_dup 3)))
10499 (use (match_dup 1))
10500 (clobber (reg:CC FLAGS_REG))])]
10502 operands[4] = INTVAL (operands[2]) < 0 ? constm1_rtx : const0_rtx;
10504 [(set_attr "type" "multi")
10505 (set_attr "mode" "SI")])
10507 (define_expand "divmodqi4"
10508 [(parallel [(set (match_operand:QI 0 "register_operand")
10510 (match_operand:QI 1 "register_operand")
10511 (match_operand:QI 2 "nonimmediate_operand")))
10512 (set (match_operand:QI 3 "register_operand")
10513 (mod:QI (match_dup 1) (match_dup 2)))
10514 (clobber (reg:CC FLAGS_REG))])]
10515 "TARGET_QIMODE_MATH"
10520 tmp0 = gen_reg_rtx (HImode);
10521 tmp1 = gen_reg_rtx (HImode);
10523 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
10524 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
10525 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
10527 /* Extract remainder from AH. */
10528 tmp1 = gen_rtx_ZERO_EXTRACT (HImode, tmp0, GEN_INT (8), GEN_INT (8));
10529 tmp1 = lowpart_subreg (QImode, tmp1, HImode);
10530 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
10532 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
10533 set_unique_reg_note (insn, REG_EQUAL, mod);
10535 /* Extract quotient from AL. */
10536 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
10538 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
10539 set_unique_reg_note (insn, REG_EQUAL, div);
10544 (define_expand "udivmodqi4"
10545 [(parallel [(set (match_operand:QI 0 "register_operand")
10547 (match_operand:QI 1 "register_operand")
10548 (match_operand:QI 2 "nonimmediate_operand")))
10549 (set (match_operand:QI 3 "register_operand")
10550 (umod:QI (match_dup 1) (match_dup 2)))
10551 (clobber (reg:CC FLAGS_REG))])]
10552 "TARGET_QIMODE_MATH"
10557 tmp0 = gen_reg_rtx (HImode);
10558 tmp1 = gen_reg_rtx (HImode);
10560 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
10561 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
10562 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
10564 /* Extract remainder from AH. */
10565 tmp1 = gen_rtx_ZERO_EXTRACT (HImode, tmp0, GEN_INT (8), GEN_INT (8));
10566 tmp1 = lowpart_subreg (QImode, tmp1, HImode);
10567 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
10569 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
10570 set_unique_reg_note (insn, REG_EQUAL, mod);
10572 /* Extract quotient from AL. */
10573 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
10575 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
10576 set_unique_reg_note (insn, REG_EQUAL, div);
10581 ;; Divide AX by r/m8, with result stored in
10584 ;; Change div/mod to HImode and extend the second argument to HImode
10585 ;; so that mode of div/mod matches with mode of arguments. Otherwise
10586 ;; combine may fail.
10587 (define_insn "<u>divmodhiqi3"
10588 [(set (match_operand:HI 0 "register_operand" "=a")
10593 (mod:HI (match_operand:HI 1 "register_operand" "0")
10595 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
10599 (div:HI (match_dup 1) (any_extend:HI (match_dup 2)))))))
10600 (clobber (reg:CC FLAGS_REG))]
10601 "TARGET_QIMODE_MATH"
10602 "<sgnprefix>div{b}\t%2"
10603 [(set_attr "type" "idiv")
10604 (set_attr "mode" "QI")])
10606 ;; We cannot use div/idiv for double division, because it causes
10607 ;; "division by zero" on the overflow and that's not what we expect
10608 ;; from truncate. Because true (non truncating) double division is
10609 ;; never generated, we can't create this insn anyway.
10612 ; [(set (match_operand:SI 0 "register_operand" "=a")
10614 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
10616 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
10617 ; (set (match_operand:SI 3 "register_operand" "=d")
10619 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
10620 ; (clobber (reg:CC FLAGS_REG))]
10622 ; "div{l}\t{%2, %0|%0, %2}"
10623 ; [(set_attr "type" "idiv")])
10625 ;;- Logical AND instructions
10627 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
10628 ;; Note that this excludes ah.
10630 (define_expand "@test<mode>_ccno_1"
10631 [(set (reg:CCNO FLAGS_REG)
10634 (match_operand:SWI48 0 "nonimmediate_operand")
10635 (match_operand:SWI48 1 "<nonmemory_szext_operand>"))
10638 (define_expand "testqi_ccz_1"
10639 [(set (reg:CCZ FLAGS_REG)
10642 (match_operand:QI 0 "nonimmediate_operand")
10643 (match_operand:QI 1 "nonmemory_operand"))
10646 (define_insn "*testdi_1"
10647 [(set (reg FLAGS_REG)
10650 (match_operand:DI 0 "nonimmediate_operand" "%r,rm")
10651 (match_operand:DI 1 "x86_64_szext_nonmemory_operand" "Z,re"))
10654 && ix86_match_ccmode
10656 /* If we are going to emit testl instead of testq, and the operands[1]
10657 constant might have the SImode sign bit set, make sure the sign
10658 flag isn't tested, because the instruction will set the sign flag
10659 based on bit 31 rather than bit 63. If it isn't CONST_INT,
10660 conservatively assume it might have bit 31 set. */
10661 (satisfies_constraint_Z (operands[1])
10662 && (!CONST_INT_P (operands[1])
10663 || val_signbit_known_set_p (SImode, INTVAL (operands[1]))))
10664 ? CCZmode : CCNOmode)"
10666 test{l}\t{%k1, %k0|%k0, %k1}
10667 test{q}\t{%1, %0|%0, %1}"
10668 [(set_attr "type" "test")
10669 (set_attr "mode" "SI,DI")])
10671 (define_insn "*testqi_1_maybe_si"
10672 [(set (reg FLAGS_REG)
10675 (match_operand:QI 0 "nonimmediate_operand" "%qm,qm,r")
10676 (match_operand:QI 1 "nonmemory_operand" "q,n,n"))
10678 "ix86_match_ccmode (insn,
10679 CONST_INT_P (operands[1])
10680 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
10682 if (get_attr_mode (insn) == MODE_SI)
10684 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
10685 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
10686 return "test{l}\t{%1, %k0|%k0, %1}";
10688 return "test{b}\t{%1, %0|%0, %1}";
10690 [(set_attr "type" "test")
10692 (cond [(eq_attr "alternative" "2")
10693 (const_string "SI")
10694 (and (match_test "optimize_insn_for_size_p ()")
10695 (and (match_operand 0 "ext_QIreg_operand")
10696 (match_operand 1 "const_0_to_127_operand")))
10697 (const_string "SI")
10699 (const_string "QI")))
10700 (set_attr "pent_pair" "uv,np,np")])
10702 (define_insn "*test<mode>_1"
10703 [(set (reg FLAGS_REG)
10706 (match_operand:SWI124 0 "nonimmediate_operand" "%<r>m,*a,<r>m")
10707 (match_operand:SWI124 1 "<nonmemory_szext_operand>" "<r>,<i>,<i>"))
10709 "ix86_match_ccmode (insn, CCNOmode)"
10710 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
10711 [(set_attr "type" "test")
10712 (set_attr "mode" "<MODE>")
10713 (set_attr "pent_pair" "uv,uv,np")])
10715 (define_expand "testqi_ext_1_ccno"
10716 [(set (reg:CCNO FLAGS_REG)
10721 (match_operand:HI 0 "register_operand")
10724 (match_operand:QI 1 "const_int_operand"))
10727 (define_insn "*testqi_ext<mode>_1"
10728 [(set (reg FLAGS_REG)
10732 (match_operator:SWI248 2 "extract_operator"
10733 [(match_operand 0 "int248_register_operand" "Q,Q")
10736 (match_operand:QI 1 "general_x64constmem_operand" "QnBc,m"))
10738 "ix86_match_ccmode (insn, CCNOmode)"
10739 "test{b}\t{%1, %h0|%h0, %1}"
10740 [(set_attr "isa" "*,nox64")
10741 (set_attr "type" "test")
10742 (set_attr "mode" "QI")])
10744 (define_insn "*testqi_ext<mode>_2"
10745 [(set (reg FLAGS_REG)
10749 (match_operator:SWI248 2 "extract_operator"
10750 [(match_operand 0 "int248_register_operand" "Q")
10754 (match_operator:SWI248 3 "extract_operator"
10755 [(match_operand 1 "int248_register_operand" "Q")
10757 (const_int 8)]) 0))
10759 "ix86_match_ccmode (insn, CCNOmode)"
10760 "test{b}\t{%h1, %h0|%h0, %h1}"
10761 [(set_attr "type" "test")
10762 (set_attr "mode" "QI")])
10764 ;; Provide a *testti instruction that STV can implement using ptest.
10765 ;; This pattern splits into *andti3_doubleword and *cmpti_doubleword.
10766 (define_insn_and_split "*testti_doubleword"
10767 [(set (reg:CCZ FLAGS_REG)
10769 (and:TI (match_operand:TI 0 "register_operand")
10770 (match_operand:TI 1 "general_operand"))
10773 && ix86_pre_reload_split ()"
10776 [(parallel [(set (match_dup 2) (and:TI (match_dup 0) (match_dup 1)))
10777 (clobber (reg:CC FLAGS_REG))])
10778 (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 2) (const_int 0)))]
10780 operands[2] = gen_reg_rtx (TImode);
10781 if (!x86_64_hilo_general_operand (operands[1], TImode))
10782 operands[1] = force_reg (TImode, operands[1]);
10785 ;; Combine likes to form bit extractions for some tests. Humor it.
10786 (define_insn_and_split "*testqi_ext_3"
10787 [(set (match_operand 0 "flags_reg_operand")
10788 (match_operator 1 "compare_operator"
10789 [(zero_extract:SWI248
10790 (match_operand 2 "int_nonimmediate_operand" "rm")
10791 (match_operand 3 "const_int_operand")
10792 (match_operand 4 "const_int_operand"))
10794 "/* Ensure that resulting mask is zero or sign extended operand. */
10795 INTVAL (operands[4]) >= 0
10796 && ((INTVAL (operands[3]) > 0
10797 && INTVAL (operands[3]) + INTVAL (operands[4]) <= 32)
10798 || (<MODE>mode == DImode
10799 && INTVAL (operands[3]) > 32
10800 && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))
10801 && ix86_match_ccmode (insn,
10802 /* If zero_extract mode precision is the same
10803 as len, the SF of the zero_extract
10804 comparison will be the most significant
10805 extracted bit, but this could be matched
10806 after splitting only for pos 0 len all bits
10807 trivial extractions. Require CCZmode. */
10808 (GET_MODE_PRECISION (<MODE>mode)
10809 == INTVAL (operands[3]))
10810 /* Otherwise, require CCZmode if we'd use a mask
10811 with the most significant bit set and can't
10812 widen it to wider mode. *testdi_1 also
10813 requires CCZmode if the mask has bit
10814 31 set and all bits above it clear. */
10815 || (INTVAL (operands[3]) + INTVAL (operands[4])
10817 /* We can't widen also if val is not a REG. */
10818 || (INTVAL (operands[3]) + INTVAL (operands[4])
10819 == GET_MODE_PRECISION (GET_MODE (operands[2]))
10820 && !register_operand (operands[2],
10821 GET_MODE (operands[2])))
10822 /* And we shouldn't widen if
10823 TARGET_PARTIAL_REG_STALL. */
10824 || (TARGET_PARTIAL_REG_STALL
10825 && (INTVAL (operands[3]) + INTVAL (operands[4])
10826 >= (paradoxical_subreg_p (operands[2])
10828 (GET_MODE (SUBREG_REG (operands[2])))
10830 ? GET_MODE_PRECISION
10831 (GET_MODE (SUBREG_REG (operands[2])))
10832 : GET_MODE_PRECISION
10833 (GET_MODE (operands[2])))))
10834 ? CCZmode : CCNOmode)"
10837 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
10839 rtx val = operands[2];
10840 HOST_WIDE_INT len = INTVAL (operands[3]);
10841 HOST_WIDE_INT pos = INTVAL (operands[4]);
10842 machine_mode mode = GET_MODE (val);
10844 if (SUBREG_P (val))
10846 machine_mode submode = GET_MODE (SUBREG_REG (val));
10848 /* Narrow paradoxical subregs to prevent partial register stalls. */
10849 if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)
10850 && GET_MODE_CLASS (submode) == MODE_INT
10851 && (GET_MODE (operands[0]) == CCZmode
10852 || pos + len < GET_MODE_PRECISION (submode)
10853 || REG_P (SUBREG_REG (val))))
10855 val = SUBREG_REG (val);
10860 /* Small HImode tests can be converted to QImode. */
10862 && register_operand (val, HImode))
10864 rtx nval = gen_lowpart (QImode, val);
10866 || GET_MODE (operands[0]) == CCZmode
10874 gcc_assert (pos + len <= GET_MODE_PRECISION (mode));
10876 /* If the mask is going to have the sign bit set in the mode
10877 we want to do the comparison in and user isn't interested just
10878 in the zero flag, then we must widen the target mode. */
10879 if (pos + len == GET_MODE_PRECISION (mode)
10880 && GET_MODE (operands[0]) != CCZmode)
10882 gcc_assert (pos + len < 32 && !MEM_P (val));
10884 val = gen_lowpart (mode, val);
10888 = wi::shifted_mask (pos, len, false, GET_MODE_PRECISION (mode));
10890 operands[2] = gen_rtx_AND (mode, val, immed_wide_int_const (mask, mode));
10893 ;; Split and;cmp (as optimized by combine) into not;test
10894 ;; Except when TARGET_BMI provides andn (*andn_<mode>_ccno).
10895 (define_insn_and_split "*test<mode>_not"
10896 [(set (reg:CCZ FLAGS_REG)
10899 (not:SWI (match_operand:SWI 0 "register_operand"))
10900 (match_operand:SWI 1 "<nonmemory_szext_operand>"))
10902 "ix86_pre_reload_split ()
10903 && (!TARGET_BMI || !REG_P (operands[1]))"
10906 [(set (match_dup 2) (not:SWI (match_dup 0)))
10907 (set (reg:CCZ FLAGS_REG)
10908 (compare:CCZ (and:SWI (match_dup 2) (match_dup 1))
10910 "operands[2] = gen_reg_rtx (<MODE>mode);")
10912 ;; Split and;cmp (as optimized by combine) into andn;cmp $0
10913 (define_insn_and_split "*test<mode>_not_doubleword"
10914 [(set (reg:CCZ FLAGS_REG)
10917 (not:DWI (match_operand:DWI 0 "nonimmediate_operand"))
10918 (match_operand:DWI 1 "nonimmediate_operand"))
10920 "ix86_pre_reload_split ()"
10924 [(set (match_dup 2) (and:DWI (not:DWI (match_dup 0)) (match_dup 1)))
10925 (clobber (reg:CC FLAGS_REG))])
10926 (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 2) (const_int 0)))]
10928 operands[0] = force_reg (<MODE>mode, operands[0]);
10929 operands[2] = gen_reg_rtx (<MODE>mode);
10932 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
10933 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
10934 ;; this is relatively important trick.
10935 ;; Do the conversion only post-reload to avoid limiting of the register class
10938 [(set (match_operand 0 "flags_reg_operand")
10939 (match_operator 1 "compare_operator"
10940 [(and (match_operand 2 "QIreg_operand")
10941 (match_operand 3 "const_int_operand"))
10944 && GET_MODE (operands[2]) != QImode
10945 && ((ix86_match_ccmode (insn, CCZmode)
10946 && !(INTVAL (operands[3]) & ~(255 << 8)))
10947 || (ix86_match_ccmode (insn, CCNOmode)
10948 && !(INTVAL (operands[3]) & ~(127 << 8))))"
10949 [(set (match_dup 0)
10953 (zero_extract:HI (match_dup 2)
10959 operands[2] = gen_lowpart (HImode, operands[2]);
10960 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, QImode);
10964 [(set (match_operand 0 "flags_reg_operand")
10965 (match_operator 1 "compare_operator"
10966 [(and (match_operand 2 "nonimmediate_operand")
10967 (match_operand 3 "const_int_operand"))
10970 && GET_MODE (operands[2]) != QImode
10971 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
10972 && ((ix86_match_ccmode (insn, CCZmode)
10973 && !(INTVAL (operands[3]) & ~255))
10974 || (ix86_match_ccmode (insn, CCNOmode)
10975 && !(INTVAL (operands[3]) & ~127)))"
10976 [(set (match_dup 0)
10977 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
10980 operands[2] = gen_lowpart (QImode, operands[2]);
10981 operands[3] = gen_int_mode (INTVAL (operands[3]), QImode);
10984 ;; %%% This used to optimize known byte-wide and operations to memory,
10985 ;; and sometimes to QImode registers. If this is considered useful,
10986 ;; it should be done with splitters.
10988 (define_expand "and<mode>3"
10989 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
10990 (and:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
10991 (match_operand:SDWIM 2 "<general_szext_operand>")))]
10994 machine_mode mode = <MODE>mode;
10996 if (GET_MODE_SIZE (<MODE>mode) > UNITS_PER_WORD
10997 && !x86_64_hilo_general_operand (operands[2], <MODE>mode))
10998 operands[2] = force_reg (<MODE>mode, operands[2]);
11000 if (GET_MODE_SIZE (<MODE>mode) <= UNITS_PER_WORD
11001 && const_int_operand (operands[2], <MODE>mode)
11002 && register_operand (operands[0], <MODE>mode)
11003 && !(TARGET_ZERO_EXTEND_WITH_AND
11004 && optimize_function_for_speed_p (cfun)))
11006 unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
11008 if (ival == GET_MODE_MASK (SImode))
11010 else if (ival == GET_MODE_MASK (HImode))
11012 else if (ival == GET_MODE_MASK (QImode))
11016 if (mode != <MODE>mode)
11017 emit_insn (gen_extend_insn
11018 (operands[0], gen_lowpart (mode, operands[1]),
11019 <MODE>mode, mode, 1));
11021 ix86_expand_binary_operator (AND, <MODE>mode, operands);
11026 (define_insn_and_split "*and<dwi>3_doubleword"
11027 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
11029 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
11030 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
11031 (clobber (reg:CC FLAGS_REG))]
11032 "ix86_binary_operator_ok (AND, <DWI>mode, operands)"
11034 "&& reload_completed"
11035 [(const_int:DWIH 0)]
11037 bool emit_insn_deleted_note_p = false;
11039 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
11041 if (operands[2] == const0_rtx)
11042 emit_move_insn (operands[0], const0_rtx);
11043 else if (operands[2] == constm1_rtx)
11044 emit_insn_deleted_note_p = true;
11046 ix86_expand_binary_operator (AND, <MODE>mode, &operands[0]);
11048 if (operands[5] == const0_rtx)
11049 emit_move_insn (operands[3], const0_rtx);
11050 else if (operands[5] == constm1_rtx)
11052 if (emit_insn_deleted_note_p)
11053 emit_note (NOTE_INSN_DELETED);
11056 ix86_expand_binary_operator (AND, <MODE>mode, &operands[3]);
11061 (define_insn "*anddi_1"
11062 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,?k")
11064 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
11065 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m,L,k")))
11066 (clobber (reg:CC FLAGS_REG))]
11067 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
11069 and{l}\t{%k2, %k0|%k0, %k2}
11070 and{q}\t{%2, %0|%0, %2}
11071 and{q}\t{%2, %0|%0, %2}
11074 [(set_attr "isa" "x64,x64,x64,x64,avx512bw")
11075 (set_attr "type" "alu,alu,alu,imovx,msklog")
11076 (set_attr "length_immediate" "*,*,*,0,*")
11077 (set (attr "prefix_rex")
11079 (and (eq_attr "type" "imovx")
11080 (and (match_test "INTVAL (operands[2]) == 0xff")
11081 (match_operand 1 "ext_QIreg_operand")))
11083 (const_string "*")))
11084 (set_attr "mode" "SI,DI,DI,SI,DI")])
11086 (define_insn_and_split "*anddi_1_btr"
11087 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11089 (match_operand:DI 1 "nonimmediate_operand" "%0")
11090 (match_operand:DI 2 "const_int_operand" "n")))
11091 (clobber (reg:CC FLAGS_REG))]
11092 "TARGET_64BIT && TARGET_USE_BT
11093 && ix86_binary_operator_ok (AND, DImode, operands)
11094 && IN_RANGE (exact_log2 (~INTVAL (operands[2])), 31, 63)"
11096 "&& reload_completed"
11097 [(parallel [(set (zero_extract:DI (match_dup 0)
11101 (clobber (reg:CC FLAGS_REG))])]
11102 "operands[3] = GEN_INT (exact_log2 (~INTVAL (operands[2])));"
11103 [(set_attr "type" "alu1")
11104 (set_attr "prefix_0f" "1")
11105 (set_attr "znver1_decode" "double")
11106 (set_attr "mode" "DI")])
11108 ;; Turn *anddi_1 into *andsi_1_zext if possible.
11110 [(set (match_operand:DI 0 "register_operand")
11111 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
11112 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
11113 (clobber (reg:CC FLAGS_REG))]
11115 [(parallel [(set (match_dup 0)
11116 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
11117 (clobber (reg:CC FLAGS_REG))])]
11119 if (GET_CODE (operands[2]) == SYMBOL_REF
11120 || GET_CODE (operands[2]) == LABEL_REF)
11122 operands[2] = shallow_copy_rtx (operands[2]);
11123 PUT_MODE (operands[2], SImode);
11125 else if (GET_CODE (operands[2]) == CONST)
11127 /* (const:DI (plus:DI (symbol_ref:DI ("...")) (const_int N))) */
11128 operands[2] = copy_rtx (operands[2]);
11129 PUT_MODE (operands[2], SImode);
11130 PUT_MODE (XEXP (operands[2], 0), SImode);
11131 PUT_MODE (XEXP (XEXP (operands[2], 0), 0), SImode);
11134 operands[2] = gen_lowpart (SImode, operands[2]);
11137 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
11138 (define_insn "*andsi_1_zext"
11139 [(set (match_operand:DI 0 "register_operand" "=r")
11141 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
11142 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
11143 (clobber (reg:CC FLAGS_REG))]
11144 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
11145 "and{l}\t{%2, %k0|%k0, %2}"
11146 [(set_attr "type" "alu")
11147 (set_attr "mode" "SI")])
11149 (define_insn "*and<mode>_1"
11150 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya,?k")
11151 (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm,k")
11152 (match_operand:SWI24 2 "<general_operand>" "r<i>,<m>,L,k")))
11153 (clobber (reg:CC FLAGS_REG))]
11154 "ix86_binary_operator_ok (AND, <MODE>mode, operands)"
11156 and{<imodesuffix>}\t{%2, %0|%0, %2}
11157 and{<imodesuffix>}\t{%2, %0|%0, %2}
11161 (cond [(eq_attr "alternative" "3")
11162 (if_then_else (eq_attr "mode" "SI")
11163 (const_string "avx512bw")
11164 (const_string "avx512f"))
11166 (const_string "*")))
11167 (set_attr "type" "alu,alu,imovx,msklog")
11168 (set_attr "length_immediate" "*,*,0,*")
11169 (set (attr "prefix_rex")
11171 (and (eq_attr "type" "imovx")
11172 (and (match_test "INTVAL (operands[2]) == 0xff")
11173 (match_operand 1 "ext_QIreg_operand")))
11175 (const_string "*")))
11176 (set_attr "mode" "<MODE>,<MODE>,SI,<MODE>")])
11178 (define_insn "*andqi_1"
11179 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,?k")
11180 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
11181 (match_operand:QI 2 "general_operand" "qn,m,rn,k")))
11182 (clobber (reg:CC FLAGS_REG))]
11183 "ix86_binary_operator_ok (AND, QImode, operands)"
11185 and{b}\t{%2, %0|%0, %2}
11186 and{b}\t{%2, %0|%0, %2}
11187 and{l}\t{%k2, %k0|%k0, %k2}
11189 [(set_attr "type" "alu,alu,alu,msklog")
11191 (cond [(eq_attr "alternative" "2")
11192 (const_string "SI")
11193 (and (eq_attr "alternative" "3")
11194 (match_test "!TARGET_AVX512DQ"))
11195 (const_string "HI")
11197 (const_string "QI")))
11198 ;; Potential partial reg stall on alternative 2.
11199 (set (attr "preferred_for_speed")
11200 (cond [(eq_attr "alternative" "2")
11201 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
11202 (symbol_ref "true")))])
11204 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
11205 (define_insn_and_split "*and<mode>_1_slp"
11206 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
11207 (and:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0,!<r>")
11208 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
11209 (clobber (reg:CC FLAGS_REG))]
11210 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
11212 and{<imodesuffix>}\t{%2, %0|%0, %2}
11214 "&& reload_completed"
11215 [(set (strict_low_part (match_dup 0)) (match_dup 1))
11217 [(set (strict_low_part (match_dup 0))
11218 (and:SWI12 (match_dup 0) (match_dup 2)))
11219 (clobber (reg:CC FLAGS_REG))])]
11221 [(set_attr "type" "alu")
11222 (set_attr "mode" "<MODE>")])
11225 [(set (match_operand:SWI248 0 "register_operand")
11226 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
11227 (match_operand:SWI248 2 "const_int_operand")))
11228 (clobber (reg:CC FLAGS_REG))]
11230 && (!REG_P (operands[1])
11231 || REGNO (operands[0]) != REGNO (operands[1]))"
11234 unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
11237 if (ival == GET_MODE_MASK (SImode))
11239 else if (ival == GET_MODE_MASK (HImode))
11241 else if (ival == GET_MODE_MASK (QImode))
11244 gcc_unreachable ();
11246 /* Zero extend to SImode to avoid partial register stalls. */
11247 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
11248 operands[0] = gen_lowpart (SImode, operands[0]);
11250 emit_insn (gen_extend_insn
11251 (operands[0], gen_lowpart (mode, operands[1]),
11252 GET_MODE (operands[0]), mode, 1));
11257 [(set (match_operand:SWI48 0 "register_operand")
11258 (and:SWI48 (match_dup 0)
11259 (const_int -65536)))
11260 (clobber (reg:CC FLAGS_REG))]
11261 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
11262 || optimize_function_for_size_p (cfun)"
11263 [(set (strict_low_part (match_dup 1)) (const_int 0))]
11264 "operands[1] = gen_lowpart (HImode, operands[0]);")
11267 [(set (match_operand:SWI248 0 "any_QIreg_operand")
11268 (and:SWI248 (match_dup 0)
11270 (clobber (reg:CC FLAGS_REG))]
11271 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11272 && reload_completed"
11273 [(set (strict_low_part (match_dup 1)) (const_int 0))]
11274 "operands[1] = gen_lowpart (QImode, operands[0]);")
11277 [(set (match_operand:SWI248 0 "QIreg_operand")
11278 (and:SWI248 (match_dup 0)
11279 (const_int -65281)))
11280 (clobber (reg:CC FLAGS_REG))]
11281 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11282 && reload_completed"
11284 [(set (zero_extract:HI (match_dup 0)
11290 (zero_extract:HI (match_dup 0)
11294 (zero_extract:HI (match_dup 0)
11296 (const_int 8)) 0)) 0))
11297 (clobber (reg:CC FLAGS_REG))])]
11298 "operands[0] = gen_lowpart (HImode, operands[0]);")
11300 (define_insn "*anddi_2"
11301 [(set (reg FLAGS_REG)
11304 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
11305 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m"))
11307 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
11308 (and:DI (match_dup 1) (match_dup 2)))]
11310 && ix86_match_ccmode
11312 /* If we are going to emit andl instead of andq, and the operands[2]
11313 constant might have the SImode sign bit set, make sure the sign
11314 flag isn't tested, because the instruction will set the sign flag
11315 based on bit 31 rather than bit 63. If it isn't CONST_INT,
11316 conservatively assume it might have bit 31 set. */
11317 (satisfies_constraint_Z (operands[2])
11318 && (!CONST_INT_P (operands[2])
11319 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
11320 ? CCZmode : CCNOmode)
11321 && ix86_binary_operator_ok (AND, DImode, operands)"
11323 and{l}\t{%k2, %k0|%k0, %k2}
11324 and{q}\t{%2, %0|%0, %2}
11325 and{q}\t{%2, %0|%0, %2}"
11326 [(set_attr "type" "alu")
11327 (set_attr "mode" "SI,DI,DI")])
11329 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
11330 (define_insn "*andsi_2_zext"
11331 [(set (reg FLAGS_REG)
11333 (match_operand:SI 1 "nonimmediate_operand" "%0")
11334 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
11336 (set (match_operand:DI 0 "register_operand" "=r")
11337 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
11338 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
11339 && ix86_binary_operator_ok (AND, SImode, operands)"
11340 "and{l}\t{%2, %k0|%k0, %2}"
11341 [(set_attr "type" "alu")
11342 (set_attr "mode" "SI")])
11344 (define_insn "*andqi_2_maybe_si"
11345 [(set (reg FLAGS_REG)
11347 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
11348 (match_operand:QI 2 "general_operand" "qn,m,n"))
11350 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
11351 (and:QI (match_dup 1) (match_dup 2)))]
11352 "ix86_binary_operator_ok (AND, QImode, operands)
11353 && ix86_match_ccmode (insn,
11354 CONST_INT_P (operands[2])
11355 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
11357 if (get_attr_mode (insn) == MODE_SI)
11359 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
11360 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
11361 return "and{l}\t{%2, %k0|%k0, %2}";
11363 return "and{b}\t{%2, %0|%0, %2}";
11365 [(set_attr "type" "alu")
11367 (cond [(eq_attr "alternative" "2")
11368 (const_string "SI")
11369 (and (match_test "optimize_insn_for_size_p ()")
11370 (and (match_operand 0 "ext_QIreg_operand")
11371 (match_operand 2 "const_0_to_127_operand")))
11372 (const_string "SI")
11374 (const_string "QI")))
11375 ;; Potential partial reg stall on alternative 2.
11376 (set (attr "preferred_for_speed")
11377 (cond [(eq_attr "alternative" "2")
11378 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
11379 (symbol_ref "true")))])
11381 (define_insn "*and<mode>_2"
11382 [(set (reg FLAGS_REG)
11383 (compare (and:SWI124
11384 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
11385 (match_operand:SWI124 2 "<general_operand>" "<r><i>,<m>"))
11387 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>m,<r>")
11388 (and:SWI124 (match_dup 1) (match_dup 2)))]
11389 "ix86_match_ccmode (insn, CCNOmode)
11390 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
11391 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
11392 [(set_attr "type" "alu")
11393 (set_attr "mode" "<MODE>")])
11395 (define_insn "*andqi_ext<mode>_0"
11396 [(set (match_operand:QI 0 "nonimm_x64constmem_operand" "=QBc,m")
11399 (match_operator:SWI248 3 "extract_operator"
11400 [(match_operand 2 "int248_register_operand" "Q,Q")
11403 (match_operand:QI 1 "nonimm_x64constmem_operand" "0,0")))
11404 (clobber (reg:CC FLAGS_REG))]
11406 "and{b}\t{%h2, %0|%0, %h2}"
11407 [(set_attr "isa" "*,nox64")
11408 (set_attr "type" "alu")
11409 (set_attr "mode" "QI")])
11411 (define_expand "andqi_ext_1"
11413 [(set (zero_extract:HI (match_operand:HI 0 "register_operand")
11419 (zero_extract:HI (match_operand:HI 1 "register_operand")
11422 (match_operand:QI 2 "const_int_operand")) 0))
11423 (clobber (reg:CC FLAGS_REG))])])
11425 (define_insn "*andqi_ext<mode>_1"
11426 [(set (zero_extract:SWI248
11427 (match_operand 0 "int248_register_operand" "+Q,Q")
11433 (match_operator:SWI248 3 "extract_operator"
11434 [(match_operand 1 "int248_register_operand" "0,0")
11437 (match_operand:QI 2 "general_x64constmem_operand" "QnBc,m")) 0))
11438 (clobber (reg:CC FLAGS_REG))]
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 ;; Generated by peephole translating test to and. This shows up
11447 ;; often in fp comparisons.
11448 (define_insn "*andqi_ext<mode>_1_cc"
11449 [(set (reg FLAGS_REG)
11453 (match_operator:SWI248 3 "extract_operator"
11454 [(match_operand 1 "int248_register_operand" "0,0")
11457 (match_operand:QI 2 "general_x64constmem_operand" "QnBc,m"))
11459 (set (zero_extract:SWI248
11460 (match_operand 0 "int248_register_operand" "+Q,Q")
11470 (match_dup 2)) 0))]
11471 "ix86_match_ccmode (insn, CCNOmode)
11472 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
11473 && rtx_equal_p (operands[0], operands[1])"
11474 "and{b}\t{%2, %h0|%h0, %2}"
11475 [(set_attr "isa" "*,nox64")
11476 (set_attr "type" "alu")
11477 (set_attr "mode" "QI")])
11479 (define_insn "*andqi_ext<mode>_2"
11480 [(set (zero_extract:SWI248
11481 (match_operand 0 "int248_register_operand" "+Q")
11487 (match_operator:SWI248 3 "extract_operator"
11488 [(match_operand 1 "int248_register_operand" "%0")
11492 (match_operator:SWI248 4 "extract_operator"
11493 [(match_operand 2 "int248_register_operand" "Q")
11495 (const_int 8)]) 0)) 0))
11496 (clobber (reg:CC FLAGS_REG))]
11497 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
11498 rtx_equal_p (operands[0], operands[1])
11499 || rtx_equal_p (operands[0], operands[2])"
11500 "and{b}\t{%h2, %h0|%h0, %h2}"
11501 [(set_attr "type" "alu")
11502 (set_attr "mode" "QI")])
11504 ;; *andqi_ext<mode>_3 is defined via *<code>qi_ext<mode>_3 below.
11506 ;; Convert wide AND instructions with immediate operand to shorter QImode
11507 ;; equivalents when possible.
11508 ;; Don't do the splitting with memory operands, since it introduces risk
11509 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
11510 ;; for size, but that can (should?) be handled by generic code instead.
11512 [(set (match_operand:SWI248 0 "QIreg_operand")
11513 (and:SWI248 (match_operand:SWI248 1 "register_operand")
11514 (match_operand:SWI248 2 "const_int_operand")))
11515 (clobber (reg:CC FLAGS_REG))]
11517 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11518 && !(~INTVAL (operands[2]) & ~(255 << 8))"
11520 [(set (zero_extract:HI (match_dup 0)
11526 (zero_extract:HI (match_dup 1)
11530 (clobber (reg:CC FLAGS_REG))])]
11532 operands[0] = gen_lowpart (HImode, operands[0]);
11533 operands[1] = gen_lowpart (HImode, operands[1]);
11534 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
11537 ;; Since AND can be encoded with sign extended immediate, this is only
11538 ;; profitable when 7th bit is not set.
11540 [(set (match_operand:SWI248 0 "any_QIreg_operand")
11541 (and:SWI248 (match_operand:SWI248 1 "general_operand")
11542 (match_operand:SWI248 2 "const_int_operand")))
11543 (clobber (reg:CC FLAGS_REG))]
11545 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11546 && !(~INTVAL (operands[2]) & ~255)
11547 && !(INTVAL (operands[2]) & 128)"
11548 [(parallel [(set (strict_low_part (match_dup 0))
11549 (and:QI (match_dup 1)
11551 (clobber (reg:CC FLAGS_REG))])]
11553 operands[0] = gen_lowpart (QImode, operands[0]);
11554 operands[1] = gen_lowpart (QImode, operands[1]);
11555 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
11558 (define_insn_and_split "*andn<dwi>3_doubleword_bmi"
11559 [(set (match_operand:<DWI> 0 "register_operand" "=&r,r,r")
11561 (not:<DWI> (match_operand:<DWI> 1 "register_operand" "r,0,r"))
11562 (match_operand:<DWI> 2 "nonimmediate_operand" "ro,ro,0")))
11563 (clobber (reg:CC FLAGS_REG))]
11566 "&& reload_completed"
11567 [(parallel [(set (match_dup 0)
11568 (and:DWIH (not:DWIH (match_dup 1)) (match_dup 2)))
11569 (clobber (reg:CC FLAGS_REG))])
11570 (parallel [(set (match_dup 3)
11571 (and:DWIH (not:DWIH (match_dup 4)) (match_dup 5)))
11572 (clobber (reg:CC FLAGS_REG))])]
11573 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
11575 (define_insn_and_split "*andn<mode>3_doubleword"
11576 [(set (match_operand:DWI 0 "register_operand")
11578 (not:DWI (match_operand:DWI 1 "register_operand"))
11579 (match_operand:DWI 2 "nonimmediate_operand")))
11580 (clobber (reg:CC FLAGS_REG))]
11582 && ix86_pre_reload_split ()"
11585 [(set (match_dup 3) (not:DWI (match_dup 1)))
11586 (parallel [(set (match_dup 0)
11587 (and:DWI (match_dup 3) (match_dup 2)))
11588 (clobber (reg:CC FLAGS_REG))])]
11589 "operands[3] = gen_reg_rtx (<MODE>mode);")
11591 (define_insn "*andn<mode>_1"
11592 [(set (match_operand:SWI48 0 "register_operand" "=r,r,?k")
11594 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r,k"))
11595 (match_operand:SWI48 2 "nonimmediate_operand" "r,m,k")))
11596 (clobber (reg:CC FLAGS_REG))]
11597 "TARGET_BMI || TARGET_AVX512BW"
11599 andn\t{%2, %1, %0|%0, %1, %2}
11600 andn\t{%2, %1, %0|%0, %1, %2}
11602 [(set_attr "isa" "bmi,bmi,avx512bw")
11603 (set_attr "type" "bitmanip,bitmanip,msklog")
11604 (set_attr "btver2_decode" "direct, double,*")
11605 (set_attr "mode" "<MODE>")])
11607 (define_insn "*andn<mode>_1"
11608 [(set (match_operand:SWI12 0 "register_operand" "=r,?k")
11610 (not:SWI12 (match_operand:SWI12 1 "register_operand" "r,k"))
11611 (match_operand:SWI12 2 "register_operand" "r,k")))
11612 (clobber (reg:CC FLAGS_REG))]
11613 "TARGET_BMI || TARGET_AVX512BW"
11615 andn\t{%k2, %k1, %k0|%k0, %k1, %k2}
11617 [(set_attr "isa" "bmi,avx512f")
11618 (set_attr "type" "bitmanip,msklog")
11619 (set_attr "btver2_decode" "direct,*")
11621 (cond [(eq_attr "alternative" "0")
11622 (const_string "SI")
11623 (and (eq_attr "alternative" "1")
11624 (match_test "!TARGET_AVX512DQ"))
11625 (const_string "HI")
11627 (const_string "<MODE>")))])
11629 (define_insn "*andn_<mode>_ccno"
11630 [(set (reg FLAGS_REG)
11633 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
11634 (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
11636 (clobber (match_scratch:SWI48 0 "=r,r"))]
11637 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
11638 "andn\t{%2, %1, %0|%0, %1, %2}"
11639 [(set_attr "type" "bitmanip")
11640 (set_attr "btver2_decode" "direct, double")
11641 (set_attr "mode" "<MODE>")])
11643 ;; Split *andnsi_1 after reload with -Oz when not;and is shorter.
11645 [(set (match_operand:SI 0 "register_operand")
11646 (and:SI (not:SI (match_operand:SI 1 "register_operand"))
11647 (match_operand:SI 2 "nonimmediate_operand")))
11648 (clobber (reg:CC FLAGS_REG))]
11650 && optimize_insn_for_size_p () && optimize_size > 1
11651 && REGNO (operands[0]) == REGNO (operands[1])
11652 && LEGACY_INT_REG_P (operands[0])
11653 && !REX_INT_REG_P (operands[2])
11654 && !reg_overlap_mentioned_p (operands[0], operands[2])"
11655 [(set (match_dup 0) (not:SI (match_dup 1)))
11656 (parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
11657 (clobber (reg:CC FLAGS_REG))])])
11659 ;; Split *andn_si_ccno with -Oz when not;test is shorter.
11661 [(set (match_operand 0 "flags_reg_operand")
11662 (match_operator 1 "compare_operator"
11663 [(and:SI (not:SI (match_operand:SI 2 "general_reg_operand"))
11664 (match_operand:SI 3 "nonimmediate_operand"))
11666 (clobber (match_dup 2))]
11668 && optimize_insn_for_size_p () && optimize_size > 1
11669 && LEGACY_INT_REG_P (operands[2])
11670 && !REX_INT_REG_P (operands[3])
11671 && !reg_overlap_mentioned_p (operands[2], operands[3])"
11672 [(set (match_dup 2) (not:SI (match_dup 2)))
11673 (set (match_dup 0) (match_op_dup 1
11674 [(and:SI (match_dup 3) (match_dup 2))
11677 ;; Variant 1 of 4: Split ((A | B) ^ A) ^ C as (B & ~A) ^ C.
11679 [(set (match_operand:SWI48 0 "register_operand")
11682 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
11683 (match_operand:SWI48 2 "nonimmediate_operand"))
11685 (match_operand:SWI48 3 "nonimmediate_operand")))
11686 (clobber (reg:CC FLAGS_REG))]
11689 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 1)) (match_dup 2)))
11690 (clobber (reg:CC FLAGS_REG))])
11692 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
11693 (clobber (reg:CC FLAGS_REG))])]
11694 "operands[4] = gen_reg_rtx (<MODE>mode);")
11696 ;; Variant 2 of 4: Split ((A | B) ^ B) ^ C as (A & ~B) ^ C.
11698 [(set (match_operand:SWI48 0 "register_operand")
11701 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
11702 (match_operand:SWI48 2 "register_operand"))
11704 (match_operand:SWI48 3 "nonimmediate_operand")))
11705 (clobber (reg:CC FLAGS_REG))]
11708 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 2)) (match_dup 1)))
11709 (clobber (reg:CC FLAGS_REG))])
11711 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
11712 (clobber (reg:CC FLAGS_REG))])]
11713 "operands[4] = gen_reg_rtx (<MODE>mode);")
11715 ;; Variant 3 of 4: Split ((A | B) ^ C) ^ A as (B & ~A) ^ C.
11717 [(set (match_operand:SWI48 0 "register_operand")
11720 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
11721 (match_operand:SWI48 2 "nonimmediate_operand"))
11722 (match_operand:SWI48 3 "nonimmediate_operand"))
11724 (clobber (reg:CC FLAGS_REG))]
11727 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 1)) (match_dup 2)))
11728 (clobber (reg:CC FLAGS_REG))])
11730 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
11731 (clobber (reg:CC FLAGS_REG))])]
11732 "operands[4] = gen_reg_rtx (<MODE>mode);")
11734 ;; Variant 4 of 4: Split ((A | B) ^ C) ^ B as (A & ~B) ^ C.
11736 [(set (match_operand:SWI48 0 "register_operand")
11739 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
11740 (match_operand:SWI48 2 "register_operand"))
11741 (match_operand:SWI48 3 "nonimmediate_operand"))
11743 (clobber (reg:CC FLAGS_REG))]
11746 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 2)) (match_dup 1)))
11747 (clobber (reg:CC FLAGS_REG))])
11749 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
11750 (clobber (reg:CC FLAGS_REG))])]
11751 "operands[4] = gen_reg_rtx (<MODE>mode);")
11753 ;; Logical inclusive and exclusive OR instructions
11755 ;; %%% This used to optimize known byte-wide and operations to memory.
11756 ;; If this is considered useful, it should be done with splitters.
11758 (define_expand "<code><mode>3"
11759 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
11760 (any_or:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
11761 (match_operand:SDWIM 2 "<general_operand>")))]
11764 if (GET_MODE_SIZE (<MODE>mode) > UNITS_PER_WORD
11765 && !x86_64_hilo_general_operand (operands[2], <MODE>mode))
11766 operands[2] = force_reg (<MODE>mode, operands[2]);
11768 ix86_expand_binary_operator (<CODE>, <MODE>mode, operands);
11772 (define_insn_and_split "*<code><dwi>3_doubleword"
11773 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
11775 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
11776 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
11777 (clobber (reg:CC FLAGS_REG))]
11778 "ix86_binary_operator_ok (<CODE>, <DWI>mode, operands)"
11780 "&& reload_completed"
11781 [(const_int:DWIH 0)]
11783 /* This insn may disappear completely when operands[2] == const0_rtx
11784 and operands[0] == operands[1], which requires a NOTE_INSN_DELETED. */
11785 bool emit_insn_deleted_note_p = false;
11787 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
11789 if (operands[2] == const0_rtx)
11790 emit_insn_deleted_note_p = true;
11791 else if (operands[2] == constm1_rtx)
11794 emit_move_insn (operands[0], constm1_rtx);
11796 ix86_expand_unary_operator (NOT, <MODE>mode, &operands[0]);
11799 ix86_expand_binary_operator (<CODE>, <MODE>mode, &operands[0]);
11801 if (operands[5] == const0_rtx)
11803 if (emit_insn_deleted_note_p)
11804 emit_note (NOTE_INSN_DELETED);
11806 else if (operands[5] == constm1_rtx)
11809 emit_move_insn (operands[3], constm1_rtx);
11811 ix86_expand_unary_operator (NOT, <MODE>mode, &operands[3]);
11814 ix86_expand_binary_operator (<CODE>, <MODE>mode, &operands[3]);
11819 (define_insn "*<code><mode>_1"
11820 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,?k")
11822 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,k")
11823 (match_operand:SWI248 2 "<general_operand>" "r<i>,<m>,k")))
11824 (clobber (reg:CC FLAGS_REG))]
11825 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11827 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
11828 <logic>{<imodesuffix>}\t{%2, %0|%0, %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 "*notxor<mode>_1"
11841 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,?k")
11844 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,k")
11845 (match_operand:SWI248 2 "<general_operand>" "r<i>,<m>,k"))))
11846 (clobber (reg:CC FLAGS_REG))]
11847 "ix86_binary_operator_ok (XOR, <MODE>mode, operands)"
11849 "&& reload_completed"
11851 [(set (match_dup 0)
11852 (xor:SWI248 (match_dup 1) (match_dup 2)))
11853 (clobber (reg:CC FLAGS_REG))])
11855 (not:SWI248 (match_dup 0)))]
11857 if (MASK_REG_P (operands[0]))
11859 emit_insn (gen_kxnor<mode> (operands[0], operands[1], operands[2]));
11864 (cond [(eq_attr "alternative" "2")
11865 (if_then_else (eq_attr "mode" "SI,DI")
11866 (const_string "avx512bw")
11867 (const_string "avx512f"))
11869 (const_string "*")))
11870 (set_attr "type" "alu, alu, msklog")
11871 (set_attr "mode" "<MODE>")])
11873 (define_insn_and_split "*iordi_1_bts"
11874 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11876 (match_operand:DI 1 "nonimmediate_operand" "%0")
11877 (match_operand:DI 2 "const_int_operand" "n")))
11878 (clobber (reg:CC FLAGS_REG))]
11879 "TARGET_64BIT && TARGET_USE_BT
11880 && ix86_binary_operator_ok (IOR, DImode, operands)
11881 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
11883 "&& reload_completed"
11884 [(parallel [(set (zero_extract:DI (match_dup 0)
11888 (clobber (reg:CC FLAGS_REG))])]
11889 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
11890 [(set_attr "type" "alu1")
11891 (set_attr "prefix_0f" "1")
11892 (set_attr "znver1_decode" "double")
11893 (set_attr "mode" "DI")])
11895 (define_insn_and_split "*xordi_1_btc"
11896 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11898 (match_operand:DI 1 "nonimmediate_operand" "%0")
11899 (match_operand:DI 2 "const_int_operand" "n")))
11900 (clobber (reg:CC FLAGS_REG))]
11901 "TARGET_64BIT && TARGET_USE_BT
11902 && ix86_binary_operator_ok (XOR, DImode, operands)
11903 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
11905 "&& reload_completed"
11906 [(parallel [(set (zero_extract:DI (match_dup 0)
11909 (not:DI (zero_extract:DI (match_dup 0)
11912 (clobber (reg:CC FLAGS_REG))])]
11913 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
11914 [(set_attr "type" "alu1")
11915 (set_attr "prefix_0f" "1")
11916 (set_attr "znver1_decode" "double")
11917 (set_attr "mode" "DI")])
11919 ;; Optimize a ^ ((a ^ b) & mask) to (~mask & a) | (b & mask)
11920 (define_insn_and_split "*xor2andn"
11921 [(set (match_operand:SWI248 0 "register_operand")
11925 (match_operand:SWI248 1 "nonimmediate_operand")
11926 (match_operand:SWI248 2 "nonimmediate_operand"))
11927 (match_operand:SWI248 3 "nonimmediate_operand"))
11929 (clobber (reg:CC FLAGS_REG))]
11930 "TARGET_BMI && ix86_pre_reload_split ()"
11933 [(parallel [(set (match_dup 4)
11938 (clobber (reg:CC FLAGS_REG))])
11939 (parallel [(set (match_dup 5)
11943 (clobber (reg:CC FLAGS_REG))])
11944 (parallel [(set (match_dup 0)
11948 (clobber (reg:CC FLAGS_REG))])]
11950 operands[1] = force_reg (<MODE>mode, operands[1]);
11951 operands[3] = force_reg (<MODE>mode, operands[3]);
11952 operands[4] = gen_reg_rtx (<MODE>mode);
11953 operands[5] = gen_reg_rtx (<MODE>mode);
11956 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
11957 (define_insn "*<code>si_1_zext"
11958 [(set (match_operand:DI 0 "register_operand" "=r")
11960 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
11961 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
11962 (clobber (reg:CC FLAGS_REG))]
11963 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11964 "<logic>{l}\t{%2, %k0|%k0, %2}"
11965 [(set_attr "type" "alu")
11966 (set_attr "mode" "SI")])
11968 (define_insn "*<code>si_1_zext_imm"
11969 [(set (match_operand:DI 0 "register_operand" "=r")
11971 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
11972 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
11973 (clobber (reg:CC FLAGS_REG))]
11974 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11975 "<logic>{l}\t{%2, %k0|%k0, %2}"
11976 [(set_attr "type" "alu")
11977 (set_attr "mode" "SI")])
11979 (define_insn "*<code>qi_1"
11980 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,?k")
11981 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
11982 (match_operand:QI 2 "general_operand" "qn,m,rn,k")))
11983 (clobber (reg:CC FLAGS_REG))]
11984 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
11986 <logic>{b}\t{%2, %0|%0, %2}
11987 <logic>{b}\t{%2, %0|%0, %2}
11988 <logic>{l}\t{%k2, %k0|%k0, %k2}
11990 [(set_attr "isa" "*,*,*,avx512f")
11991 (set_attr "type" "alu,alu,alu,msklog")
11993 (cond [(eq_attr "alternative" "2")
11994 (const_string "SI")
11995 (and (eq_attr "alternative" "3")
11996 (match_test "!TARGET_AVX512DQ"))
11997 (const_string "HI")
11999 (const_string "QI")))
12000 ;; Potential partial reg stall on alternative 2.
12001 (set (attr "preferred_for_speed")
12002 (cond [(eq_attr "alternative" "2")
12003 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
12004 (symbol_ref "true")))])
12006 (define_insn_and_split "*notxorqi_1"
12007 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,?k")
12009 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
12010 (match_operand:QI 2 "general_operand" "qn,m,rn,k"))))
12011 (clobber (reg:CC FLAGS_REG))]
12012 "ix86_binary_operator_ok (XOR, QImode, operands)"
12014 "&& reload_completed"
12016 [(set (match_dup 0)
12017 (xor:QI (match_dup 1) (match_dup 2)))
12018 (clobber (reg:CC FLAGS_REG))])
12020 (not:QI (match_dup 0)))]
12022 if (mask_reg_operand (operands[0], QImode))
12024 emit_insn (gen_kxnorqi (operands[0], operands[1], operands[2]));
12028 [(set_attr "isa" "*,*,*,avx512f")
12029 (set_attr "type" "alu,alu,alu,msklog")
12031 (cond [(eq_attr "alternative" "2")
12032 (const_string "SI")
12033 (and (eq_attr "alternative" "3")
12034 (match_test "!TARGET_AVX512DQ"))
12035 (const_string "HI")
12037 (const_string "QI")))
12038 ;; Potential partial reg stall on alternative 2.
12039 (set (attr "preferred_for_speed")
12040 (cond [(eq_attr "alternative" "2")
12041 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
12042 (symbol_ref "true")))])
12044 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
12045 (define_insn_and_split "*<code><mode>_1_slp"
12046 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
12047 (any_or:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0,!<r>")
12048 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
12049 (clobber (reg:CC FLAGS_REG))]
12050 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
12052 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
12054 "&& reload_completed"
12055 [(set (strict_low_part (match_dup 0)) (match_dup 1))
12057 [(set (strict_low_part (match_dup 0))
12058 (any_or:SWI12 (match_dup 0) (match_dup 2)))
12059 (clobber (reg:CC FLAGS_REG))])]
12061 [(set_attr "type" "alu")
12062 (set_attr "mode" "<MODE>")])
12064 ;; convert (sign_extend:WIDE (any_logic:NARROW (memory, immediate)))
12065 ;; to (any_logic:WIDE (sign_extend (memory)), (sign_extend (immediate))).
12066 ;; This eliminates sign extension after logic operation.
12069 [(set (match_operand:SWI248 0 "register_operand")
12070 (sign_extend:SWI248
12071 (any_logic:QI (match_operand:QI 1 "memory_operand")
12072 (match_operand:QI 2 "const_int_operand"))))]
12074 [(set (match_dup 3) (sign_extend:SWI248 (match_dup 1)))
12075 (set (match_dup 0) (any_logic:SWI248 (match_dup 3) (match_dup 2)))]
12076 "operands[3] = gen_reg_rtx (<MODE>mode);")
12079 [(set (match_operand:SWI48 0 "register_operand")
12081 (any_logic:HI (match_operand:HI 1 "memory_operand")
12082 (match_operand:HI 2 "const_int_operand"))))]
12084 [(set (match_dup 3) (sign_extend:SWI48 (match_dup 1)))
12085 (set (match_dup 0) (any_logic:SWI48 (match_dup 3) (match_dup 2)))]
12086 "operands[3] = gen_reg_rtx (<MODE>mode);")
12089 [(set (match_operand:DI 0 "register_operand")
12091 (any_logic:SI (match_operand:SI 1 "memory_operand")
12092 (match_operand:SI 2 "const_int_operand"))))]
12094 [(set (match_dup 3) (sign_extend:DI (match_dup 1)))
12095 (set (match_dup 0) (any_logic:DI (match_dup 3) (match_dup 2)))]
12096 "operands[3] = gen_reg_rtx (DImode);")
12098 (define_insn "*<code><mode>_2"
12099 [(set (reg FLAGS_REG)
12100 (compare (any_or:SWI
12101 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
12102 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
12104 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
12105 (any_or:SWI (match_dup 1) (match_dup 2)))]
12106 "ix86_match_ccmode (insn, CCNOmode)
12107 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
12108 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
12109 [(set_attr "type" "alu")
12110 (set_attr "mode" "<MODE>")])
12112 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
12113 ;; ??? Special case for immediate operand is missing - it is tricky.
12114 (define_insn "*<code>si_2_zext"
12115 [(set (reg FLAGS_REG)
12116 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
12117 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
12119 (set (match_operand:DI 0 "register_operand" "=r")
12120 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
12121 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
12122 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12123 "<logic>{l}\t{%2, %k0|%k0, %2}"
12124 [(set_attr "type" "alu")
12125 (set_attr "mode" "SI")])
12127 (define_insn "*<code>si_2_zext_imm"
12128 [(set (reg FLAGS_REG)
12129 (compare (any_or:SI
12130 (match_operand:SI 1 "nonimmediate_operand" "%0")
12131 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
12133 (set (match_operand:DI 0 "register_operand" "=r")
12134 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12135 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
12136 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12137 "<logic>{l}\t{%2, %k0|%k0, %2}"
12138 [(set_attr "type" "alu")
12139 (set_attr "mode" "SI")])
12141 (define_insn "*<code><mode>_3"
12142 [(set (reg FLAGS_REG)
12143 (compare (any_or:SWI
12144 (match_operand:SWI 1 "nonimmediate_operand" "%0")
12145 (match_operand:SWI 2 "<general_operand>" "<g>"))
12147 (clobber (match_scratch:SWI 0 "=<r>"))]
12148 "ix86_match_ccmode (insn, CCNOmode)
12149 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12150 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
12151 [(set_attr "type" "alu")
12152 (set_attr "mode" "<MODE>")])
12154 (define_insn "*<code>qi_ext<mode>_0"
12155 [(set (match_operand:QI 0 "nonimm_x64constmem_operand" "=QBc,m")
12158 (match_operator:SWI248 3 "extract_operator"
12159 [(match_operand 2 "int248_register_operand" "Q,Q")
12162 (match_operand:QI 1 "nonimm_x64constmem_operand" "0,0")))
12163 (clobber (reg:CC FLAGS_REG))]
12165 "<logic>{b}\t{%h2, %0|%0, %h2}"
12166 [(set_attr "isa" "*,nox64")
12167 (set_attr "type" "alu")
12168 (set_attr "mode" "QI")])
12170 (define_insn "*<code>qi_ext<mode>_1"
12171 [(set (zero_extract:SWI248
12172 (match_operand 0 "int248_register_operand" "+Q,Q")
12178 (match_operator:SWI248 3 "extract_operator"
12179 [(match_operand 1 "int248_register_operand" "0,0")
12182 (match_operand:QI 2 "general_x64constmem_operand" "QnBc,m")) 0))
12183 (clobber (reg:CC FLAGS_REG))]
12184 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12185 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
12186 && rtx_equal_p (operands[0], operands[1])"
12187 "<logic>{b}\t{%2, %h0|%h0, %2}"
12188 [(set_attr "isa" "*,nox64")
12189 (set_attr "type" "alu")
12190 (set_attr "mode" "QI")])
12192 (define_insn "*<code>qi_ext<mode>_2"
12193 [(set (zero_extract:SWI248
12194 (match_operand 0 "int248_register_operand" "+Q")
12200 (match_operator:SWI248 3 "extract_operator"
12201 [(match_operand 1 "int248_register_operand" "%0")
12205 (match_operator:SWI248 4 "extract_operator"
12206 [(match_operand 2 "int248_register_operand" "Q")
12208 (const_int 8)]) 0)) 0))
12209 (clobber (reg:CC FLAGS_REG))]
12210 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12211 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
12212 && (rtx_equal_p (operands[0], operands[1])
12213 || rtx_equal_p (operands[0], operands[2]))"
12214 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
12215 [(set_attr "type" "alu")
12216 (set_attr "mode" "QI")])
12218 (define_insn "*<code>qi_ext<mode>_3"
12219 [(set (zero_extract:SWI248
12220 (match_operand 0 "int248_register_operand" "+Q")
12223 (zero_extract:SWI248
12225 (match_operand 1 "int248_register_operand" "%0")
12226 (match_operand 2 "int248_register_operand" "Q"))
12229 (clobber (reg:CC FLAGS_REG))]
12230 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12231 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
12232 && (rtx_equal_p (operands[0], operands[1])
12233 || rtx_equal_p (operands[0], operands[2]))"
12234 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
12235 [(set_attr "type" "alu")
12236 (set_attr "mode" "QI")])
12238 ;; Convert wide OR instructions with immediate operand to shorter QImode
12239 ;; equivalents when possible.
12240 ;; Don't do the splitting with memory operands, since it introduces risk
12241 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
12242 ;; for size, but that can (should?) be handled by generic code instead.
12244 [(set (match_operand:SWI248 0 "QIreg_operand")
12245 (any_or:SWI248 (match_operand:SWI248 1 "register_operand")
12246 (match_operand:SWI248 2 "const_int_operand")))
12247 (clobber (reg:CC FLAGS_REG))]
12249 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12250 && !(INTVAL (operands[2]) & ~(255 << 8))"
12252 [(set (zero_extract:HI (match_dup 0)
12258 (zero_extract:HI (match_dup 1)
12262 (clobber (reg:CC FLAGS_REG))])]
12264 /* Handle the case where INTVAL (operands[2]) == 0. */
12265 if (operands[2] == const0_rtx)
12267 if (!rtx_equal_p (operands[0], operands[1]))
12268 emit_move_insn (operands[0], operands[1]);
12270 emit_note (NOTE_INSN_DELETED);
12273 operands[0] = gen_lowpart (HImode, operands[0]);
12274 operands[1] = gen_lowpart (HImode, operands[1]);
12275 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
12278 ;; Since OR can be encoded with sign extended immediate, this is only
12279 ;; profitable when 7th bit is set.
12281 [(set (match_operand:SWI248 0 "any_QIreg_operand")
12282 (any_or:SWI248 (match_operand:SWI248 1 "general_operand")
12283 (match_operand:SWI248 2 "const_int_operand")))
12284 (clobber (reg:CC FLAGS_REG))]
12286 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12287 && !(INTVAL (operands[2]) & ~255)
12288 && (INTVAL (operands[2]) & 128)"
12289 [(parallel [(set (strict_low_part (match_dup 0))
12290 (any_or:QI (match_dup 1)
12292 (clobber (reg:CC FLAGS_REG))])]
12294 operands[0] = gen_lowpart (QImode, operands[0]);
12295 operands[1] = gen_lowpart (QImode, operands[1]);
12296 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
12299 (define_expand "xorqi_ext_1_cc"
12301 [(set (reg:CCNO FLAGS_REG)
12305 (zero_extract:HI (match_operand:HI 1 "register_operand")
12308 (match_operand:QI 2 "const_int_operand"))
12310 (set (zero_extract:HI (match_operand:HI 0 "register_operand")
12316 (zero_extract:HI (match_dup 1)
12319 (match_dup 2)) 0))])])
12321 (define_insn "*xorqi_ext<mode>_1_cc"
12322 [(set (reg FLAGS_REG)
12326 (match_operator:SWI248 3 "extract_operator"
12327 [(match_operand 1 "int248_register_operand" "0,0")
12330 (match_operand:QI 2 "general_x64constmem_operand" "QnBc,m"))
12332 (set (zero_extract:SWI248
12333 (match_operand 0 "int248_register_operand" "+Q,Q")
12343 (match_dup 2)) 0))]
12344 "ix86_match_ccmode (insn, CCNOmode)
12345 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
12346 && rtx_equal_p (operands[0], operands[1])"
12347 "xor{b}\t{%2, %h0|%h0, %2}"
12348 [(set_attr "isa" "*,nox64")
12349 (set_attr "type" "alu")
12350 (set_attr "mode" "QI")])
12352 ;; Peephole2 rega = 0; rega op= regb into rega = regb.
12354 [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
12356 (clobber (reg:CC FLAGS_REG))])
12357 (parallel [(set (match_dup 0)
12358 (any_or_plus:SWI (match_dup 0)
12359 (match_operand:SWI 1 "<general_operand>")))
12360 (clobber (reg:CC FLAGS_REG))])]
12361 "!reg_mentioned_p (operands[0], operands[1])"
12362 [(set (match_dup 0) (match_dup 1))])
12364 ;; Peephole2 dead instruction in rega = 0; rega op= rega.
12366 [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
12368 (clobber (reg:CC FLAGS_REG))])
12369 (parallel [(set (match_dup 0)
12370 (any_or_plus:SWI (match_dup 0) (match_dup 0)))
12371 (clobber (reg:CC FLAGS_REG))])]
12373 [(parallel [(set (match_dup 0) (const_int 0))
12374 (clobber (reg:CC FLAGS_REG))])])
12376 ;; Split DST = (HI<<32)|LO early to minimize register usage.
12377 (define_insn_and_split "*concat<mode><dwi>3_1"
12378 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
12380 (ashift:<DWI> (match_operand:<DWI> 1 "register_operand" "r,r")
12381 (match_operand:QI 2 "const_int_operand"))
12383 (match_operand:DWIH 3 "nonimmediate_operand" "r,m"))))]
12384 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT"
12386 "&& reload_completed"
12389 split_double_concat (<DWI>mode, operands[0], operands[3],
12390 gen_lowpart (<MODE>mode, operands[1]));
12394 (define_insn_and_split "*concat<mode><dwi>3_2"
12395 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
12398 (match_operand:DWIH 1 "nonimmediate_operand" "r,m"))
12399 (ashift:<DWI> (match_operand:<DWI> 2 "register_operand" "r,r")
12400 (match_operand:QI 3 "const_int_operand"))))]
12401 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12403 "&& reload_completed"
12406 split_double_concat (<DWI>mode, operands[0], operands[1],
12407 gen_lowpart (<MODE>mode, operands[2]));
12411 (define_insn_and_split "*concatditi3_3"
12412 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro,r,r,&r,x")
12416 (match_operand:DI 1 "nonimmediate_operand" "r,m,r,m,x"))
12417 (match_operand:QI 2 "const_int_operand"))
12419 (match_operand:DI 3 "nonimmediate_operand" "r,r,m,m,0"))))]
12421 && INTVAL (operands[2]) == 64"
12423 "&& reload_completed"
12426 if (SSE_REG_P (operands[0]))
12428 rtx tmp = gen_rtx_REG (V2DImode, REGNO (operands[0]));
12429 emit_insn (gen_vec_concatv2di (tmp, operands[3], operands[1]));
12432 split_double_concat (TImode, operands[0], operands[3], operands[1]);
12436 (define_insn_and_split "*concatsidi3_3"
12437 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro,r,r,&r")
12441 (match_operand:SI 1 "nonimmediate_operand" "r,m,r,m"))
12442 (match_operand:QI 2 "const_int_operand"))
12444 (match_operand:SI 3 "nonimmediate_operand" "r,r,m,m"))))]
12446 && INTVAL (operands[2]) == 32"
12448 "&& reload_completed"
12451 split_double_concat (DImode, operands[0], operands[3], operands[1]);
12455 (define_insn_and_split "*concat<mode><dwi>3_4"
12456 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,r,&r")
12459 (match_operand:DWIH 1 "nonimmediate_operand" "r,m,r,m"))
12462 (match_operand:DWIH 2 "nonimmediate_operand" "r,r,m,m"))
12463 (match_operand:QI 3 "const_int_operand"))))]
12464 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12466 "&& reload_completed"
12469 split_double_concat (<DWI>mode, operands[0], operands[1], operands[2]);
12473 (define_insn_and_split "*concat<half><mode>3_5"
12474 [(set (match_operand:DWI 0 "nonimmediate_operand" "=r,o,o")
12476 (ashift:DWI (match_operand:DWI 1 "register_operand" "r,r,r")
12477 (match_operand:QI 2 "const_int_operand"))
12478 (match_operand:DWI 3 "const_scalar_int_operand" "n,n,Wd")))]
12479 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT / 2
12480 && (<MODE>mode == DImode
12481 ? CONST_INT_P (operands[3])
12482 && (UINTVAL (operands[3]) & ~GET_MODE_MASK (SImode)) == 0
12483 : CONST_INT_P (operands[3])
12484 ? INTVAL (operands[3]) >= 0
12485 : CONST_WIDE_INT_NUNITS (operands[3]) == 2
12486 && CONST_WIDE_INT_ELT (operands[3], 1) == 0)
12487 && !(CONST_INT_P (operands[3])
12488 ? ix86_endbr_immediate_operand (operands[3], VOIDmode)
12489 : ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[3],
12493 "&& reload_completed"
12496 rtx op3 = simplify_subreg (<HALF>mode, operands[3], <MODE>mode, 0);
12497 split_double_concat (<MODE>mode, operands[0], op3,
12498 gen_lowpart (<HALF>mode, operands[1]));
12501 [(set_attr "isa" "*,nox64,x64")])
12503 (define_insn_and_split "*concat<mode><dwi>3_6"
12504 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,o,r")
12508 (match_operand:DWIH 1 "nonimmediate_operand" "r,r,r,m"))
12509 (match_operand:QI 2 "const_int_operand"))
12510 (match_operand:<DWI> 3 "const_scalar_int_operand" "n,n,Wd,n")))]
12511 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT
12512 && (<DWI>mode == DImode
12513 ? CONST_INT_P (operands[3])
12514 && (UINTVAL (operands[3]) & ~GET_MODE_MASK (SImode)) == 0
12515 : CONST_INT_P (operands[3])
12516 ? INTVAL (operands[3]) >= 0
12517 : CONST_WIDE_INT_NUNITS (operands[3]) == 2
12518 && CONST_WIDE_INT_ELT (operands[3], 1) == 0)
12519 && !(CONST_INT_P (operands[3])
12520 ? ix86_endbr_immediate_operand (operands[3], VOIDmode)
12521 : ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[3],
12525 "&& reload_completed"
12528 rtx op3 = simplify_subreg (<MODE>mode, operands[3], <DWI>mode, 0);
12529 split_double_concat (<DWI>mode, operands[0], op3, operands[1]);
12532 [(set_attr "isa" "*,nox64,x64,*")])
12534 (define_insn_and_split "*concat<mode><dwi>3_7"
12535 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,o,r")
12538 (match_operand:DWIH 1 "nonimmediate_operand" "r,r,r,m"))
12539 (match_operand:<DWI> 2 "const_scalar_int_operand" "n,n,Wd,n")))]
12540 "<DWI>mode == DImode
12541 ? CONST_INT_P (operands[2])
12542 && (UINTVAL (operands[2]) & GET_MODE_MASK (SImode)) == 0
12543 && !ix86_endbr_immediate_operand (operands[2], VOIDmode)
12544 : CONST_WIDE_INT_P (operands[2])
12545 && CONST_WIDE_INT_NUNITS (operands[2]) == 2
12546 && CONST_WIDE_INT_ELT (operands[2], 0) == 0
12547 && !ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[2],
12551 "&& reload_completed"
12555 if (<DWI>mode == DImode)
12556 op2 = gen_int_mode (INTVAL (operands[2]) >> 32, <MODE>mode);
12558 op2 = gen_int_mode (CONST_WIDE_INT_ELT (operands[2], 1), <MODE>mode);
12559 split_double_concat (<DWI>mode, operands[0], operands[1], op2);
12562 [(set_attr "isa" "*,nox64,x64,*")])
12564 ;; Negation instructions
12566 (define_expand "neg<mode>2"
12567 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
12568 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
12570 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
12572 (define_insn_and_split "*neg<dwi>2_doubleword"
12573 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
12574 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
12575 (clobber (reg:CC FLAGS_REG))]
12576 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
12578 "&& reload_completed"
12580 [(set (reg:CCC FLAGS_REG)
12581 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
12582 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
12584 [(set (match_dup 2)
12585 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
12588 (clobber (reg:CC FLAGS_REG))])
12590 [(set (match_dup 2)
12591 (neg:DWIH (match_dup 2)))
12592 (clobber (reg:CC FLAGS_REG))])]
12593 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
12606 [(set (match_operand:SWI48 0 "general_reg_operand")
12607 (match_operand:SWI48 1 "nonimmediate_gr_operand"))
12609 [(set (reg:CCC FLAGS_REG)
12610 (unspec:CCC [(match_operand:SWI48 2 "general_reg_operand")
12611 (const_int 0)] UNSPEC_CC_NE))
12612 (set (match_dup 2) (neg:SWI48 (match_dup 2)))])
12614 [(set (match_dup 0)
12615 (plus:SWI48 (plus:SWI48
12616 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
12619 (clobber (reg:CC FLAGS_REG))])
12621 [(set (match_dup 0)
12622 (neg:SWI48 (match_dup 0)))
12623 (clobber (reg:CC FLAGS_REG))])]
12624 "REGNO (operands[0]) != REGNO (operands[2])
12625 && !reg_mentioned_p (operands[0], operands[1])
12626 && !reg_mentioned_p (operands[2], operands[1])"
12628 [(set (reg:CCC FLAGS_REG)
12629 (unspec:CCC [(match_dup 2) (const_int 0)] UNSPEC_CC_NE))
12630 (set (match_dup 2) (neg:SWI48 (match_dup 2)))])
12632 [(set (match_dup 0)
12633 (minus:SWI48 (minus:SWI48
12635 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0)))
12637 (clobber (reg:CC FLAGS_REG))])]
12638 "ix86_expand_clear (operands[0]);")
12647 ;; sbbl %edx, %edx // *x86_mov<mode>cc_0_m1
12651 [(set (match_operand:SWI48 0 "general_reg_operand") (const_int 0))
12652 (clobber (reg:CC FLAGS_REG))])
12654 [(set (reg:CCC FLAGS_REG)
12655 (unspec:CCC [(match_operand:SWI48 1 "general_reg_operand")
12656 (const_int 0)] UNSPEC_CC_NE))
12657 (set (match_dup 1) (neg:SWI48 (match_dup 1)))])
12659 [(set (match_dup 0)
12660 (plus:SWI48 (plus:SWI48
12661 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
12664 (clobber (reg:CC FLAGS_REG))])
12666 [(set (match_dup 0)
12667 (neg:SWI48 (match_dup 0)))
12668 (clobber (reg:CC FLAGS_REG))])]
12669 "REGNO (operands[0]) != REGNO (operands[1])"
12671 [(set (reg:CCC FLAGS_REG)
12672 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
12673 (set (match_dup 1) (neg:SWI48 (match_dup 1)))])
12675 [(set (match_dup 0)
12676 (if_then_else:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
12679 (clobber (reg:CC FLAGS_REG))])])
12681 (define_insn "*neg<mode>_1"
12682 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
12683 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
12684 (clobber (reg:CC FLAGS_REG))]
12685 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
12686 "neg{<imodesuffix>}\t%0"
12687 [(set_attr "type" "negnot")
12688 (set_attr "mode" "<MODE>")])
12690 (define_insn "*negsi_1_zext"
12691 [(set (match_operand:DI 0 "register_operand" "=r")
12693 (neg:SI (match_operand:SI 1 "register_operand" "0"))))
12694 (clobber (reg:CC FLAGS_REG))]
12695 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
12697 [(set_attr "type" "negnot")
12698 (set_attr "mode" "SI")])
12700 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
12701 (define_insn_and_split "*neg<mode>_1_slp"
12702 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
12703 (neg:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")))
12704 (clobber (reg:CC FLAGS_REG))]
12705 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
12707 neg{<imodesuffix>}\t%0
12709 "&& reload_completed"
12710 [(set (strict_low_part (match_dup 0)) (match_dup 1))
12712 [(set (strict_low_part (match_dup 0))
12713 (neg:SWI12 (match_dup 0)))
12714 (clobber (reg:CC FLAGS_REG))])]
12716 [(set_attr "type" "negnot")
12717 (set_attr "mode" "<MODE>")])
12719 (define_insn "*neg<mode>_2"
12720 [(set (reg FLAGS_REG)
12722 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
12724 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
12725 (neg:SWI (match_dup 1)))]
12726 "ix86_match_ccmode (insn, CCGOCmode)
12727 && ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
12728 "neg{<imodesuffix>}\t%0"
12729 [(set_attr "type" "negnot")
12730 (set_attr "mode" "<MODE>")])
12732 (define_insn "*negsi_2_zext"
12733 [(set (reg FLAGS_REG)
12735 (neg:SI (match_operand:SI 1 "register_operand" "0"))
12737 (set (match_operand:DI 0 "register_operand" "=r")
12739 (neg:SI (match_dup 1))))]
12740 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12741 && ix86_unary_operator_ok (NEG, SImode, operands)"
12743 [(set_attr "type" "negnot")
12744 (set_attr "mode" "SI")])
12746 (define_insn "*neg<mode>_ccc_1"
12747 [(set (reg:CCC FLAGS_REG)
12749 [(match_operand:SWI 1 "nonimmediate_operand" "0")
12750 (const_int 0)] UNSPEC_CC_NE))
12751 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
12752 (neg:SWI (match_dup 1)))]
12754 "neg{<imodesuffix>}\t%0"
12755 [(set_attr "type" "negnot")
12756 (set_attr "mode" "<MODE>")])
12758 (define_insn "*neg<mode>_ccc_2"
12759 [(set (reg:CCC FLAGS_REG)
12761 [(match_operand:SWI 1 "nonimmediate_operand" "0")
12762 (const_int 0)] UNSPEC_CC_NE))
12763 (clobber (match_scratch:SWI 0 "=<r>"))]
12765 "neg{<imodesuffix>}\t%0"
12766 [(set_attr "type" "negnot")
12767 (set_attr "mode" "<MODE>")])
12769 (define_expand "x86_neg<mode>_ccc"
12771 [(set (reg:CCC FLAGS_REG)
12772 (unspec:CCC [(match_operand:SWI48 1 "register_operand")
12773 (const_int 0)] UNSPEC_CC_NE))
12774 (set (match_operand:SWI48 0 "register_operand")
12775 (neg:SWI48 (match_dup 1)))])])
12777 (define_insn "*negqi_ext<mode>_2"
12778 [(set (zero_extract:SWI248
12779 (match_operand 0 "int248_register_operand" "+Q")
12785 (match_operator:SWI248 2 "extract_operator"
12786 [(match_operand 1 "int248_register_operand" "0")
12788 (const_int 8)]) 0)) 0))
12789 (clobber (reg:CC FLAGS_REG))]
12790 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
12791 rtx_equal_p (operands[0], operands[1])"
12793 [(set_attr "type" "negnot")
12794 (set_attr "mode" "QI")])
12796 ;; Negate with jump on overflow.
12797 (define_expand "negv<mode>3"
12798 [(parallel [(set (reg:CCO FLAGS_REG)
12800 [(match_operand:SWI 1 "register_operand")
12801 (match_dup 3)] UNSPEC_CC_NE))
12802 (set (match_operand:SWI 0 "register_operand")
12803 (neg:SWI (match_dup 1)))])
12804 (set (pc) (if_then_else
12805 (eq (reg:CCO FLAGS_REG) (const_int 0))
12806 (label_ref (match_operand 2))
12811 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
12815 (define_insn "*negv<mode>3"
12816 [(set (reg:CCO FLAGS_REG)
12817 (unspec:CCO [(match_operand:SWI 1 "nonimmediate_operand" "0")
12818 (match_operand:SWI 2 "const_int_operand")]
12820 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
12821 (neg:SWI (match_dup 1)))]
12822 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
12823 && mode_signbit_p (<MODE>mode, operands[2])"
12824 "neg{<imodesuffix>}\t%0"
12825 [(set_attr "type" "negnot")
12826 (set_attr "mode" "<MODE>")])
12828 ;; Optimize *negsi_1 followed by *cmpsi_ccno_1 (PR target/91384)
12830 [(set (match_operand:SWI 0 "general_reg_operand")
12831 (match_operand:SWI 1 "general_reg_operand"))
12832 (parallel [(set (match_dup 0) (neg:SWI (match_dup 0)))
12833 (clobber (reg:CC FLAGS_REG))])
12834 (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))]
12836 [(set (match_dup 0) (match_dup 1))
12837 (parallel [(set (reg:CCZ FLAGS_REG)
12838 (compare:CCZ (neg:SWI (match_dup 0)) (const_int 0)))
12839 (set (match_dup 0) (neg:SWI (match_dup 0)))])])
12841 ;; Special expand pattern to handle integer mode abs
12843 (define_expand "abs<mode>2"
12845 [(set (match_operand:SDWIM 0 "register_operand")
12847 (match_operand:SDWIM 1 "general_operand")))
12848 (clobber (reg:CC FLAGS_REG))])]
12850 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)"
12852 if (TARGET_EXPAND_ABS)
12854 machine_mode mode = <MODE>mode;
12855 operands[1] = force_reg (mode, operands[1]);
12857 /* Generate rtx abs using:
12858 abs (x) = (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)) */
12860 rtx shift_amount = gen_int_mode (GET_MODE_PRECISION (mode) - 1, QImode);
12861 rtx shift_dst = expand_simple_binop (mode, ASHIFTRT, operands[1],
12862 shift_amount, NULL_RTX,
12864 rtx xor_dst = expand_simple_binop (mode, XOR, shift_dst, operands[1],
12865 operands[0], 0, OPTAB_DIRECT);
12866 rtx minus_dst = expand_simple_binop (mode, MINUS, xor_dst, shift_dst,
12867 operands[0], 0, OPTAB_DIRECT);
12868 if (!rtx_equal_p (minus_dst, operands[0]))
12869 emit_move_insn (operands[0], minus_dst);
12874 (define_insn_and_split "*abs<dwi>2_doubleword"
12875 [(set (match_operand:<DWI> 0 "register_operand")
12877 (match_operand:<DWI> 1 "general_operand")))
12878 (clobber (reg:CC FLAGS_REG))]
12880 && ix86_pre_reload_split ()"
12884 [(set (reg:CCC FLAGS_REG)
12885 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
12886 (set (match_dup 2) (neg:DWIH (match_dup 1)))])
12888 [(set (match_dup 5)
12889 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
12892 (clobber (reg:CC FLAGS_REG))])
12894 [(set (reg:CCGOC FLAGS_REG)
12896 (neg:DWIH (match_dup 5))
12899 (neg:DWIH (match_dup 5)))])
12902 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
12907 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
12911 operands[1] = force_reg (<DWI>mode, operands[1]);
12912 operands[2] = gen_reg_rtx (<DWI>mode);
12914 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
12917 (define_insn_and_split "*nabs<dwi>2_doubleword"
12918 [(set (match_operand:<DWI> 0 "register_operand")
12921 (match_operand:<DWI> 1 "general_operand"))))
12922 (clobber (reg:CC FLAGS_REG))]
12924 && ix86_pre_reload_split ()"
12928 [(set (reg:CCC FLAGS_REG)
12929 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
12930 (set (match_dup 2) (neg:DWIH (match_dup 1)))])
12932 [(set (match_dup 5)
12933 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
12936 (clobber (reg:CC FLAGS_REG))])
12938 [(set (reg:CCGOC FLAGS_REG)
12940 (neg:DWIH (match_dup 5))
12943 (neg:DWIH (match_dup 5)))])
12946 (lt (reg:CCGOC FLAGS_REG) (const_int 0))
12951 (lt (reg:CCGOC FLAGS_REG) (const_int 0))
12955 operands[1] = force_reg (<DWI>mode, operands[1]);
12956 operands[2] = gen_reg_rtx (<DWI>mode);
12958 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
12961 (define_insn_and_split "*abs<mode>2_1"
12962 [(set (match_operand:SWI 0 "register_operand")
12964 (match_operand:SWI 1 "general_operand")))
12965 (clobber (reg:CC FLAGS_REG))]
12967 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
12968 && ix86_pre_reload_split ()"
12972 [(set (reg:CCGOC FLAGS_REG)
12974 (neg:SWI (match_dup 1))
12977 (neg:SWI (match_dup 1)))])
12980 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
12984 operands[1] = force_reg (<MODE>mode, operands[1]);
12985 operands[2] = gen_reg_rtx (<MODE>mode);
12988 (define_insn_and_split "*nabs<mode>2_1"
12989 [(set (match_operand:SWI 0 "register_operand")
12992 (match_operand:SWI 1 "general_operand"))))
12993 (clobber (reg:CC FLAGS_REG))]
12995 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
12996 && ix86_pre_reload_split ()"
13000 [(set (reg:CCGOC FLAGS_REG)
13002 (neg:SWI (match_dup 1))
13005 (neg:SWI (match_dup 1)))])
13008 (lt (reg:CCGOC FLAGS_REG) (const_int 0))
13012 operands[1] = force_reg (<MODE>mode, operands[1]);
13013 operands[2] = gen_reg_rtx (<MODE>mode);
13016 (define_expand "<code>tf2"
13017 [(set (match_operand:TF 0 "register_operand")
13018 (absneg:TF (match_operand:TF 1 "register_operand")))]
13020 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
13022 (define_insn_and_split "*<code>tf2_1"
13023 [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
13025 (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m")))
13026 (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))]
13029 "&& reload_completed"
13030 [(set (match_dup 0)
13031 (<absneg_op>:TF (match_dup 1) (match_dup 2)))]
13035 if (MEM_P (operands[1]))
13036 std::swap (operands[1], operands[2]);
13040 if (operands_match_p (operands[0], operands[2]))
13041 std::swap (operands[1], operands[2]);
13044 [(set_attr "isa" "noavx,noavx,avx,avx")])
13046 (define_insn_and_split "*nabstf2_1"
13047 [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
13050 (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m"))))
13051 (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))]
13054 "&& reload_completed"
13055 [(set (match_dup 0)
13056 (ior:TF (match_dup 1) (match_dup 2)))]
13060 if (MEM_P (operands[1]))
13061 std::swap (operands[1], operands[2]);
13065 if (operands_match_p (operands[0], operands[2]))
13066 std::swap (operands[1], operands[2]);
13069 [(set_attr "isa" "noavx,noavx,avx,avx")])
13071 (define_expand "<code>hf2"
13072 [(set (match_operand:HF 0 "register_operand")
13073 (absneg:HF (match_operand:HF 1 "register_operand")))]
13074 "TARGET_AVX512FP16"
13075 "ix86_expand_fp_absneg_operator (<CODE>, HFmode, operands); DONE;")
13077 (define_expand "<code><mode>2"
13078 [(set (match_operand:X87MODEF 0 "register_operand")
13079 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
13080 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13081 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
13083 ;; Changing of sign for FP values is doable using integer unit too.
13084 (define_insn "*<code><mode>2_i387_1"
13085 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
13087 (match_operand:X87MODEF 1 "register_operand" "0,0")))
13088 (clobber (reg:CC FLAGS_REG))]
13089 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13093 [(set (match_operand:X87MODEF 0 "fp_register_operand")
13094 (absneg:X87MODEF (match_operand:X87MODEF 1 "fp_register_operand")))
13095 (clobber (reg:CC FLAGS_REG))]
13096 "TARGET_80387 && reload_completed"
13097 [(set (match_dup 0) (absneg:X87MODEF (match_dup 1)))])
13100 [(set (match_operand:X87MODEF 0 "general_reg_operand")
13101 (absneg:X87MODEF (match_operand:X87MODEF 1 "general_reg_operand")))
13102 (clobber (reg:CC FLAGS_REG))]
13103 "TARGET_80387 && reload_completed"
13105 "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
13107 (define_insn_and_split "*<code>hf2_1"
13108 [(set (match_operand:HF 0 "register_operand" "=Yv")
13110 (match_operand:HF 1 "register_operand" "Yv")))
13111 (use (match_operand:V8HF 2 "vector_operand" "Yvm"))
13112 (clobber (reg:CC FLAGS_REG))]
13113 "TARGET_AVX512FP16"
13115 "&& reload_completed"
13116 [(set (match_dup 0)
13117 (<absneg_op>:V8HF (match_dup 1) (match_dup 2)))]
13119 operands[0] = lowpart_subreg (V8HFmode, operands[0], HFmode);
13120 operands[1] = lowpart_subreg (V8HFmode, operands[1], HFmode);
13123 (define_insn "*<code><mode>2_1"
13124 [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv,f,!r")
13126 (match_operand:MODEF 1 "register_operand" "0,x,Yv,0,0")))
13127 (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm,X,X"))
13128 (clobber (reg:CC FLAGS_REG))]
13129 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13131 [(set_attr "isa" "noavx,noavx,avx,*,*")
13132 (set (attr "enabled")
13134 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
13136 (eq_attr "alternative" "3,4")
13137 (symbol_ref "TARGET_MIX_SSE_I387")
13138 (const_string "*"))
13140 (eq_attr "alternative" "3,4")
13141 (symbol_ref "true")
13142 (symbol_ref "false"))))])
13145 [(set (match_operand:MODEF 0 "sse_reg_operand")
13147 (match_operand:MODEF 1 "sse_reg_operand")))
13148 (use (match_operand:<ssevecmodef> 2 "vector_operand"))
13149 (clobber (reg:CC FLAGS_REG))]
13150 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13151 && reload_completed"
13152 [(set (match_dup 0)
13153 (<absneg_op>:<ssevecmodef> (match_dup 1) (match_dup 2)))]
13155 machine_mode mode = <MODE>mode;
13156 machine_mode vmode = <ssevecmodef>mode;
13158 operands[0] = lowpart_subreg (vmode, operands[0], mode);
13159 operands[1] = lowpart_subreg (vmode, operands[1], mode);
13161 if (!TARGET_AVX && operands_match_p (operands[0], operands[2]))
13162 std::swap (operands[1], operands[2]);
13166 [(set (match_operand:MODEF 0 "fp_register_operand")
13167 (absneg:MODEF (match_operand:MODEF 1 "fp_register_operand")))
13168 (use (match_operand 2))
13169 (clobber (reg:CC FLAGS_REG))]
13170 "TARGET_80387 && reload_completed"
13171 [(set (match_dup 0) (absneg:MODEF (match_dup 1)))])
13174 [(set (match_operand:MODEF 0 "general_reg_operand")
13175 (absneg:MODEF (match_operand:MODEF 1 "general_reg_operand")))
13176 (use (match_operand 2))
13177 (clobber (reg:CC FLAGS_REG))]
13178 "TARGET_80387 && reload_completed"
13180 "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
13182 (define_insn_and_split "*nabs<mode>2_1"
13183 [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv")
13186 (match_operand:MODEF 1 "register_operand" "0,x,Yv"))))
13187 (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm"))]
13188 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13190 "&& reload_completed"
13191 [(set (match_dup 0)
13192 (ior:<ssevecmodef> (match_dup 1) (match_dup 2)))]
13194 machine_mode mode = <MODE>mode;
13195 machine_mode vmode = <ssevecmodef>mode;
13197 operands[0] = lowpart_subreg (vmode, operands[0], mode);
13198 operands[1] = lowpart_subreg (vmode, operands[1], mode);
13200 if (!TARGET_AVX && operands_match_p (operands[0], operands[2]))
13201 std::swap (operands[1], operands[2]);
13203 [(set_attr "isa" "noavx,noavx,avx")])
13205 ;; Conditionalize these after reload. If they match before reload, we
13206 ;; lose the clobber and ability to use integer instructions.
13208 (define_insn "*<code><mode>2_i387"
13209 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
13210 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
13211 "TARGET_80387 && reload_completed"
13212 "<absneg_mnemonic>"
13213 [(set_attr "type" "fsgn")
13214 (set_attr "mode" "<MODE>")])
13216 ;; Copysign instructions
13218 (define_expand "copysign<mode>3"
13219 [(match_operand:SSEMODEF 0 "register_operand")
13220 (match_operand:SSEMODEF 1 "nonmemory_operand")
13221 (match_operand:SSEMODEF 2 "register_operand")]
13222 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13223 || (TARGET_SSE && (<MODE>mode == TFmode))
13224 || (TARGET_AVX512FP16 && (<MODE>mode ==HFmode))"
13225 "ix86_expand_copysign (operands); DONE;")
13227 (define_expand "xorsign<mode>3"
13228 [(match_operand:MODEFH 0 "register_operand")
13229 (match_operand:MODEFH 1 "register_operand")
13230 (match_operand:MODEFH 2 "register_operand")]
13231 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13232 || <MODE>mode == HFmode"
13234 if (rtx_equal_p (operands[1], operands[2]))
13235 emit_insn (gen_abs<mode>2 (operands[0], operands[1]));
13237 ix86_expand_xorsign (operands);
13241 ;; One complement instructions
13243 (define_expand "one_cmpl<mode>2"
13244 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
13245 (not:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
13247 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
13249 (define_insn_and_split "*one_cmpl<dwi>2_doubleword"
13250 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
13251 (not:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))]
13252 "ix86_unary_operator_ok (NOT, <DWI>mode, operands)"
13254 "&& reload_completed"
13255 [(set (match_dup 0)
13256 (not:DWIH (match_dup 1)))
13258 (not:DWIH (match_dup 3)))]
13259 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
13261 (define_insn "*one_cmpl<mode>2_1"
13262 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,?k")
13263 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0,k")))]
13264 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
13266 not{<imodesuffix>}\t%0
13269 (cond [(eq_attr "alternative" "1")
13270 (if_then_else (eq_attr "mode" "SI,DI")
13271 (const_string "avx512bw")
13272 (const_string "avx512f"))
13274 (const_string "*")))
13275 (set_attr "type" "negnot,msklog")
13276 (set_attr "mode" "<MODE>")])
13278 (define_insn "*one_cmplsi2_1_zext"
13279 [(set (match_operand:DI 0 "register_operand" "=r,?k")
13281 (not:SI (match_operand:SI 1 "register_operand" "0,k"))))]
13282 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
13286 [(set_attr "isa" "x64,avx512bw")
13287 (set_attr "type" "negnot,msklog")
13288 (set_attr "mode" "SI,SI")])
13290 (define_insn "*one_cmplqi2_1"
13291 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,?k")
13292 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
13293 "ix86_unary_operator_ok (NOT, QImode, operands)"
13298 [(set_attr "isa" "*,*,avx512f")
13299 (set_attr "type" "negnot,negnot,msklog")
13301 (cond [(eq_attr "alternative" "1")
13302 (const_string "SI")
13303 (and (eq_attr "alternative" "2")
13304 (match_test "!TARGET_AVX512DQ"))
13305 (const_string "HI")
13307 (const_string "QI")))
13308 ;; Potential partial reg stall on alternative 1.
13309 (set (attr "preferred_for_speed")
13310 (cond [(eq_attr "alternative" "1")
13311 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
13312 (symbol_ref "true")))])
13314 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
13315 (define_insn_and_split "*one_cmpl<mode>_1_slp"
13316 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
13317 (not:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")))]
13318 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
13320 not{<imodesuffix>}\t%0
13322 "&& reload_completed"
13323 [(set (strict_low_part (match_dup 0)) (match_dup 1))
13324 (set (strict_low_part (match_dup 0))
13325 (not:SWI12 (match_dup 0)))]
13327 [(set_attr "type" "negnot")
13328 (set_attr "mode" "<MODE>")])
13330 (define_insn "*one_cmpl<mode>2_2"
13331 [(set (reg FLAGS_REG)
13332 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
13334 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
13335 (not:SWI (match_dup 1)))]
13336 "ix86_match_ccmode (insn, CCNOmode)
13337 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
13339 [(set_attr "type" "alu1")
13340 (set_attr "mode" "<MODE>")])
13343 [(set (match_operand 0 "flags_reg_operand")
13344 (match_operator 2 "compare_operator"
13345 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
13347 (set (match_operand:SWI 1 "nonimmediate_operand")
13348 (not:SWI (match_dup 3)))]
13349 "ix86_match_ccmode (insn, CCNOmode)"
13350 [(parallel [(set (match_dup 0)
13351 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
13354 (xor:SWI (match_dup 3) (const_int -1)))])])
13356 (define_insn "*one_cmplsi2_2_zext"
13357 [(set (reg FLAGS_REG)
13358 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
13360 (set (match_operand:DI 0 "register_operand" "=r")
13361 (zero_extend:DI (not:SI (match_dup 1))))]
13362 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
13363 && ix86_unary_operator_ok (NOT, SImode, operands)"
13365 [(set_attr "type" "alu1")
13366 (set_attr "mode" "SI")])
13369 [(set (match_operand 0 "flags_reg_operand")
13370 (match_operator 2 "compare_operator"
13371 [(not:SI (match_operand:SI 3 "register_operand"))
13373 (set (match_operand:DI 1 "register_operand")
13374 (zero_extend:DI (not:SI (match_dup 3))))]
13375 "ix86_match_ccmode (insn, CCNOmode)"
13376 [(parallel [(set (match_dup 0)
13377 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
13380 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
13382 ;; Shift instructions
13384 ;; DImode shifts are implemented using the i386 "shift double" opcode,
13385 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
13386 ;; is variable, then the count is in %cl and the "imm" operand is dropped
13387 ;; from the assembler input.
13389 ;; This instruction shifts the target reg/mem as usual, but instead of
13390 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
13391 ;; is a left shift double, bits are taken from the high order bits of
13392 ;; reg, else if the insn is a shift right double, bits are taken from the
13393 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
13394 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
13396 ;; Since sh[lr]d does not change the `reg' operand, that is done
13397 ;; separately, making all shifts emit pairs of shift double and normal
13398 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
13399 ;; support a 63 bit shift, each shift where the count is in a reg expands
13400 ;; to a pair of shifts, a branch, a shift by 32 and a label.
13402 ;; If the shift count is a constant, we need never emit more than one
13403 ;; shift pair, instead using moves and sign extension for counts greater
13406 (define_expand "ashl<mode>3"
13407 [(set (match_operand:SDWIM 0 "<shift_operand>")
13408 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
13409 (match_operand:QI 2 "nonmemory_operand")))]
13411 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
13413 (define_insn_and_split "*ashl<dwi>3_doubleword_mask"
13414 [(set (match_operand:<DWI> 0 "register_operand")
13416 (match_operand:<DWI> 1 "register_operand")
13419 (match_operand 2 "int248_register_operand" "c")
13420 (match_operand 3 "const_int_operand")) 0)))
13421 (clobber (reg:CC FLAGS_REG))]
13422 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
13423 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
13424 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
13425 && ix86_pre_reload_split ()"
13429 [(set (match_dup 6)
13430 (ior:DWIH (ashift:DWIH (match_dup 6)
13431 (and:QI (match_dup 2) (match_dup 8)))
13433 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
13434 (minus:QI (match_dup 9)
13435 (and:QI (match_dup 2) (match_dup 8)))) 0)))
13436 (clobber (reg:CC FLAGS_REG))])
13438 [(set (match_dup 4)
13439 (ashift:DWIH (match_dup 5) (match_dup 2)))
13440 (clobber (reg:CC FLAGS_REG))])]
13442 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
13444 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
13445 operands[2] = gen_lowpart (QImode, operands[2]);
13446 emit_insn (gen_ashl<dwi>3_doubleword (operands[0], operands[1],
13451 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
13453 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
13454 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
13456 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13457 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13460 xops[0] = gen_reg_rtx (GET_MODE (operands[2]));
13461 xops[1] = operands[2];
13462 xops[2] = GEN_INT (INTVAL (operands[3])
13463 & ((<MODE_SIZE> * BITS_PER_UNIT) - 1));
13464 ix86_expand_binary_operator (AND, GET_MODE (operands[2]), xops);
13465 operands[2] = xops[0];
13468 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
13469 operands[2] = gen_lowpart (QImode, operands[2]);
13471 if (!rtx_equal_p (operands[6], operands[7]))
13472 emit_move_insn (operands[6], operands[7]);
13475 (define_insn_and_split "*ashl<dwi>3_doubleword_mask_1"
13476 [(set (match_operand:<DWI> 0 "register_operand")
13478 (match_operand:<DWI> 1 "register_operand")
13480 (match_operand:QI 2 "register_operand" "c")
13481 (match_operand:QI 3 "const_int_operand"))))
13482 (clobber (reg:CC FLAGS_REG))]
13483 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
13484 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
13485 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
13486 && ix86_pre_reload_split ()"
13490 [(set (match_dup 6)
13491 (ior:DWIH (ashift:DWIH (match_dup 6)
13492 (and:QI (match_dup 2) (match_dup 8)))
13494 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
13495 (minus:QI (match_dup 9)
13496 (and:QI (match_dup 2) (match_dup 8)))) 0)))
13497 (clobber (reg:CC FLAGS_REG))])
13499 [(set (match_dup 4)
13500 (ashift:DWIH (match_dup 5) (match_dup 2)))
13501 (clobber (reg:CC FLAGS_REG))])]
13503 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
13505 emit_insn (gen_ashl<dwi>3_doubleword (operands[0], operands[1],
13510 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
13512 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
13513 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
13515 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13516 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13518 rtx tem = gen_reg_rtx (QImode);
13519 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
13523 if (!rtx_equal_p (operands[6], operands[7]))
13524 emit_move_insn (operands[6], operands[7]);
13527 (define_insn "ashl<mode>3_doubleword"
13528 [(set (match_operand:DWI 0 "register_operand" "=&r")
13529 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n")
13530 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
13531 (clobber (reg:CC FLAGS_REG))]
13534 [(set_attr "type" "multi")])
13537 [(set (match_operand:DWI 0 "register_operand")
13538 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
13539 (match_operand:QI 2 "nonmemory_operand")))
13540 (clobber (reg:CC FLAGS_REG))]
13541 "epilogue_completed"
13543 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
13545 ;; By default we don't ask for a scratch register, because when DWImode
13546 ;; values are manipulated, registers are already at a premium. But if
13547 ;; we have one handy, we won't turn it away.
13550 [(match_scratch:DWIH 3 "r")
13551 (parallel [(set (match_operand:<DWI> 0 "register_operand")
13553 (match_operand:<DWI> 1 "nonmemory_operand")
13554 (match_operand:QI 2 "nonmemory_operand")))
13555 (clobber (reg:CC FLAGS_REG))])
13559 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
13561 (define_insn_and_split "*ashl<dwi>3_doubleword_highpart"
13562 [(set (match_operand:<DWI> 0 "register_operand" "=r")
13564 (any_extend:<DWI> (match_operand:DWIH 1 "nonimmediate_operand" "rm"))
13565 (match_operand:QI 2 "const_int_operand")))
13566 (clobber (reg:CC FLAGS_REG))]
13567 "INTVAL (operands[2]) >= <MODE_SIZE> * BITS_PER_UNIT
13568 && INTVAL (operands[2]) < <MODE_SIZE> * BITS_PER_UNIT * 2"
13570 "&& reload_completed"
13573 split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[3]);
13574 int bits = INTVAL (operands[2]) - (<MODE_SIZE> * BITS_PER_UNIT);
13575 if (!rtx_equal_p (operands[3], operands[1]))
13576 emit_move_insn (operands[3], operands[1]);
13578 emit_insn (gen_ashl<mode>3 (operands[3], operands[3], GEN_INT (bits)));
13579 ix86_expand_clear (operands[0]);
13583 (define_insn "x86_64_shld"
13584 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
13585 (ior:DI (ashift:DI (match_dup 0)
13586 (and:QI (match_operand:QI 2 "nonmemory_operand" "Jc")
13591 (match_operand:DI 1 "register_operand" "r"))
13592 (minus:QI (const_int 64)
13593 (and:QI (match_dup 2) (const_int 63)))) 0)))
13594 (clobber (reg:CC FLAGS_REG))]
13596 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
13597 [(set_attr "type" "ishift")
13598 (set_attr "prefix_0f" "1")
13599 (set_attr "mode" "DI")
13600 (set_attr "athlon_decode" "vector")
13601 (set_attr "amdfam10_decode" "vector")
13602 (set_attr "bdver1_decode" "vector")])
13604 (define_insn "x86_64_shld_1"
13605 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
13606 (ior:DI (ashift:DI (match_dup 0)
13607 (match_operand:QI 2 "const_0_to_63_operand"))
13611 (match_operand:DI 1 "register_operand" "r"))
13612 (match_operand:QI 3 "const_0_to_255_operand")) 0)))
13613 (clobber (reg:CC FLAGS_REG))]
13615 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])"
13616 "shld{q}\t{%2, %1, %0|%0, %1, %2}"
13617 [(set_attr "type" "ishift")
13618 (set_attr "prefix_0f" "1")
13619 (set_attr "mode" "DI")
13620 (set_attr "length_immediate" "1")
13621 (set_attr "athlon_decode" "vector")
13622 (set_attr "amdfam10_decode" "vector")
13623 (set_attr "bdver1_decode" "vector")])
13625 (define_insn_and_split "*x86_64_shld_shrd_1_nozext"
13626 [(set (match_operand:DI 0 "nonimmediate_operand")
13627 (ior:DI (ashift:DI (match_operand:DI 4 "nonimmediate_operand")
13628 (match_operand:QI 2 "const_0_to_63_operand"))
13630 (match_operand:DI 1 "nonimmediate_operand")
13631 (match_operand:QI 3 "const_0_to_63_operand"))))
13632 (clobber (reg:CC FLAGS_REG))]
13634 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])
13635 && ix86_pre_reload_split ()"
13640 if (rtx_equal_p (operands[4], operands[0]))
13642 operands[1] = force_reg (DImode, operands[1]);
13643 emit_insn (gen_x86_64_shld_1 (operands[0], operands[1], operands[2], operands[3]));
13645 else if (rtx_equal_p (operands[1], operands[0]))
13647 operands[4] = force_reg (DImode, operands[4]);
13648 emit_insn (gen_x86_64_shrd_1 (operands[0], operands[4], operands[3], operands[2]));
13652 operands[1] = force_reg (DImode, operands[1]);
13653 rtx tmp = gen_reg_rtx (DImode);
13654 emit_move_insn (tmp, operands[4]);
13655 emit_insn (gen_x86_64_shld_1 (tmp, operands[1], operands[2], operands[3]));
13656 emit_move_insn (operands[0], tmp);
13661 (define_insn_and_split "*x86_64_shld_2"
13662 [(set (match_operand:DI 0 "nonimmediate_operand")
13663 (ior:DI (ashift:DI (match_dup 0)
13664 (match_operand:QI 2 "nonmemory_operand"))
13665 (lshiftrt:DI (match_operand:DI 1 "register_operand")
13666 (minus:QI (const_int 64) (match_dup 2)))))
13667 (clobber (reg:CC FLAGS_REG))]
13668 "TARGET_64BIT && ix86_pre_reload_split ()"
13671 [(parallel [(set (match_dup 0)
13672 (ior:DI (ashift:DI (match_dup 0)
13673 (and:QI (match_dup 2) (const_int 63)))
13676 (zero_extend:TI (match_dup 1))
13677 (minus:QI (const_int 64)
13678 (and:QI (match_dup 2)
13679 (const_int 63)))) 0)))
13680 (clobber (reg:CC FLAGS_REG))])])
13682 (define_insn "x86_shld"
13683 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
13684 (ior:SI (ashift:SI (match_dup 0)
13685 (and:QI (match_operand:QI 2 "nonmemory_operand" "Ic")
13690 (match_operand:SI 1 "register_operand" "r"))
13691 (minus:QI (const_int 32)
13692 (and:QI (match_dup 2) (const_int 31)))) 0)))
13693 (clobber (reg:CC FLAGS_REG))]
13695 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
13696 [(set_attr "type" "ishift")
13697 (set_attr "prefix_0f" "1")
13698 (set_attr "mode" "SI")
13699 (set_attr "pent_pair" "np")
13700 (set_attr "athlon_decode" "vector")
13701 (set_attr "amdfam10_decode" "vector")
13702 (set_attr "bdver1_decode" "vector")])
13704 (define_insn "x86_shld_1"
13705 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
13706 (ior:SI (ashift:SI (match_dup 0)
13707 (match_operand:QI 2 "const_0_to_31_operand"))
13711 (match_operand:SI 1 "register_operand" "r"))
13712 (match_operand:QI 3 "const_0_to_63_operand")) 0)))
13713 (clobber (reg:CC FLAGS_REG))]
13714 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])"
13715 "shld{l}\t{%2, %1, %0|%0, %1, %2}"
13716 [(set_attr "type" "ishift")
13717 (set_attr "prefix_0f" "1")
13718 (set_attr "length_immediate" "1")
13719 (set_attr "mode" "SI")
13720 (set_attr "pent_pair" "np")
13721 (set_attr "athlon_decode" "vector")
13722 (set_attr "amdfam10_decode" "vector")
13723 (set_attr "bdver1_decode" "vector")])
13725 (define_insn_and_split "*x86_shld_shrd_1_nozext"
13726 [(set (match_operand:SI 0 "nonimmediate_operand")
13727 (ior:SI (ashift:SI (match_operand:SI 4 "nonimmediate_operand")
13728 (match_operand:QI 2 "const_0_to_31_operand"))
13730 (match_operand:SI 1 "nonimmediate_operand")
13731 (match_operand:QI 3 "const_0_to_31_operand"))))
13732 (clobber (reg:CC FLAGS_REG))]
13733 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])
13734 && ix86_pre_reload_split ()"
13739 if (rtx_equal_p (operands[4], operands[0]))
13741 operands[1] = force_reg (SImode, operands[1]);
13742 emit_insn (gen_x86_shld_1 (operands[0], operands[1], operands[2], operands[3]));
13744 else if (rtx_equal_p (operands[1], operands[0]))
13746 operands[4] = force_reg (SImode, operands[4]);
13747 emit_insn (gen_x86_shrd_1 (operands[0], operands[4], operands[3], operands[2]));
13751 operands[1] = force_reg (SImode, operands[1]);
13752 rtx tmp = gen_reg_rtx (SImode);
13753 emit_move_insn (tmp, operands[4]);
13754 emit_insn (gen_x86_shld_1 (tmp, operands[1], operands[2], operands[3]));
13755 emit_move_insn (operands[0], tmp);
13760 (define_insn_and_split "*x86_shld_2"
13761 [(set (match_operand:SI 0 "nonimmediate_operand")
13762 (ior:SI (ashift:SI (match_dup 0)
13763 (match_operand:QI 2 "nonmemory_operand"))
13764 (lshiftrt:SI (match_operand:SI 1 "register_operand")
13765 (minus:QI (const_int 32) (match_dup 2)))))
13766 (clobber (reg:CC FLAGS_REG))]
13767 "TARGET_64BIT && ix86_pre_reload_split ()"
13770 [(parallel [(set (match_dup 0)
13771 (ior:SI (ashift:SI (match_dup 0)
13772 (and:QI (match_dup 2) (const_int 31)))
13775 (zero_extend:DI (match_dup 1))
13776 (minus:QI (const_int 32)
13777 (and:QI (match_dup 2)
13778 (const_int 31)))) 0)))
13779 (clobber (reg:CC FLAGS_REG))])])
13781 (define_expand "@x86_shift<mode>_adj_1"
13782 [(set (reg:CCZ FLAGS_REG)
13783 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
13786 (set (match_operand:SWI48 0 "register_operand")
13787 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
13788 (match_operand:SWI48 1 "register_operand")
13791 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
13792 (match_operand:SWI48 3 "register_operand")
13795 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
13797 (define_expand "@x86_shift<mode>_adj_2"
13798 [(use (match_operand:SWI48 0 "register_operand"))
13799 (use (match_operand:SWI48 1 "register_operand"))
13800 (use (match_operand:QI 2 "register_operand"))]
13803 rtx_code_label *label = gen_label_rtx ();
13806 emit_insn (gen_testqi_ccz_1 (operands[2],
13807 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
13809 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
13810 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
13811 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
13812 gen_rtx_LABEL_REF (VOIDmode, label),
13814 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
13815 JUMP_LABEL (tmp) = label;
13817 emit_move_insn (operands[0], operands[1]);
13818 ix86_expand_clear (operands[1]);
13820 emit_label (label);
13821 LABEL_NUSES (label) = 1;
13826 ;; Avoid useless masking of count operand.
13827 (define_insn_and_split "*ashl<mode>3_mask"
13828 [(set (match_operand:SWI48 0 "nonimmediate_operand")
13830 (match_operand:SWI48 1 "nonimmediate_operand")
13833 (match_operand 2 "int248_register_operand" "c,r")
13834 (match_operand 3 "const_int_operand")) 0)))
13835 (clobber (reg:CC FLAGS_REG))]
13836 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
13837 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
13838 == GET_MODE_BITSIZE (<MODE>mode)-1
13839 && ix86_pre_reload_split ()"
13843 [(set (match_dup 0)
13844 (ashift:SWI48 (match_dup 1)
13846 (clobber (reg:CC FLAGS_REG))])]
13848 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
13849 operands[2] = gen_lowpart (QImode, operands[2]);
13851 [(set_attr "isa" "*,bmi2")])
13853 (define_insn_and_split "*ashl<mode>3_mask_1"
13854 [(set (match_operand:SWI48 0 "nonimmediate_operand")
13856 (match_operand:SWI48 1 "nonimmediate_operand")
13858 (match_operand:QI 2 "register_operand" "c,r")
13859 (match_operand:QI 3 "const_int_operand"))))
13860 (clobber (reg:CC FLAGS_REG))]
13861 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
13862 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
13863 == GET_MODE_BITSIZE (<MODE>mode)-1
13864 && ix86_pre_reload_split ()"
13868 [(set (match_dup 0)
13869 (ashift:SWI48 (match_dup 1)
13871 (clobber (reg:CC FLAGS_REG))])]
13873 [(set_attr "isa" "*,bmi2")])
13875 (define_insn "*bmi2_ashl<mode>3_1"
13876 [(set (match_operand:SWI48 0 "register_operand" "=r")
13877 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13878 (match_operand:SWI48 2 "register_operand" "r")))]
13880 "shlx\t{%2, %1, %0|%0, %1, %2}"
13881 [(set_attr "type" "ishiftx")
13882 (set_attr "mode" "<MODE>")])
13884 (define_insn "*ashl<mode>3_1"
13885 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,?k")
13886 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm,k")
13887 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r,<KS>")))
13888 (clobber (reg:CC FLAGS_REG))]
13889 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
13891 switch (get_attr_type (insn))
13899 gcc_assert (operands[2] == const1_rtx);
13900 gcc_assert (rtx_equal_p (operands[0], operands[1]));
13901 return "add{<imodesuffix>}\t%0, %0";
13904 if (operands[2] == const1_rtx
13905 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
13906 return "sal{<imodesuffix>}\t%0";
13908 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
13911 [(set_attr "isa" "*,*,bmi2,avx512bw")
13913 (cond [(eq_attr "alternative" "1")
13914 (const_string "lea")
13915 (eq_attr "alternative" "2")
13916 (const_string "ishiftx")
13917 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
13918 (match_operand 0 "register_operand"))
13919 (match_operand 2 "const1_operand"))
13920 (const_string "alu")
13921 (eq_attr "alternative" "3")
13922 (const_string "msklog")
13924 (const_string "ishift")))
13925 (set (attr "length_immediate")
13927 (ior (eq_attr "type" "alu")
13928 (and (eq_attr "type" "ishift")
13929 (and (match_operand 2 "const1_operand")
13930 (ior (match_test "TARGET_SHIFT1")
13931 (match_test "optimize_function_for_size_p (cfun)")))))
13933 (const_string "*")))
13934 (set_attr "mode" "<MODE>")])
13936 ;; Convert shift to the shiftx pattern to avoid flags dependency.
13938 [(set (match_operand:SWI48 0 "register_operand")
13939 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
13940 (match_operand:QI 2 "register_operand")))
13941 (clobber (reg:CC FLAGS_REG))]
13942 "TARGET_BMI2 && reload_completed"
13943 [(set (match_dup 0)
13944 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
13945 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
13947 (define_insn "*bmi2_ashlsi3_1_zext"
13948 [(set (match_operand:DI 0 "register_operand" "=r")
13950 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
13951 (match_operand:SI 2 "register_operand" "r"))))]
13952 "TARGET_64BIT && TARGET_BMI2"
13953 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
13954 [(set_attr "type" "ishiftx")
13955 (set_attr "mode" "SI")])
13957 (define_insn "*ashlsi3_1_zext"
13958 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
13960 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
13961 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
13962 (clobber (reg:CC FLAGS_REG))]
13963 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
13965 switch (get_attr_type (insn))
13972 gcc_assert (operands[2] == const1_rtx);
13973 return "add{l}\t%k0, %k0";
13976 if (operands[2] == const1_rtx
13977 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
13978 return "sal{l}\t%k0";
13980 return "sal{l}\t{%2, %k0|%k0, %2}";
13983 [(set_attr "isa" "*,*,bmi2")
13985 (cond [(eq_attr "alternative" "1")
13986 (const_string "lea")
13987 (eq_attr "alternative" "2")
13988 (const_string "ishiftx")
13989 (and (match_test "TARGET_DOUBLE_WITH_ADD")
13990 (match_operand 2 "const1_operand"))
13991 (const_string "alu")
13993 (const_string "ishift")))
13994 (set (attr "length_immediate")
13996 (ior (eq_attr "type" "alu")
13997 (and (eq_attr "type" "ishift")
13998 (and (match_operand 2 "const1_operand")
13999 (ior (match_test "TARGET_SHIFT1")
14000 (match_test "optimize_function_for_size_p (cfun)")))))
14002 (const_string "*")))
14003 (set_attr "mode" "SI")])
14005 ;; Convert shift to the shiftx pattern to avoid flags dependency.
14007 [(set (match_operand:DI 0 "register_operand")
14009 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
14010 (match_operand:QI 2 "register_operand"))))
14011 (clobber (reg:CC FLAGS_REG))]
14012 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
14013 [(set (match_dup 0)
14014 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
14015 "operands[2] = gen_lowpart (SImode, operands[2]);")
14017 (define_insn "*ashlhi3_1"
14018 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp,?k")
14019 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l,k")
14020 (match_operand:QI 2 "nonmemory_operand" "cI,M,Ww")))
14021 (clobber (reg:CC FLAGS_REG))]
14022 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
14024 switch (get_attr_type (insn))
14031 gcc_assert (operands[2] == const1_rtx);
14032 return "add{w}\t%0, %0";
14035 if (operands[2] == const1_rtx
14036 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14037 return "sal{w}\t%0";
14039 return "sal{w}\t{%2, %0|%0, %2}";
14042 [(set_attr "isa" "*,*,avx512f")
14044 (cond [(eq_attr "alternative" "1")
14045 (const_string "lea")
14046 (eq_attr "alternative" "2")
14047 (const_string "msklog")
14048 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14049 (match_operand 0 "register_operand"))
14050 (match_operand 2 "const1_operand"))
14051 (const_string "alu")
14053 (const_string "ishift")))
14054 (set (attr "length_immediate")
14056 (ior (eq_attr "type" "alu")
14057 (and (eq_attr "type" "ishift")
14058 (and (match_operand 2 "const1_operand")
14059 (ior (match_test "TARGET_SHIFT1")
14060 (match_test "optimize_function_for_size_p (cfun)")))))
14062 (const_string "*")))
14063 (set_attr "mode" "HI,SI,HI")])
14065 (define_insn "*ashlqi3_1"
14066 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp,?k")
14067 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l,k")
14068 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M,Wb")))
14069 (clobber (reg:CC FLAGS_REG))]
14070 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
14072 switch (get_attr_type (insn))
14079 gcc_assert (operands[2] == const1_rtx);
14080 if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
14081 return "add{l}\t%k0, %k0";
14083 return "add{b}\t%0, %0";
14086 if (operands[2] == const1_rtx
14087 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14089 if (get_attr_mode (insn) == MODE_SI)
14090 return "sal{l}\t%k0";
14092 return "sal{b}\t%0";
14096 if (get_attr_mode (insn) == MODE_SI)
14097 return "sal{l}\t{%2, %k0|%k0, %2}";
14099 return "sal{b}\t{%2, %0|%0, %2}";
14103 [(set_attr "isa" "*,*,*,avx512dq")
14105 (cond [(eq_attr "alternative" "2")
14106 (const_string "lea")
14107 (eq_attr "alternative" "3")
14108 (const_string "msklog")
14109 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14110 (match_operand 0 "register_operand"))
14111 (match_operand 2 "const1_operand"))
14112 (const_string "alu")
14114 (const_string "ishift")))
14115 (set (attr "length_immediate")
14117 (ior (eq_attr "type" "alu")
14118 (and (eq_attr "type" "ishift")
14119 (and (match_operand 2 "const1_operand")
14120 (ior (match_test "TARGET_SHIFT1")
14121 (match_test "optimize_function_for_size_p (cfun)")))))
14123 (const_string "*")))
14124 (set_attr "mode" "QI,SI,SI,QI")
14125 ;; Potential partial reg stall on alternative 1.
14126 (set (attr "preferred_for_speed")
14127 (cond [(eq_attr "alternative" "1")
14128 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
14129 (symbol_ref "true")))])
14131 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
14132 (define_insn_and_split "*ashl<mode>3_1_slp"
14133 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
14134 (ashift:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
14135 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
14136 (clobber (reg:CC FLAGS_REG))]
14137 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
14139 if (which_alternative)
14142 switch (get_attr_type (insn))
14145 gcc_assert (operands[2] == const1_rtx);
14146 return "add{<imodesuffix>}\t%0, %0";
14149 if (operands[2] == const1_rtx
14150 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14151 return "sal{<imodesuffix>}\t%0";
14153 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14156 "&& reload_completed"
14157 [(set (strict_low_part (match_dup 0)) (match_dup 1))
14159 [(set (strict_low_part (match_dup 0))
14160 (ashift:SWI12 (match_dup 0) (match_dup 2)))
14161 (clobber (reg:CC FLAGS_REG))])]
14163 [(set (attr "type")
14164 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
14165 (match_operand 2 "const1_operand"))
14166 (const_string "alu")
14168 (const_string "ishift")))
14169 (set (attr "length_immediate")
14171 (ior (eq_attr "type" "alu")
14172 (and (eq_attr "type" "ishift")
14173 (and (match_operand 2 "const1_operand")
14174 (ior (match_test "TARGET_SHIFT1")
14175 (match_test "optimize_function_for_size_p (cfun)")))))
14177 (const_string "*")))
14178 (set_attr "mode" "<MODE>")])
14180 ;; Convert ashift to the lea pattern to avoid flags dependency.
14182 [(set (match_operand:SWI 0 "general_reg_operand")
14183 (ashift:SWI (match_operand:SWI 1 "index_reg_operand")
14184 (match_operand 2 "const_0_to_3_operand")))
14185 (clobber (reg:CC FLAGS_REG))]
14187 && REGNO (operands[0]) != REGNO (operands[1])"
14188 [(set (match_dup 0)
14189 (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
14191 if (<MODE>mode != <LEAMODE>mode)
14193 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
14194 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
14196 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
14199 ;; Convert ashift to the lea pattern to avoid flags dependency.
14201 [(set (match_operand:DI 0 "general_reg_operand")
14203 (ashift:SI (match_operand:SI 1 "index_reg_operand")
14204 (match_operand 2 "const_0_to_3_operand"))))
14205 (clobber (reg:CC FLAGS_REG))]
14206 "TARGET_64BIT && reload_completed
14207 && REGNO (operands[0]) != REGNO (operands[1])"
14208 [(set (match_dup 0)
14209 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
14211 operands[1] = gen_lowpart (SImode, operands[1]);
14212 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
14215 ;; This pattern can't accept a variable shift count, since shifts by
14216 ;; zero don't affect the flags. We assume that shifts by constant
14217 ;; zero are optimized away.
14218 (define_insn "*ashl<mode>3_cmp"
14219 [(set (reg FLAGS_REG)
14221 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
14222 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
14224 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
14225 (ashift:SWI (match_dup 1) (match_dup 2)))]
14226 "(optimize_function_for_size_p (cfun)
14227 || !TARGET_PARTIAL_FLAG_REG_STALL
14228 || (operands[2] == const1_rtx
14230 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
14231 && ix86_match_ccmode (insn, CCGOCmode)
14232 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
14234 switch (get_attr_type (insn))
14237 gcc_assert (operands[2] == const1_rtx);
14238 return "add{<imodesuffix>}\t%0, %0";
14241 if (operands[2] == const1_rtx
14242 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14243 return "sal{<imodesuffix>}\t%0";
14245 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14248 [(set (attr "type")
14249 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14250 (match_operand 0 "register_operand"))
14251 (match_operand 2 "const1_operand"))
14252 (const_string "alu")
14254 (const_string "ishift")))
14255 (set (attr "length_immediate")
14257 (ior (eq_attr "type" "alu")
14258 (and (eq_attr "type" "ishift")
14259 (and (match_operand 2 "const1_operand")
14260 (ior (match_test "TARGET_SHIFT1")
14261 (match_test "optimize_function_for_size_p (cfun)")))))
14263 (const_string "*")))
14264 (set_attr "mode" "<MODE>")])
14266 (define_insn "*ashlsi3_cmp_zext"
14267 [(set (reg FLAGS_REG)
14269 (ashift:SI (match_operand:SI 1 "register_operand" "0")
14270 (match_operand:QI 2 "const_1_to_31_operand"))
14272 (set (match_operand:DI 0 "register_operand" "=r")
14273 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
14275 && (optimize_function_for_size_p (cfun)
14276 || !TARGET_PARTIAL_FLAG_REG_STALL
14277 || (operands[2] == const1_rtx
14279 || TARGET_DOUBLE_WITH_ADD)))
14280 && ix86_match_ccmode (insn, CCGOCmode)
14281 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
14283 switch (get_attr_type (insn))
14286 gcc_assert (operands[2] == const1_rtx);
14287 return "add{l}\t%k0, %k0";
14290 if (operands[2] == const1_rtx
14291 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14292 return "sal{l}\t%k0";
14294 return "sal{l}\t{%2, %k0|%k0, %2}";
14297 [(set (attr "type")
14298 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
14299 (match_operand 2 "const1_operand"))
14300 (const_string "alu")
14302 (const_string "ishift")))
14303 (set (attr "length_immediate")
14305 (ior (eq_attr "type" "alu")
14306 (and (eq_attr "type" "ishift")
14307 (and (match_operand 2 "const1_operand")
14308 (ior (match_test "TARGET_SHIFT1")
14309 (match_test "optimize_function_for_size_p (cfun)")))))
14311 (const_string "*")))
14312 (set_attr "mode" "SI")])
14314 (define_insn "*ashl<mode>3_cconly"
14315 [(set (reg FLAGS_REG)
14317 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
14318 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
14320 (clobber (match_scratch:SWI 0 "=<r>"))]
14321 "(optimize_function_for_size_p (cfun)
14322 || !TARGET_PARTIAL_FLAG_REG_STALL
14323 || (operands[2] == const1_rtx
14325 || TARGET_DOUBLE_WITH_ADD)))
14326 && ix86_match_ccmode (insn, CCGOCmode)"
14328 switch (get_attr_type (insn))
14331 gcc_assert (operands[2] == const1_rtx);
14332 return "add{<imodesuffix>}\t%0, %0";
14335 if (operands[2] == const1_rtx
14336 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14337 return "sal{<imodesuffix>}\t%0";
14339 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14342 [(set (attr "type")
14343 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14344 (match_operand 0 "register_operand"))
14345 (match_operand 2 "const1_operand"))
14346 (const_string "alu")
14348 (const_string "ishift")))
14349 (set (attr "length_immediate")
14351 (ior (eq_attr "type" "alu")
14352 (and (eq_attr "type" "ishift")
14353 (and (match_operand 2 "const1_operand")
14354 (ior (match_test "TARGET_SHIFT1")
14355 (match_test "optimize_function_for_size_p (cfun)")))))
14357 (const_string "*")))
14358 (set_attr "mode" "<MODE>")])
14360 (define_insn "*ashlqi_ext<mode>_2"
14361 [(set (zero_extract:SWI248
14362 (match_operand 0 "int248_register_operand" "+Q")
14368 (match_operator:SWI248 3 "extract_operator"
14369 [(match_operand 1 "int248_register_operand" "0")
14372 (match_operand:QI 2 "nonmemory_operand" "cI")) 0))
14373 (clobber (reg:CC FLAGS_REG))]
14374 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
14375 rtx_equal_p (operands[0], operands[1])"
14377 switch (get_attr_type (insn))
14380 gcc_assert (operands[2] == const1_rtx);
14381 return "add{b}\t%h0, %h0";
14384 if (operands[2] == const1_rtx
14385 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14386 return "sal{b}\t%h0";
14388 return "sal{b}\t{%2, %h0|%h0, %2}";
14391 [(set (attr "type")
14392 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
14393 (match_operand 2 "const1_operand"))
14394 (const_string "alu")
14396 (const_string "ishift")))
14397 (set (attr "length_immediate")
14399 (ior (eq_attr "type" "alu")
14400 (and (eq_attr "type" "ishift")
14401 (and (match_operand 2 "const1_operand")
14402 (ior (match_test "TARGET_SHIFT1")
14403 (match_test "optimize_function_for_size_p (cfun)")))))
14405 (const_string "*")))
14406 (set_attr "mode" "QI")])
14408 ;; See comment above `ashl<mode>3' about how this works.
14410 (define_expand "<insn><mode>3"
14411 [(set (match_operand:SDWIM 0 "<shift_operand>")
14412 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
14413 (match_operand:QI 2 "nonmemory_operand")))]
14415 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
14417 ;; Avoid useless masking of count operand.
14418 (define_insn_and_split "*<insn><mode>3_mask"
14419 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14421 (match_operand:SWI48 1 "nonimmediate_operand")
14424 (match_operand 2 "int248_register_operand" "c,r")
14425 (match_operand 3 "const_int_operand")) 0)))
14426 (clobber (reg:CC FLAGS_REG))]
14427 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
14428 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
14429 == GET_MODE_BITSIZE (<MODE>mode)-1
14430 && ix86_pre_reload_split ()"
14434 [(set (match_dup 0)
14435 (any_shiftrt:SWI48 (match_dup 1)
14437 (clobber (reg:CC FLAGS_REG))])]
14439 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14440 operands[2] = gen_lowpart (QImode, operands[2]);
14442 [(set_attr "isa" "*,bmi2")])
14444 (define_insn_and_split "*<insn><mode>3_mask_1"
14445 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14447 (match_operand:SWI48 1 "nonimmediate_operand")
14449 (match_operand:QI 2 "register_operand" "c,r")
14450 (match_operand:QI 3 "const_int_operand"))))
14451 (clobber (reg:CC FLAGS_REG))]
14452 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
14453 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
14454 == GET_MODE_BITSIZE (<MODE>mode)-1
14455 && ix86_pre_reload_split ()"
14459 [(set (match_dup 0)
14460 (any_shiftrt:SWI48 (match_dup 1)
14462 (clobber (reg:CC FLAGS_REG))])]
14464 [(set_attr "isa" "*,bmi2")])
14466 (define_insn_and_split "*<insn><dwi>3_doubleword_mask"
14467 [(set (match_operand:<DWI> 0 "register_operand")
14469 (match_operand:<DWI> 1 "register_operand")
14472 (match_operand 2 "int248_register_operand" "c")
14473 (match_operand 3 "const_int_operand")) 0)))
14474 (clobber (reg:CC FLAGS_REG))]
14475 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
14476 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
14477 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
14478 && ix86_pre_reload_split ()"
14482 [(set (match_dup 4)
14483 (ior:DWIH (lshiftrt:DWIH (match_dup 4)
14484 (and:QI (match_dup 2) (match_dup 8)))
14486 (ashift:<DWI> (zero_extend:<DWI> (match_dup 7))
14487 (minus:QI (match_dup 9)
14488 (and:QI (match_dup 2) (match_dup 8)))) 0)))
14489 (clobber (reg:CC FLAGS_REG))])
14491 [(set (match_dup 6)
14492 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
14493 (clobber (reg:CC FLAGS_REG))])]
14495 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
14497 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14498 operands[2] = gen_lowpart (QImode, operands[2]);
14499 emit_insn (gen_<insn><dwi>3_doubleword (operands[0], operands[1],
14504 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
14506 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
14507 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
14509 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14510 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14513 xops[0] = gen_reg_rtx (GET_MODE (operands[2]));
14514 xops[1] = operands[2];
14515 xops[2] = GEN_INT (INTVAL (operands[3])
14516 & ((<MODE_SIZE> * BITS_PER_UNIT) - 1));
14517 ix86_expand_binary_operator (AND, GET_MODE (operands[2]), xops);
14518 operands[2] = xops[0];
14521 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14522 operands[2] = gen_lowpart (QImode, operands[2]);
14524 if (!rtx_equal_p (operands[4], operands[5]))
14525 emit_move_insn (operands[4], operands[5]);
14528 (define_insn_and_split "*<insn><dwi>3_doubleword_mask_1"
14529 [(set (match_operand:<DWI> 0 "register_operand")
14531 (match_operand:<DWI> 1 "register_operand")
14533 (match_operand:QI 2 "register_operand" "c")
14534 (match_operand:QI 3 "const_int_operand"))))
14535 (clobber (reg:CC FLAGS_REG))]
14536 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
14537 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
14538 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
14539 && ix86_pre_reload_split ()"
14543 [(set (match_dup 4)
14544 (ior:DWIH (lshiftrt:DWIH (match_dup 4)
14545 (and:QI (match_dup 2) (match_dup 8)))
14547 (ashift:<DWI> (zero_extend:<DWI> (match_dup 7))
14548 (minus:QI (match_dup 9)
14549 (and:QI (match_dup 2) (match_dup 8)))) 0)))
14550 (clobber (reg:CC FLAGS_REG))])
14552 [(set (match_dup 6)
14553 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
14554 (clobber (reg:CC FLAGS_REG))])]
14556 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
14558 emit_insn (gen_<insn><dwi>3_doubleword (operands[0], operands[1],
14563 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
14565 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
14566 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
14568 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14569 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14571 rtx tem = gen_reg_rtx (QImode);
14572 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
14576 if (!rtx_equal_p (operands[4], operands[5]))
14577 emit_move_insn (operands[4], operands[5]);
14580 (define_insn_and_split "<insn><mode>3_doubleword"
14581 [(set (match_operand:DWI 0 "register_operand" "=&r")
14582 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
14583 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
14584 (clobber (reg:CC FLAGS_REG))]
14587 "epilogue_completed"
14589 "ix86_split_<insn> (operands, NULL_RTX, <MODE>mode); DONE;"
14590 [(set_attr "type" "multi")])
14592 ;; By default we don't ask for a scratch register, because when DWImode
14593 ;; values are manipulated, registers are already at a premium. But if
14594 ;; we have one handy, we won't turn it away.
14597 [(match_scratch:DWIH 3 "r")
14598 (parallel [(set (match_operand:<DWI> 0 "register_operand")
14600 (match_operand:<DWI> 1 "register_operand")
14601 (match_operand:QI 2 "nonmemory_operand")))
14602 (clobber (reg:CC FLAGS_REG))])
14606 "ix86_split_<insn> (operands, operands[3], <DWI>mode); DONE;")
14608 (define_insn "x86_64_shrd"
14609 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
14610 (ior:DI (lshiftrt:DI (match_dup 0)
14611 (and:QI (match_operand:QI 2 "nonmemory_operand" "Jc")
14616 (match_operand:DI 1 "register_operand" "r"))
14617 (minus:QI (const_int 64)
14618 (and:QI (match_dup 2) (const_int 63)))) 0)))
14619 (clobber (reg:CC FLAGS_REG))]
14621 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
14622 [(set_attr "type" "ishift")
14623 (set_attr "prefix_0f" "1")
14624 (set_attr "mode" "DI")
14625 (set_attr "athlon_decode" "vector")
14626 (set_attr "amdfam10_decode" "vector")
14627 (set_attr "bdver1_decode" "vector")])
14629 (define_insn "x86_64_shrd_1"
14630 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
14631 (ior:DI (lshiftrt:DI (match_dup 0)
14632 (match_operand:QI 2 "const_0_to_63_operand"))
14636 (match_operand:DI 1 "register_operand" "r"))
14637 (match_operand:QI 3 "const_0_to_255_operand")) 0)))
14638 (clobber (reg:CC FLAGS_REG))]
14640 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])"
14641 "shrd{q}\t{%2, %1, %0|%0, %1, %2}"
14642 [(set_attr "type" "ishift")
14643 (set_attr "prefix_0f" "1")
14644 (set_attr "length_immediate" "1")
14645 (set_attr "mode" "DI")
14646 (set_attr "athlon_decode" "vector")
14647 (set_attr "amdfam10_decode" "vector")
14648 (set_attr "bdver1_decode" "vector")])
14650 (define_insn_and_split "*x86_64_shrd_shld_1_nozext"
14651 [(set (match_operand:DI 0 "nonimmediate_operand")
14652 (ior:DI (lshiftrt:DI (match_operand:DI 4 "nonimmediate_operand")
14653 (match_operand:QI 2 "const_0_to_63_operand"))
14655 (match_operand:DI 1 "nonimmediate_operand")
14656 (match_operand:QI 3 "const_0_to_63_operand"))))
14657 (clobber (reg:CC FLAGS_REG))]
14659 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])
14660 && ix86_pre_reload_split ()"
14665 if (rtx_equal_p (operands[4], operands[0]))
14667 operands[1] = force_reg (DImode, operands[1]);
14668 emit_insn (gen_x86_64_shrd_1 (operands[0], operands[1], operands[2], operands[3]));
14670 else if (rtx_equal_p (operands[1], operands[0]))
14672 operands[4] = force_reg (DImode, operands[4]);
14673 emit_insn (gen_x86_64_shld_1 (operands[0], operands[4], operands[3], operands[2]));
14677 operands[1] = force_reg (DImode, operands[1]);
14678 rtx tmp = gen_reg_rtx (DImode);
14679 emit_move_insn (tmp, operands[4]);
14680 emit_insn (gen_x86_64_shrd_1 (tmp, operands[1], operands[2], operands[3]));
14681 emit_move_insn (operands[0], tmp);
14686 (define_insn_and_split "*x86_64_shrd_2"
14687 [(set (match_operand:DI 0 "nonimmediate_operand")
14688 (ior:DI (lshiftrt:DI (match_dup 0)
14689 (match_operand:QI 2 "nonmemory_operand"))
14690 (ashift:DI (match_operand:DI 1 "register_operand")
14691 (minus:QI (const_int 64) (match_dup 2)))))
14692 (clobber (reg:CC FLAGS_REG))]
14693 "TARGET_64BIT && ix86_pre_reload_split ()"
14696 [(parallel [(set (match_dup 0)
14697 (ior:DI (lshiftrt:DI (match_dup 0)
14698 (and:QI (match_dup 2) (const_int 63)))
14701 (zero_extend:TI (match_dup 1))
14702 (minus:QI (const_int 64)
14703 (and:QI (match_dup 2)
14704 (const_int 63)))) 0)))
14705 (clobber (reg:CC FLAGS_REG))])])
14707 (define_insn "x86_shrd"
14708 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
14709 (ior:SI (lshiftrt:SI (match_dup 0)
14710 (and:QI (match_operand:QI 2 "nonmemory_operand" "Ic")
14715 (match_operand:SI 1 "register_operand" "r"))
14716 (minus:QI (const_int 32)
14717 (and:QI (match_dup 2) (const_int 31)))) 0)))
14718 (clobber (reg:CC FLAGS_REG))]
14720 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
14721 [(set_attr "type" "ishift")
14722 (set_attr "prefix_0f" "1")
14723 (set_attr "mode" "SI")
14724 (set_attr "pent_pair" "np")
14725 (set_attr "athlon_decode" "vector")
14726 (set_attr "amdfam10_decode" "vector")
14727 (set_attr "bdver1_decode" "vector")])
14729 (define_insn "x86_shrd_1"
14730 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
14731 (ior:SI (lshiftrt:SI (match_dup 0)
14732 (match_operand:QI 2 "const_0_to_31_operand"))
14736 (match_operand:SI 1 "register_operand" "r"))
14737 (match_operand:QI 3 "const_0_to_63_operand")) 0)))
14738 (clobber (reg:CC FLAGS_REG))]
14739 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])"
14740 "shrd{l}\t{%2, %1, %0|%0, %1, %2}"
14741 [(set_attr "type" "ishift")
14742 (set_attr "prefix_0f" "1")
14743 (set_attr "length_immediate" "1")
14744 (set_attr "mode" "SI")
14745 (set_attr "pent_pair" "np")
14746 (set_attr "athlon_decode" "vector")
14747 (set_attr "amdfam10_decode" "vector")
14748 (set_attr "bdver1_decode" "vector")])
14750 (define_insn_and_split "*x86_shrd_shld_1_nozext"
14751 [(set (match_operand:SI 0 "nonimmediate_operand")
14752 (ior:SI (lshiftrt:SI (match_operand:SI 4 "nonimmediate_operand")
14753 (match_operand:QI 2 "const_0_to_31_operand"))
14755 (match_operand:SI 1 "nonimmediate_operand")
14756 (match_operand:QI 3 "const_0_to_31_operand"))))
14757 (clobber (reg:CC FLAGS_REG))]
14758 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])
14759 && ix86_pre_reload_split ()"
14764 if (rtx_equal_p (operands[4], operands[0]))
14766 operands[1] = force_reg (SImode, operands[1]);
14767 emit_insn (gen_x86_shrd_1 (operands[0], operands[1], operands[2], operands[3]));
14769 else if (rtx_equal_p (operands[1], operands[0]))
14771 operands[4] = force_reg (SImode, operands[4]);
14772 emit_insn (gen_x86_shld_1 (operands[0], operands[4], operands[3], operands[2]));
14776 operands[1] = force_reg (SImode, operands[1]);
14777 rtx tmp = gen_reg_rtx (SImode);
14778 emit_move_insn (tmp, operands[4]);
14779 emit_insn (gen_x86_shrd_1 (tmp, operands[1], operands[2], operands[3]));
14780 emit_move_insn (operands[0], tmp);
14785 (define_insn_and_split "*x86_shrd_2"
14786 [(set (match_operand:SI 0 "nonimmediate_operand")
14787 (ior:SI (lshiftrt:SI (match_dup 0)
14788 (match_operand:QI 2 "nonmemory_operand"))
14789 (ashift:SI (match_operand:SI 1 "register_operand")
14790 (minus:QI (const_int 32) (match_dup 2)))))
14791 (clobber (reg:CC FLAGS_REG))]
14792 "TARGET_64BIT && ix86_pre_reload_split ()"
14795 [(parallel [(set (match_dup 0)
14796 (ior:SI (lshiftrt:SI (match_dup 0)
14797 (and:QI (match_dup 2) (const_int 31)))
14800 (zero_extend:DI (match_dup 1))
14801 (minus:QI (const_int 32)
14802 (and:QI (match_dup 2)
14803 (const_int 31)))) 0)))
14804 (clobber (reg:CC FLAGS_REG))])])
14806 ;; Base name for insn mnemonic.
14807 (define_mode_attr cvt_mnemonic
14808 [(SI "{cltd|cdq}") (DI "{cqto|cqo}")])
14810 (define_insn "ashr<mode>3_cvt"
14811 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=*d,rm")
14813 (match_operand:SWI48 1 "nonimmediate_operand" "*a,0")
14814 (match_operand:QI 2 "const_int_operand")))
14815 (clobber (reg:CC FLAGS_REG))]
14816 "INTVAL (operands[2]) == GET_MODE_BITSIZE (<MODE>mode)-1
14817 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
14818 && ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
14821 sar{<imodesuffix>}\t{%2, %0|%0, %2}"
14822 [(set_attr "type" "imovx,ishift")
14823 (set_attr "prefix_0f" "0,*")
14824 (set_attr "length_immediate" "0,*")
14825 (set_attr "modrm" "0,1")
14826 (set_attr "mode" "<MODE>")])
14828 (define_insn "*ashrsi3_cvt_zext"
14829 [(set (match_operand:DI 0 "register_operand" "=*d,r")
14831 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
14832 (match_operand:QI 2 "const_int_operand"))))
14833 (clobber (reg:CC FLAGS_REG))]
14834 "TARGET_64BIT && INTVAL (operands[2]) == 31
14835 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
14836 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
14839 sar{l}\t{%2, %k0|%k0, %2}"
14840 [(set_attr "type" "imovx,ishift")
14841 (set_attr "prefix_0f" "0,*")
14842 (set_attr "length_immediate" "0,*")
14843 (set_attr "modrm" "0,1")
14844 (set_attr "mode" "SI")])
14846 (define_expand "@x86_shift<mode>_adj_3"
14847 [(use (match_operand:SWI48 0 "register_operand"))
14848 (use (match_operand:SWI48 1 "register_operand"))
14849 (use (match_operand:QI 2 "register_operand"))]
14852 rtx_code_label *label = gen_label_rtx ();
14855 emit_insn (gen_testqi_ccz_1 (operands[2],
14856 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
14858 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
14859 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
14860 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
14861 gen_rtx_LABEL_REF (VOIDmode, label),
14863 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
14864 JUMP_LABEL (tmp) = label;
14866 emit_move_insn (operands[0], operands[1]);
14867 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
14868 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
14869 emit_label (label);
14870 LABEL_NUSES (label) = 1;
14875 (define_insn "*bmi2_<insn><mode>3_1"
14876 [(set (match_operand:SWI48 0 "register_operand" "=r")
14877 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14878 (match_operand:SWI48 2 "register_operand" "r")))]
14880 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
14881 [(set_attr "type" "ishiftx")
14882 (set_attr "mode" "<MODE>")])
14884 (define_insn "*ashr<mode>3_1"
14885 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
14887 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
14888 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
14889 (clobber (reg:CC FLAGS_REG))]
14890 "ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
14892 switch (get_attr_type (insn))
14898 if (operands[2] == const1_rtx
14899 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14900 return "sar{<imodesuffix>}\t%0";
14902 return "sar{<imodesuffix>}\t{%2, %0|%0, %2}";
14905 [(set_attr "isa" "*,bmi2")
14906 (set_attr "type" "ishift,ishiftx")
14907 (set (attr "length_immediate")
14909 (and (match_operand 2 "const1_operand")
14910 (ior (match_test "TARGET_SHIFT1")
14911 (match_test "optimize_function_for_size_p (cfun)")))
14913 (const_string "*")))
14914 (set_attr "mode" "<MODE>")])
14916 ;; Specialization of *lshr<mode>3_1 below, extracting the SImode
14917 ;; highpart of a DI to be extracted, but allowing it to be clobbered.
14918 (define_insn_and_split "*highpartdisi2"
14919 [(set (subreg:DI (match_operand:SI 0 "register_operand" "=r,x,?k") 0)
14920 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0,k")
14922 (clobber (reg:CC FLAGS_REG))]
14925 "&& reload_completed"
14927 [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 32)))
14928 (clobber (reg:CC FLAGS_REG))])]
14930 if (SSE_REG_P (operands[0]))
14932 rtx tmp = gen_rtx_REG (V4SImode, REGNO (operands[0]));
14933 emit_insn (gen_sse_shufps_v4si (tmp, tmp, tmp,
14934 const1_rtx, const1_rtx,
14935 GEN_INT (5), GEN_INT (5)));
14938 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
14941 (define_insn "*lshr<mode>3_1"
14942 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,?k")
14944 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm,k")
14945 (match_operand:QI 2 "nonmemory_operand" "c<S>,r,<KS>")))
14946 (clobber (reg:CC FLAGS_REG))]
14947 "ix86_binary_operator_ok (LSHIFTRT, <MODE>mode, operands)"
14949 switch (get_attr_type (insn))
14956 if (operands[2] == const1_rtx
14957 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14958 return "shr{<imodesuffix>}\t%0";
14960 return "shr{<imodesuffix>}\t{%2, %0|%0, %2}";
14963 [(set_attr "isa" "*,bmi2,avx512bw")
14964 (set_attr "type" "ishift,ishiftx,msklog")
14965 (set (attr "length_immediate")
14967 (and (and (match_operand 2 "const1_operand")
14968 (eq_attr "alternative" "0"))
14969 (ior (match_test "TARGET_SHIFT1")
14970 (match_test "optimize_function_for_size_p (cfun)")))
14972 (const_string "*")))
14973 (set_attr "mode" "<MODE>")])
14975 ;; Convert shift to the shiftx pattern to avoid flags dependency.
14977 [(set (match_operand:SWI48 0 "register_operand")
14978 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
14979 (match_operand:QI 2 "register_operand")))
14980 (clobber (reg:CC FLAGS_REG))]
14981 "TARGET_BMI2 && reload_completed"
14982 [(set (match_dup 0)
14983 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
14984 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
14986 (define_insn "*bmi2_<insn>si3_1_zext"
14987 [(set (match_operand:DI 0 "register_operand" "=r")
14989 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
14990 (match_operand:SI 2 "register_operand" "r"))))]
14991 "TARGET_64BIT && TARGET_BMI2"
14992 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
14993 [(set_attr "type" "ishiftx")
14994 (set_attr "mode" "SI")])
14996 (define_insn "*<insn>si3_1_zext"
14997 [(set (match_operand:DI 0 "register_operand" "=r,r")
14999 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
15000 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
15001 (clobber (reg:CC FLAGS_REG))]
15002 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
15004 switch (get_attr_type (insn))
15010 if (operands[2] == const1_rtx
15011 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15012 return "<shift>{l}\t%k0";
15014 return "<shift>{l}\t{%2, %k0|%k0, %2}";
15017 [(set_attr "isa" "*,bmi2")
15018 (set_attr "type" "ishift,ishiftx")
15019 (set (attr "length_immediate")
15021 (and (match_operand 2 "const1_operand")
15022 (ior (match_test "TARGET_SHIFT1")
15023 (match_test "optimize_function_for_size_p (cfun)")))
15025 (const_string "*")))
15026 (set_attr "mode" "SI")])
15028 ;; Convert shift to the shiftx pattern to avoid flags dependency.
15030 [(set (match_operand:DI 0 "register_operand")
15032 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
15033 (match_operand:QI 2 "register_operand"))))
15034 (clobber (reg:CC FLAGS_REG))]
15035 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
15036 [(set (match_dup 0)
15037 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
15038 "operands[2] = gen_lowpart (SImode, operands[2]);")
15040 (define_insn "*ashr<mode>3_1"
15041 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
15043 (match_operand:SWI12 1 "nonimmediate_operand" "0")
15044 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
15045 (clobber (reg:CC FLAGS_REG))]
15046 "ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
15048 if (operands[2] == const1_rtx
15049 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15050 return "sar{<imodesuffix>}\t%0";
15052 return "sar{<imodesuffix>}\t{%2, %0|%0, %2}";
15054 [(set_attr "type" "ishift")
15055 (set (attr "length_immediate")
15057 (and (match_operand 2 "const1_operand")
15058 (ior (match_test "TARGET_SHIFT1")
15059 (match_test "optimize_function_for_size_p (cfun)")))
15061 (const_string "*")))
15062 (set_attr "mode" "<MODE>")])
15064 (define_insn "*lshrqi3_1"
15065 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,?k")
15067 (match_operand:QI 1 "nonimmediate_operand" "0, k")
15068 (match_operand:QI 2 "nonmemory_operand" "cI,Wb")))
15069 (clobber (reg:CC FLAGS_REG))]
15070 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
15072 switch (get_attr_type (insn))
15075 if (operands[2] == const1_rtx
15076 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15077 return "shr{b}\t%0";
15079 return "shr{b}\t{%2, %0|%0, %2}";
15083 gcc_unreachable ();
15086 [(set_attr "isa" "*,avx512dq")
15087 (set_attr "type" "ishift,msklog")
15088 (set (attr "length_immediate")
15090 (and (and (match_operand 2 "const1_operand")
15091 (eq_attr "alternative" "0"))
15092 (ior (match_test "TARGET_SHIFT1")
15093 (match_test "optimize_function_for_size_p (cfun)")))
15095 (const_string "*")))
15096 (set_attr "mode" "QI")])
15098 (define_insn "*lshrhi3_1"
15099 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm, ?k")
15101 (match_operand:HI 1 "nonimmediate_operand" "0, k")
15102 (match_operand:QI 2 "nonmemory_operand" "cI, Ww")))
15103 (clobber (reg:CC FLAGS_REG))]
15104 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
15106 switch (get_attr_type (insn))
15109 if (operands[2] == const1_rtx
15110 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15111 return "shr{w}\t%0";
15113 return "shr{w}\t{%2, %0|%0, %2}";
15117 gcc_unreachable ();
15120 [(set_attr "isa" "*, avx512f")
15121 (set_attr "type" "ishift,msklog")
15122 (set (attr "length_immediate")
15124 (and (and (match_operand 2 "const1_operand")
15125 (eq_attr "alternative" "0"))
15126 (ior (match_test "TARGET_SHIFT1")
15127 (match_test "optimize_function_for_size_p (cfun)")))
15129 (const_string "*")))
15130 (set_attr "mode" "HI")])
15132 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
15133 (define_insn_and_split "*<insn><mode>3_1_slp"
15134 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
15135 (any_shiftrt:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
15136 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
15137 (clobber (reg:CC FLAGS_REG))]
15138 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
15140 if (which_alternative)
15143 if (operands[2] == const1_rtx
15144 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15145 return "<shift>{<imodesuffix>}\t%0";
15147 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
15149 "&& reload_completed"
15150 [(set (strict_low_part (match_dup 0)) (match_dup 1))
15152 [(set (strict_low_part (match_dup 0))
15153 (any_shiftrt:SWI12 (match_dup 0) (match_dup 2)))
15154 (clobber (reg:CC FLAGS_REG))])]
15156 [(set_attr "type" "ishift")
15157 (set (attr "length_immediate")
15159 (and (match_operand 2 "const1_operand")
15160 (ior (match_test "TARGET_SHIFT1")
15161 (match_test "optimize_function_for_size_p (cfun)")))
15163 (const_string "*")))
15164 (set_attr "mode" "<MODE>")])
15166 ;; This pattern can't accept a variable shift count, since shifts by
15167 ;; zero don't affect the flags. We assume that shifts by constant
15168 ;; zero are optimized away.
15169 (define_insn "*<insn><mode>3_cmp"
15170 [(set (reg FLAGS_REG)
15173 (match_operand:SWI 1 "nonimmediate_operand" "0")
15174 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
15176 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
15177 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
15178 "(optimize_function_for_size_p (cfun)
15179 || !TARGET_PARTIAL_FLAG_REG_STALL
15180 || (operands[2] == const1_rtx
15182 && ix86_match_ccmode (insn, CCGOCmode)
15183 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
15185 if (operands[2] == const1_rtx
15186 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15187 return "<shift>{<imodesuffix>}\t%0";
15189 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
15191 [(set_attr "type" "ishift")
15192 (set (attr "length_immediate")
15194 (and (match_operand 2 "const1_operand")
15195 (ior (match_test "TARGET_SHIFT1")
15196 (match_test "optimize_function_for_size_p (cfun)")))
15198 (const_string "*")))
15199 (set_attr "mode" "<MODE>")])
15201 (define_insn "*<insn>si3_cmp_zext"
15202 [(set (reg FLAGS_REG)
15204 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
15205 (match_operand:QI 2 "const_1_to_31_operand"))
15207 (set (match_operand:DI 0 "register_operand" "=r")
15208 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
15210 && (optimize_function_for_size_p (cfun)
15211 || !TARGET_PARTIAL_FLAG_REG_STALL
15212 || (operands[2] == const1_rtx
15214 && ix86_match_ccmode (insn, CCGOCmode)
15215 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
15217 if (operands[2] == const1_rtx
15218 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15219 return "<shift>{l}\t%k0";
15221 return "<shift>{l}\t{%2, %k0|%k0, %2}";
15223 [(set_attr "type" "ishift")
15224 (set (attr "length_immediate")
15226 (and (match_operand 2 "const1_operand")
15227 (ior (match_test "TARGET_SHIFT1")
15228 (match_test "optimize_function_for_size_p (cfun)")))
15230 (const_string "*")))
15231 (set_attr "mode" "SI")])
15233 (define_insn "*<insn><mode>3_cconly"
15234 [(set (reg FLAGS_REG)
15237 (match_operand:SWI 1 "register_operand" "0")
15238 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
15240 (clobber (match_scratch:SWI 0 "=<r>"))]
15241 "(optimize_function_for_size_p (cfun)
15242 || !TARGET_PARTIAL_FLAG_REG_STALL
15243 || (operands[2] == const1_rtx
15245 && ix86_match_ccmode (insn, CCGOCmode)"
15247 if (operands[2] == const1_rtx
15248 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15249 return "<shift>{<imodesuffix>}\t%0";
15251 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
15253 [(set_attr "type" "ishift")
15254 (set (attr "length_immediate")
15256 (and (match_operand 2 "const1_operand")
15257 (ior (match_test "TARGET_SHIFT1")
15258 (match_test "optimize_function_for_size_p (cfun)")))
15260 (const_string "*")))
15261 (set_attr "mode" "<MODE>")])
15263 (define_insn "*<insn>qi_ext<mode>_2"
15264 [(set (zero_extract:SWI248
15265 (match_operand 0 "int248_register_operand" "+Q")
15271 (match_operator:SWI248 3 "extract_operator"
15272 [(match_operand 1 "int248_register_operand" "0")
15275 (match_operand:QI 2 "nonmemory_operand" "cI")) 0))
15276 (clobber (reg:CC FLAGS_REG))]
15277 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
15278 rtx_equal_p (operands[0], operands[1])"
15280 if (operands[2] == const1_rtx
15281 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15282 return "<shift>{b}\t%h0";
15284 return "<shift>{b}\t{%2, %h0|%h0, %2}";
15286 [(set_attr "type" "ishift")
15287 (set (attr "length_immediate")
15289 (and (match_operand 2 "const1_operand")
15290 (ior (match_test "TARGET_SHIFT1")
15291 (match_test "optimize_function_for_size_p (cfun)")))
15293 (const_string "*")))
15294 (set_attr "mode" "QI")])
15296 (define_insn_and_split "*extend<dwi>2_doubleword_highpart"
15297 [(set (match_operand:<DWI> 0 "register_operand" "=r")
15299 (ashift:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")
15300 (match_operand:QI 2 "const_int_operand"))
15301 (match_operand:QI 3 "const_int_operand")))
15302 (clobber (reg:CC FLAGS_REG))]
15303 "INTVAL (operands[2]) == INTVAL (operands[3])
15304 && UINTVAL (operands[2]) < <MODE_SIZE> * BITS_PER_UNIT"
15306 "&& reload_completed"
15307 [(parallel [(set (match_dup 4)
15308 (ashift:DWIH (match_dup 4) (match_dup 2)))
15309 (clobber (reg:CC FLAGS_REG))])
15310 (parallel [(set (match_dup 4)
15311 (ashiftrt:DWIH (match_dup 4) (match_dup 2)))
15312 (clobber (reg:CC FLAGS_REG))])]
15313 "split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[4]);")
15315 (define_insn_and_split "*extendv2di2_highpart_stv"
15316 [(set (match_operand:V2DI 0 "register_operand" "=v")
15318 (ashift:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "vm")
15319 (match_operand:QI 2 "const_int_operand"))
15320 (match_operand:QI 3 "const_int_operand")))]
15321 "!TARGET_64BIT && TARGET_STV && TARGET_AVX512VL
15322 && INTVAL (operands[2]) == INTVAL (operands[3])
15323 && UINTVAL (operands[2]) < 32"
15325 "&& reload_completed"
15326 [(set (match_dup 0)
15327 (ashift:V2DI (match_dup 1) (match_dup 2)))
15329 (ashiftrt:V2DI (match_dup 0) (match_dup 2)))])
15331 ;; Rotate instructions
15333 (define_expand "<insn>ti3"
15334 [(set (match_operand:TI 0 "register_operand")
15335 (any_rotate:TI (match_operand:TI 1 "register_operand")
15336 (match_operand:QI 2 "nonmemory_operand")))]
15339 if (const_1_to_63_operand (operands[2], VOIDmode))
15340 emit_insn (gen_ix86_<insn>ti3_doubleword
15341 (operands[0], operands[1], operands[2]));
15342 else if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 64)
15343 emit_insn (gen_<insn>64ti2_doubleword (operands[0], operands[1]));
15346 rtx amount = force_reg (QImode, operands[2]);
15347 rtx src_lo = gen_lowpart (DImode, operands[1]);
15348 rtx src_hi = gen_highpart (DImode, operands[1]);
15349 rtx tmp_lo = gen_reg_rtx (DImode);
15350 rtx tmp_hi = gen_reg_rtx (DImode);
15351 emit_move_insn (tmp_lo, src_lo);
15352 emit_move_insn (tmp_hi, src_hi);
15353 rtx (*shiftd) (rtx, rtx, rtx)
15354 = (<CODE> == ROTATE) ? gen_x86_64_shld : gen_x86_64_shrd;
15355 emit_insn (shiftd (tmp_lo, src_hi, amount));
15356 emit_insn (shiftd (tmp_hi, src_lo, amount));
15357 rtx dst_lo = gen_lowpart (DImode, operands[0]);
15358 rtx dst_hi = gen_highpart (DImode, operands[0]);
15359 emit_move_insn (dst_lo, tmp_lo);
15360 emit_move_insn (dst_hi, tmp_hi);
15361 emit_insn (gen_x86_shiftdi_adj_1 (dst_lo, dst_hi, amount, tmp_lo));
15366 (define_expand "<insn>di3"
15367 [(set (match_operand:DI 0 "shiftdi_operand")
15368 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
15369 (match_operand:QI 2 "nonmemory_operand")))]
15373 ix86_expand_binary_operator (<CODE>, DImode, operands);
15374 else if (const_1_to_31_operand (operands[2], VOIDmode))
15375 emit_insn (gen_ix86_<insn>di3_doubleword
15376 (operands[0], operands[1], operands[2]));
15377 else if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 32)
15378 emit_insn (gen_<insn>32di2_doubleword (operands[0], operands[1]));
15385 (define_expand "<insn><mode>3"
15386 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
15387 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
15388 (match_operand:QI 2 "nonmemory_operand")))]
15390 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
15392 ;; Avoid useless masking of count operand.
15393 (define_insn_and_split "*<insn><mode>3_mask"
15394 [(set (match_operand:SWI 0 "nonimmediate_operand")
15396 (match_operand:SWI 1 "nonimmediate_operand")
15399 (match_operand 2 "int248_register_operand" "c")
15400 (match_operand 3 "const_int_operand")) 0)))
15401 (clobber (reg:CC FLAGS_REG))]
15402 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
15403 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15404 == GET_MODE_BITSIZE (<MODE>mode)-1
15405 && ix86_pre_reload_split ()"
15409 [(set (match_dup 0)
15410 (any_rotate:SWI (match_dup 1)
15412 (clobber (reg:CC FLAGS_REG))])]
15414 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
15415 operands[2] = gen_lowpart (QImode, operands[2]);
15419 [(set (match_operand:SWI 0 "register_operand")
15421 (match_operand:SWI 1 "const_int_operand")
15424 (match_operand 2 "int248_register_operand")
15425 (match_operand 3 "const_int_operand")) 0)))]
15426 "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode) - 1))
15427 == GET_MODE_BITSIZE (<MODE>mode) - 1"
15428 [(set (match_dup 4) (match_dup 1))
15430 (any_rotate:SWI (match_dup 4)
15431 (subreg:QI (match_dup 2) 0)))]
15432 "operands[4] = gen_reg_rtx (<MODE>mode);")
15434 (define_insn_and_split "*<insn><mode>3_mask_1"
15435 [(set (match_operand:SWI 0 "nonimmediate_operand")
15437 (match_operand:SWI 1 "nonimmediate_operand")
15439 (match_operand:QI 2 "register_operand" "c")
15440 (match_operand:QI 3 "const_int_operand"))))
15441 (clobber (reg:CC FLAGS_REG))]
15442 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
15443 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15444 == GET_MODE_BITSIZE (<MODE>mode)-1
15445 && ix86_pre_reload_split ()"
15449 [(set (match_dup 0)
15450 (any_rotate:SWI (match_dup 1)
15452 (clobber (reg:CC FLAGS_REG))])])
15455 [(set (match_operand:SWI 0 "register_operand")
15457 (match_operand:SWI 1 "const_int_operand")
15459 (match_operand:QI 2 "register_operand")
15460 (match_operand:QI 3 "const_int_operand"))))]
15461 "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode) - 1))
15462 == GET_MODE_BITSIZE (<MODE>mode) - 1"
15463 [(set (match_dup 4) (match_dup 1))
15465 (any_rotate:SWI (match_dup 4) (match_dup 2)))]
15466 "operands[4] = gen_reg_rtx (<MODE>mode);")
15468 ;; Implement rotation using two double-precision
15469 ;; shift instructions and a scratch register.
15471 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
15472 [(set (match_operand:<DWI> 0 "register_operand" "=r")
15473 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
15474 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
15475 (clobber (reg:CC FLAGS_REG))
15476 (clobber (match_scratch:DWIH 3 "=&r"))]
15480 [(set (match_dup 3) (match_dup 4))
15482 [(set (match_dup 4)
15483 (ior:DWIH (ashift:DWIH (match_dup 4)
15484 (and:QI (match_dup 2) (match_dup 6)))
15486 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
15487 (minus:QI (match_dup 7)
15488 (and:QI (match_dup 2)
15489 (match_dup 6)))) 0)))
15490 (clobber (reg:CC FLAGS_REG))])
15492 [(set (match_dup 5)
15493 (ior:DWIH (ashift:DWIH (match_dup 5)
15494 (and:QI (match_dup 2) (match_dup 6)))
15496 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 3))
15497 (minus:QI (match_dup 7)
15498 (and:QI (match_dup 2)
15499 (match_dup 6)))) 0)))
15500 (clobber (reg:CC FLAGS_REG))])]
15502 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
15503 operands[7] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
15505 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
15508 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
15509 [(set (match_operand:<DWI> 0 "register_operand" "=r")
15510 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
15511 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
15512 (clobber (reg:CC FLAGS_REG))
15513 (clobber (match_scratch:DWIH 3 "=&r"))]
15517 [(set (match_dup 3) (match_dup 4))
15519 [(set (match_dup 4)
15520 (ior:DWIH (lshiftrt:DWIH (match_dup 4)
15521 (and:QI (match_dup 2) (match_dup 6)))
15523 (ashift:<DWI> (zero_extend:<DWI> (match_dup 5))
15524 (minus:QI (match_dup 7)
15525 (and:QI (match_dup 2)
15526 (match_dup 6)))) 0)))
15527 (clobber (reg:CC FLAGS_REG))])
15529 [(set (match_dup 5)
15530 (ior:DWIH (lshiftrt:DWIH (match_dup 5)
15531 (and:QI (match_dup 2) (match_dup 6)))
15533 (ashift:<DWI> (zero_extend:<DWI> (match_dup 3))
15534 (minus:QI (match_dup 7)
15535 (and:QI (match_dup 2)
15536 (match_dup 6)))) 0)))
15537 (clobber (reg:CC FLAGS_REG))])]
15539 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
15540 operands[7] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
15542 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
15545 (define_insn_and_split "<insn>32di2_doubleword"
15546 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
15547 (any_rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,r,o")
15551 "&& reload_completed"
15552 [(set (match_dup 0) (match_dup 3))
15553 (set (match_dup 2) (match_dup 1))]
15555 split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);
15556 if (rtx_equal_p (operands[0], operands[1]))
15558 emit_insn (gen_swapsi (operands[0], operands[2]));
15563 (define_insn_and_split "<insn>64ti2_doubleword"
15564 [(set (match_operand:TI 0 "register_operand" "=r,r,r")
15565 (any_rotate:TI (match_operand:TI 1 "nonimmediate_operand" "0,r,o")
15569 "&& reload_completed"
15570 [(set (match_dup 0) (match_dup 3))
15571 (set (match_dup 2) (match_dup 1))]
15573 split_double_mode (TImode, &operands[0], 2, &operands[0], &operands[2]);
15574 if (rtx_equal_p (operands[0], operands[1]))
15576 emit_insn (gen_swapdi (operands[0], operands[2]));
15581 (define_mode_attr rorx_immediate_operand
15582 [(SI "const_0_to_31_operand")
15583 (DI "const_0_to_63_operand")])
15585 (define_insn "*bmi2_rorx<mode>3_1"
15586 [(set (match_operand:SWI48 0 "register_operand" "=r")
15588 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
15589 (match_operand:QI 2 "<rorx_immediate_operand>" "<S>")))]
15590 "TARGET_BMI2 && !optimize_function_for_size_p (cfun)"
15591 "rorx\t{%2, %1, %0|%0, %1, %2}"
15592 [(set_attr "type" "rotatex")
15593 (set_attr "mode" "<MODE>")])
15595 (define_insn "*<insn><mode>3_1"
15596 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
15598 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
15599 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
15600 (clobber (reg:CC FLAGS_REG))]
15601 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
15603 switch (get_attr_type (insn))
15609 if (operands[2] == const1_rtx
15610 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15611 return "<rotate>{<imodesuffix>}\t%0";
15613 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
15616 [(set_attr "isa" "*,bmi2")
15617 (set_attr "type" "rotate,rotatex")
15618 (set (attr "preferred_for_size")
15619 (cond [(eq_attr "alternative" "0")
15620 (symbol_ref "true")]
15621 (symbol_ref "false")))
15622 (set (attr "length_immediate")
15624 (and (eq_attr "type" "rotate")
15625 (and (match_operand 2 "const1_operand")
15626 (ior (match_test "TARGET_SHIFT1")
15627 (match_test "optimize_function_for_size_p (cfun)"))))
15629 (const_string "*")))
15630 (set_attr "mode" "<MODE>")])
15632 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
15634 [(set (match_operand:SWI48 0 "register_operand")
15635 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
15636 (match_operand:QI 2 "const_int_operand")))
15637 (clobber (reg:CC FLAGS_REG))]
15638 "TARGET_BMI2 && reload_completed && !optimize_function_for_size_p (cfun)"
15639 [(set (match_dup 0)
15640 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
15642 int bitsize = GET_MODE_BITSIZE (<MODE>mode);
15644 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
15648 [(set (match_operand:SWI48 0 "register_operand")
15649 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
15650 (match_operand:QI 2 "const_int_operand")))
15651 (clobber (reg:CC FLAGS_REG))]
15652 "TARGET_BMI2 && reload_completed && !optimize_function_for_size_p (cfun)"
15653 [(set (match_dup 0)
15654 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
15656 (define_insn "*bmi2_rorxsi3_1_zext"
15657 [(set (match_operand:DI 0 "register_operand" "=r")
15659 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
15660 (match_operand:QI 2 "const_0_to_31_operand"))))]
15661 "TARGET_64BIT && TARGET_BMI2 && !optimize_function_for_size_p (cfun)"
15662 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
15663 [(set_attr "type" "rotatex")
15664 (set_attr "mode" "SI")])
15666 (define_insn "*<insn>si3_1_zext"
15667 [(set (match_operand:DI 0 "register_operand" "=r,r")
15669 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
15670 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
15671 (clobber (reg:CC FLAGS_REG))]
15672 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
15674 switch (get_attr_type (insn))
15680 if (operands[2] == const1_rtx
15681 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15682 return "<rotate>{l}\t%k0";
15684 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
15687 [(set_attr "isa" "*,bmi2")
15688 (set_attr "type" "rotate,rotatex")
15689 (set (attr "preferred_for_size")
15690 (cond [(eq_attr "alternative" "0")
15691 (symbol_ref "true")]
15692 (symbol_ref "false")))
15693 (set (attr "length_immediate")
15695 (and (eq_attr "type" "rotate")
15696 (and (match_operand 2 "const1_operand")
15697 (ior (match_test "TARGET_SHIFT1")
15698 (match_test "optimize_function_for_size_p (cfun)"))))
15700 (const_string "*")))
15701 (set_attr "mode" "SI")])
15703 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
15705 [(set (match_operand:DI 0 "register_operand")
15707 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
15708 (match_operand:QI 2 "const_int_operand"))))
15709 (clobber (reg:CC FLAGS_REG))]
15710 "TARGET_64BIT && TARGET_BMI2 && reload_completed
15711 && !optimize_function_for_size_p (cfun)"
15712 [(set (match_dup 0)
15713 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
15715 int bitsize = GET_MODE_BITSIZE (SImode);
15717 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
15721 [(set (match_operand:DI 0 "register_operand")
15723 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
15724 (match_operand:QI 2 "const_int_operand"))))
15725 (clobber (reg:CC FLAGS_REG))]
15726 "TARGET_64BIT && TARGET_BMI2 && reload_completed
15727 && !optimize_function_for_size_p (cfun)"
15728 [(set (match_dup 0)
15729 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
15731 (define_insn "*<insn><mode>3_1"
15732 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
15733 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
15734 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
15735 (clobber (reg:CC FLAGS_REG))]
15736 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
15738 if (operands[2] == const1_rtx
15739 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15740 return "<rotate>{<imodesuffix>}\t%0";
15742 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
15744 [(set_attr "type" "rotate")
15745 (set (attr "length_immediate")
15747 (and (match_operand 2 "const1_operand")
15748 (ior (match_test "TARGET_SHIFT1")
15749 (match_test "optimize_function_for_size_p (cfun)")))
15751 (const_string "*")))
15752 (set_attr "mode" "<MODE>")])
15754 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
15755 (define_insn_and_split "*<insn><mode>3_1_slp"
15756 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
15757 (any_rotate:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
15758 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
15759 (clobber (reg:CC FLAGS_REG))]
15760 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
15762 if (which_alternative)
15765 if (operands[2] == const1_rtx
15766 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15767 return "<rotate>{<imodesuffix>}\t%0";
15769 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
15771 "&& reload_completed"
15772 [(set (strict_low_part (match_dup 0)) (match_dup 1))
15774 [(set (strict_low_part (match_dup 0))
15775 (any_rotate:SWI12 (match_dup 0) (match_dup 2)))
15776 (clobber (reg:CC FLAGS_REG))])]
15778 [(set_attr "type" "rotate")
15779 (set (attr "length_immediate")
15781 (and (match_operand 2 "const1_operand")
15782 (ior (match_test "TARGET_SHIFT1")
15783 (match_test "optimize_function_for_size_p (cfun)")))
15785 (const_string "*")))
15786 (set_attr "mode" "<MODE>")])
15789 [(set (match_operand:HI 0 "QIreg_operand")
15790 (any_rotate:HI (match_dup 0) (const_int 8)))
15791 (clobber (reg:CC FLAGS_REG))]
15793 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
15794 [(parallel [(set (strict_low_part (match_dup 0))
15795 (bswap:HI (match_dup 0)))
15796 (clobber (reg:CC FLAGS_REG))])])
15798 ;; Bit set / bit test instructions
15800 ;; %%% bts, btr, btc
15802 ;; These instructions are *slow* when applied to memory.
15804 (define_code_attr btsc [(ior "bts") (xor "btc")])
15806 (define_insn "*<btsc><mode>"
15807 [(set (match_operand:SWI48 0 "register_operand" "=r")
15809 (ashift:SWI48 (const_int 1)
15810 (match_operand:QI 2 "register_operand" "r"))
15811 (match_operand:SWI48 1 "register_operand" "0")))
15812 (clobber (reg:CC FLAGS_REG))]
15814 "<btsc>{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
15815 [(set_attr "type" "alu1")
15816 (set_attr "prefix_0f" "1")
15817 (set_attr "znver1_decode" "double")
15818 (set_attr "mode" "<MODE>")])
15820 ;; Avoid useless masking of count operand.
15821 (define_insn_and_split "*<btsc><mode>_mask"
15822 [(set (match_operand:SWI48 0 "register_operand")
15828 (match_operand 1 "int248_register_operand")
15829 (match_operand 2 "const_int_operand")) 0))
15830 (match_operand:SWI48 3 "register_operand")))
15831 (clobber (reg:CC FLAGS_REG))]
15833 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15834 == GET_MODE_BITSIZE (<MODE>mode)-1
15835 && ix86_pre_reload_split ()"
15839 [(set (match_dup 0)
15841 (ashift:SWI48 (const_int 1)
15844 (clobber (reg:CC FLAGS_REG))])]
15846 operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
15847 operands[1] = gen_lowpart (QImode, operands[1]);
15850 (define_insn_and_split "*<btsc><mode>_mask_1"
15851 [(set (match_operand:SWI48 0 "register_operand")
15856 (match_operand:QI 1 "register_operand")
15857 (match_operand:QI 2 "const_int_operand")))
15858 (match_operand:SWI48 3 "register_operand")))
15859 (clobber (reg:CC FLAGS_REG))]
15861 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15862 == GET_MODE_BITSIZE (<MODE>mode)-1
15863 && ix86_pre_reload_split ()"
15867 [(set (match_dup 0)
15869 (ashift:SWI48 (const_int 1)
15872 (clobber (reg:CC FLAGS_REG))])])
15874 (define_insn "*btr<mode>"
15875 [(set (match_operand:SWI48 0 "register_operand" "=r")
15877 (rotate:SWI48 (const_int -2)
15878 (match_operand:QI 2 "register_operand" "r"))
15879 (match_operand:SWI48 1 "register_operand" "0")))
15880 (clobber (reg:CC FLAGS_REG))]
15882 "btr{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
15883 [(set_attr "type" "alu1")
15884 (set_attr "prefix_0f" "1")
15885 (set_attr "znver1_decode" "double")
15886 (set_attr "mode" "<MODE>")])
15888 ;; Avoid useless masking of count operand.
15889 (define_insn_and_split "*btr<mode>_mask"
15890 [(set (match_operand:SWI48 0 "register_operand")
15896 (match_operand 1 "int248_register_operand")
15897 (match_operand 2 "const_int_operand")) 0))
15898 (match_operand:SWI48 3 "register_operand")))
15899 (clobber (reg:CC FLAGS_REG))]
15901 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15902 == GET_MODE_BITSIZE (<MODE>mode)-1
15903 && ix86_pre_reload_split ()"
15907 [(set (match_dup 0)
15909 (rotate:SWI48 (const_int -2)
15912 (clobber (reg:CC FLAGS_REG))])]
15914 operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
15915 operands[1] = gen_lowpart (QImode, operands[1]);
15918 (define_insn_and_split "*btr<mode>_mask_1"
15919 [(set (match_operand:SWI48 0 "register_operand")
15924 (match_operand:QI 1 "register_operand")
15925 (match_operand:QI 2 "const_int_operand")))
15926 (match_operand:SWI48 3 "register_operand")))
15927 (clobber (reg:CC FLAGS_REG))]
15929 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15930 == GET_MODE_BITSIZE (<MODE>mode)-1
15931 && ix86_pre_reload_split ()"
15935 [(set (match_dup 0)
15937 (rotate:SWI48 (const_int -2)
15940 (clobber (reg:CC FLAGS_REG))])])
15942 (define_insn_and_split "*btr<mode>_1"
15943 [(set (match_operand:SWI12 0 "register_operand")
15946 (rotate:SI (const_int -2)
15947 (match_operand:QI 2 "register_operand")) 0)
15948 (match_operand:SWI12 1 "nonimmediate_operand")))
15949 (clobber (reg:CC FLAGS_REG))]
15950 "TARGET_USE_BT && ix86_pre_reload_split ()"
15954 [(set (match_dup 0)
15955 (and:SI (rotate:SI (const_int -2) (match_dup 2))
15957 (clobber (reg:CC FLAGS_REG))])]
15959 operands[0] = lowpart_subreg (SImode, operands[0], <MODE>mode);
15960 operands[1] = force_reg (<MODE>mode, operands[1]);
15961 operands[1] = lowpart_subreg (SImode, operands[1], <MODE>mode);
15964 (define_insn_and_split "*btr<mode>_2"
15965 [(set (zero_extract:HI
15966 (match_operand:SWI12 0 "nonimmediate_operand")
15968 (zero_extend:SI (match_operand:QI 1 "register_operand")))
15970 (clobber (reg:CC FLAGS_REG))]
15971 "TARGET_USE_BT && ix86_pre_reload_split ()"
15973 "&& MEM_P (operands[0])"
15974 [(set (match_dup 2) (match_dup 0))
15976 [(set (match_dup 3)
15977 (and:SI (rotate:SI (const_int -2) (match_dup 1))
15979 (clobber (reg:CC FLAGS_REG))])
15980 (set (match_dup 0) (match_dup 5))]
15982 operands[2] = gen_reg_rtx (<MODE>mode);
15983 operands[5] = gen_reg_rtx (<MODE>mode);
15984 operands[3] = lowpart_subreg (SImode, operands[5], <MODE>mode);
15985 operands[4] = lowpart_subreg (SImode, operands[2], <MODE>mode);
15989 [(set (zero_extract:HI
15990 (match_operand:SWI12 0 "register_operand")
15992 (zero_extend:SI (match_operand:QI 1 "register_operand")))
15994 (clobber (reg:CC FLAGS_REG))]
15995 "TARGET_USE_BT && ix86_pre_reload_split ()"
15997 [(set (match_dup 0)
15998 (and:SI (rotate:SI (const_int -2) (match_dup 1))
16000 (clobber (reg:CC FLAGS_REG))])]
16002 operands[2] = lowpart_subreg (SImode, operands[0], <MODE>mode);
16003 operands[0] = lowpart_subreg (SImode, operands[0], <MODE>mode);
16006 ;; These instructions are never faster than the corresponding
16007 ;; and/ior/xor operations when using immediate operand, so with
16008 ;; 32-bit there's no point. But in 64-bit, we can't hold the
16009 ;; relevant immediates within the instruction itself, so operating
16010 ;; on bits in the high 32-bits of a register becomes easier.
16012 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
16013 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
16014 ;; negdf respectively, so they can never be disabled entirely.
16016 (define_insn "*btsq_imm"
16017 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
16019 (match_operand 1 "const_0_to_63_operand"))
16021 (clobber (reg:CC FLAGS_REG))]
16022 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
16023 "bts{q}\t{%1, %0|%0, %1}"
16024 [(set_attr "type" "alu1")
16025 (set_attr "prefix_0f" "1")
16026 (set_attr "znver1_decode" "double")
16027 (set_attr "mode" "DI")])
16029 (define_insn "*btrq_imm"
16030 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
16032 (match_operand 1 "const_0_to_63_operand"))
16034 (clobber (reg:CC FLAGS_REG))]
16035 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
16036 "btr{q}\t{%1, %0|%0, %1}"
16037 [(set_attr "type" "alu1")
16038 (set_attr "prefix_0f" "1")
16039 (set_attr "znver1_decode" "double")
16040 (set_attr "mode" "DI")])
16042 (define_insn "*btcq_imm"
16043 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
16045 (match_operand 1 "const_0_to_63_operand"))
16046 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
16047 (clobber (reg:CC FLAGS_REG))]
16048 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
16049 "btc{q}\t{%1, %0|%0, %1}"
16050 [(set_attr "type" "alu1")
16051 (set_attr "prefix_0f" "1")
16052 (set_attr "znver1_decode" "double")
16053 (set_attr "mode" "DI")])
16055 ;; Allow Nocona to avoid these instructions if a register is available.
16058 [(match_scratch:DI 2 "r")
16059 (parallel [(set (zero_extract:DI
16060 (match_operand:DI 0 "nonimmediate_operand")
16062 (match_operand 1 "const_0_to_63_operand"))
16064 (clobber (reg:CC FLAGS_REG))])]
16065 "TARGET_64BIT && !TARGET_USE_BT"
16066 [(parallel [(set (match_dup 0)
16067 (ior:DI (match_dup 0) (match_dup 3)))
16068 (clobber (reg:CC FLAGS_REG))])]
16070 int i = INTVAL (operands[1]);
16072 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
16074 if (!x86_64_immediate_operand (operands[3], DImode))
16076 emit_move_insn (operands[2], operands[3]);
16077 operands[3] = operands[2];
16082 [(match_scratch:DI 2 "r")
16083 (parallel [(set (zero_extract:DI
16084 (match_operand:DI 0 "nonimmediate_operand")
16086 (match_operand 1 "const_0_to_63_operand"))
16088 (clobber (reg:CC FLAGS_REG))])]
16089 "TARGET_64BIT && !TARGET_USE_BT"
16090 [(parallel [(set (match_dup 0)
16091 (and:DI (match_dup 0) (match_dup 3)))
16092 (clobber (reg:CC FLAGS_REG))])]
16094 int i = INTVAL (operands[1]);
16096 operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
16098 if (!x86_64_immediate_operand (operands[3], DImode))
16100 emit_move_insn (operands[2], operands[3]);
16101 operands[3] = operands[2];
16106 [(match_scratch:DI 2 "r")
16107 (parallel [(set (zero_extract:DI
16108 (match_operand:DI 0 "nonimmediate_operand")
16110 (match_operand 1 "const_0_to_63_operand"))
16111 (not:DI (zero_extract:DI
16112 (match_dup 0) (const_int 1) (match_dup 1))))
16113 (clobber (reg:CC FLAGS_REG))])]
16114 "TARGET_64BIT && !TARGET_USE_BT"
16115 [(parallel [(set (match_dup 0)
16116 (xor:DI (match_dup 0) (match_dup 3)))
16117 (clobber (reg:CC FLAGS_REG))])]
16119 int i = INTVAL (operands[1]);
16121 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
16123 if (!x86_64_immediate_operand (operands[3], DImode))
16125 emit_move_insn (operands[2], operands[3]);
16126 operands[3] = operands[2];
16132 (define_insn "*bt<mode>"
16133 [(set (reg:CCC FLAGS_REG)
16135 (zero_extract:SWI48
16136 (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
16138 (match_operand:SI 1 "nonmemory_operand" "r<S>,<S>"))
16142 switch (get_attr_mode (insn))
16145 return "bt{l}\t{%1, %k0|%k0, %1}";
16148 return "bt{q}\t{%q1, %0|%0, %q1}";
16151 gcc_unreachable ();
16154 [(set_attr "type" "alu1")
16155 (set_attr "prefix_0f" "1")
16158 (and (match_test "CONST_INT_P (operands[1])")
16159 (match_test "INTVAL (operands[1]) < 32"))
16160 (const_string "SI")
16161 (const_string "<MODE>")))])
16163 (define_insn_and_split "*jcc_bt<mode>"
16165 (if_then_else (match_operator 0 "bt_comparison_operator"
16166 [(zero_extract:SWI48
16167 (match_operand:SWI48 1 "nonimmediate_operand")
16169 (match_operand:SI 2 "nonmemory_operand"))
16171 (label_ref (match_operand 3))
16173 (clobber (reg:CC FLAGS_REG))]
16174 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
16175 && (CONST_INT_P (operands[2])
16176 ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
16177 && INTVAL (operands[2])
16178 >= (optimize_function_for_size_p (cfun) ? 8 : 32))
16179 : !memory_operand (operands[1], <MODE>mode))
16180 && ix86_pre_reload_split ()"
16183 [(set (reg:CCC FLAGS_REG)
16185 (zero_extract:SWI48
16191 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16192 (label_ref (match_dup 3))
16195 operands[0] = shallow_copy_rtx (operands[0]);
16196 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16199 (define_insn_and_split "*jcc_bt<mode>_1"
16201 (if_then_else (match_operator 0 "bt_comparison_operator"
16202 [(zero_extract:SWI48
16203 (match_operand:SWI48 1 "register_operand")
16206 (match_operand:QI 2 "register_operand")))
16208 (label_ref (match_operand 3))
16210 (clobber (reg:CC FLAGS_REG))]
16211 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
16212 && ix86_pre_reload_split ()"
16215 [(set (reg:CCC FLAGS_REG)
16217 (zero_extract:SWI48
16223 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16224 (label_ref (match_dup 3))
16227 operands[2] = lowpart_subreg (SImode, operands[2], QImode);
16228 operands[0] = shallow_copy_rtx (operands[0]);
16229 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16232 ;; Avoid useless masking of bit offset operand.
16233 (define_insn_and_split "*jcc_bt<mode>_mask"
16235 (if_then_else (match_operator 0 "bt_comparison_operator"
16236 [(zero_extract:SWI48
16237 (match_operand:SWI48 1 "register_operand")
16240 (match_operand:SI 2 "register_operand")
16241 (match_operand 3 "const_int_operand")))])
16242 (label_ref (match_operand 4))
16244 (clobber (reg:CC FLAGS_REG))]
16245 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
16246 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16247 == GET_MODE_BITSIZE (<MODE>mode)-1
16248 && ix86_pre_reload_split ()"
16251 [(set (reg:CCC FLAGS_REG)
16253 (zero_extract:SWI48
16259 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16260 (label_ref (match_dup 4))
16263 operands[0] = shallow_copy_rtx (operands[0]);
16264 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16267 (define_insn_and_split "*jcc_bt<mode>_mask_1"
16269 (if_then_else (match_operator 0 "bt_comparison_operator"
16270 [(zero_extract:SWI48
16271 (match_operand:SWI48 1 "register_operand")
16276 (match_operand 2 "int248_register_operand")
16277 (match_operand 3 "const_int_operand")) 0)))])
16278 (label_ref (match_operand 4))
16280 (clobber (reg:CC FLAGS_REG))]
16281 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
16282 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16283 == GET_MODE_BITSIZE (<MODE>mode)-1
16284 && ix86_pre_reload_split ()"
16287 [(set (reg:CCC FLAGS_REG)
16289 (zero_extract:SWI48
16295 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16296 (label_ref (match_dup 4))
16299 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
16300 operands[2] = gen_lowpart (SImode, operands[2]);
16301 operands[0] = shallow_copy_rtx (operands[0]);
16302 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16305 ;; Help combine recognize bt followed by cmov
16307 [(set (match_operand:SWI248 0 "register_operand")
16308 (if_then_else:SWI248
16309 (match_operator 5 "bt_comparison_operator"
16310 [(zero_extract:SWI48
16311 (match_operand:SWI48 1 "register_operand")
16313 (zero_extend:SI (match_operand:QI 2 "register_operand")))
16315 (match_operand:SWI248 3 "nonimmediate_operand")
16316 (match_operand:SWI248 4 "nonimmediate_operand")))]
16317 "TARGET_USE_BT && TARGET_CMOVE
16318 && !(MEM_P (operands[3]) && MEM_P (operands[4]))
16319 && ix86_pre_reload_split ()"
16320 [(set (reg:CCC FLAGS_REG)
16322 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16325 (if_then_else:SWI248 (eq (reg:CCC FLAGS_REG) (const_int 0))
16329 if (GET_CODE (operands[5]) == EQ)
16330 std::swap (operands[3], operands[4]);
16331 operands[2] = lowpart_subreg (SImode, operands[2], QImode);
16334 ;; Help combine recognize bt followed by setc
16335 (define_insn_and_split "*bt<mode>_setcqi"
16336 [(set (subreg:SWI48 (match_operand:QI 0 "register_operand") 0)
16337 (zero_extract:SWI48
16338 (match_operand:SWI48 1 "register_operand")
16340 (zero_extend:SI (match_operand:QI 2 "register_operand"))))
16341 (clobber (reg:CC FLAGS_REG))]
16342 "TARGET_USE_BT && ix86_pre_reload_split ()"
16345 [(set (reg:CCC FLAGS_REG)
16347 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16350 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
16351 "operands[2] = lowpart_subreg (SImode, operands[2], QImode);")
16353 ;; Help combine recognize bt followed by setnc
16354 (define_insn_and_split "*bt<mode>_setncqi"
16355 [(set (match_operand:QI 0 "register_operand")
16359 (lshiftrt:SWI48 (match_operand:SWI48 1 "register_operand")
16360 (match_operand:QI 2 "register_operand")) 0))
16362 (clobber (reg:CC FLAGS_REG))]
16363 "TARGET_USE_BT && ix86_pre_reload_split ()"
16366 [(set (reg:CCC FLAGS_REG)
16368 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16371 (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))]
16372 "operands[2] = lowpart_subreg (SImode, operands[2], QImode);")
16374 (define_insn_and_split "*bt<mode>_setnc<mode>"
16375 [(set (match_operand:SWI48 0 "register_operand")
16378 (lshiftrt:SWI48 (match_operand:SWI48 1 "register_operand")
16379 (match_operand:QI 2 "register_operand")))
16381 (clobber (reg:CC FLAGS_REG))]
16382 "TARGET_USE_BT && ix86_pre_reload_split ()"
16385 [(set (reg:CCC FLAGS_REG)
16387 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16390 (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))
16391 (set (match_dup 0) (zero_extend:SWI48 (match_dup 3)))]
16393 operands[2] = lowpart_subreg (SImode, operands[2], QImode);
16394 operands[3] = gen_reg_rtx (QImode);
16397 ;; Help combine recognize bt followed by setnc (PR target/110588)
16398 (define_insn_and_split "*bt<mode>_setncqi_2"
16399 [(set (match_operand:QI 0 "register_operand")
16401 (zero_extract:SWI48
16402 (match_operand:SWI48 1 "register_operand")
16404 (zero_extend:SI (match_operand:QI 2 "register_operand")))
16406 (clobber (reg:CC FLAGS_REG))]
16407 "TARGET_USE_BT && ix86_pre_reload_split ()"
16410 [(set (reg:CCC FLAGS_REG)
16412 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16415 (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))]
16416 "operands[2] = lowpart_subreg (SImode, operands[2], QImode);")
16418 ;; Store-flag instructions.
16421 [(set (match_operand:QI 0 "nonimmediate_operand")
16422 (match_operator:QI 1 "add_comparison_operator"
16423 [(not:SWI (match_operand:SWI 2 "register_operand"))
16424 (match_operand:SWI 3 "nonimmediate_operand")]))]
16426 [(set (reg:CCC FLAGS_REG)
16428 (plus:SWI (match_dup 2) (match_dup 3))
16431 (match_op_dup 1 [(reg:CCC FLAGS_REG) (const_int 0)]))])
16434 [(set (match_operand:QI 0 "nonimmediate_operand")
16435 (match_operator:QI 1 "shr_comparison_operator"
16436 [(match_operand:DI 2 "register_operand")
16437 (match_operand 3 "const_int_operand")]))]
16439 && IN_RANGE (exact_log2 (UINTVAL (operands[3]) + 1), 32, 63)"
16440 [(set (reg:CCZ FLAGS_REG)
16442 (lshiftrt:DI (match_dup 2) (match_dup 4))
16445 (match_op_dup 1 [(reg:CCZ FLAGS_REG) (const_int 0)]))]
16447 enum rtx_code new_code;
16449 operands[1] = shallow_copy_rtx (operands[1]);
16450 switch (GET_CODE (operands[1]))
16452 case GTU: new_code = NE; break;
16453 case LEU: new_code = EQ; break;
16454 default: gcc_unreachable ();
16456 PUT_CODE (operands[1], new_code);
16458 operands[4] = GEN_INT (exact_log2 (UINTVAL (operands[3]) + 1));
16461 ;; For all sCOND expanders, also expand the compare or test insn that
16462 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
16464 (define_insn_and_split "*setcc_di_1"
16465 [(set (match_operand:DI 0 "register_operand" "=q")
16466 (match_operator:DI 1 "ix86_comparison_operator"
16467 [(reg FLAGS_REG) (const_int 0)]))]
16468 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
16470 "&& reload_completed"
16471 [(set (match_dup 2) (match_dup 1))
16472 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
16474 operands[1] = shallow_copy_rtx (operands[1]);
16475 PUT_MODE (operands[1], QImode);
16476 operands[2] = gen_lowpart (QImode, operands[0]);
16479 (define_insn_and_split "*setcc_<mode>_1_and"
16480 [(set (match_operand:SWI24 0 "register_operand" "=q")
16481 (match_operator:SWI24 1 "ix86_comparison_operator"
16482 [(reg FLAGS_REG) (const_int 0)]))
16483 (clobber (reg:CC FLAGS_REG))]
16484 "!TARGET_PARTIAL_REG_STALL
16485 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
16487 "&& reload_completed"
16488 [(set (match_dup 2) (match_dup 1))
16489 (parallel [(set (match_dup 0) (zero_extend:SWI24 (match_dup 2)))
16490 (clobber (reg:CC FLAGS_REG))])]
16492 operands[1] = shallow_copy_rtx (operands[1]);
16493 PUT_MODE (operands[1], QImode);
16494 operands[2] = gen_lowpart (QImode, operands[0]);
16497 (define_insn_and_split "*setcc_<mode>_1_movzbl"
16498 [(set (match_operand:SWI24 0 "register_operand" "=q")
16499 (match_operator:SWI24 1 "ix86_comparison_operator"
16500 [(reg FLAGS_REG) (const_int 0)]))]
16501 "!TARGET_PARTIAL_REG_STALL
16502 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
16504 "&& reload_completed"
16505 [(set (match_dup 2) (match_dup 1))
16506 (set (match_dup 0) (zero_extend:SWI24 (match_dup 2)))]
16508 operands[1] = shallow_copy_rtx (operands[1]);
16509 PUT_MODE (operands[1], QImode);
16510 operands[2] = gen_lowpart (QImode, operands[0]);
16513 (define_insn "*setcc_qi"
16514 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
16515 (match_operator:QI 1 "ix86_comparison_operator"
16516 [(reg FLAGS_REG) (const_int 0)]))]
16519 [(set_attr "type" "setcc")
16520 (set_attr "mode" "QI")])
16522 (define_insn "*setcc_qi_slp"
16523 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+q"))
16524 (match_operator:QI 1 "ix86_comparison_operator"
16525 [(reg FLAGS_REG) (const_int 0)]))]
16528 [(set_attr "type" "setcc")
16529 (set_attr "mode" "QI")])
16531 ;; In general it is not safe to assume too much about CCmode registers,
16532 ;; so simplify-rtx stops when it sees a second one. Under certain
16533 ;; conditions this is safe on x86, so help combine not create
16540 [(set (match_operand:QI 0 "nonimmediate_operand")
16541 (ne:QI (match_operator 1 "ix86_comparison_operator"
16542 [(reg FLAGS_REG) (const_int 0)])
16545 [(set (match_dup 0) (match_dup 1))]
16547 operands[1] = shallow_copy_rtx (operands[1]);
16548 PUT_MODE (operands[1], QImode);
16552 [(set (strict_low_part (match_operand:QI 0 "register_operand"))
16553 (ne:QI (match_operator 1 "ix86_comparison_operator"
16554 [(reg FLAGS_REG) (const_int 0)])
16557 [(set (match_dup 0) (match_dup 1))]
16559 operands[1] = shallow_copy_rtx (operands[1]);
16560 PUT_MODE (operands[1], QImode);
16564 [(set (match_operand:QI 0 "nonimmediate_operand")
16565 (eq:QI (match_operator 1 "ix86_comparison_operator"
16566 [(reg FLAGS_REG) (const_int 0)])
16569 [(set (match_dup 0) (match_dup 1))]
16571 operands[1] = shallow_copy_rtx (operands[1]);
16572 PUT_MODE (operands[1], QImode);
16573 PUT_CODE (operands[1],
16574 ix86_reverse_condition (GET_CODE (operands[1]),
16575 GET_MODE (XEXP (operands[1], 0))));
16577 /* Make sure that (a) the CCmode we have for the flags is strong
16578 enough for the reversed compare or (b) we have a valid FP compare. */
16579 if (! ix86_comparison_operator (operands[1], VOIDmode))
16584 [(set (strict_low_part (match_operand:QI 0 "register_operand"))
16585 (eq:QI (match_operator 1 "ix86_comparison_operator"
16586 [(reg FLAGS_REG) (const_int 0)])
16589 [(set (match_dup 0) (match_dup 1))]
16591 operands[1] = shallow_copy_rtx (operands[1]);
16592 PUT_MODE (operands[1], QImode);
16593 PUT_CODE (operands[1],
16594 ix86_reverse_condition (GET_CODE (operands[1]),
16595 GET_MODE (XEXP (operands[1], 0))));
16597 /* Make sure that (a) the CCmode we have for the flags is strong
16598 enough for the reversed compare or (b) we have a valid FP compare. */
16599 if (! ix86_comparison_operator (operands[1], VOIDmode))
16603 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
16604 ;; subsequent logical operations are used to imitate conditional moves.
16605 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
16608 (define_insn "setcc_<mode>_sse"
16609 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16610 (match_operator:MODEF 3 "sse_comparison_operator"
16611 [(match_operand:MODEF 1 "register_operand" "0,x")
16612 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
16613 "SSE_FLOAT_MODE_P (<MODE>mode)"
16615 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
16616 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16617 [(set_attr "isa" "noavx,avx")
16618 (set_attr "type" "ssecmp")
16619 (set_attr "length_immediate" "1")
16620 (set_attr "prefix" "orig,vex")
16621 (set_attr "mode" "<MODE>")])
16623 (define_insn "setcc_hf_mask"
16624 [(set (match_operand:QI 0 "register_operand" "=k")
16626 [(match_operand:HF 1 "register_operand" "v")
16627 (match_operand:HF 2 "nonimmediate_operand" "vm")
16628 (match_operand:SI 3 "const_0_to_31_operand")]
16630 "TARGET_AVX512FP16"
16631 "vcmpsh\t{%3, %2, %1, %0|%0, %1, %2, %3}"
16632 [(set_attr "type" "ssecmp")
16633 (set_attr "prefix" "evex")
16634 (set_attr "mode" "HF")])
16637 ;; Basic conditional jump instructions.
16642 (match_operator 1 "add_comparison_operator"
16643 [(not:SWI (match_operand:SWI 2 "register_operand"))
16644 (match_operand:SWI 3 "nonimmediate_operand")])
16645 (label_ref (match_operand 0))
16648 [(set (reg:CCC FLAGS_REG)
16650 (plus:SWI (match_dup 2) (match_dup 3))
16653 (if_then_else (match_op_dup 1 [(reg:CCC FLAGS_REG) (const_int 0)])
16654 (label_ref (match_operand 0))
16660 (match_operator 1 "shr_comparison_operator"
16661 [(match_operand:DI 2 "register_operand")
16662 (match_operand 3 "const_int_operand")])
16663 (label_ref (match_operand 0))
16666 && IN_RANGE (exact_log2 (UINTVAL (operands[3]) + 1), 32, 63)"
16667 [(set (reg:CCZ FLAGS_REG)
16669 (lshiftrt:DI (match_dup 2) (match_dup 4))
16672 (if_then_else (match_op_dup 1 [(reg:CCZ FLAGS_REG) (const_int 0)])
16673 (label_ref (match_operand 0))
16676 enum rtx_code new_code;
16678 operands[1] = shallow_copy_rtx (operands[1]);
16679 switch (GET_CODE (operands[1]))
16681 case GTU: new_code = NE; break;
16682 case LEU: new_code = EQ; break;
16683 default: gcc_unreachable ();
16685 PUT_CODE (operands[1], new_code);
16687 operands[4] = GEN_INT (exact_log2 (UINTVAL (operands[3]) + 1));
16690 ;; We ignore the overflow flag for signed branch instructions.
16692 (define_insn "*jcc"
16694 (if_then_else (match_operator 1 "ix86_comparison_operator"
16695 [(reg FLAGS_REG) (const_int 0)])
16696 (label_ref (match_operand 0))
16700 [(set_attr "type" "ibr")
16701 (set_attr "modrm" "0")
16702 (set (attr "length")
16704 (and (ge (minus (match_dup 0) (pc))
16706 (lt (minus (match_dup 0) (pc))
16711 ;; In general it is not safe to assume too much about CCmode registers,
16712 ;; so simplify-rtx stops when it sees a second one. Under certain
16713 ;; conditions this is safe on x86, so help combine not create
16721 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
16722 [(reg FLAGS_REG) (const_int 0)])
16724 (label_ref (match_operand 1))
16728 (if_then_else (match_dup 0)
16729 (label_ref (match_dup 1))
16732 operands[0] = shallow_copy_rtx (operands[0]);
16733 PUT_MODE (operands[0], VOIDmode);
16738 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
16739 [(reg FLAGS_REG) (const_int 0)])
16741 (label_ref (match_operand 1))
16745 (if_then_else (match_dup 0)
16746 (label_ref (match_dup 1))
16749 operands[0] = shallow_copy_rtx (operands[0]);
16750 PUT_MODE (operands[0], VOIDmode);
16751 PUT_CODE (operands[0],
16752 ix86_reverse_condition (GET_CODE (operands[0]),
16753 GET_MODE (XEXP (operands[0], 0))));
16755 /* Make sure that (a) the CCmode we have for the flags is strong
16756 enough for the reversed compare or (b) we have a valid FP compare. */
16757 if (! ix86_comparison_operator (operands[0], VOIDmode))
16761 ;; Unconditional and other jump instructions
16763 (define_insn "jump"
16765 (label_ref (match_operand 0)))]
16768 [(set_attr "type" "ibr")
16769 (set_attr "modrm" "0")
16770 (set (attr "length")
16772 (and (ge (minus (match_dup 0) (pc))
16774 (lt (minus (match_dup 0) (pc))
16779 (define_expand "indirect_jump"
16780 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
16783 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
16784 operands[0] = convert_memory_address (word_mode, operands[0]);
16785 cfun->machine->has_local_indirect_jump = true;
16788 (define_insn "*indirect_jump"
16789 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
16791 "* return ix86_output_indirect_jmp (operands[0]);"
16792 [(set (attr "type")
16793 (if_then_else (match_test "(cfun->machine->indirect_branch_type
16794 != indirect_branch_keep)")
16795 (const_string "multi")
16796 (const_string "ibr")))
16797 (set_attr "length_immediate" "0")])
16799 (define_expand "tablejump"
16800 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
16801 (use (label_ref (match_operand 1)))])]
16804 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
16805 relative. Convert the relative address to an absolute address. */
16809 enum rtx_code code;
16811 /* We can't use @GOTOFF for text labels on VxWorks;
16812 see gotoff_operand. */
16813 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
16817 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
16819 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
16823 op1 = pic_offset_table_rtx;
16828 op0 = pic_offset_table_rtx;
16832 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
16836 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
16837 operands[0] = convert_memory_address (word_mode, operands[0]);
16838 cfun->machine->has_local_indirect_jump = true;
16841 (define_insn "*tablejump_1"
16842 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
16843 (use (label_ref (match_operand 1)))]
16845 "* return ix86_output_indirect_jmp (operands[0]);"
16846 [(set (attr "type")
16847 (if_then_else (match_test "(cfun->machine->indirect_branch_type
16848 != indirect_branch_keep)")
16849 (const_string "multi")
16850 (const_string "ibr")))
16851 (set_attr "length_immediate" "0")])
16853 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
16856 [(set (match_operand 4 "flags_reg_operand") (match_operand 0))
16857 (set (match_operand:QI 1 "register_operand")
16858 (match_operator:QI 2 "ix86_comparison_operator"
16859 [(reg FLAGS_REG) (const_int 0)]))
16860 (set (match_operand 3 "any_QIreg_operand")
16861 (zero_extend (match_dup 1)))]
16862 "(peep2_reg_dead_p (3, operands[1])
16863 || operands_match_p (operands[1], operands[3]))
16864 && ! reg_overlap_mentioned_p (operands[3], operands[0])
16865 && peep2_regno_dead_p (0, FLAGS_REG)"
16866 [(set (match_dup 4) (match_dup 0))
16867 (set (strict_low_part (match_dup 5))
16870 operands[5] = gen_lowpart (QImode, operands[3]);
16871 ix86_expand_clear (operands[3]);
16875 [(parallel [(set (match_operand 5 "flags_reg_operand") (match_operand 0))
16876 (match_operand 4)])
16877 (set (match_operand:QI 1 "register_operand")
16878 (match_operator:QI 2 "ix86_comparison_operator"
16879 [(reg FLAGS_REG) (const_int 0)]))
16880 (set (match_operand 3 "any_QIreg_operand")
16881 (zero_extend (match_dup 1)))]
16882 "(peep2_reg_dead_p (3, operands[1])
16883 || operands_match_p (operands[1], operands[3]))
16884 && ! reg_overlap_mentioned_p (operands[3], operands[0])
16885 && ! reg_overlap_mentioned_p (operands[3], operands[4])
16886 && ! reg_set_p (operands[3], operands[4])
16887 && peep2_regno_dead_p (0, FLAGS_REG)"
16888 [(parallel [(set (match_dup 5) (match_dup 0))
16890 (set (strict_low_part (match_dup 6))
16893 operands[6] = gen_lowpart (QImode, operands[3]);
16894 ix86_expand_clear (operands[3]);
16898 [(set (match_operand 6 "flags_reg_operand") (match_operand 0))
16899 (parallel [(set (match_operand 7 "flags_reg_operand") (match_operand 1))
16900 (match_operand 5)])
16901 (set (match_operand:QI 2 "register_operand")
16902 (match_operator:QI 3 "ix86_comparison_operator"
16903 [(reg FLAGS_REG) (const_int 0)]))
16904 (set (match_operand 4 "any_QIreg_operand")
16905 (zero_extend (match_dup 2)))]
16906 "(peep2_reg_dead_p (4, operands[2])
16907 || operands_match_p (operands[2], operands[4]))
16908 && ! reg_overlap_mentioned_p (operands[4], operands[0])
16909 && ! reg_overlap_mentioned_p (operands[4], operands[1])
16910 && ! reg_overlap_mentioned_p (operands[4], operands[5])
16911 && ! reg_set_p (operands[4], operands[5])
16912 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
16913 && peep2_regno_dead_p (0, FLAGS_REG)"
16914 [(set (match_dup 6) (match_dup 0))
16915 (parallel [(set (match_dup 7) (match_dup 1))
16917 (set (strict_low_part (match_dup 8))
16920 operands[8] = gen_lowpart (QImode, operands[4]);
16921 ix86_expand_clear (operands[4]);
16924 ;; Similar, but match zero extend with andsi3.
16927 [(set (match_operand 4 "flags_reg_operand") (match_operand 0))
16928 (set (match_operand:QI 1 "register_operand")
16929 (match_operator:QI 2 "ix86_comparison_operator"
16930 [(reg FLAGS_REG) (const_int 0)]))
16931 (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
16932 (and:SI (match_dup 3) (const_int 255)))
16933 (clobber (reg:CC FLAGS_REG))])]
16934 "REGNO (operands[1]) == REGNO (operands[3])
16935 && ! reg_overlap_mentioned_p (operands[3], operands[0])
16936 && peep2_regno_dead_p (0, FLAGS_REG)"
16937 [(set (match_dup 4) (match_dup 0))
16938 (set (strict_low_part (match_dup 5))
16941 operands[5] = gen_lowpart (QImode, operands[3]);
16942 ix86_expand_clear (operands[3]);
16946 [(parallel [(set (match_operand 5 "flags_reg_operand") (match_operand 0))
16947 (match_operand 4)])
16948 (set (match_operand:QI 1 "register_operand")
16949 (match_operator:QI 2 "ix86_comparison_operator"
16950 [(reg FLAGS_REG) (const_int 0)]))
16951 (parallel [(set (match_operand 3 "any_QIreg_operand")
16952 (zero_extend (match_dup 1)))
16953 (clobber (reg:CC FLAGS_REG))])]
16954 "(peep2_reg_dead_p (3, operands[1])
16955 || operands_match_p (operands[1], operands[3]))
16956 && ! reg_overlap_mentioned_p (operands[3], operands[0])
16957 && ! reg_overlap_mentioned_p (operands[3], operands[4])
16958 && ! reg_set_p (operands[3], operands[4])
16959 && peep2_regno_dead_p (0, FLAGS_REG)"
16960 [(parallel [(set (match_dup 5) (match_dup 0))
16962 (set (strict_low_part (match_dup 6))
16965 operands[6] = gen_lowpart (QImode, operands[3]);
16966 ix86_expand_clear (operands[3]);
16970 [(set (match_operand 6 "flags_reg_operand") (match_operand 0))
16971 (parallel [(set (match_operand 7 "flags_reg_operand") (match_operand 1))
16972 (match_operand 5)])
16973 (set (match_operand:QI 2 "register_operand")
16974 (match_operator:QI 3 "ix86_comparison_operator"
16975 [(reg FLAGS_REG) (const_int 0)]))
16976 (parallel [(set (match_operand 4 "any_QIreg_operand")
16977 (zero_extend (match_dup 2)))
16978 (clobber (reg:CC FLAGS_REG))])]
16979 "(peep2_reg_dead_p (4, operands[2])
16980 || operands_match_p (operands[2], operands[4]))
16981 && ! reg_overlap_mentioned_p (operands[4], operands[0])
16982 && ! reg_overlap_mentioned_p (operands[4], operands[1])
16983 && ! reg_overlap_mentioned_p (operands[4], operands[5])
16984 && ! reg_set_p (operands[4], operands[5])
16985 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
16986 && peep2_regno_dead_p (0, FLAGS_REG)"
16987 [(set (match_dup 6) (match_dup 0))
16988 (parallel [(set (match_dup 7) (match_dup 1))
16990 (set (strict_low_part (match_dup 8))
16993 operands[8] = gen_lowpart (QImode, operands[4]);
16994 ix86_expand_clear (operands[4]);
16997 ;; Call instructions.
16999 ;; The predicates normally associated with named expanders are not properly
17000 ;; checked for calls. This is a bug in the generic code, but it isn't that
17001 ;; easy to fix. Ignore it for now and be prepared to fix things up.
17003 ;; P6 processors will jump to the address after the decrement when %esp
17004 ;; is used as a call operand, so they will execute return address as a code.
17005 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
17007 ;; Register constraint for call instruction.
17008 (define_mode_attr c [(SI "l") (DI "r")])
17010 ;; Call subroutine returning no value.
17012 (define_expand "call"
17013 [(call (match_operand:QI 0)
17015 (use (match_operand 2))]
17018 ix86_expand_call (NULL, operands[0], operands[1],
17019 operands[2], NULL, false);
17023 (define_expand "sibcall"
17024 [(call (match_operand:QI 0)
17026 (use (match_operand 2))]
17029 ix86_expand_call (NULL, operands[0], operands[1],
17030 operands[2], NULL, true);
17034 (define_insn "*call"
17035 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
17036 (match_operand 1))]
17037 "!SIBLING_CALL_P (insn)"
17038 "* return ix86_output_call_insn (insn, operands[0]);"
17039 [(set_attr "type" "call")])
17041 ;; This covers both call and sibcall since only GOT slot is allowed.
17042 (define_insn "*call_got_x32"
17043 [(call (mem:QI (zero_extend:DI
17044 (match_operand:SI 0 "GOT_memory_operand" "Bg")))
17045 (match_operand 1))]
17048 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
17049 return ix86_output_call_insn (insn, fnaddr);
17051 [(set_attr "type" "call")])
17053 ;; Since sibcall never returns, we can only use call-clobbered register
17055 (define_insn "*sibcall_GOT_32"
17058 (match_operand:SI 0 "register_no_elim_operand" "U")
17059 (match_operand:SI 1 "GOT32_symbol_operand"))))
17060 (match_operand 2))]
17063 && !TARGET_INDIRECT_BRANCH_REGISTER
17064 && SIBLING_CALL_P (insn)"
17066 rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
17067 fnaddr = gen_const_mem (SImode, fnaddr);
17068 return ix86_output_call_insn (insn, fnaddr);
17070 [(set_attr "type" "call")])
17072 (define_insn "*sibcall"
17073 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
17074 (match_operand 1))]
17075 "SIBLING_CALL_P (insn)"
17076 "* return ix86_output_call_insn (insn, operands[0]);"
17077 [(set_attr "type" "call")])
17079 (define_insn "*sibcall_memory"
17080 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
17082 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17083 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
17084 "* return ix86_output_call_insn (insn, operands[0]);"
17085 [(set_attr "type" "call")])
17088 [(set (match_operand:W 0 "register_operand")
17089 (match_operand:W 1 "memory_operand"))
17090 (call (mem:QI (match_dup 0))
17091 (match_operand 3))]
17093 && !TARGET_INDIRECT_BRANCH_REGISTER
17094 && SIBLING_CALL_P (peep2_next_insn (1))
17095 && !reg_mentioned_p (operands[0],
17096 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17097 [(parallel [(call (mem:QI (match_dup 1))
17099 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17102 [(set (match_operand:W 0 "register_operand")
17103 (match_operand:W 1 "memory_operand"))
17104 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17105 (call (mem:QI (match_dup 0))
17106 (match_operand 3))]
17108 && !TARGET_INDIRECT_BRANCH_REGISTER
17109 && SIBLING_CALL_P (peep2_next_insn (2))
17110 && !reg_mentioned_p (operands[0],
17111 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17112 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17113 (parallel [(call (mem:QI (match_dup 1))
17115 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17117 (define_expand "call_pop"
17118 [(parallel [(call (match_operand:QI 0)
17119 (match_operand:SI 1))
17120 (set (reg:SI SP_REG)
17121 (plus:SI (reg:SI SP_REG)
17122 (match_operand:SI 3)))])]
17125 ix86_expand_call (NULL, operands[0], operands[1],
17126 operands[2], operands[3], false);
17130 (define_insn "*call_pop"
17131 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz"))
17133 (set (reg:SI SP_REG)
17134 (plus:SI (reg:SI SP_REG)
17135 (match_operand:SI 2 "immediate_operand" "i")))]
17136 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17137 "* return ix86_output_call_insn (insn, operands[0]);"
17138 [(set_attr "type" "call")])
17140 (define_insn "*sibcall_pop"
17141 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
17143 (set (reg:SI SP_REG)
17144 (plus:SI (reg:SI SP_REG)
17145 (match_operand:SI 2 "immediate_operand" "i")))]
17146 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17147 "* return ix86_output_call_insn (insn, operands[0]);"
17148 [(set_attr "type" "call")])
17150 (define_insn "*sibcall_pop_memory"
17151 [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs"))
17153 (set (reg:SI SP_REG)
17154 (plus:SI (reg:SI SP_REG)
17155 (match_operand:SI 2 "immediate_operand" "i")))
17156 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17158 "* return ix86_output_call_insn (insn, operands[0]);"
17159 [(set_attr "type" "call")])
17162 [(set (match_operand:SI 0 "register_operand")
17163 (match_operand:SI 1 "memory_operand"))
17164 (parallel [(call (mem:QI (match_dup 0))
17166 (set (reg:SI SP_REG)
17167 (plus:SI (reg:SI SP_REG)
17168 (match_operand:SI 4 "immediate_operand")))])]
17169 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
17170 && !reg_mentioned_p (operands[0],
17171 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17172 [(parallel [(call (mem:QI (match_dup 1))
17174 (set (reg:SI SP_REG)
17175 (plus:SI (reg:SI SP_REG)
17177 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17180 [(set (match_operand:SI 0 "register_operand")
17181 (match_operand:SI 1 "memory_operand"))
17182 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17183 (parallel [(call (mem:QI (match_dup 0))
17185 (set (reg:SI SP_REG)
17186 (plus:SI (reg:SI SP_REG)
17187 (match_operand:SI 4 "immediate_operand")))])]
17188 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
17189 && !reg_mentioned_p (operands[0],
17190 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17191 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17192 (parallel [(call (mem:QI (match_dup 1))
17194 (set (reg:SI SP_REG)
17195 (plus:SI (reg:SI SP_REG)
17197 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17199 ;; Combining simple memory jump instruction
17202 [(set (match_operand:W 0 "register_operand")
17203 (match_operand:W 1 "memory_operand"))
17204 (set (pc) (match_dup 0))]
17206 && !TARGET_INDIRECT_BRANCH_REGISTER
17207 && peep2_reg_dead_p (2, operands[0])"
17208 [(set (pc) (match_dup 1))])
17210 ;; Call subroutine, returning value in operand 0
17212 (define_expand "call_value"
17213 [(set (match_operand 0)
17214 (call (match_operand:QI 1)
17215 (match_operand 2)))
17216 (use (match_operand 3))]
17219 ix86_expand_call (operands[0], operands[1], operands[2],
17220 operands[3], NULL, false);
17224 (define_expand "sibcall_value"
17225 [(set (match_operand 0)
17226 (call (match_operand:QI 1)
17227 (match_operand 2)))
17228 (use (match_operand 3))]
17231 ix86_expand_call (operands[0], operands[1], operands[2],
17232 operands[3], NULL, true);
17236 (define_insn "*call_value"
17237 [(set (match_operand 0)
17238 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
17239 (match_operand 2)))]
17240 "!SIBLING_CALL_P (insn)"
17241 "* return ix86_output_call_insn (insn, operands[1]);"
17242 [(set_attr "type" "callv")])
17244 ;; This covers both call and sibcall since only GOT slot is allowed.
17245 (define_insn "*call_value_got_x32"
17246 [(set (match_operand 0)
17249 (match_operand:SI 1 "GOT_memory_operand" "Bg")))
17250 (match_operand 2)))]
17253 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
17254 return ix86_output_call_insn (insn, fnaddr);
17256 [(set_attr "type" "callv")])
17258 ;; Since sibcall never returns, we can only use call-clobbered register
17260 (define_insn "*sibcall_value_GOT_32"
17261 [(set (match_operand 0)
17264 (match_operand:SI 1 "register_no_elim_operand" "U")
17265 (match_operand:SI 2 "GOT32_symbol_operand"))))
17266 (match_operand 3)))]
17269 && !TARGET_INDIRECT_BRANCH_REGISTER
17270 && SIBLING_CALL_P (insn)"
17272 rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
17273 fnaddr = gen_const_mem (SImode, fnaddr);
17274 return ix86_output_call_insn (insn, fnaddr);
17276 [(set_attr "type" "callv")])
17278 (define_insn "*sibcall_value"
17279 [(set (match_operand 0)
17280 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
17281 (match_operand 2)))]
17282 "SIBLING_CALL_P (insn)"
17283 "* return ix86_output_call_insn (insn, operands[1]);"
17284 [(set_attr "type" "callv")])
17286 (define_insn "*sibcall_value_memory"
17287 [(set (match_operand 0)
17288 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
17289 (match_operand 2)))
17290 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17291 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
17292 "* return ix86_output_call_insn (insn, operands[1]);"
17293 [(set_attr "type" "callv")])
17296 [(set (match_operand:W 0 "register_operand")
17297 (match_operand:W 1 "memory_operand"))
17298 (set (match_operand 2)
17299 (call (mem:QI (match_dup 0))
17300 (match_operand 3)))]
17302 && !TARGET_INDIRECT_BRANCH_REGISTER
17303 && SIBLING_CALL_P (peep2_next_insn (1))
17304 && !reg_mentioned_p (operands[0],
17305 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17306 [(parallel [(set (match_dup 2)
17307 (call (mem:QI (match_dup 1))
17309 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17312 [(set (match_operand:W 0 "register_operand")
17313 (match_operand:W 1 "memory_operand"))
17314 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17315 (set (match_operand 2)
17316 (call (mem:QI (match_dup 0))
17317 (match_operand 3)))]
17319 && !TARGET_INDIRECT_BRANCH_REGISTER
17320 && SIBLING_CALL_P (peep2_next_insn (2))
17321 && !reg_mentioned_p (operands[0],
17322 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17323 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17324 (parallel [(set (match_dup 2)
17325 (call (mem:QI (match_dup 1))
17327 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17329 (define_expand "call_value_pop"
17330 [(parallel [(set (match_operand 0)
17331 (call (match_operand:QI 1)
17332 (match_operand:SI 2)))
17333 (set (reg:SI SP_REG)
17334 (plus:SI (reg:SI SP_REG)
17335 (match_operand:SI 4)))])]
17338 ix86_expand_call (operands[0], operands[1], operands[2],
17339 operands[3], operands[4], false);
17343 (define_insn "*call_value_pop"
17344 [(set (match_operand 0)
17345 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz"))
17346 (match_operand 2)))
17347 (set (reg:SI SP_REG)
17348 (plus:SI (reg:SI SP_REG)
17349 (match_operand:SI 3 "immediate_operand" "i")))]
17350 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17351 "* return ix86_output_call_insn (insn, operands[1]);"
17352 [(set_attr "type" "callv")])
17354 (define_insn "*sibcall_value_pop"
17355 [(set (match_operand 0)
17356 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
17357 (match_operand 2)))
17358 (set (reg:SI SP_REG)
17359 (plus:SI (reg:SI SP_REG)
17360 (match_operand:SI 3 "immediate_operand" "i")))]
17361 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17362 "* return ix86_output_call_insn (insn, operands[1]);"
17363 [(set_attr "type" "callv")])
17365 (define_insn "*sibcall_value_pop_memory"
17366 [(set (match_operand 0)
17367 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
17368 (match_operand 2)))
17369 (set (reg:SI SP_REG)
17370 (plus:SI (reg:SI SP_REG)
17371 (match_operand:SI 3 "immediate_operand" "i")))
17372 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17374 "* return ix86_output_call_insn (insn, operands[1]);"
17375 [(set_attr "type" "callv")])
17378 [(set (match_operand:SI 0 "register_operand")
17379 (match_operand:SI 1 "memory_operand"))
17380 (parallel [(set (match_operand 2)
17381 (call (mem:QI (match_dup 0))
17382 (match_operand 3)))
17383 (set (reg:SI SP_REG)
17384 (plus:SI (reg:SI SP_REG)
17385 (match_operand:SI 4 "immediate_operand")))])]
17386 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
17387 && !reg_mentioned_p (operands[0],
17388 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17389 [(parallel [(set (match_dup 2)
17390 (call (mem:QI (match_dup 1))
17392 (set (reg:SI SP_REG)
17393 (plus:SI (reg:SI SP_REG)
17395 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17398 [(set (match_operand:SI 0 "register_operand")
17399 (match_operand:SI 1 "memory_operand"))
17400 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17401 (parallel [(set (match_operand 2)
17402 (call (mem:QI (match_dup 0))
17403 (match_operand 3)))
17404 (set (reg:SI SP_REG)
17405 (plus:SI (reg:SI SP_REG)
17406 (match_operand:SI 4 "immediate_operand")))])]
17407 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
17408 && !reg_mentioned_p (operands[0],
17409 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17410 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17411 (parallel [(set (match_dup 2)
17412 (call (mem:QI (match_dup 1))
17414 (set (reg:SI SP_REG)
17415 (plus:SI (reg:SI SP_REG)
17417 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17419 ;; Call subroutine returning any type.
17421 (define_expand "untyped_call"
17422 [(parallel [(call (match_operand 0)
17425 (match_operand 2)])]
17430 /* In order to give reg-stack an easier job in validating two
17431 coprocessor registers as containing a possible return value,
17432 simply pretend the untyped call returns a complex long double
17435 We can't use SSE_REGPARM_MAX here since callee is unprototyped
17436 and should have the default ABI. */
17438 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
17439 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
17440 operands[0], const0_rtx,
17441 GEN_INT ((TARGET_64BIT
17442 ? (ix86_abi == SYSV_ABI
17443 ? X86_64_SSE_REGPARM_MAX
17444 : X86_64_MS_SSE_REGPARM_MAX)
17445 : X86_32_SSE_REGPARM_MAX)
17449 for (i = 0; i < XVECLEN (operands[2], 0); i++)
17451 rtx set = XVECEXP (operands[2], 0, i);
17452 emit_move_insn (SET_DEST (set), SET_SRC (set));
17455 /* The optimizer does not know that the call sets the function value
17456 registers we stored in the result block. We avoid problems by
17457 claiming that all hard registers are used and clobbered at this
17459 emit_insn (gen_blockage ());
17464 ;; Prologue and epilogue instructions
17466 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
17467 ;; all of memory. This blocks insns from being moved across this point.
17469 (define_insn "blockage"
17470 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
17473 [(set_attr "length" "0")])
17475 ;; Do not schedule instructions accessing memory across this point.
17477 (define_expand "memory_blockage"
17478 [(set (match_dup 0)
17479 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
17482 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
17483 MEM_VOLATILE_P (operands[0]) = 1;
17486 (define_insn "*memory_blockage"
17487 [(set (match_operand:BLK 0)
17488 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
17491 [(set_attr "length" "0")])
17493 ;; As USE insns aren't meaningful after reload, this is used instead
17494 ;; to prevent deleting instructions setting registers for PIC code
17495 (define_insn "prologue_use"
17496 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
17499 [(set_attr "length" "0")])
17501 ;; Insn emitted into the body of a function to return from a function.
17502 ;; This is only done if the function's epilogue is known to be simple.
17503 ;; See comments for ix86_can_use_return_insn_p in i386.cc.
17505 (define_expand "return"
17507 "ix86_can_use_return_insn_p ()"
17509 if (crtl->args.pops_args)
17511 rtx popc = GEN_INT (crtl->args.pops_args);
17512 emit_jump_insn (gen_simple_return_pop_internal (popc));
17517 ;; We need to disable this for TARGET_SEH, as otherwise
17518 ;; shrink-wrapped prologue gets enabled too. This might exceed
17519 ;; the maximum size of prologue in unwind information.
17520 ;; Also disallow shrink-wrapping if using stack slot to pass the
17521 ;; static chain pointer - the first instruction has to be pushl %esi
17522 ;; and it can't be moved around, as we use alternate entry points
17524 ;; Also disallow for ms_hook_prologue functions which have frame
17525 ;; pointer set up in function label which is correctly handled in
17526 ;; ix86_expand_{prologue|epligoue}() only.
17528 (define_expand "simple_return"
17530 "!TARGET_SEH && !ix86_static_chain_on_stack && !ix86_function_ms_hook_prologue (cfun->decl)"
17532 if (crtl->args.pops_args)
17534 rtx popc = GEN_INT (crtl->args.pops_args);
17535 emit_jump_insn (gen_simple_return_pop_internal (popc));
17540 (define_insn "simple_return_internal"
17543 "* return ix86_output_function_return (false);"
17544 [(set_attr "length" "1")
17545 (set_attr "atom_unit" "jeu")
17546 (set_attr "length_immediate" "0")
17547 (set_attr "modrm" "0")])
17549 (define_insn "interrupt_return"
17551 (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
17554 return TARGET_64BIT ? (TARGET_UINTR ? "uiret" : "iretq") : "iret";
17557 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
17558 ;; instruction Athlon and K8 have.
17560 (define_insn "simple_return_internal_long"
17562 (unspec [(const_int 0)] UNSPEC_REP)]
17564 "* return ix86_output_function_return (true);"
17565 [(set_attr "length" "2")
17566 (set_attr "atom_unit" "jeu")
17567 (set_attr "length_immediate" "0")
17568 (set_attr "prefix_rep" "1")
17569 (set_attr "modrm" "0")])
17571 (define_insn_and_split "simple_return_pop_internal"
17573 (use (match_operand:SI 0 "const_int_operand"))]
17576 "&& cfun->machine->function_return_type != indirect_branch_keep"
17578 "ix86_split_simple_return_pop_internal (operands[0]); DONE;"
17579 [(set_attr "length" "3")
17580 (set_attr "atom_unit" "jeu")
17581 (set_attr "length_immediate" "2")
17582 (set_attr "modrm" "0")])
17584 (define_expand "simple_return_indirect_internal"
17587 (use (match_operand 0 "register_operand"))])])
17589 (define_insn "*simple_return_indirect_internal<mode>"
17591 (use (match_operand:W 0 "register_operand" "r"))]
17593 "* return ix86_output_indirect_function_return (operands[0]);"
17594 [(set (attr "type")
17595 (if_then_else (match_test "(cfun->machine->indirect_branch_type
17596 != indirect_branch_keep)")
17597 (const_string "multi")
17598 (const_string "ibr")))
17599 (set_attr "length_immediate" "0")])
17605 [(set_attr "length" "1")
17606 (set_attr "length_immediate" "0")
17607 (set_attr "modrm" "0")])
17609 ;; Generate nops. Operand 0 is the number of nops, up to 8.
17610 (define_insn "nops"
17611 [(unspec_volatile [(match_operand 0 "const_int_operand")]
17615 int num = INTVAL (operands[0]);
17617 gcc_assert (IN_RANGE (num, 1, 8));
17620 fputs ("\tnop\n", asm_out_file);
17624 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
17625 (set_attr "length_immediate" "0")
17626 (set_attr "modrm" "0")])
17628 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
17629 ;; branch prediction penalty for the third jump in a 16-byte
17633 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
17636 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
17637 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
17639 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
17640 The align insn is used to avoid 3 jump instructions in the row to improve
17641 branch prediction and the benefits hardly outweigh the cost of extra 8
17642 nops on the average inserted by full alignment pseudo operation. */
17646 [(set_attr "length" "16")])
17648 (define_expand "prologue"
17651 "ix86_expand_prologue (); DONE;")
17653 (define_expand "set_got"
17655 [(set (match_operand:SI 0 "register_operand")
17656 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
17657 (clobber (reg:CC FLAGS_REG))])]
17660 if (flag_pic && !TARGET_VXWORKS_RTP)
17661 ix86_pc_thunk_call_expanded = true;
17664 (define_insn "*set_got"
17665 [(set (match_operand:SI 0 "register_operand" "=r")
17666 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
17667 (clobber (reg:CC FLAGS_REG))]
17669 "* return output_set_got (operands[0], NULL_RTX);"
17670 [(set_attr "type" "multi")
17671 (set_attr "length" "12")])
17673 (define_expand "set_got_labelled"
17675 [(set (match_operand:SI 0 "register_operand")
17676 (unspec:SI [(label_ref (match_operand 1))]
17678 (clobber (reg:CC FLAGS_REG))])]
17681 if (flag_pic && !TARGET_VXWORKS_RTP)
17682 ix86_pc_thunk_call_expanded = true;
17685 (define_insn "*set_got_labelled"
17686 [(set (match_operand:SI 0 "register_operand" "=r")
17687 (unspec:SI [(label_ref (match_operand 1))]
17689 (clobber (reg:CC FLAGS_REG))]
17691 "* return output_set_got (operands[0], operands[1]);"
17692 [(set_attr "type" "multi")
17693 (set_attr "length" "12")])
17695 (define_insn "set_got_rex64"
17696 [(set (match_operand:DI 0 "register_operand" "=r")
17697 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
17699 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
17700 [(set_attr "type" "lea")
17701 (set_attr "length_address" "4")
17702 (set_attr "mode" "DI")])
17704 (define_insn "set_rip_rex64"
17705 [(set (match_operand:DI 0 "register_operand" "=r")
17706 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
17708 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
17709 [(set_attr "type" "lea")
17710 (set_attr "length_address" "4")
17711 (set_attr "mode" "DI")])
17713 (define_insn "set_got_offset_rex64"
17714 [(set (match_operand:DI 0 "register_operand" "=r")
17716 [(label_ref (match_operand 1))]
17717 UNSPEC_SET_GOT_OFFSET))]
17719 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
17720 [(set_attr "type" "imov")
17721 (set_attr "length_immediate" "0")
17722 (set_attr "length_address" "8")
17723 (set_attr "mode" "DI")])
17725 (define_expand "epilogue"
17728 "ix86_expand_epilogue (1); DONE;")
17730 (define_expand "sibcall_epilogue"
17733 "ix86_expand_epilogue (0); DONE;")
17735 (define_expand "eh_return"
17736 [(use (match_operand 0 "register_operand"))]
17739 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
17741 /* Tricky bit: we write the address of the handler to which we will
17742 be returning into someone else's stack frame, one word below the
17743 stack address we wish to restore. */
17744 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
17745 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
17746 /* Return address is always in word_mode. */
17747 tmp = gen_rtx_MEM (word_mode, tmp);
17748 if (GET_MODE (ra) != word_mode)
17749 ra = convert_to_mode (word_mode, ra, 1);
17750 emit_move_insn (tmp, ra);
17752 emit_jump_insn (gen_eh_return_internal ());
17757 (define_insn_and_split "eh_return_internal"
17761 "epilogue_completed"
17763 "ix86_expand_epilogue (2); DONE;")
17765 (define_expand "@leave_<mode>"
17767 [(set (reg:W SP_REG) (plus:W (reg:W BP_REG) (match_dup 0)))
17768 (set (reg:W BP_REG) (mem:W (reg:W BP_REG)))
17769 (clobber (mem:BLK (scratch)))])]
17771 "operands[0] = GEN_INT (<MODE_SIZE>);")
17773 (define_insn "*leave"
17774 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
17775 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
17776 (clobber (mem:BLK (scratch)))]
17779 [(set_attr "type" "leave")])
17781 (define_insn "*leave_rex64"
17782 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
17783 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
17784 (clobber (mem:BLK (scratch)))]
17787 [(set_attr "type" "leave")])
17789 ;; Handle -fsplit-stack.
17791 (define_expand "split_stack_prologue"
17795 ix86_expand_split_stack_prologue ();
17799 ;; In order to support the call/return predictor, we use a return
17800 ;; instruction which the middle-end doesn't see.
17801 (define_insn "split_stack_return"
17802 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
17803 UNSPECV_SPLIT_STACK_RETURN)]
17806 if (operands[0] == const0_rtx)
17811 [(set_attr "atom_unit" "jeu")
17812 (set_attr "modrm" "0")
17813 (set (attr "length")
17814 (if_then_else (match_operand:SI 0 "const0_operand")
17817 (set (attr "length_immediate")
17818 (if_then_else (match_operand:SI 0 "const0_operand")
17822 ;; If there are operand 0 bytes available on the stack, jump to
17825 (define_expand "split_stack_space_check"
17826 [(set (pc) (if_then_else
17827 (ltu (minus (reg SP_REG)
17828 (match_operand 0 "register_operand"))
17830 (label_ref (match_operand 1))
17834 rtx reg = gen_reg_rtx (Pmode);
17836 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, operands[0]));
17838 operands[2] = ix86_split_stack_guard ();
17839 ix86_expand_branch (GEU, reg, operands[2], operands[1]);
17844 ;; Bit manipulation instructions.
17846 (define_expand "ffs<mode>2"
17847 [(set (match_dup 2) (const_int -1))
17848 (parallel [(set (match_dup 3) (match_dup 4))
17849 (set (match_operand:SWI48 0 "register_operand")
17851 (match_operand:SWI48 1 "nonimmediate_operand")))])
17852 (set (match_dup 0) (if_then_else:SWI48
17853 (eq (match_dup 3) (const_int 0))
17856 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
17857 (clobber (reg:CC FLAGS_REG))])]
17860 machine_mode flags_mode;
17862 if (<MODE>mode == SImode && !TARGET_CMOVE)
17864 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
17868 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
17870 operands[2] = gen_reg_rtx (<MODE>mode);
17871 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
17872 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
17875 (define_insn_and_split "ffssi2_no_cmove"
17876 [(set (match_operand:SI 0 "register_operand" "=r")
17877 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
17878 (clobber (match_scratch:SI 2 "=&q"))
17879 (clobber (reg:CC FLAGS_REG))]
17882 "&& reload_completed"
17883 [(parallel [(set (match_dup 4) (match_dup 5))
17884 (set (match_dup 0) (ctz:SI (match_dup 1)))])
17885 (set (strict_low_part (match_dup 3))
17886 (eq:QI (match_dup 4) (const_int 0)))
17887 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
17888 (clobber (reg:CC FLAGS_REG))])
17889 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
17890 (clobber (reg:CC FLAGS_REG))])
17891 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
17892 (clobber (reg:CC FLAGS_REG))])]
17894 machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
17896 operands[3] = gen_lowpart (QImode, operands[2]);
17897 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
17898 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
17900 ix86_expand_clear (operands[2]);
17903 (define_insn_and_split "*tzcnt<mode>_1"
17904 [(set (reg:CCC FLAGS_REG)
17905 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
17907 (set (match_operand:SWI48 0 "register_operand" "=r")
17908 (ctz:SWI48 (match_dup 1)))]
17910 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
17911 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
17912 && optimize_function_for_speed_p (cfun)
17913 && !reg_mentioned_p (operands[0], operands[1])"
17915 [(set (reg:CCC FLAGS_REG)
17916 (compare:CCC (match_dup 1) (const_int 0)))
17918 (ctz:SWI48 (match_dup 1)))
17919 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
17920 "ix86_expand_clear (operands[0]);"
17921 [(set_attr "type" "alu1")
17922 (set_attr "prefix_0f" "1")
17923 (set_attr "prefix_rep" "1")
17924 (set_attr "btver2_decode" "double")
17925 (set_attr "mode" "<MODE>")])
17927 ; False dependency happens when destination is only updated by tzcnt,
17928 ; lzcnt or popcnt. There is no false dependency when destination is
17929 ; also used in source.
17930 (define_insn "*tzcnt<mode>_1_falsedep"
17931 [(set (reg:CCC FLAGS_REG)
17932 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
17934 (set (match_operand:SWI48 0 "register_operand" "=r")
17935 (ctz:SWI48 (match_dup 1)))
17936 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
17937 UNSPEC_INSN_FALSE_DEP)]
17939 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
17940 [(set_attr "type" "alu1")
17941 (set_attr "prefix_0f" "1")
17942 (set_attr "prefix_rep" "1")
17943 (set_attr "btver2_decode" "double")
17944 (set_attr "mode" "<MODE>")])
17946 (define_insn "*bsf<mode>_1"
17947 [(set (reg:CCZ FLAGS_REG)
17948 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
17950 (set (match_operand:SWI48 0 "register_operand" "=r")
17951 (ctz:SWI48 (match_dup 1)))]
17953 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
17954 [(set_attr "type" "alu1")
17955 (set_attr "prefix_0f" "1")
17956 (set_attr "btver2_decode" "double")
17957 (set_attr "znver1_decode" "vector")
17958 (set_attr "mode" "<MODE>")])
17960 (define_insn_and_split "ctz<mode>2"
17961 [(set (match_operand:SWI48 0 "register_operand" "=r")
17963 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
17964 (clobber (reg:CC FLAGS_REG))]
17968 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
17969 else if (optimize_function_for_size_p (cfun))
17971 else if (TARGET_CPU_P (GENERIC))
17972 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
17973 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
17975 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
17977 "(TARGET_BMI || TARGET_CPU_P (GENERIC))
17978 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
17979 && optimize_function_for_speed_p (cfun)
17980 && !reg_mentioned_p (operands[0], operands[1])"
17982 [(set (match_dup 0)
17983 (ctz:SWI48 (match_dup 1)))
17984 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
17985 (clobber (reg:CC FLAGS_REG))])]
17986 "ix86_expand_clear (operands[0]);"
17987 [(set_attr "type" "alu1")
17988 (set_attr "prefix_0f" "1")
17989 (set (attr "prefix_rep")
17991 (ior (match_test "TARGET_BMI")
17992 (and (not (match_test "optimize_function_for_size_p (cfun)"))
17993 (match_test "TARGET_CPU_P (GENERIC)")))
17995 (const_string "0")))
17996 (set_attr "mode" "<MODE>")])
17998 ; False dependency happens when destination is only updated by tzcnt,
17999 ; lzcnt or popcnt. There is no false dependency when destination is
18000 ; also used in source.
18001 (define_insn "*ctz<mode>2_falsedep"
18002 [(set (match_operand:SWI48 0 "register_operand" "=r")
18004 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18005 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18006 UNSPEC_INSN_FALSE_DEP)
18007 (clobber (reg:CC FLAGS_REG))]
18011 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
18012 else if (TARGET_CPU_P (GENERIC))
18013 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
18014 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
18016 gcc_unreachable ();
18018 [(set_attr "type" "alu1")
18019 (set_attr "prefix_0f" "1")
18020 (set_attr "prefix_rep" "1")
18021 (set_attr "mode" "<MODE>")])
18023 (define_insn_and_split "*ctzsi2_zext"
18024 [(set (match_operand:DI 0 "register_operand" "=r")
18028 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
18030 (clobber (reg:CC FLAGS_REG))]
18031 "TARGET_BMI && TARGET_64BIT"
18032 "tzcnt{l}\t{%1, %k0|%k0, %1}"
18033 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18034 && optimize_function_for_speed_p (cfun)
18035 && !reg_mentioned_p (operands[0], operands[1])"
18037 [(set (match_dup 0)
18038 (and:DI (subreg:DI (ctz:SI (match_dup 1)) 0) (const_int 63)))
18039 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18040 (clobber (reg:CC FLAGS_REG))])]
18041 "ix86_expand_clear (operands[0]);"
18042 [(set_attr "type" "alu1")
18043 (set_attr "prefix_0f" "1")
18044 (set_attr "prefix_rep" "1")
18045 (set_attr "mode" "SI")])
18047 ; False dependency happens when destination is only updated by tzcnt,
18048 ; lzcnt or popcnt. There is no false dependency when destination is
18049 ; also used in source.
18050 (define_insn "*ctzsi2_zext_falsedep"
18051 [(set (match_operand:DI 0 "register_operand" "=r")
18055 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
18057 (unspec [(match_operand:DI 2 "register_operand" "0")]
18058 UNSPEC_INSN_FALSE_DEP)
18059 (clobber (reg:CC FLAGS_REG))]
18060 "TARGET_BMI && TARGET_64BIT"
18061 "tzcnt{l}\t{%1, %k0|%k0, %1}"
18062 [(set_attr "type" "alu1")
18063 (set_attr "prefix_0f" "1")
18064 (set_attr "prefix_rep" "1")
18065 (set_attr "mode" "SI")])
18067 (define_insn_and_split "*ctzsidi2_<s>ext"
18068 [(set (match_operand:DI 0 "register_operand" "=r")
18071 (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18072 (clobber (reg:CC FLAGS_REG))]
18076 return "tzcnt{l}\t{%1, %k0|%k0, %1}";
18077 else if (TARGET_CPU_P (GENERIC)
18078 && !optimize_function_for_size_p (cfun))
18079 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
18080 return "rep%; bsf{l}\t{%1, %k0|%k0, %1}";
18081 return "bsf{l}\t{%1, %k0|%k0, %1}";
18083 "(TARGET_BMI || TARGET_CPU_P (GENERIC))
18084 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18085 && optimize_function_for_speed_p (cfun)
18086 && !reg_mentioned_p (operands[0], operands[1])"
18088 [(set (match_dup 0)
18089 (any_extend:DI (ctz:SI (match_dup 1))))
18090 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18091 (clobber (reg:CC FLAGS_REG))])]
18092 "ix86_expand_clear (operands[0]);"
18093 [(set_attr "type" "alu1")
18094 (set_attr "prefix_0f" "1")
18095 (set (attr "prefix_rep")
18097 (ior (match_test "TARGET_BMI")
18098 (and (not (match_test "optimize_function_for_size_p (cfun)"))
18099 (match_test "TARGET_CPU_P (GENERIC)")))
18101 (const_string "0")))
18102 (set_attr "mode" "SI")])
18104 (define_insn "*ctzsidi2_<s>ext_falsedep"
18105 [(set (match_operand:DI 0 "register_operand" "=r")
18108 (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18109 (unspec [(match_operand:DI 2 "register_operand" "0")]
18110 UNSPEC_INSN_FALSE_DEP)
18111 (clobber (reg:CC FLAGS_REG))]
18115 return "tzcnt{l}\t{%1, %k0|%k0, %1}";
18116 else if (TARGET_CPU_P (GENERIC))
18117 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
18118 return "rep%; bsf{l}\t{%1, %k0|%k0, %1}";
18120 gcc_unreachable ();
18122 [(set_attr "type" "alu1")
18123 (set_attr "prefix_0f" "1")
18124 (set_attr "prefix_rep" "1")
18125 (set_attr "mode" "SI")])
18127 (define_insn "bsr_rex64"
18128 [(set (reg:CCZ FLAGS_REG)
18129 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
18131 (set (match_operand:DI 0 "register_operand" "=r")
18132 (minus:DI (const_int 63)
18133 (clz:DI (match_dup 1))))]
18135 "bsr{q}\t{%1, %0|%0, %1}"
18136 [(set_attr "type" "alu1")
18137 (set_attr "prefix_0f" "1")
18138 (set_attr "znver1_decode" "vector")
18139 (set_attr "mode" "DI")])
18141 (define_insn "bsr_rex64_1"
18142 [(set (match_operand:DI 0 "register_operand" "=r")
18143 (minus:DI (const_int 63)
18144 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
18145 (clobber (reg:CC FLAGS_REG))]
18146 "!TARGET_LZCNT && TARGET_64BIT"
18147 "bsr{q}\t{%1, %0|%0, %1}"
18148 [(set_attr "type" "alu1")
18149 (set_attr "prefix_0f" "1")
18150 (set_attr "znver1_decode" "vector")
18151 (set_attr "mode" "DI")])
18153 (define_insn "bsr_rex64_1_zext"
18154 [(set (match_operand:DI 0 "register_operand" "=r")
18156 (minus:SI (const_int 63)
18158 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
18160 (clobber (reg:CC FLAGS_REG))]
18161 "!TARGET_LZCNT && TARGET_64BIT"
18162 "bsr{q}\t{%1, %0|%0, %1}"
18163 [(set_attr "type" "alu1")
18164 (set_attr "prefix_0f" "1")
18165 (set_attr "znver1_decode" "vector")
18166 (set_attr "mode" "DI")])
18169 [(set (reg:CCZ FLAGS_REG)
18170 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
18172 (set (match_operand:SI 0 "register_operand" "=r")
18173 (minus:SI (const_int 31)
18174 (clz:SI (match_dup 1))))]
18176 "bsr{l}\t{%1, %0|%0, %1}"
18177 [(set_attr "type" "alu1")
18178 (set_attr "prefix_0f" "1")
18179 (set_attr "znver1_decode" "vector")
18180 (set_attr "mode" "SI")])
18182 (define_insn "bsr_1"
18183 [(set (match_operand:SI 0 "register_operand" "=r")
18184 (minus:SI (const_int 31)
18185 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18186 (clobber (reg:CC FLAGS_REG))]
18188 "bsr{l}\t{%1, %0|%0, %1}"
18189 [(set_attr "type" "alu1")
18190 (set_attr "prefix_0f" "1")
18191 (set_attr "znver1_decode" "vector")
18192 (set_attr "mode" "SI")])
18194 (define_insn "bsr_zext_1"
18195 [(set (match_operand:DI 0 "register_operand" "=r")
18199 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))))
18200 (clobber (reg:CC FLAGS_REG))]
18201 "!TARGET_LZCNT && TARGET_64BIT"
18202 "bsr{l}\t{%1, %k0|%k0, %1}"
18203 [(set_attr "type" "alu1")
18204 (set_attr "prefix_0f" "1")
18205 (set_attr "znver1_decode" "vector")
18206 (set_attr "mode" "SI")])
18208 ; As bsr is undefined behavior on zero and for other input
18209 ; values it is in range 0 to 63, we can optimize away sign-extends.
18210 (define_insn_and_split "*bsr_rex64_2"
18211 [(set (match_operand:DI 0 "register_operand")
18216 (subreg:SI (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
18219 (clobber (reg:CC FLAGS_REG))]
18220 "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
18223 [(parallel [(set (reg:CCZ FLAGS_REG)
18224 (compare:CCZ (match_dup 1) (const_int 0)))
18226 (minus:DI (const_int 63) (clz:DI (match_dup 1))))])
18227 (parallel [(set (match_dup 0)
18228 (zero_extend:DI (xor:SI (match_dup 3) (const_int 63))))
18229 (clobber (reg:CC FLAGS_REG))])]
18231 operands[2] = gen_reg_rtx (DImode);
18232 operands[3] = lowpart_subreg (SImode, operands[2], DImode);
18235 (define_insn_and_split "*bsr_2"
18236 [(set (match_operand:DI 0 "register_operand")
18241 (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
18243 (clobber (reg:CC FLAGS_REG))]
18244 "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
18247 [(parallel [(set (reg:CCZ FLAGS_REG)
18248 (compare:CCZ (match_dup 1) (const_int 0)))
18250 (minus:SI (const_int 31) (clz:SI (match_dup 1))))])
18251 (parallel [(set (match_dup 0)
18252 (zero_extend:DI (xor:SI (match_dup 2) (const_int 31))))
18253 (clobber (reg:CC FLAGS_REG))])]
18254 "operands[2] = gen_reg_rtx (SImode);")
18256 ; Splitters to optimize 64 - __builtin_clzl (x) or 32 - __builtin_clz (x).
18257 ; Again, as for !TARGET_LZCNT CLZ is UB at zero, CLZ is guaranteed to be
18258 ; in [0, 63] or [0, 31] range.
18260 [(set (match_operand:SI 0 "register_operand")
18262 (match_operand:SI 2 "const_int_operand")
18264 (minus:SI (const_int 63)
18266 (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
18269 "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
18270 [(set (match_dup 3)
18271 (minus:DI (const_int 63) (clz:DI (match_dup 1))))
18273 (plus:SI (match_dup 5) (match_dup 4)))]
18275 operands[3] = gen_reg_rtx (DImode);
18276 operands[5] = lowpart_subreg (SImode, operands[3], DImode);
18277 if (INTVAL (operands[2]) == 63)
18279 emit_insn (gen_bsr_rex64_1_zext (operands[3], operands[1]));
18280 emit_move_insn (operands[0], operands[5]);
18283 operands[4] = gen_int_mode (UINTVAL (operands[2]) - 63, SImode);
18287 [(set (match_operand:SI 0 "register_operand")
18289 (match_operand:SI 2 "const_int_operand")
18291 (minus:SI (const_int 31)
18292 (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
18294 "!TARGET_LZCNT && ix86_pre_reload_split ()"
18295 [(set (match_dup 3)
18296 (minus:SI (const_int 31) (clz:SI (match_dup 1))))
18298 (plus:SI (match_dup 3) (match_dup 4)))]
18300 if (INTVAL (operands[2]) == 31)
18302 emit_insn (gen_bsr_1 (operands[0], operands[1]));
18305 operands[3] = gen_reg_rtx (SImode);
18306 operands[4] = gen_int_mode (UINTVAL (operands[2]) - 31, SImode);
18310 [(set (match_operand:DI 0 "register_operand")
18312 (match_operand:DI 2 "const_int_operand")
18315 (minus:SI (const_int 63)
18317 (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
18322 && ix86_pre_reload_split ()
18323 && ((unsigned HOST_WIDE_INT)
18324 trunc_int_for_mode (UINTVAL (operands[2]) - 63, SImode)
18325 == UINTVAL (operands[2]) - 63)"
18326 [(set (match_dup 3)
18327 (minus:DI (const_int 63) (clz:DI (match_dup 1))))
18329 (plus:DI (match_dup 3) (match_dup 4)))]
18331 if (INTVAL (operands[2]) == 63)
18333 emit_insn (gen_bsr_rex64_1 (operands[0], operands[1]));
18336 operands[3] = gen_reg_rtx (DImode);
18337 operands[4] = GEN_INT (UINTVAL (operands[2]) - 63);
18341 [(set (match_operand:DI 0 "register_operand")
18343 (match_operand:DI 2 "const_int_operand")
18346 (minus:SI (const_int 31)
18347 (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
18348 (const_int 31)))))]
18351 && ix86_pre_reload_split ()
18352 && ((unsigned HOST_WIDE_INT)
18353 trunc_int_for_mode (UINTVAL (operands[2]) - 31, SImode)
18354 == UINTVAL (operands[2]) - 31)"
18355 [(set (match_dup 3)
18356 (zero_extend:DI (minus:SI (const_int 31) (clz:SI (match_dup 1)))))
18358 (plus:DI (match_dup 3) (match_dup 4)))]
18360 if (INTVAL (operands[2]) == 31)
18362 emit_insn (gen_bsr_zext_1 (operands[0], operands[1]));
18365 operands[3] = gen_reg_rtx (DImode);
18366 operands[4] = GEN_INT (UINTVAL (operands[2]) - 31);
18369 (define_expand "clz<mode>2"
18371 [(set (reg:CCZ FLAGS_REG)
18372 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18374 (set (match_dup 3) (minus:SWI48
18376 (clz:SWI48 (match_dup 1))))])
18378 [(set (match_operand:SWI48 0 "register_operand")
18379 (xor:SWI48 (match_dup 3) (match_dup 2)))
18380 (clobber (reg:CC FLAGS_REG))])]
18385 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
18388 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
18389 operands[3] = gen_reg_rtx (<MODE>mode);
18392 (define_insn_and_split "clz<mode>2_lzcnt"
18393 [(set (match_operand:SWI48 0 "register_operand" "=r")
18395 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18396 (clobber (reg:CC FLAGS_REG))]
18398 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
18399 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18400 && optimize_function_for_speed_p (cfun)
18401 && !reg_mentioned_p (operands[0], operands[1])"
18403 [(set (match_dup 0)
18404 (clz:SWI48 (match_dup 1)))
18405 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18406 (clobber (reg:CC FLAGS_REG))])]
18407 "ix86_expand_clear (operands[0]);"
18408 [(set_attr "prefix_rep" "1")
18409 (set_attr "type" "bitmanip")
18410 (set_attr "mode" "<MODE>")])
18412 ; False dependency happens when destination is only updated by tzcnt,
18413 ; lzcnt or popcnt. There is no false dependency when destination is
18414 ; also used in source.
18415 (define_insn "*clz<mode>2_lzcnt_falsedep"
18416 [(set (match_operand:SWI48 0 "register_operand" "=r")
18418 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18419 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18420 UNSPEC_INSN_FALSE_DEP)
18421 (clobber (reg:CC FLAGS_REG))]
18423 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
18424 [(set_attr "prefix_rep" "1")
18425 (set_attr "type" "bitmanip")
18426 (set_attr "mode" "<MODE>")])
18428 (define_insn_and_split "*clzsi2_lzcnt_zext"
18429 [(set (match_operand:DI 0 "register_operand" "=r")
18433 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
18435 (clobber (reg:CC FLAGS_REG))]
18436 "TARGET_LZCNT && TARGET_64BIT"
18437 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18438 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18439 && optimize_function_for_speed_p (cfun)
18440 && !reg_mentioned_p (operands[0], operands[1])"
18442 [(set (match_dup 0)
18443 (and:DI (subreg:DI (clz:SI (match_dup 1)) 0) (const_int 63)))
18444 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18445 (clobber (reg:CC FLAGS_REG))])]
18446 "ix86_expand_clear (operands[0]);"
18447 [(set_attr "prefix_rep" "1")
18448 (set_attr "type" "bitmanip")
18449 (set_attr "mode" "SI")])
18451 ; False dependency happens when destination is only updated by tzcnt,
18452 ; lzcnt or popcnt. There is no false dependency when destination is
18453 ; also used in source.
18454 (define_insn "*clzsi2_lzcnt_zext_falsedep"
18455 [(set (match_operand:DI 0 "register_operand" "=r")
18459 (match_operand:SWI48 1 "nonimmediate_operand" "rm")) 0)
18461 (unspec [(match_operand:DI 2 "register_operand" "0")]
18462 UNSPEC_INSN_FALSE_DEP)
18463 (clobber (reg:CC FLAGS_REG))]
18465 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18466 [(set_attr "prefix_rep" "1")
18467 (set_attr "type" "bitmanip")
18468 (set_attr "mode" "SI")])
18470 (define_insn_and_split "*clzsi2_lzcnt_zext_2"
18471 [(set (match_operand:DI 0 "register_operand" "=r")
18473 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18474 (clobber (reg:CC FLAGS_REG))]
18475 "TARGET_LZCNT && TARGET_64BIT"
18476 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18477 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18478 && optimize_function_for_speed_p (cfun)
18479 && !reg_mentioned_p (operands[0], operands[1])"
18481 [(set (match_dup 0)
18482 (zero_extend:DI (clz:SI (match_dup 1))))
18483 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18484 (clobber (reg:CC FLAGS_REG))])]
18485 "ix86_expand_clear (operands[0]);"
18486 [(set_attr "prefix_rep" "1")
18487 (set_attr "type" "bitmanip")
18488 (set_attr "mode" "SI")])
18490 ; False dependency happens when destination is only updated by tzcnt,
18491 ; lzcnt or popcnt. There is no false dependency when destination is
18492 ; also used in source.
18493 (define_insn "*clzsi2_lzcnt_zext_2_falsedep"
18494 [(set (match_operand:DI 0 "register_operand" "=r")
18496 (clz:SI (match_operand:SWI48 1 "nonimmediate_operand" "rm"))))
18497 (unspec [(match_operand:DI 2 "register_operand" "0")]
18498 UNSPEC_INSN_FALSE_DEP)
18499 (clobber (reg:CC FLAGS_REG))]
18501 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18502 [(set_attr "prefix_rep" "1")
18503 (set_attr "type" "bitmanip")
18504 (set_attr "mode" "SI")])
18506 (define_int_iterator LT_ZCNT
18507 [(UNSPEC_TZCNT "TARGET_BMI")
18508 (UNSPEC_LZCNT "TARGET_LZCNT")])
18510 (define_int_attr lt_zcnt
18511 [(UNSPEC_TZCNT "tzcnt")
18512 (UNSPEC_LZCNT "lzcnt")])
18514 (define_int_attr lt_zcnt_type
18515 [(UNSPEC_TZCNT "alu1")
18516 (UNSPEC_LZCNT "bitmanip")])
18518 ;; Version of lzcnt/tzcnt that is expanded from intrinsics. This version
18519 ;; provides operand size as output when source operand is zero.
18521 (define_insn_and_split "<lt_zcnt>_<mode>"
18522 [(set (match_operand:SWI48 0 "register_operand" "=r")
18524 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
18525 (clobber (reg:CC FLAGS_REG))]
18527 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
18528 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18529 && optimize_function_for_speed_p (cfun)
18530 && !reg_mentioned_p (operands[0], operands[1])"
18532 [(set (match_dup 0)
18533 (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
18534 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18535 (clobber (reg:CC FLAGS_REG))])]
18536 "ix86_expand_clear (operands[0]);"
18537 [(set_attr "type" "<lt_zcnt_type>")
18538 (set_attr "prefix_0f" "1")
18539 (set_attr "prefix_rep" "1")
18540 (set_attr "mode" "<MODE>")])
18542 ; False dependency happens when destination is only updated by tzcnt,
18543 ; lzcnt or popcnt. There is no false dependency when destination is
18544 ; also used in source.
18545 (define_insn "*<lt_zcnt>_<mode>_falsedep"
18546 [(set (match_operand:SWI48 0 "register_operand" "=r")
18548 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
18549 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18550 UNSPEC_INSN_FALSE_DEP)
18551 (clobber (reg:CC FLAGS_REG))]
18553 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
18554 [(set_attr "type" "<lt_zcnt_type>")
18555 (set_attr "prefix_0f" "1")
18556 (set_attr "prefix_rep" "1")
18557 (set_attr "mode" "<MODE>")])
18559 (define_insn "<lt_zcnt>_hi"
18560 [(set (match_operand:HI 0 "register_operand" "=r")
18562 [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT))
18563 (clobber (reg:CC FLAGS_REG))]
18565 "<lt_zcnt>{w}\t{%1, %0|%0, %1}"
18566 [(set_attr "type" "<lt_zcnt_type>")
18567 (set_attr "prefix_0f" "1")
18568 (set_attr "prefix_rep" "1")
18569 (set_attr "mode" "HI")])
18571 ;; BMI instructions.
18573 (define_insn "bmi_bextr_<mode>"
18574 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
18575 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
18576 (match_operand:SWI48 2 "register_operand" "r,r")]
18578 (clobber (reg:CC FLAGS_REG))]
18580 "bextr\t{%2, %1, %0|%0, %1, %2}"
18581 [(set_attr "type" "bitmanip")
18582 (set_attr "btver2_decode" "direct, double")
18583 (set_attr "mode" "<MODE>")])
18585 (define_insn "*bmi_bextr_<mode>_ccz"
18586 [(set (reg:CCZ FLAGS_REG)
18588 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
18589 (match_operand:SWI48 2 "register_operand" "r,r")]
18592 (clobber (match_scratch:SWI48 0 "=r,r"))]
18594 "bextr\t{%2, %1, %0|%0, %1, %2}"
18595 [(set_attr "type" "bitmanip")
18596 (set_attr "btver2_decode" "direct, double")
18597 (set_attr "mode" "<MODE>")])
18599 (define_insn "*bmi_blsi_<mode>"
18600 [(set (match_operand:SWI48 0 "register_operand" "=r")
18603 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
18605 (clobber (reg:CC FLAGS_REG))]
18607 "blsi\t{%1, %0|%0, %1}"
18608 [(set_attr "type" "bitmanip")
18609 (set_attr "btver2_decode" "double")
18610 (set_attr "mode" "<MODE>")])
18612 (define_insn "*bmi_blsi_<mode>_cmp"
18613 [(set (reg FLAGS_REG)
18616 (neg:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
18619 (set (match_operand:SWI48 0 "register_operand" "=r")
18620 (and:SWI48 (neg:SWI48 (match_dup 1)) (match_dup 1)))]
18621 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
18622 "blsi\t{%1, %0|%0, %1}"
18623 [(set_attr "type" "bitmanip")
18624 (set_attr "btver2_decode" "double")
18625 (set_attr "mode" "<MODE>")])
18627 (define_insn "*bmi_blsi_<mode>_ccno"
18628 [(set (reg FLAGS_REG)
18631 (neg:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
18634 (clobber (match_scratch:SWI48 0 "=r"))]
18635 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
18636 "blsi\t{%1, %0|%0, %1}"
18637 [(set_attr "type" "bitmanip")
18638 (set_attr "btver2_decode" "double")
18639 (set_attr "mode" "<MODE>")])
18641 (define_insn "*bmi_blsmsk_<mode>"
18642 [(set (match_operand:SWI48 0 "register_operand" "=r")
18645 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18648 (clobber (reg:CC FLAGS_REG))]
18650 "blsmsk\t{%1, %0|%0, %1}"
18651 [(set_attr "type" "bitmanip")
18652 (set_attr "btver2_decode" "double")
18653 (set_attr "mode" "<MODE>")])
18655 (define_insn "*bmi_blsr_<mode>"
18656 [(set (match_operand:SWI48 0 "register_operand" "=r")
18659 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18662 (clobber (reg:CC FLAGS_REG))]
18664 "blsr\t{%1, %0|%0, %1}"
18665 [(set_attr "type" "bitmanip")
18666 (set_attr "btver2_decode" "double")
18667 (set_attr "mode" "<MODE>")])
18669 (define_insn "*bmi_blsr_<mode>_cmp"
18670 [(set (reg:CCZ FLAGS_REG)
18674 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18678 (set (match_operand:SWI48 0 "register_operand" "=r")
18685 "blsr\t{%1, %0|%0, %1}"
18686 [(set_attr "type" "bitmanip")
18687 (set_attr "btver2_decode" "double")
18688 (set_attr "mode" "<MODE>")])
18690 (define_insn "*bmi_blsr_<mode>_ccz"
18691 [(set (reg:CCZ FLAGS_REG)
18695 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18699 (clobber (match_scratch:SWI48 0 "=r"))]
18701 "blsr\t{%1, %0|%0, %1}"
18702 [(set_attr "type" "bitmanip")
18703 (set_attr "btver2_decode" "double")
18704 (set_attr "mode" "<MODE>")])
18706 ;; BMI2 instructions.
18707 (define_expand "bmi2_bzhi_<mode>3"
18709 [(set (match_operand:SWI48 0 "register_operand")
18710 (if_then_else:SWI48
18711 (ne:QI (and:SWI48 (match_operand:SWI48 2 "register_operand")
18714 (zero_extract:SWI48
18715 (match_operand:SWI48 1 "nonimmediate_operand")
18716 (umin:SWI48 (and:SWI48 (match_dup 2) (const_int 255))
18720 (clobber (reg:CC FLAGS_REG))])]
18722 "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
18724 (define_insn "*bmi2_bzhi_<mode>3"
18725 [(set (match_operand:SWI48 0 "register_operand" "=r")
18726 (if_then_else:SWI48
18727 (ne:QI (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
18730 (zero_extract:SWI48
18731 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18732 (umin:SWI48 (and:SWI48 (match_dup 2) (const_int 255))
18733 (match_operand:SWI48 3 "const_int_operand"))
18736 (clobber (reg:CC FLAGS_REG))]
18737 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
18738 "bzhi\t{%2, %1, %0|%0, %1, %2}"
18739 [(set_attr "type" "bitmanip")
18740 (set_attr "prefix" "vex")
18741 (set_attr "mode" "<MODE>")])
18743 (define_insn "*bmi2_bzhi_<mode>3_1"
18744 [(set (match_operand:SWI48 0 "register_operand" "=r")
18745 (if_then_else:SWI48
18746 (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0))
18747 (zero_extract:SWI48
18748 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18749 (umin:SWI48 (zero_extend:SWI48 (match_dup 2))
18750 (match_operand:SWI48 3 "const_int_operand"))
18753 (clobber (reg:CC FLAGS_REG))]
18754 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
18755 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
18756 [(set_attr "type" "bitmanip")
18757 (set_attr "prefix" "vex")
18758 (set_attr "mode" "<MODE>")])
18760 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
18761 [(set (reg:CCZ FLAGS_REG)
18763 (if_then_else:SWI48
18764 (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0))
18765 (zero_extract:SWI48
18766 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18767 (umin:SWI48 (zero_extend:SWI48 (match_dup 2))
18768 (match_operand:SWI48 3 "const_int_operand"))
18772 (clobber (match_scratch:SWI48 0 "=r"))]
18773 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
18774 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
18775 [(set_attr "type" "bitmanip")
18776 (set_attr "prefix" "vex")
18777 (set_attr "mode" "<MODE>")])
18779 (define_insn "*bmi2_bzhi_<mode>3_2"
18780 [(set (match_operand:SWI48 0 "register_operand" "=r")
18783 (ashift:SWI48 (const_int 1)
18784 (match_operand:QI 2 "register_operand" "r"))
18786 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18787 (clobber (reg:CC FLAGS_REG))]
18789 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
18790 [(set_attr "type" "bitmanip")
18791 (set_attr "prefix" "vex")
18792 (set_attr "mode" "<MODE>")])
18794 (define_insn "*bmi2_bzhi_<mode>3_3"
18795 [(set (match_operand:SWI48 0 "register_operand" "=r")
18798 (ashift:SWI48 (const_int -1)
18799 (match_operand:QI 2 "register_operand" "r")))
18800 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18801 (clobber (reg:CC FLAGS_REG))]
18803 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
18804 [(set_attr "type" "bitmanip")
18805 (set_attr "prefix" "vex")
18806 (set_attr "mode" "<MODE>")])
18808 (define_insn "*bmi2_bzhi_zero_extendsidi_4"
18809 [(set (match_operand:DI 0 "register_operand" "=r")
18813 (ashift:SI (const_int 1)
18814 (match_operand:QI 2 "register_operand" "r"))
18816 (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18817 (clobber (reg:CC FLAGS_REG))]
18818 "TARGET_64BIT && TARGET_BMI2"
18819 "bzhi\t{%q2, %q1, %q0|%q0, %q1, %q2}"
18820 [(set_attr "type" "bitmanip")
18821 (set_attr "prefix" "vex")
18822 (set_attr "mode" "DI")])
18824 (define_insn "*bmi2_bzhi_zero_extendsidi_5"
18825 [(set (match_operand:DI 0 "register_operand" "=r")
18829 (ashift:SI (const_int 1)
18830 (match_operand:QI 2 "register_operand" "r"))
18832 (match_operand:DI 1 "nonimmediate_operand" "rm")))
18833 (clobber (reg:CC FLAGS_REG))]
18834 "TARGET_64BIT && TARGET_BMI2"
18835 "bzhi\t{%q2, %q1, %q0|%q0, %q1, %q2}"
18836 [(set_attr "type" "bitmanip")
18837 (set_attr "prefix" "vex")
18838 (set_attr "mode" "DI")])
18840 (define_insn "bmi2_pdep_<mode>3"
18841 [(set (match_operand:SWI48 0 "register_operand" "=r")
18842 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
18843 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
18846 "pdep\t{%2, %1, %0|%0, %1, %2}"
18847 [(set_attr "type" "bitmanip")
18848 (set_attr "prefix" "vex")
18849 (set_attr "mode" "<MODE>")])
18851 (define_insn "bmi2_pext_<mode>3"
18852 [(set (match_operand:SWI48 0 "register_operand" "=r")
18853 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
18854 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
18857 "pext\t{%2, %1, %0|%0, %1, %2}"
18858 [(set_attr "type" "bitmanip")
18859 (set_attr "prefix" "vex")
18860 (set_attr "mode" "<MODE>")])
18862 ;; TBM instructions.
18863 (define_insn "@tbm_bextri_<mode>"
18864 [(set (match_operand:SWI48 0 "register_operand" "=r")
18865 (zero_extract:SWI48
18866 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18867 (match_operand 2 "const_0_to_255_operand")
18868 (match_operand 3 "const_0_to_255_operand")))
18869 (clobber (reg:CC FLAGS_REG))]
18872 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
18873 return "bextr\t{%2, %1, %0|%0, %1, %2}";
18875 [(set_attr "type" "bitmanip")
18876 (set_attr "mode" "<MODE>")])
18878 (define_insn "*tbm_blcfill_<mode>"
18879 [(set (match_operand:SWI48 0 "register_operand" "=r")
18882 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18885 (clobber (reg:CC FLAGS_REG))]
18887 "blcfill\t{%1, %0|%0, %1}"
18888 [(set_attr "type" "bitmanip")
18889 (set_attr "mode" "<MODE>")])
18891 (define_insn "*tbm_blci_<mode>"
18892 [(set (match_operand:SWI48 0 "register_operand" "=r")
18896 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18899 (clobber (reg:CC FLAGS_REG))]
18901 "blci\t{%1, %0|%0, %1}"
18902 [(set_attr "type" "bitmanip")
18903 (set_attr "mode" "<MODE>")])
18905 (define_insn "*tbm_blcic_<mode>"
18906 [(set (match_operand:SWI48 0 "register_operand" "=r")
18909 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18913 (clobber (reg:CC FLAGS_REG))]
18915 "blcic\t{%1, %0|%0, %1}"
18916 [(set_attr "type" "bitmanip")
18917 (set_attr "mode" "<MODE>")])
18919 (define_insn "*tbm_blcmsk_<mode>"
18920 [(set (match_operand:SWI48 0 "register_operand" "=r")
18923 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18926 (clobber (reg:CC FLAGS_REG))]
18928 "blcmsk\t{%1, %0|%0, %1}"
18929 [(set_attr "type" "bitmanip")
18930 (set_attr "mode" "<MODE>")])
18932 (define_insn "*tbm_blcs_<mode>"
18933 [(set (match_operand:SWI48 0 "register_operand" "=r")
18936 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18939 (clobber (reg:CC FLAGS_REG))]
18941 "blcs\t{%1, %0|%0, %1}"
18942 [(set_attr "type" "bitmanip")
18943 (set_attr "mode" "<MODE>")])
18945 (define_insn "*tbm_blsfill_<mode>"
18946 [(set (match_operand:SWI48 0 "register_operand" "=r")
18949 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18952 (clobber (reg:CC FLAGS_REG))]
18954 "blsfill\t{%1, %0|%0, %1}"
18955 [(set_attr "type" "bitmanip")
18956 (set_attr "mode" "<MODE>")])
18958 (define_insn "*tbm_blsic_<mode>"
18959 [(set (match_operand:SWI48 0 "register_operand" "=r")
18962 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18966 (clobber (reg:CC FLAGS_REG))]
18968 "blsic\t{%1, %0|%0, %1}"
18969 [(set_attr "type" "bitmanip")
18970 (set_attr "mode" "<MODE>")])
18972 (define_insn "*tbm_t1mskc_<mode>"
18973 [(set (match_operand:SWI48 0 "register_operand" "=r")
18976 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18980 (clobber (reg:CC FLAGS_REG))]
18982 "t1mskc\t{%1, %0|%0, %1}"
18983 [(set_attr "type" "bitmanip")
18984 (set_attr "mode" "<MODE>")])
18986 (define_insn "*tbm_tzmsk_<mode>"
18987 [(set (match_operand:SWI48 0 "register_operand" "=r")
18990 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18994 (clobber (reg:CC FLAGS_REG))]
18996 "tzmsk\t{%1, %0|%0, %1}"
18997 [(set_attr "type" "bitmanip")
18998 (set_attr "mode" "<MODE>")])
19000 (define_insn_and_split "popcount<mode>2"
19001 [(set (match_operand:SWI48 0 "register_operand" "=r")
19003 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
19004 (clobber (reg:CC FLAGS_REG))]
19008 return "popcnt\t{%1, %0|%0, %1}";
19010 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
19013 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
19014 && optimize_function_for_speed_p (cfun)
19015 && !reg_mentioned_p (operands[0], operands[1])"
19017 [(set (match_dup 0)
19018 (popcount:SWI48 (match_dup 1)))
19019 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
19020 (clobber (reg:CC FLAGS_REG))])]
19021 "ix86_expand_clear (operands[0]);"
19022 [(set_attr "prefix_rep" "1")
19023 (set_attr "type" "bitmanip")
19024 (set_attr "mode" "<MODE>")])
19026 ; False dependency happens when destination is only updated by tzcnt,
19027 ; lzcnt or popcnt. There is no false dependency when destination is
19028 ; also used in source.
19029 (define_insn "*popcount<mode>2_falsedep"
19030 [(set (match_operand:SWI48 0 "register_operand" "=r")
19032 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
19033 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
19034 UNSPEC_INSN_FALSE_DEP)
19035 (clobber (reg:CC FLAGS_REG))]
19039 return "popcnt\t{%1, %0|%0, %1}";
19041 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
19044 [(set_attr "prefix_rep" "1")
19045 (set_attr "type" "bitmanip")
19046 (set_attr "mode" "<MODE>")])
19048 (define_insn_and_split "*popcountsi2_zext"
19049 [(set (match_operand:DI 0 "register_operand" "=r")
19053 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
19055 (clobber (reg:CC FLAGS_REG))]
19056 "TARGET_POPCNT && TARGET_64BIT"
19059 return "popcnt\t{%1, %k0|%k0, %1}";
19061 return "popcnt{l}\t{%1, %k0|%k0, %1}";
19064 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
19065 && optimize_function_for_speed_p (cfun)
19066 && !reg_mentioned_p (operands[0], operands[1])"
19068 [(set (match_dup 0)
19069 (and:DI (subreg:DI (popcount:SI (match_dup 1)) 0) (const_int 63)))
19070 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
19071 (clobber (reg:CC FLAGS_REG))])]
19072 "ix86_expand_clear (operands[0]);"
19073 [(set_attr "prefix_rep" "1")
19074 (set_attr "type" "bitmanip")
19075 (set_attr "mode" "SI")])
19077 ; False dependency happens when destination is only updated by tzcnt,
19078 ; lzcnt or popcnt. There is no false dependency when destination is
19079 ; also used in source.
19080 (define_insn "*popcountsi2_zext_falsedep"
19081 [(set (match_operand:DI 0 "register_operand" "=r")
19085 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
19087 (unspec [(match_operand:DI 2 "register_operand" "0")]
19088 UNSPEC_INSN_FALSE_DEP)
19089 (clobber (reg:CC FLAGS_REG))]
19090 "TARGET_POPCNT && TARGET_64BIT"
19093 return "popcnt\t{%1, %k0|%k0, %1}";
19095 return "popcnt{l}\t{%1, %k0|%k0, %1}";
19098 [(set_attr "prefix_rep" "1")
19099 (set_attr "type" "bitmanip")
19100 (set_attr "mode" "SI")])
19102 (define_insn_and_split "*popcountsi2_zext_2"
19103 [(set (match_operand:DI 0 "register_operand" "=r")
19105 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
19106 (clobber (reg:CC FLAGS_REG))]
19107 "TARGET_POPCNT && TARGET_64BIT"
19110 return "popcnt\t{%1, %k0|%k0, %1}";
19112 return "popcnt{l}\t{%1, %k0|%k0, %1}";
19115 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
19116 && optimize_function_for_speed_p (cfun)
19117 && !reg_mentioned_p (operands[0], operands[1])"
19119 [(set (match_dup 0)
19120 (zero_extend:DI (popcount:SI (match_dup 1))))
19121 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
19122 (clobber (reg:CC FLAGS_REG))])]
19123 "ix86_expand_clear (operands[0]);"
19124 [(set_attr "prefix_rep" "1")
19125 (set_attr "type" "bitmanip")
19126 (set_attr "mode" "SI")])
19128 ; False dependency happens when destination is only updated by tzcnt,
19129 ; lzcnt or popcnt. There is no false dependency when destination is
19130 ; also used in source.
19131 (define_insn "*popcountsi2_zext_2_falsedep"
19132 [(set (match_operand:DI 0 "register_operand" "=r")
19134 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
19135 (unspec [(match_operand:DI 2 "register_operand" "0")]
19136 UNSPEC_INSN_FALSE_DEP)
19137 (clobber (reg:CC FLAGS_REG))]
19138 "TARGET_POPCNT && TARGET_64BIT"
19141 return "popcnt\t{%1, %k0|%k0, %1}";
19143 return "popcnt{l}\t{%1, %k0|%k0, %1}";
19146 [(set_attr "prefix_rep" "1")
19147 (set_attr "type" "bitmanip")
19148 (set_attr "mode" "SI")])
19150 (define_insn_and_split "*popcounthi2_1"
19151 [(set (match_operand:SI 0 "register_operand")
19153 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
19154 (clobber (reg:CC FLAGS_REG))]
19156 && ix86_pre_reload_split ()"
19161 rtx tmp = gen_reg_rtx (HImode);
19163 emit_insn (gen_popcounthi2 (tmp, operands[1]));
19164 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
19168 (define_insn_and_split "*popcounthi2_2"
19169 [(set (match_operand:SI 0 "register_operand")
19171 (popcount:HI (match_operand:HI 1 "nonimmediate_operand"))))
19172 (clobber (reg:CC FLAGS_REG))]
19174 && ix86_pre_reload_split ()"
19179 rtx tmp = gen_reg_rtx (HImode);
19181 emit_insn (gen_popcounthi2 (tmp, operands[1]));
19182 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
19186 (define_insn "popcounthi2"
19187 [(set (match_operand:HI 0 "register_operand" "=r")
19189 (match_operand:HI 1 "nonimmediate_operand" "rm")))
19190 (clobber (reg:CC FLAGS_REG))]
19194 return "popcnt\t{%1, %0|%0, %1}";
19196 return "popcnt{w}\t{%1, %0|%0, %1}";
19199 [(set_attr "prefix_rep" "1")
19200 (set_attr "type" "bitmanip")
19201 (set_attr "mode" "HI")])
19203 (define_expand "bswapdi2"
19204 [(set (match_operand:DI 0 "register_operand")
19205 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
19209 operands[1] = force_reg (DImode, operands[1]);
19212 (define_expand "bswapsi2"
19213 [(set (match_operand:SI 0 "register_operand")
19214 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
19219 else if (TARGET_BSWAP)
19220 operands[1] = force_reg (SImode, operands[1]);
19223 rtx x = operands[0];
19225 emit_move_insn (x, operands[1]);
19226 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
19227 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
19228 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
19233 (define_insn "*bswap<mode>2_movbe"
19234 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
19235 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
19237 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
19240 movbe{<imodesuffix>}\t{%1, %0|%0, %1}
19241 movbe{<imodesuffix>}\t{%1, %0|%0, %1}"
19242 [(set_attr "type" "bitmanip,imov,imov")
19243 (set_attr "modrm" "0,1,1")
19244 (set_attr "prefix_0f" "*,1,1")
19245 (set_attr "prefix_extra" "*,1,1")
19246 (set_attr "mode" "<MODE>")])
19248 (define_insn "*bswap<mode>2"
19249 [(set (match_operand:SWI48 0 "register_operand" "=r")
19250 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
19253 [(set_attr "type" "bitmanip")
19254 (set_attr "modrm" "0")
19255 (set_attr "mode" "<MODE>")])
19257 (define_expand "bswaphi2"
19258 [(set (match_operand:HI 0 "register_operand")
19259 (bswap:HI (match_operand:HI 1 "nonimmediate_operand")))]
19262 (define_insn "*bswaphi2_movbe"
19263 [(set (match_operand:HI 0 "nonimmediate_operand" "=Q,r,m")
19264 (bswap:HI (match_operand:HI 1 "nonimmediate_operand" "0,m,r")))]
19266 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
19268 xchg{b}\t{%h0, %b0|%b0, %h0}
19269 movbe{w}\t{%1, %0|%0, %1}
19270 movbe{w}\t{%1, %0|%0, %1}"
19271 [(set_attr "type" "imov")
19272 (set_attr "modrm" "*,1,1")
19273 (set_attr "prefix_0f" "*,1,1")
19274 (set_attr "prefix_extra" "*,1,1")
19275 (set_attr "pent_pair" "np,*,*")
19276 (set_attr "athlon_decode" "vector,*,*")
19277 (set_attr "amdfam10_decode" "double,*,*")
19278 (set_attr "bdver1_decode" "double,*,*")
19279 (set_attr "mode" "QI,HI,HI")])
19282 [(set (match_operand:HI 0 "general_reg_operand")
19283 (bswap:HI (match_dup 0)))]
19285 && !(TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))
19286 && peep2_regno_dead_p (0, FLAGS_REG)"
19287 [(parallel [(set (match_dup 0) (rotate:HI (match_dup 0) (const_int 8)))
19288 (clobber (reg:CC FLAGS_REG))])])
19290 (define_insn "bswaphi_lowpart"
19291 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
19292 (bswap:HI (match_dup 0)))
19293 (clobber (reg:CC FLAGS_REG))]
19296 xchg{b}\t{%h0, %b0|%b0, %h0}
19297 rol{w}\t{$8, %0|%0, 8}"
19298 [(set (attr "preferred_for_size")
19299 (cond [(eq_attr "alternative" "0")
19300 (symbol_ref "true")]
19301 (symbol_ref "false")))
19302 (set (attr "preferred_for_speed")
19303 (cond [(eq_attr "alternative" "0")
19304 (symbol_ref "TARGET_USE_XCHGB")]
19305 (symbol_ref "!TARGET_USE_XCHGB")))
19306 (set_attr "length" "2,4")
19307 (set_attr "mode" "QI,HI")])
19309 (define_expand "paritydi2"
19310 [(set (match_operand:DI 0 "register_operand")
19311 (parity:DI (match_operand:DI 1 "register_operand")))]
19314 rtx scratch = gen_reg_rtx (QImode);
19315 rtx hipart1 = gen_reg_rtx (SImode);
19316 rtx lopart1 = gen_reg_rtx (SImode);
19317 rtx xor1 = gen_reg_rtx (SImode);
19318 rtx shift2 = gen_reg_rtx (SImode);
19319 rtx hipart2 = gen_reg_rtx (HImode);
19320 rtx lopart2 = gen_reg_rtx (HImode);
19321 rtx xor2 = gen_reg_rtx (HImode);
19325 rtx shift1 = gen_reg_rtx (DImode);
19326 emit_insn (gen_lshrdi3 (shift1, operands[1], GEN_INT (32)));
19327 emit_move_insn (hipart1, gen_lowpart (SImode, shift1));
19330 emit_move_insn (hipart1, gen_highpart (SImode, operands[1]));
19332 emit_move_insn (lopart1, gen_lowpart (SImode, operands[1]));
19333 emit_insn (gen_xorsi3 (xor1, hipart1, lopart1));
19335 emit_insn (gen_lshrsi3 (shift2, xor1, GEN_INT (16)));
19336 emit_move_insn (hipart2, gen_lowpart (HImode, shift2));
19337 emit_move_insn (lopart2, gen_lowpart (HImode, xor1));
19338 emit_insn (gen_xorhi3 (xor2, hipart2, lopart2));
19340 emit_insn (gen_parityhi2_cmp (xor2));
19342 ix86_expand_setcc (scratch, ORDERED,
19343 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19346 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
19349 rtx tmp = gen_reg_rtx (SImode);
19351 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
19352 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
19357 (define_expand "paritysi2"
19358 [(set (match_operand:SI 0 "register_operand")
19359 (parity:SI (match_operand:SI 1 "register_operand")))]
19362 rtx scratch = gen_reg_rtx (QImode);
19363 rtx shift = gen_reg_rtx (SImode);
19364 rtx hipart = gen_reg_rtx (HImode);
19365 rtx lopart = gen_reg_rtx (HImode);
19366 rtx tmp = gen_reg_rtx (HImode);
19368 emit_insn (gen_lshrsi3 (shift, operands[1], GEN_INT (16)));
19369 emit_move_insn (hipart, gen_lowpart (HImode, shift));
19370 emit_move_insn (lopart, gen_lowpart (HImode, operands[1]));
19371 emit_insn (gen_xorhi3 (tmp, hipart, lopart));
19373 emit_insn (gen_parityhi2_cmp (tmp));
19375 ix86_expand_setcc (scratch, ORDERED,
19376 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19378 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
19382 (define_expand "parityhi2"
19383 [(set (match_operand:HI 0 "register_operand")
19384 (parity:HI (match_operand:HI 1 "register_operand")))]
19387 rtx scratch = gen_reg_rtx (QImode);
19389 emit_insn (gen_parityhi2_cmp (operands[1]));
19391 ix86_expand_setcc (scratch, ORDERED,
19392 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19394 emit_insn (gen_zero_extendqihi2 (operands[0], scratch));
19398 (define_expand "parityqi2"
19399 [(set (match_operand:QI 0 "register_operand")
19400 (parity:QI (match_operand:QI 1 "register_operand")))]
19403 emit_insn (gen_parityqi2_cmp (operands[1]));
19405 ix86_expand_setcc (operands[0], ORDERED,
19406 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19410 (define_insn "parityhi2_cmp"
19411 [(set (reg:CC FLAGS_REG)
19412 (unspec:CC [(match_operand:HI 0 "register_operand" "+Q")]
19414 (clobber (match_dup 0))]
19416 "xor{b}\t{%h0, %b0|%b0, %h0}"
19417 [(set_attr "length" "2")
19418 (set_attr "mode" "QI")])
19420 (define_insn "parityqi2_cmp"
19421 [(set (reg:CC FLAGS_REG)
19422 (unspec:CC [(match_operand:QI 0 "register_operand" "q")]
19426 [(set_attr "mode" "QI")])
19428 ;; Replace zero_extend:HI followed by parityhi2_cmp with parityqi2_cmp
19430 [(set (match_operand:HI 0 "register_operand")
19431 (zero_extend:HI (match_operand:QI 1 "general_reg_operand")))
19432 (parallel [(set (reg:CC FLAGS_REG)
19433 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
19434 (clobber (match_dup 0))])]
19436 [(set (reg:CC FLAGS_REG)
19437 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))])
19439 ;; Eliminate QImode popcount&1 using parity flag
19441 [(set (match_operand:SI 0 "register_operand")
19442 (zero_extend:SI (match_operand:QI 1 "general_reg_operand")))
19443 (parallel [(set (match_operand:SI 2 "register_operand")
19444 (popcount:SI (match_dup 0)))
19445 (clobber (reg:CC FLAGS_REG))])
19446 (set (reg:CCZ FLAGS_REG)
19447 (compare:CCZ (and:QI (match_operand:QI 3 "register_operand")
19450 (set (pc) (if_then_else (match_operator 4 "bt_comparison_operator"
19451 [(reg:CCZ FLAGS_REG)
19453 (label_ref (match_operand 5))
19455 "REGNO (operands[2]) == REGNO (operands[3])
19456 && peep2_reg_dead_p (3, operands[0])
19457 && peep2_reg_dead_p (3, operands[2])
19458 && peep2_regno_dead_p (4, FLAGS_REG)"
19459 [(set (reg:CC FLAGS_REG)
19460 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
19461 (set (pc) (if_then_else (match_op_dup 4 [(reg:CC FLAGS_REG)
19463 (label_ref (match_dup 5))
19466 operands[4] = shallow_copy_rtx (operands[4]);
19467 PUT_CODE (operands[4], GET_CODE (operands[4]) == EQ ? UNORDERED : ORDERED);
19470 ;; Eliminate HImode popcount&1 using parity flag
19472 [(match_scratch:HI 0 "Q")
19473 (parallel [(set (match_operand:HI 1 "register_operand")
19475 (match_operand:HI 2 "nonimmediate_operand")))
19476 (clobber (reg:CC FLAGS_REG))])
19477 (set (match_operand 3 "register_operand")
19478 (zero_extend (match_dup 1)))
19479 (set (reg:CCZ FLAGS_REG)
19480 (compare:CCZ (and:QI (match_operand:QI 4 "register_operand")
19483 (set (pc) (if_then_else (match_operator 5 "bt_comparison_operator"
19484 [(reg:CCZ FLAGS_REG)
19486 (label_ref (match_operand 6))
19488 "REGNO (operands[3]) == REGNO (operands[4])
19489 && peep2_reg_dead_p (3, operands[1])
19490 && peep2_reg_dead_p (3, operands[3])
19491 && peep2_regno_dead_p (4, FLAGS_REG)"
19492 [(set (match_dup 0) (match_dup 2))
19493 (parallel [(set (reg:CC FLAGS_REG)
19494 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
19495 (clobber (match_dup 0))])
19496 (set (pc) (if_then_else (match_op_dup 5 [(reg:CC FLAGS_REG)
19498 (label_ref (match_dup 6))
19501 operands[5] = shallow_copy_rtx (operands[5]);
19502 PUT_CODE (operands[5], GET_CODE (operands[5]) == EQ ? UNORDERED : ORDERED);
19505 ;; Eliminate HImode popcount&1 using parity flag (variant 2)
19507 [(match_scratch:HI 0 "Q")
19508 (parallel [(set (match_operand:HI 1 "register_operand")
19510 (match_operand:HI 2 "nonimmediate_operand")))
19511 (clobber (reg:CC FLAGS_REG))])
19512 (set (reg:CCZ FLAGS_REG)
19513 (compare:CCZ (and:QI (match_operand:QI 3 "register_operand")
19516 (set (pc) (if_then_else (match_operator 4 "bt_comparison_operator"
19517 [(reg:CCZ FLAGS_REG)
19519 (label_ref (match_operand 5))
19521 "REGNO (operands[1]) == REGNO (operands[3])
19522 && peep2_reg_dead_p (2, operands[1])
19523 && peep2_reg_dead_p (2, operands[3])
19524 && peep2_regno_dead_p (3, FLAGS_REG)"
19525 [(set (match_dup 0) (match_dup 2))
19526 (parallel [(set (reg:CC FLAGS_REG)
19527 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
19528 (clobber (match_dup 0))])
19529 (set (pc) (if_then_else (match_op_dup 4 [(reg:CC FLAGS_REG)
19531 (label_ref (match_dup 5))
19534 operands[4] = shallow_copy_rtx (operands[4]);
19535 PUT_CODE (operands[4], GET_CODE (operands[4]) == EQ ? UNORDERED : ORDERED);
19539 ;; Thread-local storage patterns for ELF.
19541 ;; Note that these code sequences must appear exactly as shown
19542 ;; in order to allow linker relaxation.
19544 (define_insn "*tls_global_dynamic_32_gnu"
19545 [(set (match_operand:SI 0 "register_operand" "=a")
19547 [(match_operand:SI 1 "register_operand" "Yb")
19548 (match_operand 2 "tls_symbolic_operand")
19549 (match_operand 3 "constant_call_address_operand" "Bz")
19552 (clobber (match_scratch:SI 4 "=d"))
19553 (clobber (match_scratch:SI 5 "=c"))
19554 (clobber (reg:CC FLAGS_REG))]
19555 "!TARGET_64BIT && TARGET_GNU_TLS"
19557 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19559 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
19562 ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
19563 if (TARGET_SUN_TLS)
19564 #ifdef HAVE_AS_IX86_TLSGDPLT
19565 return "call\t%a2@tlsgdplt";
19567 return "call\t%p3@plt";
19569 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19570 return "call\t%P3";
19571 return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
19573 [(set_attr "type" "multi")
19574 (set_attr "length" "12")])
19576 (define_expand "tls_global_dynamic_32"
19578 [(set (match_operand:SI 0 "register_operand")
19579 (unspec:SI [(match_operand:SI 2 "register_operand")
19580 (match_operand 1 "tls_symbolic_operand")
19581 (match_operand 3 "constant_call_address_operand")
19584 (clobber (scratch:SI))
19585 (clobber (scratch:SI))
19586 (clobber (reg:CC FLAGS_REG))])]
19588 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
19590 (define_insn "*tls_global_dynamic_64_<mode>"
19591 [(set (match_operand:P 0 "register_operand" "=a")
19593 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
19594 (match_operand 3)))
19595 (unspec:P [(match_operand 1 "tls_symbolic_operand")
19601 /* The .loc directive has effect for 'the immediately following assembly
19602 instruction'. So for a sequence:
19606 the 'immediately following assembly instruction' is insn1.
19607 We want to emit an insn prefix here, but if we use .byte (as shown in
19608 'ELF Handling For Thread-Local Storage'), a preceding .loc will point
19609 inside the insn sequence, rather than to the start. After relaxation
19610 of the sequence by the linker, the .loc might point inside an insn.
19611 Use data16 prefix instead, which doesn't have this problem. */
19612 fputs ("\tdata16", asm_out_file);
19614 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
19615 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19616 fputs (ASM_SHORT "0x6666\n", asm_out_file);
19618 fputs (ASM_BYTE "0x66\n", asm_out_file);
19619 fputs ("\trex64\n", asm_out_file);
19620 if (TARGET_SUN_TLS)
19621 return "call\t%p2@plt";
19622 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19623 return "call\t%P2";
19624 return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
19626 [(set_attr "type" "multi")
19627 (set (attr "length")
19628 (symbol_ref "TARGET_X32 ? 15 : 16"))])
19630 (define_insn "*tls_global_dynamic_64_largepic"
19631 [(set (match_operand:DI 0 "register_operand" "=a")
19633 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
19634 (match_operand:DI 3 "immediate_operand" "i")))
19635 (match_operand 4)))
19636 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
19639 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
19640 && GET_CODE (operands[3]) == CONST
19641 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
19642 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
19645 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
19646 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
19647 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
19648 return "call\t{*%%rax|rax}";
19650 [(set_attr "type" "multi")
19651 (set_attr "length" "22")])
19653 (define_expand "@tls_global_dynamic_64_<mode>"
19655 [(set (match_operand:P 0 "register_operand")
19657 (mem:QI (match_operand 2))
19659 (unspec:P [(match_operand 1 "tls_symbolic_operand")
19663 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
19665 (define_insn "*tls_local_dynamic_base_32_gnu"
19666 [(set (match_operand:SI 0 "register_operand" "=a")
19668 [(match_operand:SI 1 "register_operand" "Yb")
19669 (match_operand 2 "constant_call_address_operand" "Bz")
19671 UNSPEC_TLS_LD_BASE))
19672 (clobber (match_scratch:SI 3 "=d"))
19673 (clobber (match_scratch:SI 4 "=c"))
19674 (clobber (reg:CC FLAGS_REG))]
19675 "!TARGET_64BIT && TARGET_GNU_TLS"
19678 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
19679 if (TARGET_SUN_TLS)
19681 if (HAVE_AS_IX86_TLSLDMPLT)
19682 return "call\t%&@tlsldmplt";
19684 return "call\t%p2@plt";
19686 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19687 return "call\t%P2";
19688 return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
19690 [(set_attr "type" "multi")
19691 (set_attr "length" "11")])
19693 (define_expand "tls_local_dynamic_base_32"
19695 [(set (match_operand:SI 0 "register_operand")
19697 [(match_operand:SI 1 "register_operand")
19698 (match_operand 2 "constant_call_address_operand")
19700 UNSPEC_TLS_LD_BASE))
19701 (clobber (scratch:SI))
19702 (clobber (scratch:SI))
19703 (clobber (reg:CC FLAGS_REG))])]
19705 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
19707 (define_insn "*tls_local_dynamic_base_64_<mode>"
19708 [(set (match_operand:P 0 "register_operand" "=a")
19710 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
19711 (match_operand 2)))
19712 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
19716 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
19717 if (TARGET_SUN_TLS)
19718 return "call\t%p1@plt";
19719 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19720 return "call\t%P1";
19721 return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
19723 [(set_attr "type" "multi")
19724 (set_attr "length" "12")])
19726 (define_insn "*tls_local_dynamic_base_64_largepic"
19727 [(set (match_operand:DI 0 "register_operand" "=a")
19729 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
19730 (match_operand:DI 2 "immediate_operand" "i")))
19731 (match_operand 3)))
19732 (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
19733 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
19734 && GET_CODE (operands[2]) == CONST
19735 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
19736 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
19739 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
19740 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
19741 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
19742 return "call\t{*%%rax|rax}";
19744 [(set_attr "type" "multi")
19745 (set_attr "length" "22")])
19747 (define_expand "@tls_local_dynamic_base_64_<mode>"
19749 [(set (match_operand:P 0 "register_operand")
19751 (mem:QI (match_operand 1))
19753 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
19755 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
19757 ;; Local dynamic of a single variable is a lose. Show combine how
19758 ;; to convert that back to global dynamic.
19760 (define_insn_and_split "*tls_local_dynamic_32_once"
19761 [(set (match_operand:SI 0 "register_operand" "=a")
19763 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
19764 (match_operand 2 "constant_call_address_operand" "Bz")
19766 UNSPEC_TLS_LD_BASE)
19767 (const:SI (unspec:SI
19768 [(match_operand 3 "tls_symbolic_operand")]
19770 (clobber (match_scratch:SI 4 "=d"))
19771 (clobber (match_scratch:SI 5 "=c"))
19772 (clobber (reg:CC FLAGS_REG))]
19777 [(set (match_dup 0)
19778 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
19781 (clobber (match_dup 4))
19782 (clobber (match_dup 5))
19783 (clobber (reg:CC FLAGS_REG))])])
19785 ;; Load and add the thread base pointer from %<tp_seg>:0.
19786 (define_expand "get_thread_pointer<mode>"
19787 [(set (match_operand:PTR 0 "register_operand")
19788 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
19791 /* targetm is not visible in the scope of the condition. */
19792 if (!targetm.have_tls)
19793 error ("%<__builtin_thread_pointer%> is not supported on this target");
19796 (define_insn_and_split "*load_tp_<mode>"
19797 [(set (match_operand:PTR 0 "register_operand" "=r")
19798 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
19802 [(set (match_dup 0)
19805 addr_space_t as = DEFAULT_TLS_SEG_REG;
19807 operands[1] = gen_const_mem (<MODE>mode, const0_rtx);
19808 set_mem_addr_space (operands[1], as);
19811 (define_insn_and_split "*load_tp_x32_zext"
19812 [(set (match_operand:DI 0 "register_operand" "=r")
19814 (unspec:SI [(const_int 0)] UNSPEC_TP)))]
19818 [(set (match_dup 0)
19819 (zero_extend:DI (match_dup 1)))]
19821 addr_space_t as = DEFAULT_TLS_SEG_REG;
19823 operands[1] = gen_const_mem (SImode, const0_rtx);
19824 set_mem_addr_space (operands[1], as);
19827 (define_insn_and_split "*add_tp_<mode>"
19828 [(set (match_operand:PTR 0 "register_operand" "=r")
19830 (unspec:PTR [(const_int 0)] UNSPEC_TP)
19831 (match_operand:PTR 1 "register_operand" "0")))
19832 (clobber (reg:CC FLAGS_REG))]
19837 [(set (match_dup 0)
19838 (plus:PTR (match_dup 1) (match_dup 2)))
19839 (clobber (reg:CC FLAGS_REG))])]
19841 addr_space_t as = DEFAULT_TLS_SEG_REG;
19843 operands[2] = gen_const_mem (<MODE>mode, const0_rtx);
19844 set_mem_addr_space (operands[2], as);
19847 (define_insn_and_split "*add_tp_x32_zext"
19848 [(set (match_operand:DI 0 "register_operand" "=r")
19850 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
19851 (match_operand:SI 1 "register_operand" "0"))))
19852 (clobber (reg:CC FLAGS_REG))]
19857 [(set (match_dup 0)
19859 (plus:SI (match_dup 1) (match_dup 2))))
19860 (clobber (reg:CC FLAGS_REG))])]
19862 addr_space_t as = DEFAULT_TLS_SEG_REG;
19864 operands[2] = gen_const_mem (SImode, const0_rtx);
19865 set_mem_addr_space (operands[2], as);
19868 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
19869 ;; %rax as destination of the initial executable code sequence.
19870 (define_insn "tls_initial_exec_64_sun"
19871 [(set (match_operand:DI 0 "register_operand" "=a")
19873 [(match_operand 1 "tls_symbolic_operand")]
19874 UNSPEC_TLS_IE_SUN))
19875 (clobber (reg:CC FLAGS_REG))]
19876 "TARGET_64BIT && TARGET_SUN_TLS"
19879 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
19880 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
19882 [(set_attr "type" "multi")])
19884 ;; GNU2 TLS patterns can be split.
19886 (define_expand "tls_dynamic_gnu2_32"
19887 [(set (match_dup 3)
19888 (plus:SI (match_operand:SI 2 "register_operand")
19890 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
19893 [(set (match_operand:SI 0 "register_operand")
19894 (unspec:SI [(match_dup 1) (match_dup 3)
19895 (match_dup 2) (reg:SI SP_REG)]
19897 (clobber (reg:CC FLAGS_REG))])]
19898 "!TARGET_64BIT && TARGET_GNU2_TLS"
19900 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
19901 ix86_tls_descriptor_calls_expanded_in_cfun = true;
19904 (define_insn "*tls_dynamic_gnu2_lea_32"
19905 [(set (match_operand:SI 0 "register_operand" "=r")
19906 (plus:SI (match_operand:SI 1 "register_operand" "b")
19908 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
19909 UNSPEC_TLSDESC))))]
19910 "!TARGET_64BIT && TARGET_GNU2_TLS"
19911 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
19912 [(set_attr "type" "lea")
19913 (set_attr "mode" "SI")
19914 (set_attr "length" "6")
19915 (set_attr "length_address" "4")])
19917 (define_insn "*tls_dynamic_gnu2_call_32"
19918 [(set (match_operand:SI 0 "register_operand" "=a")
19919 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
19920 (match_operand:SI 2 "register_operand" "0")
19921 ;; we have to make sure %ebx still points to the GOT
19922 (match_operand:SI 3 "register_operand" "b")
19925 (clobber (reg:CC FLAGS_REG))]
19926 "!TARGET_64BIT && TARGET_GNU2_TLS"
19927 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
19928 [(set_attr "type" "call")
19929 (set_attr "length" "2")
19930 (set_attr "length_address" "0")])
19932 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
19933 [(set (match_operand:SI 0 "register_operand" "=&a")
19935 (unspec:SI [(match_operand 3 "tls_modbase_operand")
19936 (match_operand:SI 4)
19937 (match_operand:SI 2 "register_operand" "b")
19940 (const:SI (unspec:SI
19941 [(match_operand 1 "tls_symbolic_operand")]
19943 (clobber (reg:CC FLAGS_REG))]
19944 "!TARGET_64BIT && TARGET_GNU2_TLS"
19947 [(set (match_dup 0) (match_dup 5))]
19949 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
19950 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
19953 (define_expand "@tls_dynamic_gnu2_64_<mode>"
19954 [(set (match_dup 2)
19955 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")]
19958 [(set (match_operand:PTR 0 "register_operand")
19959 (unspec:PTR [(match_dup 1) (match_dup 2) (reg:PTR SP_REG)]
19961 (clobber (reg:CC FLAGS_REG))])]
19962 "TARGET_64BIT && TARGET_GNU2_TLS"
19964 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (ptr_mode) : operands[0];
19965 ix86_tls_descriptor_calls_expanded_in_cfun = true;
19968 (define_insn "*tls_dynamic_gnu2_lea_64_<mode>"
19969 [(set (match_operand:PTR 0 "register_operand" "=r")
19970 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")]
19972 "TARGET_64BIT && TARGET_GNU2_TLS"
19973 "lea%z0\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
19974 [(set_attr "type" "lea")
19975 (set_attr "mode" "<MODE>")
19976 (set_attr "length" "7")
19977 (set_attr "length_address" "4")])
19979 (define_insn "*tls_dynamic_gnu2_call_64_<mode>"
19980 [(set (match_operand:PTR 0 "register_operand" "=a")
19981 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")
19982 (match_operand:PTR 2 "register_operand" "0")
19985 (clobber (reg:CC FLAGS_REG))]
19986 "TARGET_64BIT && TARGET_GNU2_TLS"
19987 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
19988 [(set_attr "type" "call")
19989 (set_attr "length" "2")
19990 (set_attr "length_address" "0")])
19992 (define_insn_and_split "*tls_dynamic_gnu2_combine_64_<mode>"
19993 [(set (match_operand:PTR 0 "register_operand" "=&a")
19995 (unspec:PTR [(match_operand 2 "tls_modbase_operand")
19996 (match_operand:PTR 3)
19999 (const:PTR (unspec:PTR
20000 [(match_operand 1 "tls_symbolic_operand")]
20002 (clobber (reg:CC FLAGS_REG))]
20003 "TARGET_64BIT && TARGET_GNU2_TLS"
20006 [(set (match_dup 0) (match_dup 4))]
20008 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (ptr_mode) : operands[0];
20009 emit_insn (gen_tls_dynamic_gnu2_64 (ptr_mode, operands[4], operands[1]));
20013 [(match_operand 0 "tls_address_pattern")]
20014 "TARGET_TLS_DIRECT_SEG_REFS"
20016 "operands[0] = ix86_rewrite_tls_address (operands[0]);")
20019 ;; These patterns match the binary 387 instructions for addM3, subM3,
20020 ;; mulM3 and divM3. There are three patterns for each of DFmode and
20021 ;; SFmode. The first is the normal insn, the second the same insn but
20022 ;; with one operand a conversion, and the third the same insn but with
20023 ;; the other operand a conversion. The conversion may be SFmode or
20024 ;; SImode if the target mode DFmode, but only SImode if the target mode
20027 ;; Gcc is slightly more smart about handling normal two address instructions
20028 ;; so use special patterns for add and mull.
20030 (define_insn "*fop_xf_comm_i387"
20031 [(set (match_operand:XF 0 "register_operand" "=f")
20032 (match_operator:XF 3 "binary_fp_operator"
20033 [(match_operand:XF 1 "register_operand" "%0")
20034 (match_operand:XF 2 "register_operand" "f")]))]
20036 && COMMUTATIVE_ARITH_P (operands[3])"
20037 "* return output_387_binary_op (insn, operands);"
20038 [(set (attr "type")
20039 (if_then_else (match_operand:XF 3 "mult_operator")
20040 (const_string "fmul")
20041 (const_string "fop")))
20042 (set_attr "mode" "XF")])
20044 (define_insn "*fop_<mode>_comm"
20045 [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
20046 (match_operator:MODEF 3 "binary_fp_operator"
20047 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
20048 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
20049 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20050 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
20051 && COMMUTATIVE_ARITH_P (operands[3])
20052 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
20053 "* return output_387_binary_op (insn, operands);"
20054 [(set (attr "type")
20055 (if_then_else (eq_attr "alternative" "1,2")
20056 (if_then_else (match_operand:MODEF 3 "mult_operator")
20057 (const_string "ssemul")
20058 (const_string "sseadd"))
20059 (if_then_else (match_operand:MODEF 3 "mult_operator")
20060 (const_string "fmul")
20061 (const_string "fop"))))
20062 (set_attr "isa" "*,noavx,avx")
20063 (set_attr "prefix" "orig,orig,vex")
20064 (set_attr "mode" "<MODE>")
20065 (set (attr "enabled")
20067 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
20069 (eq_attr "alternative" "0")
20070 (symbol_ref "TARGET_MIX_SSE_I387
20071 && X87_ENABLE_ARITH (<MODE>mode)")
20072 (const_string "*"))
20074 (eq_attr "alternative" "0")
20075 (symbol_ref "true")
20076 (symbol_ref "false"))))])
20078 (define_insn "*<insn>hf"
20079 [(set (match_operand:HF 0 "register_operand" "=v")
20080 (plusminusmultdiv:HF
20081 (match_operand:HF 1 "nonimmediate_operand" "<comm>v")
20082 (match_operand:HF 2 "nonimmediate_operand" "vm")))]
20084 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
20085 "v<insn>sh\t{%2, %1, %0|%0, %1, %2}"
20086 [(set_attr "prefix" "evex")
20087 (set_attr "mode" "HF")])
20089 (define_insn "*rcpsf2_sse"
20090 [(set (match_operand:SF 0 "register_operand" "=x,x,x")
20091 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m")]
20093 "TARGET_SSE && TARGET_SSE_MATH"
20095 %vrcpss\t{%d1, %0|%0, %d1}
20096 %vrcpss\t{%d1, %0|%0, %d1}
20097 %vrcpss\t{%1, %d0|%d0, %1}"
20098 [(set_attr "type" "sse")
20099 (set_attr "atom_sse_attr" "rcp")
20100 (set_attr "btver2_sse_attr" "rcp")
20101 (set_attr "prefix" "maybe_vex")
20102 (set_attr "mode" "SF")
20103 (set_attr "avx_partial_xmm_update" "false,false,true")
20104 (set (attr "preferred_for_speed")
20105 (cond [(match_test "TARGET_AVX")
20106 (symbol_ref "true")
20107 (eq_attr "alternative" "1,2")
20108 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
20110 (symbol_ref "true")))])
20112 (define_insn "rcphf2"
20113 [(set (match_operand:HF 0 "register_operand" "=v,v")
20114 (unspec:HF [(match_operand:HF 1 "nonimmediate_operand" "v,m")]
20116 "TARGET_AVX512FP16"
20118 vrcpsh\t{%d1, %0|%0, %d1}
20119 vrcpsh\t{%1, %d0|%d0, %1}"
20120 [(set_attr "type" "sse")
20121 (set_attr "prefix" "evex")
20122 (set_attr "mode" "HF")
20123 (set_attr "avx_partial_xmm_update" "false,true")])
20125 (define_insn "*fop_xf_1_i387"
20126 [(set (match_operand:XF 0 "register_operand" "=f,f")
20127 (match_operator:XF 3 "binary_fp_operator"
20128 [(match_operand:XF 1 "register_operand" "0,f")
20129 (match_operand:XF 2 "register_operand" "f,0")]))]
20131 && !COMMUTATIVE_ARITH_P (operands[3])"
20132 "* return output_387_binary_op (insn, operands);"
20133 [(set (attr "type")
20134 (if_then_else (match_operand:XF 3 "div_operator")
20135 (const_string "fdiv")
20136 (const_string "fop")))
20137 (set_attr "mode" "XF")])
20139 (define_insn "*fop_<mode>_1"
20140 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
20141 (match_operator:MODEF 3 "binary_fp_operator"
20142 [(match_operand:MODEF 1
20143 "x87nonimm_ssenomem_operand" "0,fm,0,v")
20144 (match_operand:MODEF 2
20145 "nonimmediate_operand" "fm,0,xm,vm")]))]
20146 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20147 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
20148 && !COMMUTATIVE_ARITH_P (operands[3])
20149 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
20150 "* return output_387_binary_op (insn, operands);"
20151 [(set (attr "type")
20152 (if_then_else (eq_attr "alternative" "2,3")
20153 (if_then_else (match_operand:MODEF 3 "div_operator")
20154 (const_string "ssediv")
20155 (const_string "sseadd"))
20156 (if_then_else (match_operand:MODEF 3 "div_operator")
20157 (const_string "fdiv")
20158 (const_string "fop"))))
20159 (set_attr "isa" "*,*,noavx,avx")
20160 (set_attr "prefix" "orig,orig,orig,vex")
20161 (set_attr "mode" "<MODE>")
20162 (set (attr "enabled")
20164 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
20166 (eq_attr "alternative" "0,1")
20167 (symbol_ref "TARGET_MIX_SSE_I387
20168 && X87_ENABLE_ARITH (<MODE>mode)")
20169 (const_string "*"))
20171 (eq_attr "alternative" "0,1")
20172 (symbol_ref "true")
20173 (symbol_ref "false"))))])
20175 (define_insn "*fop_<X87MODEF:mode>_2_i387"
20176 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
20177 (match_operator:X87MODEF 3 "binary_fp_operator"
20179 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
20180 (match_operand:X87MODEF 2 "register_operand" "0")]))]
20181 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
20182 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
20183 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
20184 || optimize_function_for_size_p (cfun))"
20185 "* return output_387_binary_op (insn, operands);"
20186 [(set (attr "type")
20187 (cond [(match_operand:X87MODEF 3 "mult_operator")
20188 (const_string "fmul")
20189 (match_operand:X87MODEF 3 "div_operator")
20190 (const_string "fdiv")
20192 (const_string "fop")))
20193 (set_attr "fp_int_src" "true")
20194 (set_attr "mode" "<SWI24:MODE>")])
20196 (define_insn "*fop_<X87MODEF:mode>_3_i387"
20197 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
20198 (match_operator:X87MODEF 3 "binary_fp_operator"
20199 [(match_operand:X87MODEF 1 "register_operand" "0")
20201 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
20202 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
20203 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
20204 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
20205 || optimize_function_for_size_p (cfun))"
20206 "* return output_387_binary_op (insn, operands);"
20207 [(set (attr "type")
20208 (cond [(match_operand:X87MODEF 3 "mult_operator")
20209 (const_string "fmul")
20210 (match_operand:X87MODEF 3 "div_operator")
20211 (const_string "fdiv")
20213 (const_string "fop")))
20214 (set_attr "fp_int_src" "true")
20215 (set_attr "mode" "<SWI24:MODE>")])
20217 (define_insn "*fop_xf_4_i387"
20218 [(set (match_operand:XF 0 "register_operand" "=f,f")
20219 (match_operator:XF 3 "binary_fp_operator"
20221 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
20222 (match_operand:XF 2 "register_operand" "0,f")]))]
20224 "* return output_387_binary_op (insn, operands);"
20225 [(set (attr "type")
20226 (cond [(match_operand:XF 3 "mult_operator")
20227 (const_string "fmul")
20228 (match_operand:XF 3 "div_operator")
20229 (const_string "fdiv")
20231 (const_string "fop")))
20232 (set_attr "mode" "<MODE>")])
20234 (define_insn "*fop_df_4_i387"
20235 [(set (match_operand:DF 0 "register_operand" "=f,f")
20236 (match_operator:DF 3 "binary_fp_operator"
20238 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
20239 (match_operand:DF 2 "register_operand" "0,f")]))]
20240 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
20241 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
20242 "* return output_387_binary_op (insn, operands);"
20243 [(set (attr "type")
20244 (cond [(match_operand:DF 3 "mult_operator")
20245 (const_string "fmul")
20246 (match_operand:DF 3 "div_operator")
20247 (const_string "fdiv")
20249 (const_string "fop")))
20250 (set_attr "mode" "SF")])
20252 (define_insn "*fop_xf_5_i387"
20253 [(set (match_operand:XF 0 "register_operand" "=f,f")
20254 (match_operator:XF 3 "binary_fp_operator"
20255 [(match_operand:XF 1 "register_operand" "0,f")
20257 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
20259 "* return output_387_binary_op (insn, operands);"
20260 [(set (attr "type")
20261 (cond [(match_operand:XF 3 "mult_operator")
20262 (const_string "fmul")
20263 (match_operand:XF 3 "div_operator")
20264 (const_string "fdiv")
20266 (const_string "fop")))
20267 (set_attr "mode" "<MODE>")])
20269 (define_insn "*fop_df_5_i387"
20270 [(set (match_operand:DF 0 "register_operand" "=f,f")
20271 (match_operator:DF 3 "binary_fp_operator"
20272 [(match_operand:DF 1 "register_operand" "0,f")
20274 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
20275 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
20276 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
20277 "* return output_387_binary_op (insn, operands);"
20278 [(set (attr "type")
20279 (cond [(match_operand:DF 3 "mult_operator")
20280 (const_string "fmul")
20281 (match_operand:DF 3 "div_operator")
20282 (const_string "fdiv")
20284 (const_string "fop")))
20285 (set_attr "mode" "SF")])
20287 (define_insn "*fop_xf_6_i387"
20288 [(set (match_operand:XF 0 "register_operand" "=f,f")
20289 (match_operator:XF 3 "binary_fp_operator"
20291 (match_operand:MODEF 1 "register_operand" "0,f"))
20293 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
20295 "* return output_387_binary_op (insn, operands);"
20296 [(set (attr "type")
20297 (cond [(match_operand:XF 3 "mult_operator")
20298 (const_string "fmul")
20299 (match_operand:XF 3 "div_operator")
20300 (const_string "fdiv")
20302 (const_string "fop")))
20303 (set_attr "mode" "<MODE>")])
20305 (define_insn "*fop_df_6_i387"
20306 [(set (match_operand:DF 0 "register_operand" "=f,f")
20307 (match_operator:DF 3 "binary_fp_operator"
20309 (match_operand:SF 1 "register_operand" "0,f"))
20311 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
20312 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
20313 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
20314 "* return output_387_binary_op (insn, operands);"
20315 [(set (attr "type")
20316 (cond [(match_operand:DF 3 "mult_operator")
20317 (const_string "fmul")
20318 (match_operand:DF 3 "div_operator")
20319 (const_string "fdiv")
20321 (const_string "fop")))
20322 (set_attr "mode" "SF")])
20324 ;; FPU special functions.
20326 ;; This pattern implements a no-op XFmode truncation for
20327 ;; all fancy i386 XFmode math functions.
20329 (define_insn "truncxf<mode>2_i387_noop_unspec"
20330 [(set (match_operand:MODEF 0 "nonimmediate_operand" "=mf")
20331 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
20332 UNSPEC_TRUNC_NOOP))]
20333 "TARGET_USE_FANCY_MATH_387"
20334 "* return output_387_reg_move (insn, operands);"
20335 [(set_attr "type" "fmov")
20336 (set_attr "mode" "<MODE>")])
20338 (define_insn "sqrtxf2"
20339 [(set (match_operand:XF 0 "register_operand" "=f")
20340 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
20341 "TARGET_USE_FANCY_MATH_387"
20343 [(set_attr "type" "fpspc")
20344 (set_attr "mode" "XF")
20345 (set_attr "athlon_decode" "direct")
20346 (set_attr "amdfam10_decode" "direct")
20347 (set_attr "bdver1_decode" "direct")])
20349 (define_insn "*rsqrtsf2_sse"
20350 [(set (match_operand:SF 0 "register_operand" "=x,x,x")
20351 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m")]
20353 "TARGET_SSE && TARGET_SSE_MATH"
20355 %vrsqrtss\t{%d1, %0|%0, %d1}
20356 %vrsqrtss\t{%d1, %0|%0, %d1}
20357 %vrsqrtss\t{%1, %d0|%d0, %1}"
20358 [(set_attr "type" "sse")
20359 (set_attr "atom_sse_attr" "rcp")
20360 (set_attr "btver2_sse_attr" "rcp")
20361 (set_attr "prefix" "maybe_vex")
20362 (set_attr "mode" "SF")
20363 (set_attr "avx_partial_xmm_update" "false,false,true")
20364 (set (attr "preferred_for_speed")
20365 (cond [(match_test "TARGET_AVX")
20366 (symbol_ref "true")
20367 (eq_attr "alternative" "1,2")
20368 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
20370 (symbol_ref "true")))])
20372 (define_expand "rsqrtsf2"
20373 [(set (match_operand:SF 0 "register_operand")
20374 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
20376 "TARGET_SSE && TARGET_SSE_MATH"
20378 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
20382 (define_insn "rsqrthf2"
20383 [(set (match_operand:HF 0 "register_operand" "=v,v")
20384 (unspec:HF [(match_operand:HF 1 "nonimmediate_operand" "v,m")]
20386 "TARGET_AVX512FP16"
20388 vrsqrtsh\t{%d1, %0|%0, %d1}
20389 vrsqrtsh\t{%1, %d0|%d0, %1}"
20390 [(set_attr "type" "sse")
20391 (set_attr "prefix" "evex")
20392 (set_attr "avx_partial_xmm_update" "false,true")
20393 (set_attr "mode" "HF")])
20395 (define_insn "sqrthf2"
20396 [(set (match_operand:HF 0 "register_operand" "=v,v")
20398 (match_operand:HF 1 "nonimmediate_operand" "v,m")))]
20399 "TARGET_AVX512FP16"
20401 vsqrtsh\t{%d1, %0|%0, %d1}
20402 vsqrtsh\t{%1, %d0|%d0, %1}"
20403 [(set_attr "type" "sse")
20404 (set_attr "prefix" "evex")
20405 (set_attr "avx_partial_xmm_update" "false,true")
20406 (set_attr "mode" "HF")])
20408 (define_insn "*sqrt<mode>2_sse"
20409 [(set (match_operand:MODEF 0 "register_operand" "=v,v,v")
20411 (match_operand:MODEF 1 "nonimmediate_operand" "0,v,m")))]
20412 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20414 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
20415 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
20416 %vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
20417 [(set_attr "type" "sse")
20418 (set_attr "atom_sse_attr" "sqrt")
20419 (set_attr "btver2_sse_attr" "sqrt")
20420 (set_attr "prefix" "maybe_vex")
20421 (set_attr "avx_partial_xmm_update" "false,false,true")
20422 (set_attr "mode" "<MODE>")
20423 (set (attr "preferred_for_speed")
20424 (cond [(match_test "TARGET_AVX")
20425 (symbol_ref "true")
20426 (eq_attr "alternative" "1,2")
20427 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
20429 (symbol_ref "true")))])
20431 (define_expand "sqrt<mode>2"
20432 [(set (match_operand:MODEF 0 "register_operand")
20434 (match_operand:MODEF 1 "nonimmediate_operand")))]
20435 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
20436 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
20438 if (<MODE>mode == SFmode
20439 && TARGET_SSE && TARGET_SSE_MATH
20440 && TARGET_RECIP_SQRT
20441 && !optimize_function_for_size_p (cfun)
20442 && flag_finite_math_only && !flag_trapping_math
20443 && flag_unsafe_math_optimizations)
20445 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
20449 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
20451 rtx op0 = gen_reg_rtx (XFmode);
20452 rtx op1 = gen_reg_rtx (XFmode);
20454 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20455 emit_insn (gen_sqrtxf2 (op0, op1));
20456 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
20461 (define_expand "hypot<mode>3"
20462 [(use (match_operand:MODEF 0 "register_operand"))
20463 (use (match_operand:MODEF 1 "general_operand"))
20464 (use (match_operand:MODEF 2 "general_operand"))]
20465 "TARGET_USE_FANCY_MATH_387
20466 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20467 || TARGET_MIX_SSE_I387)
20468 && flag_finite_math_only
20469 && flag_unsafe_math_optimizations"
20471 rtx op0 = gen_reg_rtx (XFmode);
20472 rtx op1 = gen_reg_rtx (XFmode);
20473 rtx op2 = gen_reg_rtx (XFmode);
20475 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20476 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20478 emit_insn (gen_mulxf3 (op1, op1, op1));
20479 emit_insn (gen_mulxf3 (op2, op2, op2));
20480 emit_insn (gen_addxf3 (op0, op2, op1));
20481 emit_insn (gen_sqrtxf2 (op0, op0));
20483 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20487 (define_insn "x86_fnstsw_1"
20488 [(set (match_operand:HI 0 "register_operand" "=a")
20489 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
20492 [(set_attr "length" "2")
20493 (set_attr "mode" "SI")
20494 (set_attr "unit" "i387")])
20496 (define_insn "fpremxf4_i387"
20497 [(set (match_operand:XF 0 "register_operand" "=f")
20498 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
20499 (match_operand:XF 3 "register_operand" "1")]
20501 (set (match_operand:XF 1 "register_operand" "=f")
20502 (unspec:XF [(match_dup 2) (match_dup 3)]
20504 (set (reg:CCFP FPSR_REG)
20505 (unspec:CCFP [(match_dup 2) (match_dup 3)]
20507 "TARGET_USE_FANCY_MATH_387"
20509 [(set_attr "type" "fpspc")
20510 (set_attr "znver1_decode" "vector")
20511 (set_attr "mode" "XF")])
20513 (define_expand "fmodxf3"
20514 [(use (match_operand:XF 0 "register_operand"))
20515 (use (match_operand:XF 1 "general_operand"))
20516 (use (match_operand:XF 2 "general_operand"))]
20517 "TARGET_USE_FANCY_MATH_387"
20519 rtx_code_label *label = gen_label_rtx ();
20521 rtx op1 = gen_reg_rtx (XFmode);
20522 rtx op2 = gen_reg_rtx (XFmode);
20524 emit_move_insn (op2, operands[2]);
20525 emit_move_insn (op1, operands[1]);
20527 emit_label (label);
20528 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
20529 ix86_emit_fp_unordered_jump (label);
20530 LABEL_NUSES (label) = 1;
20532 emit_move_insn (operands[0], op1);
20536 (define_expand "fmod<mode>3"
20537 [(use (match_operand:MODEF 0 "register_operand"))
20538 (use (match_operand:MODEF 1 "general_operand"))
20539 (use (match_operand:MODEF 2 "general_operand"))]
20540 "TARGET_USE_FANCY_MATH_387"
20542 rtx (*gen_truncxf) (rtx, rtx);
20544 rtx_code_label *label = gen_label_rtx ();
20546 rtx op1 = gen_reg_rtx (XFmode);
20547 rtx op2 = gen_reg_rtx (XFmode);
20549 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20550 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20552 emit_label (label);
20553 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
20554 ix86_emit_fp_unordered_jump (label);
20555 LABEL_NUSES (label) = 1;
20557 /* Truncate the result properly for strict SSE math. */
20558 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
20559 && !TARGET_MIX_SSE_I387)
20560 gen_truncxf = gen_truncxf<mode>2;
20562 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
20564 emit_insn (gen_truncxf (operands[0], op1));
20568 (define_insn "fprem1xf4_i387"
20569 [(set (match_operand:XF 0 "register_operand" "=f")
20570 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
20571 (match_operand:XF 3 "register_operand" "1")]
20573 (set (match_operand:XF 1 "register_operand" "=f")
20574 (unspec:XF [(match_dup 2) (match_dup 3)]
20576 (set (reg:CCFP FPSR_REG)
20577 (unspec:CCFP [(match_dup 2) (match_dup 3)]
20579 "TARGET_USE_FANCY_MATH_387"
20581 [(set_attr "type" "fpspc")
20582 (set_attr "znver1_decode" "vector")
20583 (set_attr "mode" "XF")])
20585 (define_expand "remainderxf3"
20586 [(use (match_operand:XF 0 "register_operand"))
20587 (use (match_operand:XF 1 "general_operand"))
20588 (use (match_operand:XF 2 "general_operand"))]
20589 "TARGET_USE_FANCY_MATH_387"
20591 rtx_code_label *label = gen_label_rtx ();
20593 rtx op1 = gen_reg_rtx (XFmode);
20594 rtx op2 = gen_reg_rtx (XFmode);
20596 emit_move_insn (op2, operands[2]);
20597 emit_move_insn (op1, operands[1]);
20599 emit_label (label);
20600 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
20601 ix86_emit_fp_unordered_jump (label);
20602 LABEL_NUSES (label) = 1;
20604 emit_move_insn (operands[0], op1);
20608 (define_expand "remainder<mode>3"
20609 [(use (match_operand:MODEF 0 "register_operand"))
20610 (use (match_operand:MODEF 1 "general_operand"))
20611 (use (match_operand:MODEF 2 "general_operand"))]
20612 "TARGET_USE_FANCY_MATH_387"
20614 rtx (*gen_truncxf) (rtx, rtx);
20616 rtx_code_label *label = gen_label_rtx ();
20618 rtx op1 = gen_reg_rtx (XFmode);
20619 rtx op2 = gen_reg_rtx (XFmode);
20621 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20622 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20624 emit_label (label);
20626 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
20627 ix86_emit_fp_unordered_jump (label);
20628 LABEL_NUSES (label) = 1;
20630 /* Truncate the result properly for strict SSE math. */
20631 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
20632 && !TARGET_MIX_SSE_I387)
20633 gen_truncxf = gen_truncxf<mode>2;
20635 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
20637 emit_insn (gen_truncxf (operands[0], op1));
20641 (define_int_iterator SINCOS
20645 (define_int_attr sincos
20646 [(UNSPEC_SIN "sin")
20647 (UNSPEC_COS "cos")])
20649 (define_insn "<sincos>xf2"
20650 [(set (match_operand:XF 0 "register_operand" "=f")
20651 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
20653 "TARGET_USE_FANCY_MATH_387
20654 && flag_unsafe_math_optimizations"
20656 [(set_attr "type" "fpspc")
20657 (set_attr "znver1_decode" "vector")
20658 (set_attr "mode" "XF")])
20660 (define_expand "<sincos><mode>2"
20661 [(set (match_operand:MODEF 0 "register_operand")
20662 (unspec:MODEF [(match_operand:MODEF 1 "general_operand")]
20664 "TARGET_USE_FANCY_MATH_387
20665 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20666 || TARGET_MIX_SSE_I387)
20667 && flag_unsafe_math_optimizations"
20669 rtx op0 = gen_reg_rtx (XFmode);
20670 rtx op1 = gen_reg_rtx (XFmode);
20672 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20673 emit_insn (gen_<sincos>xf2 (op0, op1));
20674 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20678 (define_insn "sincosxf3"
20679 [(set (match_operand:XF 0 "register_operand" "=f")
20680 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
20681 UNSPEC_SINCOS_COS))
20682 (set (match_operand:XF 1 "register_operand" "=f")
20683 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
20684 "TARGET_USE_FANCY_MATH_387
20685 && flag_unsafe_math_optimizations"
20687 [(set_attr "type" "fpspc")
20688 (set_attr "znver1_decode" "vector")
20689 (set_attr "mode" "XF")])
20691 (define_expand "sincos<mode>3"
20692 [(use (match_operand:MODEF 0 "register_operand"))
20693 (use (match_operand:MODEF 1 "register_operand"))
20694 (use (match_operand:MODEF 2 "general_operand"))]
20695 "TARGET_USE_FANCY_MATH_387
20696 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20697 || TARGET_MIX_SSE_I387)
20698 && flag_unsafe_math_optimizations"
20700 rtx op0 = gen_reg_rtx (XFmode);
20701 rtx op1 = gen_reg_rtx (XFmode);
20702 rtx op2 = gen_reg_rtx (XFmode);
20704 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20705 emit_insn (gen_sincosxf3 (op0, op1, op2));
20706 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20707 emit_insn (gen_truncxf<mode>2 (operands[1], op1));
20711 (define_insn "fptanxf4_i387"
20712 [(set (match_operand:SF 0 "register_operand" "=f")
20713 (match_operand:SF 3 "const1_operand"))
20714 (set (match_operand:XF 1 "register_operand" "=f")
20715 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
20717 "TARGET_USE_FANCY_MATH_387
20718 && flag_unsafe_math_optimizations"
20720 [(set_attr "type" "fpspc")
20721 (set_attr "znver1_decode" "vector")
20722 (set_attr "mode" "XF")])
20724 (define_expand "tanxf2"
20725 [(use (match_operand:XF 0 "register_operand"))
20726 (use (match_operand:XF 1 "register_operand"))]
20727 "TARGET_USE_FANCY_MATH_387
20728 && flag_unsafe_math_optimizations"
20730 rtx one = gen_reg_rtx (SFmode);
20731 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1],
20732 CONST1_RTX (SFmode)));
20736 (define_expand "tan<mode>2"
20737 [(use (match_operand:MODEF 0 "register_operand"))
20738 (use (match_operand:MODEF 1 "general_operand"))]
20739 "TARGET_USE_FANCY_MATH_387
20740 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20741 || TARGET_MIX_SSE_I387)
20742 && flag_unsafe_math_optimizations"
20744 rtx op0 = gen_reg_rtx (XFmode);
20745 rtx op1 = gen_reg_rtx (XFmode);
20747 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20748 emit_insn (gen_tanxf2 (op0, op1));
20749 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20753 (define_insn "atan2xf3"
20754 [(set (match_operand:XF 0 "register_operand" "=f")
20755 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
20756 (match_operand:XF 1 "register_operand" "f")]
20758 (clobber (match_scratch:XF 3 "=1"))]
20759 "TARGET_USE_FANCY_MATH_387
20760 && flag_unsafe_math_optimizations"
20762 [(set_attr "type" "fpspc")
20763 (set_attr "znver1_decode" "vector")
20764 (set_attr "mode" "XF")])
20766 (define_expand "atan2<mode>3"
20767 [(use (match_operand:MODEF 0 "register_operand"))
20768 (use (match_operand:MODEF 1 "general_operand"))
20769 (use (match_operand:MODEF 2 "general_operand"))]
20770 "TARGET_USE_FANCY_MATH_387
20771 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20772 || TARGET_MIX_SSE_I387)
20773 && flag_unsafe_math_optimizations"
20775 rtx op0 = gen_reg_rtx (XFmode);
20776 rtx op1 = gen_reg_rtx (XFmode);
20777 rtx op2 = gen_reg_rtx (XFmode);
20779 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20780 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20782 emit_insn (gen_atan2xf3 (op0, op1, op2));
20783 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20787 (define_expand "atanxf2"
20788 [(parallel [(set (match_operand:XF 0 "register_operand")
20789 (unspec:XF [(match_dup 2)
20790 (match_operand:XF 1 "register_operand")]
20792 (clobber (scratch:XF))])]
20793 "TARGET_USE_FANCY_MATH_387
20794 && flag_unsafe_math_optimizations"
20795 "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
20797 (define_expand "atan<mode>2"
20798 [(use (match_operand:MODEF 0 "register_operand"))
20799 (use (match_operand:MODEF 1 "general_operand"))]
20800 "TARGET_USE_FANCY_MATH_387
20801 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20802 || TARGET_MIX_SSE_I387)
20803 && flag_unsafe_math_optimizations"
20805 rtx op0 = gen_reg_rtx (XFmode);
20806 rtx op1 = gen_reg_rtx (XFmode);
20808 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20809 emit_insn (gen_atanxf2 (op0, op1));
20810 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20814 (define_expand "asinxf2"
20815 [(set (match_dup 2)
20816 (mult:XF (match_operand:XF 1 "register_operand")
20818 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
20819 (set (match_dup 5) (sqrt:XF (match_dup 4)))
20820 (parallel [(set (match_operand:XF 0 "register_operand")
20821 (unspec:XF [(match_dup 5) (match_dup 1)]
20823 (clobber (scratch:XF))])]
20824 "TARGET_USE_FANCY_MATH_387
20825 && flag_unsafe_math_optimizations"
20829 for (i = 2; i < 6; i++)
20830 operands[i] = gen_reg_rtx (XFmode);
20832 emit_move_insn (operands[3], CONST1_RTX (XFmode));
20835 (define_expand "asin<mode>2"
20836 [(use (match_operand:MODEF 0 "register_operand"))
20837 (use (match_operand:MODEF 1 "general_operand"))]
20838 "TARGET_USE_FANCY_MATH_387
20839 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20840 || TARGET_MIX_SSE_I387)
20841 && flag_unsafe_math_optimizations"
20843 rtx op0 = gen_reg_rtx (XFmode);
20844 rtx op1 = gen_reg_rtx (XFmode);
20846 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20847 emit_insn (gen_asinxf2 (op0, op1));
20848 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20852 (define_expand "acosxf2"
20853 [(set (match_dup 2)
20854 (mult:XF (match_operand:XF 1 "register_operand")
20856 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
20857 (set (match_dup 5) (sqrt:XF (match_dup 4)))
20858 (parallel [(set (match_operand:XF 0 "register_operand")
20859 (unspec:XF [(match_dup 1) (match_dup 5)]
20861 (clobber (scratch:XF))])]
20862 "TARGET_USE_FANCY_MATH_387
20863 && flag_unsafe_math_optimizations"
20867 for (i = 2; i < 6; i++)
20868 operands[i] = gen_reg_rtx (XFmode);
20870 emit_move_insn (operands[3], CONST1_RTX (XFmode));
20873 (define_expand "acos<mode>2"
20874 [(use (match_operand:MODEF 0 "register_operand"))
20875 (use (match_operand:MODEF 1 "general_operand"))]
20876 "TARGET_USE_FANCY_MATH_387
20877 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20878 || TARGET_MIX_SSE_I387)
20879 && flag_unsafe_math_optimizations"
20881 rtx op0 = gen_reg_rtx (XFmode);
20882 rtx op1 = gen_reg_rtx (XFmode);
20884 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20885 emit_insn (gen_acosxf2 (op0, op1));
20886 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20890 (define_expand "sinhxf2"
20891 [(use (match_operand:XF 0 "register_operand"))
20892 (use (match_operand:XF 1 "register_operand"))]
20893 "TARGET_USE_FANCY_MATH_387
20894 && flag_finite_math_only
20895 && flag_unsafe_math_optimizations"
20897 ix86_emit_i387_sinh (operands[0], operands[1]);
20901 (define_expand "sinh<mode>2"
20902 [(use (match_operand:MODEF 0 "register_operand"))
20903 (use (match_operand:MODEF 1 "general_operand"))]
20904 "TARGET_USE_FANCY_MATH_387
20905 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20906 || TARGET_MIX_SSE_I387)
20907 && flag_finite_math_only
20908 && flag_unsafe_math_optimizations"
20910 rtx op0 = gen_reg_rtx (XFmode);
20911 rtx op1 = gen_reg_rtx (XFmode);
20913 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20914 emit_insn (gen_sinhxf2 (op0, op1));
20915 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20919 (define_expand "coshxf2"
20920 [(use (match_operand:XF 0 "register_operand"))
20921 (use (match_operand:XF 1 "register_operand"))]
20922 "TARGET_USE_FANCY_MATH_387
20923 && flag_unsafe_math_optimizations"
20925 ix86_emit_i387_cosh (operands[0], operands[1]);
20929 (define_expand "cosh<mode>2"
20930 [(use (match_operand:MODEF 0 "register_operand"))
20931 (use (match_operand:MODEF 1 "general_operand"))]
20932 "TARGET_USE_FANCY_MATH_387
20933 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20934 || TARGET_MIX_SSE_I387)
20935 && flag_unsafe_math_optimizations"
20937 rtx op0 = gen_reg_rtx (XFmode);
20938 rtx op1 = gen_reg_rtx (XFmode);
20940 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20941 emit_insn (gen_coshxf2 (op0, op1));
20942 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20946 (define_expand "tanhxf2"
20947 [(use (match_operand:XF 0 "register_operand"))
20948 (use (match_operand:XF 1 "register_operand"))]
20949 "TARGET_USE_FANCY_MATH_387
20950 && flag_unsafe_math_optimizations"
20952 ix86_emit_i387_tanh (operands[0], operands[1]);
20956 (define_expand "tanh<mode>2"
20957 [(use (match_operand:MODEF 0 "register_operand"))
20958 (use (match_operand:MODEF 1 "general_operand"))]
20959 "TARGET_USE_FANCY_MATH_387
20960 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20961 || TARGET_MIX_SSE_I387)
20962 && flag_unsafe_math_optimizations"
20964 rtx op0 = gen_reg_rtx (XFmode);
20965 rtx op1 = gen_reg_rtx (XFmode);
20967 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20968 emit_insn (gen_tanhxf2 (op0, op1));
20969 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20973 (define_expand "asinhxf2"
20974 [(use (match_operand:XF 0 "register_operand"))
20975 (use (match_operand:XF 1 "register_operand"))]
20976 "TARGET_USE_FANCY_MATH_387
20977 && flag_finite_math_only
20978 && flag_unsafe_math_optimizations"
20980 ix86_emit_i387_asinh (operands[0], operands[1]);
20984 (define_expand "asinh<mode>2"
20985 [(use (match_operand:MODEF 0 "register_operand"))
20986 (use (match_operand:MODEF 1 "general_operand"))]
20987 "TARGET_USE_FANCY_MATH_387
20988 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20989 || TARGET_MIX_SSE_I387)
20990 && flag_finite_math_only
20991 && flag_unsafe_math_optimizations"
20993 rtx op0 = gen_reg_rtx (XFmode);
20994 rtx op1 = gen_reg_rtx (XFmode);
20996 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20997 emit_insn (gen_asinhxf2 (op0, op1));
20998 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21002 (define_expand "acoshxf2"
21003 [(use (match_operand:XF 0 "register_operand"))
21004 (use (match_operand:XF 1 "register_operand"))]
21005 "TARGET_USE_FANCY_MATH_387
21006 && flag_unsafe_math_optimizations"
21008 ix86_emit_i387_acosh (operands[0], operands[1]);
21012 (define_expand "acosh<mode>2"
21013 [(use (match_operand:MODEF 0 "register_operand"))
21014 (use (match_operand:MODEF 1 "general_operand"))]
21015 "TARGET_USE_FANCY_MATH_387
21016 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21017 || TARGET_MIX_SSE_I387)
21018 && flag_unsafe_math_optimizations"
21020 rtx op0 = gen_reg_rtx (XFmode);
21021 rtx op1 = gen_reg_rtx (XFmode);
21023 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21024 emit_insn (gen_acoshxf2 (op0, op1));
21025 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21029 (define_expand "atanhxf2"
21030 [(use (match_operand:XF 0 "register_operand"))
21031 (use (match_operand:XF 1 "register_operand"))]
21032 "TARGET_USE_FANCY_MATH_387
21033 && flag_unsafe_math_optimizations"
21035 ix86_emit_i387_atanh (operands[0], operands[1]);
21039 (define_expand "atanh<mode>2"
21040 [(use (match_operand:MODEF 0 "register_operand"))
21041 (use (match_operand:MODEF 1 "general_operand"))]
21042 "TARGET_USE_FANCY_MATH_387
21043 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21044 || TARGET_MIX_SSE_I387)
21045 && flag_unsafe_math_optimizations"
21047 rtx op0 = gen_reg_rtx (XFmode);
21048 rtx op1 = gen_reg_rtx (XFmode);
21050 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21051 emit_insn (gen_atanhxf2 (op0, op1));
21052 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21056 (define_insn "fyl2xxf3_i387"
21057 [(set (match_operand:XF 0 "register_operand" "=f")
21058 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
21059 (match_operand:XF 2 "register_operand" "f")]
21061 (clobber (match_scratch:XF 3 "=2"))]
21062 "TARGET_USE_FANCY_MATH_387
21063 && flag_unsafe_math_optimizations"
21065 [(set_attr "type" "fpspc")
21066 (set_attr "znver1_decode" "vector")
21067 (set_attr "mode" "XF")])
21069 (define_expand "logxf2"
21070 [(parallel [(set (match_operand:XF 0 "register_operand")
21071 (unspec:XF [(match_operand:XF 1 "register_operand")
21072 (match_dup 2)] UNSPEC_FYL2X))
21073 (clobber (scratch:XF))])]
21074 "TARGET_USE_FANCY_MATH_387
21075 && flag_unsafe_math_optimizations"
21078 = force_reg (XFmode, standard_80387_constant_rtx (4)); /* fldln2 */
21081 (define_expand "log<mode>2"
21082 [(use (match_operand:MODEF 0 "register_operand"))
21083 (use (match_operand:MODEF 1 "general_operand"))]
21084 "TARGET_USE_FANCY_MATH_387
21085 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21086 || TARGET_MIX_SSE_I387)
21087 && flag_unsafe_math_optimizations"
21089 rtx op0 = gen_reg_rtx (XFmode);
21090 rtx op1 = gen_reg_rtx (XFmode);
21092 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21093 emit_insn (gen_logxf2 (op0, op1));
21094 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21098 (define_expand "log10xf2"
21099 [(parallel [(set (match_operand:XF 0 "register_operand")
21100 (unspec:XF [(match_operand:XF 1 "register_operand")
21101 (match_dup 2)] UNSPEC_FYL2X))
21102 (clobber (scratch:XF))])]
21103 "TARGET_USE_FANCY_MATH_387
21104 && flag_unsafe_math_optimizations"
21107 = force_reg (XFmode, standard_80387_constant_rtx (3)); /* fldlg2 */
21110 (define_expand "log10<mode>2"
21111 [(use (match_operand:MODEF 0 "register_operand"))
21112 (use (match_operand:MODEF 1 "general_operand"))]
21113 "TARGET_USE_FANCY_MATH_387
21114 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21115 || TARGET_MIX_SSE_I387)
21116 && flag_unsafe_math_optimizations"
21118 rtx op0 = gen_reg_rtx (XFmode);
21119 rtx op1 = gen_reg_rtx (XFmode);
21121 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21122 emit_insn (gen_log10xf2 (op0, op1));
21123 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21127 (define_expand "log2xf2"
21128 [(parallel [(set (match_operand:XF 0 "register_operand")
21129 (unspec:XF [(match_operand:XF 1 "register_operand")
21130 (match_dup 2)] UNSPEC_FYL2X))
21131 (clobber (scratch:XF))])]
21132 "TARGET_USE_FANCY_MATH_387
21133 && flag_unsafe_math_optimizations"
21134 "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
21136 (define_expand "log2<mode>2"
21137 [(use (match_operand:MODEF 0 "register_operand"))
21138 (use (match_operand:MODEF 1 "general_operand"))]
21139 "TARGET_USE_FANCY_MATH_387
21140 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21141 || TARGET_MIX_SSE_I387)
21142 && flag_unsafe_math_optimizations"
21144 rtx op0 = gen_reg_rtx (XFmode);
21145 rtx op1 = gen_reg_rtx (XFmode);
21147 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21148 emit_insn (gen_log2xf2 (op0, op1));
21149 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21153 (define_insn "fyl2xp1xf3_i387"
21154 [(set (match_operand:XF 0 "register_operand" "=f")
21155 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
21156 (match_operand:XF 2 "register_operand" "f")]
21158 (clobber (match_scratch:XF 3 "=2"))]
21159 "TARGET_USE_FANCY_MATH_387
21160 && flag_unsafe_math_optimizations"
21162 [(set_attr "type" "fpspc")
21163 (set_attr "znver1_decode" "vector")
21164 (set_attr "mode" "XF")])
21166 (define_expand "log1pxf2"
21167 [(use (match_operand:XF 0 "register_operand"))
21168 (use (match_operand:XF 1 "register_operand"))]
21169 "TARGET_USE_FANCY_MATH_387
21170 && flag_unsafe_math_optimizations"
21172 ix86_emit_i387_log1p (operands[0], operands[1]);
21176 (define_expand "log1p<mode>2"
21177 [(use (match_operand:MODEF 0 "register_operand"))
21178 (use (match_operand:MODEF 1 "general_operand"))]
21179 "TARGET_USE_FANCY_MATH_387
21180 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21181 || TARGET_MIX_SSE_I387)
21182 && flag_unsafe_math_optimizations"
21184 rtx op0 = gen_reg_rtx (XFmode);
21185 rtx op1 = gen_reg_rtx (XFmode);
21187 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21188 emit_insn (gen_log1pxf2 (op0, op1));
21189 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21193 (define_insn "fxtractxf3_i387"
21194 [(set (match_operand:XF 0 "register_operand" "=f")
21195 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
21196 UNSPEC_XTRACT_FRACT))
21197 (set (match_operand:XF 1 "register_operand" "=f")
21198 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
21199 "TARGET_USE_FANCY_MATH_387
21200 && flag_unsafe_math_optimizations"
21202 [(set_attr "type" "fpspc")
21203 (set_attr "znver1_decode" "vector")
21204 (set_attr "mode" "XF")])
21206 (define_expand "logbxf2"
21207 [(parallel [(set (match_dup 2)
21208 (unspec:XF [(match_operand:XF 1 "register_operand")]
21209 UNSPEC_XTRACT_FRACT))
21210 (set (match_operand:XF 0 "register_operand")
21211 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
21212 "TARGET_USE_FANCY_MATH_387
21213 && flag_unsafe_math_optimizations"
21214 "operands[2] = gen_reg_rtx (XFmode);")
21216 (define_expand "logb<mode>2"
21217 [(use (match_operand:MODEF 0 "register_operand"))
21218 (use (match_operand:MODEF 1 "general_operand"))]
21219 "TARGET_USE_FANCY_MATH_387
21220 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21221 || TARGET_MIX_SSE_I387)
21222 && flag_unsafe_math_optimizations"
21224 rtx op0 = gen_reg_rtx (XFmode);
21225 rtx op1 = gen_reg_rtx (XFmode);
21227 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21228 emit_insn (gen_logbxf2 (op0, op1));
21229 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
21233 (define_expand "ilogbxf2"
21234 [(use (match_operand:SI 0 "register_operand"))
21235 (use (match_operand:XF 1 "register_operand"))]
21236 "TARGET_USE_FANCY_MATH_387
21237 && flag_unsafe_math_optimizations"
21241 if (optimize_insn_for_size_p ())
21244 op0 = gen_reg_rtx (XFmode);
21245 op1 = gen_reg_rtx (XFmode);
21247 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
21248 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
21252 (define_expand "ilogb<mode>2"
21253 [(use (match_operand:SI 0 "register_operand"))
21254 (use (match_operand:MODEF 1 "general_operand"))]
21255 "TARGET_USE_FANCY_MATH_387
21256 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21257 || TARGET_MIX_SSE_I387)
21258 && flag_unsafe_math_optimizations"
21262 if (optimize_insn_for_size_p ())
21265 op0 = gen_reg_rtx (XFmode);
21266 op1 = gen_reg_rtx (XFmode);
21267 op2 = gen_reg_rtx (XFmode);
21269 emit_insn (gen_extend<mode>xf2 (op2, operands[1]));
21270 emit_insn (gen_fxtractxf3_i387 (op0, op1, op2));
21271 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
21275 (define_insn "*f2xm1xf2_i387"
21276 [(set (match_operand:XF 0 "register_operand" "=f")
21277 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
21279 "TARGET_USE_FANCY_MATH_387
21280 && flag_unsafe_math_optimizations"
21282 [(set_attr "type" "fpspc")
21283 (set_attr "znver1_decode" "vector")
21284 (set_attr "mode" "XF")])
21286 (define_insn "fscalexf4_i387"
21287 [(set (match_operand:XF 0 "register_operand" "=f")
21288 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
21289 (match_operand:XF 3 "register_operand" "1")]
21290 UNSPEC_FSCALE_FRACT))
21291 (set (match_operand:XF 1 "register_operand" "=f")
21292 (unspec:XF [(match_dup 2) (match_dup 3)]
21293 UNSPEC_FSCALE_EXP))]
21294 "TARGET_USE_FANCY_MATH_387
21295 && flag_unsafe_math_optimizations"
21297 [(set_attr "type" "fpspc")
21298 (set_attr "znver1_decode" "vector")
21299 (set_attr "mode" "XF")])
21301 (define_expand "expNcorexf3"
21302 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
21303 (match_operand:XF 2 "register_operand")))
21304 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
21305 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
21306 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
21307 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
21308 (parallel [(set (match_operand:XF 0 "register_operand")
21309 (unspec:XF [(match_dup 8) (match_dup 4)]
21310 UNSPEC_FSCALE_FRACT))
21312 (unspec:XF [(match_dup 8) (match_dup 4)]
21313 UNSPEC_FSCALE_EXP))])]
21314 "TARGET_USE_FANCY_MATH_387
21315 && flag_unsafe_math_optimizations"
21319 for (i = 3; i < 10; i++)
21320 operands[i] = gen_reg_rtx (XFmode);
21322 emit_move_insn (operands[7], CONST1_RTX (XFmode));
21325 (define_expand "expxf2"
21326 [(use (match_operand:XF 0 "register_operand"))
21327 (use (match_operand:XF 1 "register_operand"))]
21328 "TARGET_USE_FANCY_MATH_387
21329 && flag_unsafe_math_optimizations"
21331 rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (5)); /* fldl2e */
21333 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
21337 (define_expand "exp<mode>2"
21338 [(use (match_operand:MODEF 0 "register_operand"))
21339 (use (match_operand:MODEF 1 "general_operand"))]
21340 "TARGET_USE_FANCY_MATH_387
21341 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21342 || TARGET_MIX_SSE_I387)
21343 && flag_unsafe_math_optimizations"
21345 rtx op0 = gen_reg_rtx (XFmode);
21346 rtx op1 = gen_reg_rtx (XFmode);
21348 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21349 emit_insn (gen_expxf2 (op0, op1));
21350 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21354 (define_expand "exp10xf2"
21355 [(use (match_operand:XF 0 "register_operand"))
21356 (use (match_operand:XF 1 "register_operand"))]
21357 "TARGET_USE_FANCY_MATH_387
21358 && flag_unsafe_math_optimizations"
21360 rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (6)); /* fldl2t */
21362 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
21366 (define_expand "exp10<mode>2"
21367 [(use (match_operand:MODEF 0 "register_operand"))
21368 (use (match_operand:MODEF 1 "general_operand"))]
21369 "TARGET_USE_FANCY_MATH_387
21370 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21371 || TARGET_MIX_SSE_I387)
21372 && flag_unsafe_math_optimizations"
21374 rtx op0 = gen_reg_rtx (XFmode);
21375 rtx op1 = gen_reg_rtx (XFmode);
21377 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21378 emit_insn (gen_exp10xf2 (op0, op1));
21379 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21383 (define_expand "exp2xf2"
21384 [(use (match_operand:XF 0 "register_operand"))
21385 (use (match_operand:XF 1 "register_operand"))]
21386 "TARGET_USE_FANCY_MATH_387
21387 && flag_unsafe_math_optimizations"
21389 rtx op2 = force_reg (XFmode, CONST1_RTX (XFmode));
21391 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
21395 (define_expand "exp2<mode>2"
21396 [(use (match_operand:MODEF 0 "register_operand"))
21397 (use (match_operand:MODEF 1 "general_operand"))]
21398 "TARGET_USE_FANCY_MATH_387
21399 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21400 || TARGET_MIX_SSE_I387)
21401 && flag_unsafe_math_optimizations"
21403 rtx op0 = gen_reg_rtx (XFmode);
21404 rtx op1 = gen_reg_rtx (XFmode);
21406 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21407 emit_insn (gen_exp2xf2 (op0, op1));
21408 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21412 (define_expand "expm1xf2"
21413 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
21415 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
21416 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
21417 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
21418 (parallel [(set (match_dup 7)
21419 (unspec:XF [(match_dup 6) (match_dup 4)]
21420 UNSPEC_FSCALE_FRACT))
21422 (unspec:XF [(match_dup 6) (match_dup 4)]
21423 UNSPEC_FSCALE_EXP))])
21424 (parallel [(set (match_dup 10)
21425 (unspec:XF [(match_dup 9) (match_dup 8)]
21426 UNSPEC_FSCALE_FRACT))
21427 (set (match_dup 11)
21428 (unspec:XF [(match_dup 9) (match_dup 8)]
21429 UNSPEC_FSCALE_EXP))])
21430 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
21431 (set (match_operand:XF 0 "register_operand")
21432 (plus:XF (match_dup 12) (match_dup 7)))]
21433 "TARGET_USE_FANCY_MATH_387
21434 && flag_unsafe_math_optimizations"
21438 for (i = 2; i < 13; i++)
21439 operands[i] = gen_reg_rtx (XFmode);
21441 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
21442 emit_move_insn (operands[9], CONST1_RTX (XFmode));
21445 (define_expand "expm1<mode>2"
21446 [(use (match_operand:MODEF 0 "register_operand"))
21447 (use (match_operand:MODEF 1 "general_operand"))]
21448 "TARGET_USE_FANCY_MATH_387
21449 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21450 || TARGET_MIX_SSE_I387)
21451 && flag_unsafe_math_optimizations"
21453 rtx op0 = gen_reg_rtx (XFmode);
21454 rtx op1 = gen_reg_rtx (XFmode);
21456 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21457 emit_insn (gen_expm1xf2 (op0, op1));
21458 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21462 (define_insn "avx512f_scalef<mode>2"
21463 [(set (match_operand:MODEF 0 "register_operand" "=v")
21465 [(match_operand:MODEF 1 "register_operand" "v")
21466 (match_operand:MODEF 2 "nonimmediate_operand" "vm")]
21469 "vscalef<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
21470 [(set_attr "prefix" "evex")
21471 (set_attr "mode" "<MODE>")])
21473 (define_expand "ldexpxf3"
21474 [(match_operand:XF 0 "register_operand")
21475 (match_operand:XF 1 "register_operand")
21476 (match_operand:SI 2 "register_operand")]
21477 "TARGET_USE_FANCY_MATH_387
21478 && flag_unsafe_math_optimizations"
21480 rtx tmp1 = gen_reg_rtx (XFmode);
21481 rtx tmp2 = gen_reg_rtx (XFmode);
21483 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
21484 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
21485 operands[1], tmp1));
21489 (define_expand "ldexp<mode>3"
21490 [(use (match_operand:MODEF 0 "register_operand"))
21491 (use (match_operand:MODEF 1 "general_operand"))
21492 (use (match_operand:SI 2 "register_operand"))]
21493 "((TARGET_USE_FANCY_MATH_387
21494 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21495 || TARGET_MIX_SSE_I387))
21496 || (TARGET_AVX512F && TARGET_SSE_MATH))
21497 && flag_unsafe_math_optimizations"
21499 /* Prefer avx512f version. */
21500 if (TARGET_AVX512F && TARGET_SSE_MATH)
21502 rtx op2 = gen_reg_rtx (<MODE>mode);
21503 operands[1] = force_reg (<MODE>mode, operands[1]);
21505 emit_insn (gen_floatsi<mode>2 (op2, operands[2]));
21506 emit_insn (gen_avx512f_scalef<mode>2 (operands[0], operands[1], op2));
21510 rtx op0 = gen_reg_rtx (XFmode);
21511 rtx op1 = gen_reg_rtx (XFmode);
21513 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21514 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
21515 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21520 (define_expand "scalbxf3"
21521 [(parallel [(set (match_operand:XF 0 " register_operand")
21522 (unspec:XF [(match_operand:XF 1 "register_operand")
21523 (match_operand:XF 2 "register_operand")]
21524 UNSPEC_FSCALE_FRACT))
21526 (unspec:XF [(match_dup 1) (match_dup 2)]
21527 UNSPEC_FSCALE_EXP))])]
21528 "TARGET_USE_FANCY_MATH_387
21529 && flag_unsafe_math_optimizations"
21530 "operands[3] = gen_reg_rtx (XFmode);")
21532 (define_expand "scalb<mode>3"
21533 [(use (match_operand:MODEF 0 "register_operand"))
21534 (use (match_operand:MODEF 1 "general_operand"))
21535 (use (match_operand:MODEF 2 "general_operand"))]
21536 "TARGET_USE_FANCY_MATH_387
21537 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21538 || TARGET_MIX_SSE_I387)
21539 && flag_unsafe_math_optimizations"
21541 rtx op0 = gen_reg_rtx (XFmode);
21542 rtx op1 = gen_reg_rtx (XFmode);
21543 rtx op2 = gen_reg_rtx (XFmode);
21545 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21546 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
21547 emit_insn (gen_scalbxf3 (op0, op1, op2));
21548 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21552 (define_expand "significandxf2"
21553 [(parallel [(set (match_operand:XF 0 "register_operand")
21554 (unspec:XF [(match_operand:XF 1 "register_operand")]
21555 UNSPEC_XTRACT_FRACT))
21557 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
21558 "TARGET_USE_FANCY_MATH_387
21559 && flag_unsafe_math_optimizations"
21560 "operands[2] = gen_reg_rtx (XFmode);")
21562 (define_expand "significand<mode>2"
21563 [(use (match_operand:MODEF 0 "register_operand"))
21564 (use (match_operand:MODEF 1 "general_operand"))]
21565 "TARGET_USE_FANCY_MATH_387
21566 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21567 || TARGET_MIX_SSE_I387)
21568 && flag_unsafe_math_optimizations"
21570 rtx op0 = gen_reg_rtx (XFmode);
21571 rtx op1 = gen_reg_rtx (XFmode);
21573 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21574 emit_insn (gen_significandxf2 (op0, op1));
21575 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21580 (define_insn "sse4_1_round<mode>2"
21581 [(set (match_operand:MODEFH 0 "register_operand" "=x,x,x,v,v")
21583 [(match_operand:MODEFH 1 "nonimmediate_operand" "0,x,m,v,m")
21584 (match_operand:SI 2 "const_0_to_15_operand")]
21588 %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
21589 %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
21590 %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
21591 vrndscale<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
21592 vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
21593 [(set_attr "type" "ssecvt")
21594 (set_attr "prefix_extra" "1,1,1,*,*")
21595 (set_attr "length_immediate" "*,*,*,1,1")
21596 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,evex,evex")
21597 (set_attr "isa" "noavx512f,noavx512f,noavx512f,avx512f,avx512f")
21598 (set_attr "avx_partial_xmm_update" "false,false,true,false,true")
21599 (set_attr "mode" "<MODE>")
21600 (set (attr "preferred_for_speed")
21601 (cond [(match_test "TARGET_AVX")
21602 (symbol_ref "true")
21603 (eq_attr "alternative" "1,2")
21604 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
21606 (symbol_ref "true")))])
21608 (define_insn "rintxf2"
21609 [(set (match_operand:XF 0 "register_operand" "=f")
21610 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
21612 "TARGET_USE_FANCY_MATH_387"
21614 [(set_attr "type" "fpspc")
21615 (set_attr "znver1_decode" "vector")
21616 (set_attr "mode" "XF")])
21618 (define_expand "rinthf2"
21619 [(match_operand:HF 0 "register_operand")
21620 (match_operand:HF 1 "nonimmediate_operand")]
21621 "TARGET_AVX512FP16"
21623 emit_insn (gen_sse4_1_roundhf2 (operands[0],
21625 GEN_INT (ROUND_MXCSR)));
21629 (define_expand "rint<mode>2"
21630 [(use (match_operand:MODEF 0 "register_operand"))
21631 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
21632 "TARGET_USE_FANCY_MATH_387
21633 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
21635 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21638 emit_insn (gen_sse4_1_round<mode>2
21639 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
21641 ix86_expand_rint (operands[0], operands[1]);
21645 rtx op0 = gen_reg_rtx (XFmode);
21646 rtx op1 = gen_reg_rtx (XFmode);
21648 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21649 emit_insn (gen_rintxf2 (op0, op1));
21650 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
21655 (define_expand "nearbyintxf2"
21656 [(set (match_operand:XF 0 "register_operand")
21657 (unspec:XF [(match_operand:XF 1 "register_operand")]
21659 "TARGET_USE_FANCY_MATH_387
21660 && !flag_trapping_math")
21662 (define_expand "nearbyinthf2"
21663 [(match_operand:HF 0 "register_operand")
21664 (match_operand:HF 1 "nonimmediate_operand")]
21665 "TARGET_AVX512FP16"
21667 emit_insn (gen_sse4_1_roundhf2 (operands[0],
21669 GEN_INT (ROUND_MXCSR | ROUND_NO_EXC)));
21673 (define_expand "nearbyint<mode>2"
21674 [(use (match_operand:MODEF 0 "register_operand"))
21675 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
21676 "(TARGET_USE_FANCY_MATH_387
21677 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21678 || TARGET_MIX_SSE_I387)
21679 && !flag_trapping_math)
21680 || (TARGET_SSE4_1 && TARGET_SSE_MATH)"
21682 if (TARGET_SSE4_1 && TARGET_SSE_MATH)
21683 emit_insn (gen_sse4_1_round<mode>2
21684 (operands[0], operands[1], GEN_INT (ROUND_MXCSR
21688 rtx op0 = gen_reg_rtx (XFmode);
21689 rtx op1 = gen_reg_rtx (XFmode);
21691 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21692 emit_insn (gen_nearbyintxf2 (op0, op1));
21693 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
21698 (define_expand "round<mode>2"
21699 [(match_operand:X87MODEF 0 "register_operand")
21700 (match_operand:X87MODEF 1 "nonimmediate_operand")]
21701 "(TARGET_USE_FANCY_MATH_387
21702 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21703 || TARGET_MIX_SSE_I387)
21704 && flag_unsafe_math_optimizations
21705 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
21706 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
21707 && !flag_trapping_math && !flag_rounding_math)"
21709 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
21710 && !flag_trapping_math && !flag_rounding_math)
21714 operands[1] = force_reg (<MODE>mode, operands[1]);
21715 ix86_expand_round_sse4 (operands[0], operands[1]);
21717 else if (TARGET_64BIT || (<MODE>mode != DFmode))
21718 ix86_expand_round (operands[0], operands[1]);
21720 ix86_expand_rounddf_32 (operands[0], operands[1]);
21724 operands[1] = force_reg (<MODE>mode, operands[1]);
21725 ix86_emit_i387_round (operands[0], operands[1]);
21730 (define_insn "lrintxfdi2"
21731 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
21732 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
21734 (clobber (match_scratch:XF 2 "=&f"))]
21735 "TARGET_USE_FANCY_MATH_387"
21736 "* return output_fix_trunc (insn, operands, false);"
21737 [(set_attr "type" "fpspc")
21738 (set_attr "mode" "DI")])
21740 (define_insn "lrintxf<mode>2"
21741 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
21742 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
21744 "TARGET_USE_FANCY_MATH_387"
21745 "* return output_fix_trunc (insn, operands, false);"
21746 [(set_attr "type" "fpspc")
21747 (set_attr "mode" "<MODE>")])
21749 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
21750 [(set (match_operand:SWI48 0 "register_operand")
21751 (unspec:SWI48 [(match_operand:MODEF 1 "nonimmediate_operand")]
21752 UNSPEC_FIX_NOTRUNC))]
21753 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
21755 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
21756 [(match_operand:SWI248x 0 "nonimmediate_operand")
21757 (match_operand:X87MODEF 1 "register_operand")]
21758 "(TARGET_USE_FANCY_MATH_387
21759 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
21760 || TARGET_MIX_SSE_I387)
21761 && flag_unsafe_math_optimizations)
21762 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
21763 && <SWI248x:MODE>mode != HImode
21764 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
21765 && !flag_trapping_math && !flag_rounding_math)"
21767 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
21768 && <SWI248x:MODE>mode != HImode
21769 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
21770 && !flag_trapping_math && !flag_rounding_math)
21771 ix86_expand_lround (operands[0], operands[1]);
21773 ix86_emit_i387_round (operands[0], operands[1]);
21777 (define_int_iterator FRNDINT_ROUNDING
21778 [UNSPEC_FRNDINT_ROUNDEVEN
21779 UNSPEC_FRNDINT_FLOOR
21780 UNSPEC_FRNDINT_CEIL
21781 UNSPEC_FRNDINT_TRUNC])
21783 (define_int_iterator FIST_ROUNDING
21787 ;; Base name for define_insn
21788 (define_int_attr rounding_insn
21789 [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven")
21790 (UNSPEC_FRNDINT_FLOOR "floor")
21791 (UNSPEC_FRNDINT_CEIL "ceil")
21792 (UNSPEC_FRNDINT_TRUNC "btrunc")
21793 (UNSPEC_FIST_FLOOR "floor")
21794 (UNSPEC_FIST_CEIL "ceil")])
21796 (define_int_attr rounding
21797 [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven")
21798 (UNSPEC_FRNDINT_FLOOR "floor")
21799 (UNSPEC_FRNDINT_CEIL "ceil")
21800 (UNSPEC_FRNDINT_TRUNC "trunc")
21801 (UNSPEC_FIST_FLOOR "floor")
21802 (UNSPEC_FIST_CEIL "ceil")])
21804 (define_int_attr ROUNDING
21805 [(UNSPEC_FRNDINT_ROUNDEVEN "ROUNDEVEN")
21806 (UNSPEC_FRNDINT_FLOOR "FLOOR")
21807 (UNSPEC_FRNDINT_CEIL "CEIL")
21808 (UNSPEC_FRNDINT_TRUNC "TRUNC")
21809 (UNSPEC_FIST_FLOOR "FLOOR")
21810 (UNSPEC_FIST_CEIL "CEIL")])
21812 ;; Rounding mode control word calculation could clobber FLAGS_REG.
21813 (define_insn_and_split "frndintxf2_<rounding>"
21814 [(set (match_operand:XF 0 "register_operand")
21815 (unspec:XF [(match_operand:XF 1 "register_operand")]
21817 (clobber (reg:CC FLAGS_REG))]
21818 "TARGET_USE_FANCY_MATH_387
21819 && (flag_fp_int_builtin_inexact || !flag_trapping_math)
21820 && ix86_pre_reload_split ()"
21825 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
21827 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
21828 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
21830 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
21831 operands[2], operands[3]));
21834 [(set_attr "type" "frndint")
21835 (set_attr "i387_cw" "<rounding>")
21836 (set_attr "mode" "XF")])
21838 (define_insn "frndintxf2_<rounding>_i387"
21839 [(set (match_operand:XF 0 "register_operand" "=f")
21840 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
21842 (use (match_operand:HI 2 "memory_operand" "m"))
21843 (use (match_operand:HI 3 "memory_operand" "m"))]
21844 "TARGET_USE_FANCY_MATH_387
21845 && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
21846 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
21847 [(set_attr "type" "frndint")
21848 (set_attr "i387_cw" "<rounding>")
21849 (set_attr "mode" "XF")])
21851 (define_expand "<rounding_insn>xf2"
21852 [(parallel [(set (match_operand:XF 0 "register_operand")
21853 (unspec:XF [(match_operand:XF 1 "register_operand")]
21855 (clobber (reg:CC FLAGS_REG))])]
21856 "TARGET_USE_FANCY_MATH_387
21857 && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
21859 (define_expand "<rounding_insn>hf2"
21860 [(parallel [(set (match_operand:HF 0 "register_operand")
21861 (unspec:HF [(match_operand:HF 1 "register_operand")]
21863 (clobber (reg:CC FLAGS_REG))])]
21864 "TARGET_AVX512FP16"
21866 emit_insn (gen_sse4_1_roundhf2 (operands[0], operands[1],
21867 GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
21871 (define_expand "<rounding_insn><mode>2"
21872 [(parallel [(set (match_operand:MODEF 0 "register_operand")
21873 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
21875 (clobber (reg:CC FLAGS_REG))])]
21876 "(TARGET_USE_FANCY_MATH_387
21877 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21878 || TARGET_MIX_SSE_I387)
21879 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
21880 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
21882 || (ROUND_<ROUNDING> != ROUND_ROUNDEVEN
21883 && (flag_fp_int_builtin_inexact || !flag_trapping_math))))"
21885 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
21887 || (ROUND_<ROUNDING> != ROUND_ROUNDEVEN
21888 && (flag_fp_int_builtin_inexact || !flag_trapping_math))))
21891 emit_insn (gen_sse4_1_round<mode>2
21892 (operands[0], operands[1],
21893 GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
21894 else if (TARGET_64BIT || (<MODE>mode != DFmode))
21896 if (ROUND_<ROUNDING> == ROUND_FLOOR)
21897 ix86_expand_floorceil (operands[0], operands[1], true);
21898 else if (ROUND_<ROUNDING> == ROUND_CEIL)
21899 ix86_expand_floorceil (operands[0], operands[1], false);
21900 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
21901 ix86_expand_trunc (operands[0], operands[1]);
21903 gcc_unreachable ();
21907 if (ROUND_<ROUNDING> == ROUND_FLOOR)
21908 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
21909 else if (ROUND_<ROUNDING> == ROUND_CEIL)
21910 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
21911 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
21912 ix86_expand_truncdf_32 (operands[0], operands[1]);
21914 gcc_unreachable ();
21919 rtx op0 = gen_reg_rtx (XFmode);
21920 rtx op1 = gen_reg_rtx (XFmode);
21922 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21923 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
21924 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
21929 ;; Rounding mode control word calculation could clobber FLAGS_REG.
21930 (define_insn_and_split "*fist<mode>2_<rounding>_1"
21931 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
21932 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
21934 (clobber (reg:CC FLAGS_REG))]
21935 "TARGET_USE_FANCY_MATH_387
21936 && flag_unsafe_math_optimizations
21937 && ix86_pre_reload_split ()"
21942 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
21944 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
21945 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
21947 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
21948 operands[2], operands[3]));
21951 [(set_attr "type" "fistp")
21952 (set_attr "i387_cw" "<rounding>")
21953 (set_attr "mode" "<MODE>")])
21955 (define_insn "fistdi2_<rounding>"
21956 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
21957 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
21959 (use (match_operand:HI 2 "memory_operand" "m"))
21960 (use (match_operand:HI 3 "memory_operand" "m"))
21961 (clobber (match_scratch:XF 4 "=&f"))]
21962 "TARGET_USE_FANCY_MATH_387
21963 && flag_unsafe_math_optimizations"
21964 "* return output_fix_trunc (insn, operands, false);"
21965 [(set_attr "type" "fistp")
21966 (set_attr "i387_cw" "<rounding>")
21967 (set_attr "mode" "DI")])
21969 (define_insn "fist<mode>2_<rounding>"
21970 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
21971 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
21973 (use (match_operand:HI 2 "memory_operand" "m"))
21974 (use (match_operand:HI 3 "memory_operand" "m"))]
21975 "TARGET_USE_FANCY_MATH_387
21976 && flag_unsafe_math_optimizations"
21977 "* return output_fix_trunc (insn, operands, false);"
21978 [(set_attr "type" "fistp")
21979 (set_attr "i387_cw" "<rounding>")
21980 (set_attr "mode" "<MODE>")])
21982 (define_expand "l<rounding_insn>xf<mode>2"
21983 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
21984 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
21986 (clobber (reg:CC FLAGS_REG))])]
21987 "TARGET_USE_FANCY_MATH_387
21988 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
21989 && flag_unsafe_math_optimizations")
21991 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
21992 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
21993 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
21995 (clobber (reg:CC FLAGS_REG))])]
21996 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
21997 && (TARGET_SSE4_1 || !flag_trapping_math)"
22001 rtx tmp = gen_reg_rtx (<MODEF:MODE>mode);
22003 emit_insn (gen_sse4_1_round<MODEF:mode>2
22004 (tmp, operands[1], GEN_INT (ROUND_<ROUNDING>
22006 emit_insn (gen_fix_trunc<MODEF:mode><SWI48:mode>2
22007 (operands[0], tmp));
22009 else if (ROUND_<ROUNDING> == ROUND_FLOOR)
22010 ix86_expand_lfloorceil (operands[0], operands[1], true);
22011 else if (ROUND_<ROUNDING> == ROUND_CEIL)
22012 ix86_expand_lfloorceil (operands[0], operands[1], false);
22014 gcc_unreachable ();
22019 (define_insn "fxam<mode>2_i387"
22020 [(set (match_operand:HI 0 "register_operand" "=a")
22022 [(match_operand:X87MODEF 1 "register_operand" "f")]
22024 "TARGET_USE_FANCY_MATH_387"
22025 "fxam\n\tfnstsw\t%0"
22026 [(set_attr "type" "multi")
22027 (set_attr "length" "4")
22028 (set_attr "unit" "i387")
22029 (set_attr "mode" "<MODE>")])
22031 (define_expand "signbittf2"
22032 [(use (match_operand:SI 0 "register_operand"))
22033 (use (match_operand:TF 1 "register_operand"))]
22038 rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
22039 rtx scratch = gen_reg_rtx (QImode);
22041 emit_insn (gen_ptesttf2 (operands[1], mask));
22042 ix86_expand_setcc (scratch, NE,
22043 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
22045 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
22049 emit_insn (gen_sse_movmskps (operands[0],
22050 gen_lowpart (V4SFmode, operands[1])));
22051 emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8)));
22056 (define_expand "signbitxf2"
22057 [(use (match_operand:SI 0 "register_operand"))
22058 (use (match_operand:XF 1 "register_operand"))]
22059 "TARGET_USE_FANCY_MATH_387"
22061 rtx scratch = gen_reg_rtx (HImode);
22063 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
22064 emit_insn (gen_andsi3 (operands[0],
22065 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
22069 (define_insn "movmsk_df"
22070 [(set (match_operand:SI 0 "register_operand" "=r")
22072 [(match_operand:DF 1 "register_operand" "x")]
22074 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
22075 "%vmovmskpd\t{%1, %0|%0, %1}"
22076 [(set_attr "type" "ssemov")
22077 (set_attr "prefix" "maybe_vex")
22078 (set_attr "mode" "DF")])
22080 ;; Use movmskpd in SSE mode to avoid store forwarding stall
22081 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
22082 (define_expand "signbitdf2"
22083 [(use (match_operand:SI 0 "register_operand"))
22084 (use (match_operand:DF 1 "register_operand"))]
22085 "TARGET_USE_FANCY_MATH_387
22086 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
22088 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
22090 emit_insn (gen_movmsk_df (operands[0], operands[1]));
22091 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
22095 rtx scratch = gen_reg_rtx (HImode);
22097 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
22098 emit_insn (gen_andsi3 (operands[0],
22099 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
22104 (define_expand "signbitsf2"
22105 [(use (match_operand:SI 0 "register_operand"))
22106 (use (match_operand:SF 1 "register_operand"))]
22107 "TARGET_USE_FANCY_MATH_387
22108 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
22110 rtx scratch = gen_reg_rtx (HImode);
22112 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
22113 emit_insn (gen_andsi3 (operands[0],
22114 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
22118 ;; Block operation instructions
22121 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
22124 [(set_attr "length" "1")
22125 (set_attr "length_immediate" "0")
22126 (set_attr "modrm" "0")])
22128 (define_expand "cpymem<mode>"
22129 [(use (match_operand:BLK 0 "memory_operand"))
22130 (use (match_operand:BLK 1 "memory_operand"))
22131 (use (match_operand:SWI48 2 "nonmemory_operand"))
22132 (use (match_operand:SWI48 3 "const_int_operand"))
22133 (use (match_operand:SI 4 "const_int_operand"))
22134 (use (match_operand:SI 5 "const_int_operand"))
22135 (use (match_operand:SI 6 ""))
22136 (use (match_operand:SI 7 ""))
22137 (use (match_operand:SI 8 ""))]
22140 if (ix86_expand_set_or_cpymem (operands[0], operands[1],
22141 operands[2], NULL, operands[3],
22142 operands[4], operands[5],
22143 operands[6], operands[7],
22144 operands[8], false))
22150 ;; Most CPUs don't like single string operations
22151 ;; Handle this case here to simplify previous expander.
22153 (define_expand "strmov"
22154 [(set (match_dup 4) (match_operand 3 "memory_operand"))
22155 (set (match_operand 1 "memory_operand") (match_dup 4))
22156 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
22157 (clobber (reg:CC FLAGS_REG))])
22158 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
22159 (clobber (reg:CC FLAGS_REG))])]
22162 /* Can't use this for non-default address spaces. */
22163 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
22166 int piece_size = GET_MODE_SIZE (GET_MODE (operands[1]));
22168 /* If .md ever supports :P for Pmode, these can be directly
22169 in the pattern above. */
22170 operands[5] = plus_constant (Pmode, operands[0], piece_size);
22171 operands[6] = plus_constant (Pmode, operands[2], piece_size);
22173 /* Can't use this if the user has appropriated esi or edi. */
22174 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
22175 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
22177 emit_insn (gen_strmov_singleop (operands[0], operands[1],
22178 operands[2], operands[3],
22179 operands[5], operands[6]));
22183 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
22186 (define_expand "strmov_singleop"
22187 [(parallel [(set (match_operand 1 "memory_operand")
22188 (match_operand 3 "memory_operand"))
22189 (set (match_operand 0 "register_operand")
22191 (set (match_operand 2 "register_operand")
22192 (match_operand 5))])]
22196 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22199 (define_insn "*strmovdi_rex_1"
22200 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
22201 (mem:DI (match_operand:P 3 "register_operand" "1")))
22202 (set (match_operand:P 0 "register_operand" "=D")
22203 (plus:P (match_dup 2)
22205 (set (match_operand:P 1 "register_operand" "=S")
22206 (plus:P (match_dup 3)
22209 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22210 && ix86_check_no_addr_space (insn)"
22212 [(set_attr "type" "str")
22213 (set_attr "memory" "both")
22214 (set_attr "mode" "DI")])
22216 (define_insn "*strmovsi_1"
22217 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
22218 (mem:SI (match_operand:P 3 "register_operand" "1")))
22219 (set (match_operand:P 0 "register_operand" "=D")
22220 (plus:P (match_dup 2)
22222 (set (match_operand:P 1 "register_operand" "=S")
22223 (plus:P (match_dup 3)
22225 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22226 && ix86_check_no_addr_space (insn)"
22228 [(set_attr "type" "str")
22229 (set_attr "memory" "both")
22230 (set_attr "mode" "SI")])
22232 (define_insn "*strmovhi_1"
22233 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
22234 (mem:HI (match_operand:P 3 "register_operand" "1")))
22235 (set (match_operand:P 0 "register_operand" "=D")
22236 (plus:P (match_dup 2)
22238 (set (match_operand:P 1 "register_operand" "=S")
22239 (plus:P (match_dup 3)
22241 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22242 && ix86_check_no_addr_space (insn)"
22244 [(set_attr "type" "str")
22245 (set_attr "memory" "both")
22246 (set_attr "mode" "HI")])
22248 (define_insn "*strmovqi_1"
22249 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
22250 (mem:QI (match_operand:P 3 "register_operand" "1")))
22251 (set (match_operand:P 0 "register_operand" "=D")
22252 (plus:P (match_dup 2)
22254 (set (match_operand:P 1 "register_operand" "=S")
22255 (plus:P (match_dup 3)
22257 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22258 && ix86_check_no_addr_space (insn)"
22260 [(set_attr "type" "str")
22261 (set_attr "memory" "both")
22262 (set (attr "prefix_rex")
22264 (match_test "<P:MODE>mode == DImode")
22266 (const_string "*")))
22267 (set_attr "mode" "QI")])
22269 (define_expand "rep_mov"
22270 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
22271 (set (match_operand 0 "register_operand")
22273 (set (match_operand 2 "register_operand")
22275 (set (match_operand 1 "memory_operand")
22276 (match_operand 3 "memory_operand"))
22277 (use (match_dup 4))])]
22281 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22284 (define_insn "*rep_movdi_rex64"
22285 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
22286 (set (match_operand:P 0 "register_operand" "=D")
22287 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
22289 (match_operand:P 3 "register_operand" "0")))
22290 (set (match_operand:P 1 "register_operand" "=S")
22291 (plus:P (ashift:P (match_dup 5) (const_int 3))
22292 (match_operand:P 4 "register_operand" "1")))
22293 (set (mem:BLK (match_dup 3))
22294 (mem:BLK (match_dup 4)))
22295 (use (match_dup 5))]
22297 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22298 && ix86_check_no_addr_space (insn)"
22300 [(set_attr "type" "str")
22301 (set_attr "prefix_rep" "1")
22302 (set_attr "memory" "both")
22303 (set_attr "mode" "DI")])
22305 (define_insn "*rep_movsi"
22306 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
22307 (set (match_operand:P 0 "register_operand" "=D")
22308 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
22310 (match_operand:P 3 "register_operand" "0")))
22311 (set (match_operand:P 1 "register_operand" "=S")
22312 (plus:P (ashift:P (match_dup 5) (const_int 2))
22313 (match_operand:P 4 "register_operand" "1")))
22314 (set (mem:BLK (match_dup 3))
22315 (mem:BLK (match_dup 4)))
22316 (use (match_dup 5))]
22317 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22318 && ix86_check_no_addr_space (insn)"
22319 "%^rep{%;} movs{l|d}"
22320 [(set_attr "type" "str")
22321 (set_attr "prefix_rep" "1")
22322 (set_attr "memory" "both")
22323 (set_attr "mode" "SI")])
22325 (define_insn "*rep_movqi"
22326 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
22327 (set (match_operand:P 0 "register_operand" "=D")
22328 (plus:P (match_operand:P 3 "register_operand" "0")
22329 (match_operand:P 5 "register_operand" "2")))
22330 (set (match_operand:P 1 "register_operand" "=S")
22331 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
22332 (set (mem:BLK (match_dup 3))
22333 (mem:BLK (match_dup 4)))
22334 (use (match_dup 5))]
22335 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22336 && ix86_check_no_addr_space (insn)"
22338 [(set_attr "type" "str")
22339 (set_attr "prefix_rep" "1")
22340 (set_attr "memory" "both")
22341 (set_attr "mode" "QI")])
22343 (define_expand "setmem<mode>"
22344 [(use (match_operand:BLK 0 "memory_operand"))
22345 (use (match_operand:SWI48 1 "nonmemory_operand"))
22346 (use (match_operand:QI 2 "nonmemory_operand"))
22347 (use (match_operand 3 "const_int_operand"))
22348 (use (match_operand:SI 4 "const_int_operand"))
22349 (use (match_operand:SI 5 "const_int_operand"))
22350 (use (match_operand:SI 6 ""))
22351 (use (match_operand:SI 7 ""))
22352 (use (match_operand:SI 8 ""))]
22355 if (ix86_expand_set_or_cpymem (operands[0], NULL,
22356 operands[1], operands[2],
22357 operands[3], operands[4],
22358 operands[5], operands[6],
22359 operands[7], operands[8], true))
22365 ;; Most CPUs don't like single string operations
22366 ;; Handle this case here to simplify previous expander.
22368 (define_expand "strset"
22369 [(set (match_operand 1 "memory_operand")
22370 (match_operand 2 "register_operand"))
22371 (parallel [(set (match_operand 0 "register_operand")
22373 (clobber (reg:CC FLAGS_REG))])]
22376 /* Can't use this for non-default address spaces. */
22377 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
22380 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
22381 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
22383 /* If .md ever supports :P for Pmode, this can be directly
22384 in the pattern above. */
22385 operands[3] = plus_constant (Pmode, operands[0],
22386 GET_MODE_SIZE (GET_MODE (operands[2])));
22388 /* Can't use this if the user has appropriated eax or edi. */
22389 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
22390 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
22392 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
22398 (define_expand "strset_singleop"
22399 [(parallel [(set (match_operand 1 "memory_operand")
22400 (match_operand 2 "register_operand"))
22401 (set (match_operand 0 "register_operand")
22403 (unspec [(const_int 0)] UNSPEC_STOS)])]
22407 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22410 (define_insn "*strsetdi_rex_1"
22411 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
22412 (match_operand:DI 2 "register_operand" "a"))
22413 (set (match_operand:P 0 "register_operand" "=D")
22414 (plus:P (match_dup 1)
22416 (unspec [(const_int 0)] UNSPEC_STOS)]
22418 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22419 && ix86_check_no_addr_space (insn)"
22421 [(set_attr "type" "str")
22422 (set_attr "memory" "store")
22423 (set_attr "mode" "DI")])
22425 (define_insn "*strsetsi_1"
22426 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
22427 (match_operand:SI 2 "register_operand" "a"))
22428 (set (match_operand:P 0 "register_operand" "=D")
22429 (plus:P (match_dup 1)
22431 (unspec [(const_int 0)] UNSPEC_STOS)]
22432 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22433 && ix86_check_no_addr_space (insn)"
22435 [(set_attr "type" "str")
22436 (set_attr "memory" "store")
22437 (set_attr "mode" "SI")])
22439 (define_insn "*strsethi_1"
22440 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
22441 (match_operand:HI 2 "register_operand" "a"))
22442 (set (match_operand:P 0 "register_operand" "=D")
22443 (plus:P (match_dup 1)
22445 (unspec [(const_int 0)] UNSPEC_STOS)]
22446 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22447 && ix86_check_no_addr_space (insn)"
22449 [(set_attr "type" "str")
22450 (set_attr "memory" "store")
22451 (set_attr "mode" "HI")])
22453 (define_insn "*strsetqi_1"
22454 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
22455 (match_operand:QI 2 "register_operand" "a"))
22456 (set (match_operand:P 0 "register_operand" "=D")
22457 (plus:P (match_dup 1)
22459 (unspec [(const_int 0)] UNSPEC_STOS)]
22460 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22461 && ix86_check_no_addr_space (insn)"
22463 [(set_attr "type" "str")
22464 (set_attr "memory" "store")
22465 (set (attr "prefix_rex")
22467 (match_test "<P:MODE>mode == DImode")
22469 (const_string "*")))
22470 (set_attr "mode" "QI")])
22472 (define_expand "rep_stos"
22473 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
22474 (set (match_operand 0 "register_operand")
22476 (set (match_operand 2 "memory_operand") (const_int 0))
22477 (use (match_operand 3 "register_operand"))
22478 (use (match_dup 1))])]
22482 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22485 (define_insn "*rep_stosdi_rex64"
22486 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
22487 (set (match_operand:P 0 "register_operand" "=D")
22488 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
22490 (match_operand:P 3 "register_operand" "0")))
22491 (set (mem:BLK (match_dup 3))
22493 (use (match_operand:DI 2 "register_operand" "a"))
22494 (use (match_dup 4))]
22496 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
22497 && ix86_check_no_addr_space (insn)"
22499 [(set_attr "type" "str")
22500 (set_attr "prefix_rep" "1")
22501 (set_attr "memory" "store")
22502 (set_attr "mode" "DI")])
22504 (define_insn "*rep_stossi"
22505 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
22506 (set (match_operand:P 0 "register_operand" "=D")
22507 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
22509 (match_operand:P 3 "register_operand" "0")))
22510 (set (mem:BLK (match_dup 3))
22512 (use (match_operand:SI 2 "register_operand" "a"))
22513 (use (match_dup 4))]
22514 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
22515 && ix86_check_no_addr_space (insn)"
22516 "%^rep{%;} stos{l|d}"
22517 [(set_attr "type" "str")
22518 (set_attr "prefix_rep" "1")
22519 (set_attr "memory" "store")
22520 (set_attr "mode" "SI")])
22522 (define_insn "*rep_stosqi"
22523 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
22524 (set (match_operand:P 0 "register_operand" "=D")
22525 (plus:P (match_operand:P 3 "register_operand" "0")
22526 (match_operand:P 4 "register_operand" "1")))
22527 (set (mem:BLK (match_dup 3))
22529 (use (match_operand:QI 2 "register_operand" "a"))
22530 (use (match_dup 4))]
22531 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
22532 && ix86_check_no_addr_space (insn)"
22534 [(set_attr "type" "str")
22535 (set_attr "prefix_rep" "1")
22536 (set_attr "memory" "store")
22537 (set (attr "prefix_rex")
22539 (match_test "<P:MODE>mode == DImode")
22541 (const_string "*")))
22542 (set_attr "mode" "QI")])
22544 (define_expand "cmpmemsi"
22545 [(set (match_operand:SI 0 "register_operand" "")
22546 (compare:SI (match_operand:BLK 1 "memory_operand" "")
22547 (match_operand:BLK 2 "memory_operand" "") ) )
22548 (use (match_operand 3 "general_operand"))
22549 (use (match_operand 4 "immediate_operand"))]
22552 if (ix86_expand_cmpstrn_or_cmpmem (operands[0], operands[1],
22553 operands[2], operands[3],
22554 operands[4], false))
22560 (define_expand "cmpstrnsi"
22561 [(set (match_operand:SI 0 "register_operand")
22562 (compare:SI (match_operand:BLK 1 "general_operand")
22563 (match_operand:BLK 2 "general_operand")))
22564 (use (match_operand 3 "general_operand"))
22565 (use (match_operand 4 "immediate_operand"))]
22568 if (ix86_expand_cmpstrn_or_cmpmem (operands[0], operands[1],
22569 operands[2], operands[3],
22570 operands[4], true))
22576 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
22578 (define_expand "cmpintqi"
22579 [(set (match_dup 1)
22580 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
22582 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
22583 (parallel [(set (match_operand:QI 0 "register_operand")
22584 (minus:QI (match_dup 1)
22586 (clobber (reg:CC FLAGS_REG))])]
22589 operands[1] = gen_reg_rtx (QImode);
22590 operands[2] = gen_reg_rtx (QImode);
22593 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
22594 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
22596 (define_expand "cmpstrnqi_nz_1"
22597 [(parallel [(set (reg:CC FLAGS_REG)
22598 (compare:CC (match_operand 4 "memory_operand")
22599 (match_operand 5 "memory_operand")))
22600 (use (match_operand 2 "register_operand"))
22601 (use (match_operand:SI 3 "immediate_operand"))
22602 (clobber (match_operand 0 "register_operand"))
22603 (clobber (match_operand 1 "register_operand"))
22604 (clobber (match_dup 2))])]
22608 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22611 (define_insn "*cmpstrnqi_nz_1"
22612 [(set (reg:CC FLAGS_REG)
22613 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
22614 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
22615 (use (match_operand:P 6 "register_operand" "2"))
22616 (use (match_operand:SI 3 "immediate_operand" "i"))
22617 (clobber (match_operand:P 0 "register_operand" "=S"))
22618 (clobber (match_operand:P 1 "register_operand" "=D"))
22619 (clobber (match_operand:P 2 "register_operand" "=c"))]
22620 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22621 && ix86_check_no_addr_space (insn)"
22623 [(set_attr "type" "str")
22624 (set_attr "mode" "QI")
22625 (set (attr "prefix_rex")
22627 (match_test "<P:MODE>mode == DImode")
22629 (const_string "*")))
22630 (set_attr "prefix_rep" "1")])
22632 ;; The same, but the count is not known to not be zero.
22634 (define_expand "cmpstrnqi_1"
22635 [(parallel [(set (reg:CC FLAGS_REG)
22636 (if_then_else:CC (ne (match_operand 2 "register_operand")
22638 (compare:CC (match_operand 4 "memory_operand")
22639 (match_operand 5 "memory_operand"))
22641 (use (match_operand:SI 3 "immediate_operand"))
22642 (use (reg:CC FLAGS_REG))
22643 (clobber (match_operand 0 "register_operand"))
22644 (clobber (match_operand 1 "register_operand"))
22645 (clobber (match_dup 2))])]
22649 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22652 (define_insn "*cmpstrnqi_1"
22653 [(set (reg:CC FLAGS_REG)
22654 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
22656 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
22657 (mem:BLK (match_operand:P 5 "register_operand" "1")))
22659 (use (match_operand:SI 3 "immediate_operand" "i"))
22660 (use (reg:CC FLAGS_REG))
22661 (clobber (match_operand:P 0 "register_operand" "=S"))
22662 (clobber (match_operand:P 1 "register_operand" "=D"))
22663 (clobber (match_operand:P 2 "register_operand" "=c"))]
22664 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22665 && ix86_check_no_addr_space (insn)"
22667 [(set_attr "type" "str")
22668 (set_attr "mode" "QI")
22669 (set (attr "prefix_rex")
22671 (match_test "<P:MODE>mode == DImode")
22673 (const_string "*")))
22674 (set_attr "prefix_rep" "1")])
22676 (define_expand "strlen<mode>"
22677 [(set (match_operand:P 0 "register_operand")
22678 (unspec:P [(match_operand:BLK 1 "general_operand")
22679 (match_operand:QI 2 "immediate_operand")
22680 (match_operand 3 "immediate_operand")]
22684 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
22690 (define_expand "strlenqi_1"
22691 [(parallel [(set (match_operand 0 "register_operand")
22693 (clobber (match_operand 1 "register_operand"))
22694 (clobber (reg:CC FLAGS_REG))])]
22698 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22701 (define_insn "*strlenqi_1"
22702 [(set (match_operand:P 0 "register_operand" "=&c")
22703 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
22704 (match_operand:QI 2 "register_operand" "a")
22705 (match_operand:P 3 "immediate_operand" "i")
22706 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
22707 (clobber (match_operand:P 1 "register_operand" "=D"))
22708 (clobber (reg:CC FLAGS_REG))]
22709 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
22710 && ix86_check_no_addr_space (insn)"
22711 "%^repnz{%;} scasb"
22712 [(set_attr "type" "str")
22713 (set_attr "mode" "QI")
22714 (set (attr "prefix_rex")
22716 (match_test "<P:MODE>mode == DImode")
22718 (const_string "*")))
22719 (set_attr "prefix_rep" "1")])
22721 ;; Peephole optimizations to clean up after cmpstrn*. This should be
22722 ;; handled in combine, but it is not currently up to the task.
22723 ;; When used for their truth value, the cmpstrn* expanders generate
22732 ;; The intermediate three instructions are unnecessary.
22734 ;; This one handles cmpstrn*_nz_1...
22737 (set (reg:CC FLAGS_REG)
22738 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
22739 (mem:BLK (match_operand 5 "register_operand"))))
22740 (use (match_operand 6 "register_operand"))
22741 (use (match_operand:SI 3 "immediate_operand"))
22742 (clobber (match_operand 0 "register_operand"))
22743 (clobber (match_operand 1 "register_operand"))
22744 (clobber (match_operand 2 "register_operand"))])
22745 (set (match_operand:QI 7 "register_operand")
22746 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
22747 (set (match_operand:QI 8 "register_operand")
22748 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
22749 (set (reg FLAGS_REG)
22750 (compare (match_dup 7) (match_dup 8)))
22752 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
22754 (set (reg:CC FLAGS_REG)
22755 (compare:CC (mem:BLK (match_dup 4))
22756 (mem:BLK (match_dup 5))))
22757 (use (match_dup 6))
22758 (use (match_dup 3))
22759 (clobber (match_dup 0))
22760 (clobber (match_dup 1))
22761 (clobber (match_dup 2))])])
22763 ;; ...and this one handles cmpstrn*_1.
22766 (set (reg:CC FLAGS_REG)
22767 (if_then_else:CC (ne (match_operand 6 "register_operand")
22769 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
22770 (mem:BLK (match_operand 5 "register_operand")))
22772 (use (match_operand:SI 3 "immediate_operand"))
22773 (use (reg:CC FLAGS_REG))
22774 (clobber (match_operand 0 "register_operand"))
22775 (clobber (match_operand 1 "register_operand"))
22776 (clobber (match_operand 2 "register_operand"))])
22777 (set (match_operand:QI 7 "register_operand")
22778 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
22779 (set (match_operand:QI 8 "register_operand")
22780 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
22781 (set (reg FLAGS_REG)
22782 (compare (match_dup 7) (match_dup 8)))
22784 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
22786 (set (reg:CC FLAGS_REG)
22787 (if_then_else:CC (ne (match_dup 6)
22789 (compare:CC (mem:BLK (match_dup 4))
22790 (mem:BLK (match_dup 5)))
22792 (use (match_dup 3))
22793 (use (reg:CC FLAGS_REG))
22794 (clobber (match_dup 0))
22795 (clobber (match_dup 1))
22796 (clobber (match_dup 2))])])
22798 ;; Conditional move instructions.
22800 (define_expand "mov<mode>cc"
22801 [(set (match_operand:SWIM 0 "register_operand")
22802 (if_then_else:SWIM (match_operand 1 "comparison_operator")
22803 (match_operand:SWIM 2 "<general_operand>")
22804 (match_operand:SWIM 3 "<general_operand>")))]
22806 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
22808 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
22809 ;; the register first winds up with `sbbl $0,reg', which is also weird.
22810 ;; So just document what we're doing explicitly.
22812 (define_expand "x86_mov<mode>cc_0_m1"
22814 [(set (match_operand:SWI48 0 "register_operand")
22815 (if_then_else:SWI48
22816 (match_operator:SWI48 2 "ix86_carry_flag_operator"
22817 [(match_operand 1 "flags_reg_operand")
22821 (clobber (reg:CC FLAGS_REG))])])
22823 (define_insn "*x86_mov<mode>cc_0_m1"
22824 [(set (match_operand:SWI48 0 "register_operand" "=r")
22825 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
22826 [(reg FLAGS_REG) (const_int 0)])
22829 (clobber (reg:CC FLAGS_REG))]
22831 "sbb{<imodesuffix>}\t%0, %0"
22832 [(set_attr "type" "alu1")
22833 (set_attr "use_carry" "1")
22834 (set_attr "pent_pair" "pu")
22835 (set_attr "mode" "<MODE>")
22836 (set_attr "length_immediate" "0")])
22838 (define_insn "*x86_mov<mode>cc_0_m1_se"
22839 [(set (match_operand:SWI48 0 "register_operand" "=r")
22840 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
22841 [(reg FLAGS_REG) (const_int 0)])
22844 (clobber (reg:CC FLAGS_REG))]
22846 "sbb{<imodesuffix>}\t%0, %0"
22847 [(set_attr "type" "alu1")
22848 (set_attr "use_carry" "1")
22849 (set_attr "pent_pair" "pu")
22850 (set_attr "mode" "<MODE>")
22851 (set_attr "length_immediate" "0")])
22853 (define_insn "*x86_mov<mode>cc_0_m1_neg"
22854 [(set (match_operand:SWI 0 "register_operand" "=<r>")
22855 (neg:SWI (match_operator 1 "ix86_carry_flag_operator"
22856 [(reg FLAGS_REG) (const_int 0)])))
22857 (clobber (reg:CC FLAGS_REG))]
22859 "sbb{<imodesuffix>}\t%0, %0"
22860 [(set_attr "type" "alu1")
22861 (set_attr "use_carry" "1")
22862 (set_attr "pent_pair" "pu")
22863 (set_attr "mode" "<MODE>")
22864 (set_attr "length_immediate" "0")])
22866 (define_expand "x86_mov<mode>cc_0_m1_neg"
22868 [(set (match_operand:SWI48 0 "register_operand")
22869 (neg:SWI48 (ltu:SWI48 (reg:CCC FLAGS_REG) (const_int 0))))
22870 (clobber (reg:CC FLAGS_REG))])])
22873 [(set (match_operand:SWI48 0 "register_operand")
22876 (match_operand 1 "int_nonimmediate_operand")
22877 (match_operand 2 "const_int_operand"))))]
22878 "x86_64_immediate_operand (operands[2], VOIDmode)
22879 && INTVAL (operands[2]) != -1
22880 && INTVAL (operands[2]) != 2147483647"
22881 [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
22883 (neg:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))))]
22884 "operands[2] = GEN_INT (INTVAL (operands[2]) + 1);")
22887 [(set (match_operand:SWI 0 "register_operand")
22890 (match_operand 1 "int_nonimmediate_operand")
22893 [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (const_int 1)))
22895 (neg:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))))])
22898 [(set (match_operand:SWI 0 "register_operand")
22901 (match_operand 1 "int_nonimmediate_operand")
22904 [(set (reg:CCC FLAGS_REG)
22905 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
22907 (neg:SWI (ltu:SWI (reg:CCC FLAGS_REG) (const_int 0))))])
22909 (define_insn "*mov<mode>cc_noc"
22910 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
22911 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
22912 [(reg FLAGS_REG) (const_int 0)])
22913 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
22914 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
22915 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
22917 cmov%O2%C1\t{%2, %0|%0, %2}
22918 cmov%O2%c1\t{%3, %0|%0, %3}"
22919 [(set_attr "type" "icmov")
22920 (set_attr "mode" "<MODE>")])
22922 (define_insn "*movsicc_noc_zext"
22923 [(set (match_operand:DI 0 "register_operand" "=r,r")
22924 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
22925 [(reg FLAGS_REG) (const_int 0)])
22927 (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
22929 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
22931 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
22933 cmov%O2%C1\t{%2, %k0|%k0, %2}
22934 cmov%O2%c1\t{%3, %k0|%k0, %3}"
22935 [(set_attr "type" "icmov")
22936 (set_attr "mode" "SI")])
22938 (define_insn "*movsicc_noc_zext_1"
22939 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r")
22941 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
22942 [(reg FLAGS_REG) (const_int 0)])
22943 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
22944 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
22946 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
22948 cmov%O2%C1\t{%2, %k0|%k0, %2}
22949 cmov%O2%c1\t{%3, %k0|%k0, %3}"
22950 [(set_attr "type" "icmov")
22951 (set_attr "mode" "SI")])
22954 ;; Don't do conditional moves with memory inputs. This splitter helps
22955 ;; register starved x86_32 by forcing inputs into registers before reload.
22957 [(set (match_operand:SWI248 0 "register_operand")
22958 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
22959 [(reg FLAGS_REG) (const_int 0)])
22960 (match_operand:SWI248 2 "nonimmediate_operand")
22961 (match_operand:SWI248 3 "nonimmediate_operand")))]
22962 "!TARGET_64BIT && TARGET_CMOVE
22963 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
22964 && (MEM_P (operands[2]) || MEM_P (operands[3]))
22965 && can_create_pseudo_p ()
22966 && optimize_insn_for_speed_p ()"
22967 [(set (match_dup 0)
22968 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
22970 operands[2] = force_reg (<MODE>mode, operands[2]);
22971 operands[3] = force_reg (<MODE>mode, operands[3]);
22974 (define_insn "*movqicc_noc"
22975 [(set (match_operand:QI 0 "register_operand" "=r,r")
22976 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
22977 [(reg FLAGS_REG) (const_int 0)])
22978 (match_operand:QI 2 "register_operand" "r,0")
22979 (match_operand:QI 3 "register_operand" "0,r")))]
22980 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
22982 [(set_attr "type" "icmov")
22983 (set_attr "mode" "QI")])
22986 [(set (match_operand:SWI12 0 "register_operand")
22987 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
22988 [(reg FLAGS_REG) (const_int 0)])
22989 (match_operand:SWI12 2 "register_operand")
22990 (match_operand:SWI12 3 "register_operand")))]
22991 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
22992 && reload_completed"
22993 [(set (match_dup 0)
22994 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
22996 operands[0] = gen_lowpart (SImode, operands[0]);
22997 operands[2] = gen_lowpart (SImode, operands[2]);
22998 operands[3] = gen_lowpart (SImode, operands[3]);
23001 ;; Don't do conditional moves with memory inputs
23003 [(match_scratch:SWI248 4 "r")
23004 (set (match_operand:SWI248 0 "register_operand")
23005 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
23006 [(reg FLAGS_REG) (const_int 0)])
23007 (match_operand:SWI248 2 "nonimmediate_operand")
23008 (match_operand:SWI248 3 "nonimmediate_operand")))]
23009 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23010 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23011 && optimize_insn_for_speed_p ()"
23012 [(set (match_dup 4) (match_dup 5))
23014 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
23016 if (MEM_P (operands[2]))
23018 operands[5] = operands[2];
23019 operands[2] = operands[4];
23021 else if (MEM_P (operands[3]))
23023 operands[5] = operands[3];
23024 operands[3] = operands[4];
23027 gcc_unreachable ();
23031 [(match_scratch:SI 4 "r")
23032 (set (match_operand:DI 0 "register_operand")
23033 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
23034 [(reg FLAGS_REG) (const_int 0)])
23036 (match_operand:SI 2 "nonimmediate_operand"))
23038 (match_operand:SI 3 "nonimmediate_operand"))))]
23040 && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23041 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23042 && optimize_insn_for_speed_p ()"
23043 [(set (match_dup 4) (match_dup 5))
23045 (if_then_else:DI (match_dup 1)
23046 (zero_extend:DI (match_dup 2))
23047 (zero_extend:DI (match_dup 3))))]
23049 if (MEM_P (operands[2]))
23051 operands[5] = operands[2];
23052 operands[2] = operands[4];
23054 else if (MEM_P (operands[3]))
23056 operands[5] = operands[3];
23057 operands[3] = operands[4];
23060 gcc_unreachable ();
23063 ;; Eliminate a reg-reg mov by inverting the condition of a cmov (#1).
23064 ;; mov r0,r1; dec r0; mov r2,r3; cmov r0,r2 -> dec r1; mov r0,r3; cmov r0, r1
23066 [(set (match_operand:SWI248 0 "general_reg_operand")
23067 (match_operand:SWI248 1 "general_reg_operand"))
23068 (parallel [(set (reg FLAGS_REG) (match_operand 5))
23069 (set (match_dup 0) (match_operand:SWI248 6))])
23070 (set (match_operand:SWI248 2 "general_reg_operand")
23071 (match_operand:SWI248 3 "general_gr_operand"))
23073 (if_then_else:SWI248 (match_operator 4 "ix86_comparison_operator"
23074 [(reg FLAGS_REG) (const_int 0)])
23078 && REGNO (operands[2]) != REGNO (operands[0])
23079 && REGNO (operands[2]) != REGNO (operands[1])
23080 && peep2_reg_dead_p (1, operands[1])
23081 && peep2_reg_dead_p (4, operands[2])
23082 && !reg_overlap_mentioned_p (operands[0], operands[3])"
23083 [(parallel [(set (match_dup 7) (match_dup 8))
23084 (set (match_dup 1) (match_dup 9))])
23085 (set (match_dup 0) (match_dup 3))
23086 (set (match_dup 0) (if_then_else:SWI248 (match_dup 4)
23090 operands[7] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
23092 = ix86_replace_reg_with_reg (operands[5], operands[0], operands[1]);
23094 = ix86_replace_reg_with_reg (operands[6], operands[0], operands[1]);
23097 ;; Eliminate a reg-reg mov by inverting the condition of a cmov (#2).
23098 ;; mov r2,r3; mov r0,r1; dec r0; cmov r0,r2 -> dec r1; mov r0,r3; cmov r0, r1
23100 [(set (match_operand:SWI248 2 "general_reg_operand")
23101 (match_operand:SWI248 3 "general_gr_operand"))
23102 (set (match_operand:SWI248 0 "general_reg_operand")
23103 (match_operand:SWI248 1 "general_reg_operand"))
23104 (parallel [(set (reg FLAGS_REG) (match_operand 5))
23105 (set (match_dup 0) (match_operand:SWI248 6))])
23107 (if_then_else:SWI248 (match_operator 4 "ix86_comparison_operator"
23108 [(reg FLAGS_REG) (const_int 0)])
23112 && REGNO (operands[2]) != REGNO (operands[0])
23113 && REGNO (operands[2]) != REGNO (operands[1])
23114 && peep2_reg_dead_p (2, operands[1])
23115 && peep2_reg_dead_p (4, operands[2])
23116 && !reg_overlap_mentioned_p (operands[0], operands[3])
23117 && !reg_mentioned_p (operands[2], operands[6])"
23118 [(parallel [(set (match_dup 7) (match_dup 8))
23119 (set (match_dup 1) (match_dup 9))])
23120 (set (match_dup 0) (match_dup 3))
23121 (set (match_dup 0) (if_then_else:SWI248 (match_dup 4)
23125 operands[7] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (2)), 0, 0));
23127 = ix86_replace_reg_with_reg (operands[5], operands[0], operands[1]);
23129 = ix86_replace_reg_with_reg (operands[6], operands[0], operands[1]);
23132 (define_insn "movhf_mask"
23133 [(set (match_operand:HF 0 "nonimmediate_operand" "=v,m,v")
23135 [(match_operand:HF 1 "nonimmediate_operand" "m,v,v")
23136 (match_operand:HF 2 "nonimm_or_0_operand" "0C,0C,0C")
23137 (match_operand:QI 3 "register_operand" "Yk,Yk,Yk")]
23138 UNSPEC_MOVCC_MASK))]
23139 "TARGET_AVX512FP16"
23141 vmovsh\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}
23142 vmovsh\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}
23143 vmovsh\t{%d1, %0%{%3%}%N2|%0%{%3%}%N2, %d1}"
23144 [(set_attr "type" "ssemov")
23145 (set_attr "prefix" "evex")
23146 (set_attr "mode" "HF")])
23148 (define_expand "movhfcc"
23149 [(set (match_operand:HF 0 "register_operand")
23151 (match_operand 1 "comparison_operator")
23152 (match_operand:HF 2 "register_operand")
23153 (match_operand:HF 3 "register_operand")))]
23154 "TARGET_AVX512FP16"
23155 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
23157 (define_expand "mov<mode>cc"
23158 [(set (match_operand:X87MODEF 0 "register_operand")
23159 (if_then_else:X87MODEF
23160 (match_operand 1 "comparison_operator")
23161 (match_operand:X87MODEF 2 "register_operand")
23162 (match_operand:X87MODEF 3 "register_operand")))]
23163 "(TARGET_80387 && TARGET_CMOVE)
23164 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
23165 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
23167 (define_insn "*movxfcc_1"
23168 [(set (match_operand:XF 0 "register_operand" "=f,f")
23169 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
23170 [(reg FLAGS_REG) (const_int 0)])
23171 (match_operand:XF 2 "register_operand" "f,0")
23172 (match_operand:XF 3 "register_operand" "0,f")))]
23173 "TARGET_80387 && TARGET_CMOVE"
23175 fcmov%F1\t{%2, %0|%0, %2}
23176 fcmov%f1\t{%3, %0|%0, %3}"
23177 [(set_attr "type" "fcmov")
23178 (set_attr "mode" "XF")])
23180 (define_insn "*movdfcc_1"
23181 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
23182 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
23183 [(reg FLAGS_REG) (const_int 0)])
23184 (match_operand:DF 2 "nonimmediate_operand"
23186 (match_operand:DF 3 "nonimmediate_operand"
23187 "0 ,f,0 ,rm,0, rm")))]
23188 "TARGET_80387 && TARGET_CMOVE
23189 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23191 fcmov%F1\t{%2, %0|%0, %2}
23192 fcmov%f1\t{%3, %0|%0, %3}
23195 cmov%O2%C1\t{%2, %0|%0, %2}
23196 cmov%O2%c1\t{%3, %0|%0, %3}"
23197 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
23198 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
23199 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
23202 [(set (match_operand:DF 0 "general_reg_operand")
23203 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
23204 [(reg FLAGS_REG) (const_int 0)])
23205 (match_operand:DF 2 "nonimmediate_operand")
23206 (match_operand:DF 3 "nonimmediate_operand")))]
23207 "!TARGET_64BIT && reload_completed"
23208 [(set (match_dup 2)
23209 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
23211 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
23213 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
23214 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
23217 (define_insn "*movsfcc_1_387"
23218 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
23219 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
23220 [(reg FLAGS_REG) (const_int 0)])
23221 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
23222 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
23223 "TARGET_80387 && TARGET_CMOVE
23224 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23226 fcmov%F1\t{%2, %0|%0, %2}
23227 fcmov%f1\t{%3, %0|%0, %3}
23228 cmov%O2%C1\t{%2, %0|%0, %2}
23229 cmov%O2%c1\t{%3, %0|%0, %3}"
23230 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
23231 (set_attr "mode" "SF,SF,SI,SI")])
23233 ;; Don't do conditional moves with memory inputs. This splitter helps
23234 ;; register starved x86_32 by forcing inputs into registers before reload.
23236 [(set (match_operand:MODEF 0 "register_operand")
23237 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
23238 [(reg FLAGS_REG) (const_int 0)])
23239 (match_operand:MODEF 2 "nonimmediate_operand")
23240 (match_operand:MODEF 3 "nonimmediate_operand")))]
23241 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
23242 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23243 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23244 && can_create_pseudo_p ()
23245 && optimize_insn_for_speed_p ()"
23246 [(set (match_dup 0)
23247 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
23249 operands[2] = force_reg (<MODE>mode, operands[2]);
23250 operands[3] = force_reg (<MODE>mode, operands[3]);
23253 ;; Don't do conditional moves with memory inputs
23255 [(match_scratch:MODEF 4 "r")
23256 (set (match_operand:MODEF 0 "general_reg_operand")
23257 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
23258 [(reg FLAGS_REG) (const_int 0)])
23259 (match_operand:MODEF 2 "nonimmediate_operand")
23260 (match_operand:MODEF 3 "nonimmediate_operand")))]
23261 "(<MODE>mode != DFmode || TARGET_64BIT)
23262 && TARGET_80387 && TARGET_CMOVE
23263 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23264 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23265 && optimize_insn_for_speed_p ()"
23266 [(set (match_dup 4) (match_dup 5))
23268 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
23270 if (MEM_P (operands[2]))
23272 operands[5] = operands[2];
23273 operands[2] = operands[4];
23275 else if (MEM_P (operands[3]))
23277 operands[5] = operands[3];
23278 operands[3] = operands[4];
23281 gcc_unreachable ();
23284 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
23285 ;; the scalar versions to have only XMM registers as operands.
23287 ;; XOP conditional move
23288 (define_insn "*xop_pcmov_<mode>"
23289 [(set (match_operand:MODEF 0 "register_operand" "=x")
23290 (if_then_else:MODEF
23291 (match_operand:MODEF 1 "register_operand" "x")
23292 (match_operand:MODEF 2 "register_operand" "x")
23293 (match_operand:MODEF 3 "register_operand" "x")))]
23295 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
23296 [(set_attr "type" "sse4arg")])
23298 ;; These versions of the min/max patterns are intentionally ignorant of
23299 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
23300 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
23301 ;; are undefined in this condition, we're certain this is correct.
23303 (define_insn "<code><mode>3"
23304 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
23306 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
23307 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
23308 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
23310 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
23311 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
23312 [(set_attr "isa" "noavx,avx")
23313 (set_attr "prefix" "orig,vex")
23314 (set_attr "type" "sseadd")
23315 (set_attr "mode" "<MODE>")])
23317 (define_insn "<code>hf3"
23318 [(set (match_operand:HF 0 "register_operand" "=v")
23320 (match_operand:HF 1 "nonimmediate_operand" "%v")
23321 (match_operand:HF 2 "nonimmediate_operand" "vm")))]
23322 "TARGET_AVX512FP16"
23323 "v<maxmin_float>sh\t{%2, %1, %0|%0, %1, %2}"
23324 [(set_attr "prefix" "evex")
23325 (set_attr "type" "sseadd")
23326 (set_attr "mode" "HF")])
23328 ;; These versions of the min/max patterns implement exactly the operations
23329 ;; min = (op1 < op2 ? op1 : op2)
23330 ;; max = (!(op1 < op2) ? op1 : op2)
23331 ;; Their operands are not commutative, and thus they may be used in the
23332 ;; presence of -0.0 and NaN.
23334 (define_insn "*ieee_s<ieee_maxmin>hf3"
23335 [(set (match_operand:HF 0 "register_operand" "=v")
23337 [(match_operand:HF 1 "register_operand" "v")
23338 (match_operand:HF 2 "nonimmediate_operand" "vm")]
23340 "TARGET_AVX512FP16"
23341 "v<ieee_maxmin>sh\t{%2, %1, %0|%0, %1, %2}"
23342 [(set_attr "prefix" "evex")
23343 (set_attr "type" "sseadd")
23344 (set_attr "mode" "HF")])
23346 (define_insn "*ieee_s<ieee_maxmin><mode>3"
23347 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
23349 [(match_operand:MODEF 1 "register_operand" "0,v")
23350 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
23352 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
23354 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
23355 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
23356 [(set_attr "isa" "noavx,avx")
23357 (set_attr "prefix" "orig,maybe_evex")
23358 (set_attr "type" "sseadd")
23359 (set_attr "mode" "<MODE>")])
23361 ;; Operands order in min/max instruction matters for signed zero and NANs.
23362 (define_insn_and_split "*ieee_max<mode>3_1"
23363 [(set (match_operand:MODEF 0 "register_operand")
23365 [(match_operand:MODEF 1 "register_operand")
23366 (match_operand:MODEF 2 "register_operand")
23368 (match_operand:MODEF 3 "register_operand")
23369 (match_operand:MODEF 4 "register_operand"))]
23371 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
23372 && (rtx_equal_p (operands[1], operands[3])
23373 && rtx_equal_p (operands[2], operands[4]))
23374 && ix86_pre_reload_split ()"
23377 [(set (match_dup 0)
23381 UNSPEC_IEEE_MAX))])
23383 (define_insn_and_split "*ieee_min<mode>3_1"
23384 [(set (match_operand:MODEF 0 "register_operand")
23386 [(match_operand:MODEF 1 "register_operand")
23387 (match_operand:MODEF 2 "register_operand")
23389 (match_operand:MODEF 3 "register_operand")
23390 (match_operand:MODEF 4 "register_operand"))]
23392 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
23393 && (rtx_equal_p (operands[1], operands[4])
23394 && rtx_equal_p (operands[2], operands[3]))
23395 && ix86_pre_reload_split ()"
23398 [(set (match_dup 0)
23402 UNSPEC_IEEE_MIN))])
23404 ;; Make two stack loads independent:
23406 ;; fld %st(0) -> fld bb
23407 ;; fmul bb fmul %st(1), %st
23409 ;; Actually we only match the last two instructions for simplicity.
23412 [(set (match_operand 0 "fp_register_operand")
23413 (match_operand 1 "fp_register_operand"))
23415 (match_operator 2 "binary_fp_operator"
23417 (match_operand 3 "memory_operand")]))]
23418 "REGNO (operands[0]) != REGNO (operands[1])"
23419 [(set (match_dup 0) (match_dup 3))
23422 [(match_dup 5) (match_dup 4)]))]
23424 operands[4] = operands[0];
23425 operands[5] = operands[1];
23427 /* The % modifier is not operational anymore in peephole2's, so we have to
23428 swap the operands manually in the case of addition and multiplication. */
23429 if (COMMUTATIVE_ARITH_P (operands[2]))
23430 std::swap (operands[4], operands[5]);
23434 [(set (match_operand 0 "fp_register_operand")
23435 (match_operand 1 "fp_register_operand"))
23437 (match_operator 2 "binary_fp_operator"
23438 [(match_operand 3 "memory_operand")
23440 "REGNO (operands[0]) != REGNO (operands[1])"
23441 [(set (match_dup 0) (match_dup 3))
23444 [(match_dup 4) (match_dup 5)]))]
23446 operands[4] = operands[0];
23447 operands[5] = operands[1];
23449 /* The % modifier is not operational anymore in peephole2's, so we have to
23450 swap the operands manually in the case of addition and multiplication. */
23451 if (COMMUTATIVE_ARITH_P (operands[2]))
23452 std::swap (operands[4], operands[5]);
23455 ;; Conditional addition patterns
23456 (define_expand "add<mode>cc"
23457 [(match_operand:SWI 0 "register_operand")
23458 (match_operand 1 "ordered_comparison_operator")
23459 (match_operand:SWI 2 "register_operand")
23460 (match_operand:SWI 3 "const_int_operand")]
23462 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
23464 ;; min/max patterns
23466 (define_code_attr maxmin_rel
23467 [(smax "GE") (smin "LE") (umax "GEU") (umin "LEU")])
23469 (define_expand "<code><mode>3"
23471 [(set (match_operand:SDWIM 0 "register_operand")
23473 (match_operand:SDWIM 1 "register_operand")
23474 (match_operand:SDWIM 2 "general_operand")))
23475 (clobber (reg:CC FLAGS_REG))])]
23477 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)")
23479 (define_insn_and_split "*<code><dwi>3_doubleword"
23480 [(set (match_operand:<DWI> 0 "register_operand")
23482 (match_operand:<DWI> 1 "register_operand")
23483 (match_operand:<DWI> 2 "general_operand")))
23484 (clobber (reg:CC FLAGS_REG))]
23486 && ix86_pre_reload_split ()"
23489 [(set (match_dup 0)
23490 (if_then_else:DWIH (match_dup 6)
23494 (if_then_else:DWIH (match_dup 6)
23498 operands[2] = force_reg (<DWI>mode, operands[2]);
23500 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
23502 rtx cmplo[2] = { operands[1], operands[2] };
23503 rtx cmphi[2] = { operands[4], operands[5] };
23505 enum rtx_code code = <maxmin_rel>;
23510 std::swap (cmplo[0], cmplo[1]);
23511 std::swap (cmphi[0], cmphi[1]);
23512 code = swap_condition (code);
23517 bool uns = (code == GEU);
23518 rtx (*sbb_insn) (machine_mode, rtx, rtx, rtx)
23519 = uns ? gen_sub3_carry_ccc : gen_sub3_carry_ccgz;
23521 emit_insn (gen_cmp_1 (<MODE>mode, cmplo[0], cmplo[1]));
23523 rtx tmp = gen_rtx_SCRATCH (<MODE>mode);
23524 emit_insn (sbb_insn (<MODE>mode, tmp, cmphi[0], cmphi[1]));
23526 rtx flags = gen_rtx_REG (uns ? CCCmode : CCGZmode, FLAGS_REG);
23527 operands[6] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
23533 gcc_unreachable ();
23537 (define_insn_and_split "*<code><mode>3_1"
23538 [(set (match_operand:SWI 0 "register_operand")
23540 (match_operand:SWI 1 "register_operand")
23541 (match_operand:SWI 2 "general_operand")))
23542 (clobber (reg:CC FLAGS_REG))]
23544 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
23545 && ix86_pre_reload_split ()"
23548 [(set (match_dup 0)
23549 (if_then_else:SWI (match_dup 3)
23553 machine_mode mode = <MODE>mode;
23554 rtx cmp_op = operands[2];
23556 operands[2] = force_reg (mode, cmp_op);
23558 enum rtx_code code = <maxmin_rel>;
23560 if (cmp_op == const1_rtx)
23562 /* Convert smax (x, 1) into (x > 0 ? x : 1).
23563 Convert umax (x, 1) into (x != 0 ? x : 1).
23564 Convert ?min (x, 1) into (x <= 0 ? x : 1). */
23565 cmp_op = const0_rtx;
23568 else if (code == GEU)
23571 /* Convert smin (x, -1) into (x < 0 ? x : -1). */
23572 else if (cmp_op == constm1_rtx && code == LE)
23574 cmp_op = const0_rtx;
23577 /* Convert smax (x, -1) into (x >= 0 ? x : -1). */
23578 else if (cmp_op == constm1_rtx && code == GE)
23579 cmp_op = const0_rtx;
23580 else if (cmp_op != const0_rtx)
23581 cmp_op = operands[2];
23583 machine_mode cmpmode = SELECT_CC_MODE (code, operands[1], cmp_op);
23584 rtx flags = gen_rtx_REG (cmpmode, FLAGS_REG);
23586 rtx tmp = gen_rtx_COMPARE (cmpmode, operands[1], cmp_op);
23587 emit_insn (gen_rtx_SET (flags, tmp));
23589 operands[3] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
23592 ;; Avoid clearing a register between a flags setting comparison and its use,
23593 ;; i.e. prefer "xorl %eax,%eax; test/cmp" over "test/cmp; movl $0, %eax".
23595 [(set (reg FLAGS_REG) (match_operand 0))
23596 (set (match_operand:SWI 1 "general_reg_operand") (const_int 0))]
23597 "peep2_regno_dead_p (0, FLAGS_REG)
23598 && !reg_overlap_mentioned_p (operands[1], operands[0])"
23599 [(set (match_dup 2) (match_dup 0))]
23601 operands[2] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
23602 ix86_expand_clear (operands[1]);
23605 ;; When optimizing for size, zeroing memory should use a register.
23607 [(match_scratch:SWI48 0 "r")
23608 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
23609 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))
23610 (set (match_operand:SWI48 3 "memory_operand") (const_int 0))
23611 (set (match_operand:SWI48 4 "memory_operand") (const_int 0))]
23612 "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
23615 ix86_expand_clear (operands[0]);
23616 emit_move_insn (operands[1], operands[0]);
23617 emit_move_insn (operands[2], operands[0]);
23618 emit_move_insn (operands[3], operands[0]);
23619 ix86_last_zero_store_uid
23620 = INSN_UID (emit_move_insn (operands[4], operands[0]));
23625 [(match_scratch:SWI48 0 "r")
23626 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
23627 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))]
23628 "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
23631 ix86_expand_clear (operands[0]);
23632 emit_move_insn (operands[1], operands[0]);
23633 ix86_last_zero_store_uid
23634 = INSN_UID (emit_move_insn (operands[2], operands[0]));
23639 [(match_scratch:SWI48 0 "r")
23640 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))]
23641 "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
23644 ix86_expand_clear (operands[0]);
23645 ix86_last_zero_store_uid
23646 = INSN_UID (emit_move_insn (operands[1], operands[0]));
23651 [(set (match_operand:SWI48 5 "memory_operand")
23652 (match_operand:SWI48 0 "general_reg_operand"))
23653 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
23654 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))
23655 (set (match_operand:SWI48 3 "memory_operand") (const_int 0))
23656 (set (match_operand:SWI48 4 "memory_operand") (const_int 0))]
23657 "optimize_insn_for_size_p ()
23658 && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
23661 emit_move_insn (operands[5], operands[0]);
23662 emit_move_insn (operands[1], operands[0]);
23663 emit_move_insn (operands[2], operands[0]);
23664 emit_move_insn (operands[3], operands[0]);
23665 ix86_last_zero_store_uid
23666 = INSN_UID (emit_move_insn (operands[4], operands[0]));
23671 [(set (match_operand:SWI48 3 "memory_operand")
23672 (match_operand:SWI48 0 "general_reg_operand"))
23673 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
23674 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))]
23675 "optimize_insn_for_size_p ()
23676 && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
23679 emit_move_insn (operands[3], operands[0]);
23680 emit_move_insn (operands[1], operands[0]);
23681 ix86_last_zero_store_uid
23682 = INSN_UID (emit_move_insn (operands[2], operands[0]));
23687 [(set (match_operand:SWI48 2 "memory_operand")
23688 (match_operand:SWI48 0 "general_reg_operand"))
23689 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))]
23690 "optimize_insn_for_size_p ()
23691 && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
23694 emit_move_insn (operands[2], operands[0]);
23695 ix86_last_zero_store_uid
23696 = INSN_UID (emit_move_insn (operands[1], operands[0]));
23700 ;; Reload dislikes loading constants directly into class_likely_spilled
23701 ;; hard registers. Try to tidy things up here.
23703 [(set (match_operand:SWI 0 "general_reg_operand")
23704 (match_operand:SWI 1 "x86_64_general_operand"))
23705 (set (match_operand:SWI 2 "general_reg_operand")
23707 "peep2_reg_dead_p (2, operands[0])"
23708 [(set (match_dup 2) (match_dup 1))])
23710 ;; Misc patterns (?)
23712 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
23713 ;; Otherwise there will be nothing to keep
23715 ;; [(set (reg ebp) (reg esp))]
23716 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
23717 ;; (clobber (eflags)]
23718 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
23720 ;; in proper program order.
23722 (define_insn "@pro_epilogue_adjust_stack_add_<mode>"
23723 [(set (match_operand:P 0 "register_operand" "=r,r")
23724 (plus:P (match_operand:P 1 "register_operand" "0,r")
23725 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
23726 (clobber (reg:CC FLAGS_REG))
23727 (clobber (mem:BLK (scratch)))]
23730 switch (get_attr_type (insn))
23733 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
23736 gcc_assert (rtx_equal_p (operands[0], operands[1]));
23737 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
23738 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
23740 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
23743 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
23744 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
23747 [(set (attr "type")
23748 (cond [(and (eq_attr "alternative" "0")
23749 (not (match_test "TARGET_OPT_AGU")))
23750 (const_string "alu")
23751 (match_operand:<MODE> 2 "const0_operand")
23752 (const_string "imov")
23754 (const_string "lea")))
23755 (set (attr "length_immediate")
23756 (cond [(eq_attr "type" "imov")
23758 (and (eq_attr "type" "alu")
23759 (match_operand 2 "const128_operand"))
23762 (const_string "*")))
23763 (set_attr "mode" "<MODE>")])
23765 (define_insn "@pro_epilogue_adjust_stack_sub_<mode>"
23766 [(set (match_operand:P 0 "register_operand" "=r")
23767 (minus:P (match_operand:P 1 "register_operand" "0")
23768 (match_operand:P 2 "register_operand" "r")))
23769 (clobber (reg:CC FLAGS_REG))
23770 (clobber (mem:BLK (scratch)))]
23772 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
23773 [(set_attr "type" "alu")
23774 (set_attr "mode" "<MODE>")])
23776 (define_insn "@allocate_stack_worker_probe_<mode>"
23777 [(set (match_operand:P 0 "register_operand" "=a")
23778 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
23779 UNSPECV_STACK_PROBE))
23780 (clobber (reg:CC FLAGS_REG))]
23781 "ix86_target_stack_probe ()"
23782 "call\t___chkstk_ms"
23783 [(set_attr "type" "multi")
23784 (set_attr "length" "5")])
23786 (define_expand "allocate_stack"
23787 [(match_operand 0 "register_operand")
23788 (match_operand 1 "general_operand")]
23789 "ix86_target_stack_probe ()"
23793 #ifndef CHECK_STACK_LIMIT
23794 #define CHECK_STACK_LIMIT 0
23797 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
23798 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
23802 x = copy_to_mode_reg (Pmode, operands[1]);
23804 emit_insn (gen_allocate_stack_worker_probe (Pmode, x, x));
23807 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
23808 stack_pointer_rtx, 0, OPTAB_DIRECT);
23810 if (x != stack_pointer_rtx)
23811 emit_move_insn (stack_pointer_rtx, x);
23813 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
23817 (define_expand "probe_stack"
23818 [(match_operand 0 "memory_operand")]
23821 emit_insn (gen_probe_stack_1
23822 (word_mode, operands[0], const0_rtx));
23826 ;; Use OR for stack probes, this is shorter.
23827 (define_insn "@probe_stack_1_<mode>"
23828 [(set (match_operand:W 0 "memory_operand" "=m")
23829 (unspec:W [(match_operand:W 1 "const0_operand")]
23830 UNSPEC_PROBE_STACK))
23831 (clobber (reg:CC FLAGS_REG))]
23833 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
23834 [(set_attr "type" "alu1")
23835 (set_attr "mode" "<MODE>")
23836 (set_attr "length_immediate" "1")])
23838 (define_insn "@adjust_stack_and_probe_<mode>"
23839 [(set (match_operand:P 0 "register_operand" "=r")
23840 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
23841 UNSPECV_PROBE_STACK_RANGE))
23842 (set (reg:P SP_REG)
23843 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand")))
23844 (clobber (reg:CC FLAGS_REG))
23845 (clobber (mem:BLK (scratch)))]
23847 "* return output_adjust_stack_and_probe (operands[0]);"
23848 [(set_attr "type" "multi")])
23850 (define_insn "@probe_stack_range_<mode>"
23851 [(set (match_operand:P 0 "register_operand" "=r")
23852 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
23853 (match_operand:P 2 "const_int_operand")]
23854 UNSPECV_PROBE_STACK_RANGE))
23855 (clobber (reg:CC FLAGS_REG))]
23857 "* return output_probe_stack_range (operands[0], operands[2]);"
23858 [(set_attr "type" "multi")])
23860 (define_expand "builtin_setjmp_receiver"
23861 [(label_ref (match_operand 0))]
23862 "!TARGET_64BIT && flag_pic"
23868 rtx_code_label *label_rtx = gen_label_rtx ();
23869 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
23870 xops[0] = xops[1] = pic_offset_table_rtx;
23871 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
23872 ix86_expand_binary_operator (MINUS, SImode, xops);
23876 emit_insn (gen_set_got (pic_offset_table_rtx));
23880 (define_expand "save_stack_nonlocal"
23881 [(set (match_operand 0 "memory_operand")
23882 (match_operand 1 "register_operand"))]
23887 if (flag_cf_protection & CF_RETURN)
23889 /* Copy shadow stack pointer to the first slot
23890 and stack pointer to the second slot. */
23891 rtx ssp_slot = adjust_address (operands[0], word_mode, 0);
23892 stack_slot = adjust_address (operands[0], Pmode, UNITS_PER_WORD);
23894 rtx reg_ssp = force_reg (word_mode, const0_rtx);
23895 emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
23896 emit_move_insn (ssp_slot, reg_ssp);
23899 stack_slot = adjust_address (operands[0], Pmode, 0);
23900 emit_move_insn (stack_slot, operands[1]);
23904 (define_expand "restore_stack_nonlocal"
23905 [(set (match_operand 0 "register_operand" "")
23906 (match_operand 1 "memory_operand" ""))]
23911 if (flag_cf_protection & CF_RETURN)
23913 /* Restore shadow stack pointer from the first slot
23914 and stack pointer from the second slot. */
23915 rtx ssp_slot = adjust_address (operands[1], word_mode, 0);
23916 stack_slot = adjust_address (operands[1], Pmode, UNITS_PER_WORD);
23918 /* Get the current shadow stack pointer. The code below will check if
23919 SHSTK feature is enabled. If it is not enabled the RDSSP instruction
23921 rtx reg_ssp = force_reg (word_mode, const0_rtx);
23922 emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
23924 /* Compare through subtraction the saved and the current ssp
23925 to decide if ssp has to be adjusted. */
23926 reg_ssp = expand_simple_binop (word_mode, MINUS,
23928 reg_ssp, 1, OPTAB_DIRECT);
23930 /* Compare and jump over adjustment code. */
23931 rtx noadj_label = gen_label_rtx ();
23932 emit_cmp_and_jump_insns (reg_ssp, const0_rtx, EQ, NULL_RTX,
23933 word_mode, 1, noadj_label);
23935 /* Compute the number of frames to adjust. */
23936 rtx reg_adj = gen_lowpart (ptr_mode, reg_ssp);
23937 rtx reg_adj_neg = expand_simple_unop (ptr_mode, NEG, reg_adj,
23940 reg_adj = expand_simple_binop (ptr_mode, LSHIFTRT, reg_adj_neg,
23941 GEN_INT (exact_log2 (UNITS_PER_WORD)),
23942 reg_adj, 1, OPTAB_DIRECT);
23944 /* Check if number of frames <= 255 so no loop is needed. */
23945 rtx inc_label = gen_label_rtx ();
23946 emit_cmp_and_jump_insns (reg_adj, GEN_INT (255), LEU, NULL_RTX,
23947 ptr_mode, 1, inc_label);
23949 /* Adjust the ssp in a loop. */
23950 rtx loop_label = gen_label_rtx ();
23951 emit_label (loop_label);
23952 LABEL_NUSES (loop_label) = 1;
23954 rtx reg_255 = force_reg (word_mode, GEN_INT (255));
23955 emit_insn (gen_incssp (word_mode, reg_255));
23957 reg_adj = expand_simple_binop (ptr_mode, MINUS,
23958 reg_adj, GEN_INT (255),
23959 reg_adj, 1, OPTAB_DIRECT);
23961 /* Compare and jump to the loop label. */
23962 emit_cmp_and_jump_insns (reg_adj, GEN_INT (255), GTU, NULL_RTX,
23963 ptr_mode, 1, loop_label);
23965 emit_label (inc_label);
23966 LABEL_NUSES (inc_label) = 1;
23968 emit_insn (gen_incssp (word_mode, reg_ssp));
23970 emit_label (noadj_label);
23971 LABEL_NUSES (noadj_label) = 1;
23974 stack_slot = adjust_address (operands[1], Pmode, 0);
23975 emit_move_insn (operands[0], stack_slot);
23980 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
23981 ;; Do not split instructions with mask registers.
23983 [(set (match_operand 0 "general_reg_operand")
23984 (match_operator 3 "promotable_binary_operator"
23985 [(match_operand 1 "general_reg_operand")
23986 (match_operand 2 "aligned_operand")]))
23987 (clobber (reg:CC FLAGS_REG))]
23988 "! TARGET_PARTIAL_REG_STALL && reload_completed
23989 && ((GET_MODE (operands[0]) == HImode
23990 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
23991 /* ??? next two lines just !satisfies_constraint_K (...) */
23992 || !CONST_INT_P (operands[2])
23993 || satisfies_constraint_K (operands[2])))
23994 || (GET_MODE (operands[0]) == QImode
23995 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
23996 [(parallel [(set (match_dup 0)
23997 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
23998 (clobber (reg:CC FLAGS_REG))])]
24000 operands[0] = gen_lowpart (SImode, operands[0]);
24001 operands[1] = gen_lowpart (SImode, operands[1]);
24002 if (GET_CODE (operands[3]) != ASHIFT)
24003 operands[2] = gen_lowpart (SImode, operands[2]);
24004 operands[3] = shallow_copy_rtx (operands[3]);
24005 PUT_MODE (operands[3], SImode);
24008 ; Promote the QImode tests, as i386 has encoding of the AND
24009 ; instruction with 32-bit sign-extended immediate and thus the
24010 ; instruction size is unchanged, except in the %eax case for
24011 ; which it is increased by one byte, hence the ! optimize_size.
24013 [(set (match_operand 0 "flags_reg_operand")
24014 (match_operator 2 "compare_operator"
24015 [(and (match_operand 3 "aligned_operand")
24016 (match_operand 4 "const_int_operand"))
24018 (set (match_operand 1 "register_operand")
24019 (and (match_dup 3) (match_dup 4)))]
24020 "! TARGET_PARTIAL_REG_STALL && reload_completed
24021 && optimize_insn_for_speed_p ()
24022 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
24023 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
24024 /* Ensure that the operand will remain sign-extended immediate. */
24025 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
24026 [(parallel [(set (match_dup 0)
24027 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
24030 (and:SI (match_dup 3) (match_dup 4)))])]
24033 = gen_int_mode (INTVAL (operands[4])
24034 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
24035 operands[1] = gen_lowpart (SImode, operands[1]);
24036 operands[3] = gen_lowpart (SImode, operands[3]);
24039 ; Don't promote the QImode tests, as i386 doesn't have encoding of
24040 ; the TEST instruction with 32-bit sign-extended immediate and thus
24041 ; the instruction size would at least double, which is not what we
24042 ; want even with ! optimize_size.
24044 [(set (match_operand 0 "flags_reg_operand")
24045 (match_operator 1 "compare_operator"
24046 [(and (match_operand:HI 2 "aligned_operand")
24047 (match_operand:HI 3 "const_int_operand"))
24049 "! TARGET_PARTIAL_REG_STALL && reload_completed
24050 && ! TARGET_FAST_PREFIX
24051 && optimize_insn_for_speed_p ()
24052 /* Ensure that the operand will remain sign-extended immediate. */
24053 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
24054 [(set (match_dup 0)
24055 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
24059 = gen_int_mode (INTVAL (operands[3])
24060 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
24061 operands[2] = gen_lowpart (SImode, operands[2]);
24065 [(set (match_operand 0 "register_operand")
24066 (neg (match_operand 1 "register_operand")))
24067 (clobber (reg:CC FLAGS_REG))]
24068 "! TARGET_PARTIAL_REG_STALL && reload_completed
24069 && (GET_MODE (operands[0]) == HImode
24070 || (GET_MODE (operands[0]) == QImode
24071 && (TARGET_PROMOTE_QImode
24072 || optimize_insn_for_size_p ())))"
24073 [(parallel [(set (match_dup 0)
24074 (neg:SI (match_dup 1)))
24075 (clobber (reg:CC FLAGS_REG))])]
24077 operands[0] = gen_lowpart (SImode, operands[0]);
24078 operands[1] = gen_lowpart (SImode, operands[1]);
24081 ;; Do not split instructions with mask regs.
24083 [(set (match_operand 0 "general_reg_operand")
24084 (not (match_operand 1 "general_reg_operand")))]
24085 "! TARGET_PARTIAL_REG_STALL && reload_completed
24086 && (GET_MODE (operands[0]) == HImode
24087 || (GET_MODE (operands[0]) == QImode
24088 && (TARGET_PROMOTE_QImode
24089 || optimize_insn_for_size_p ())))"
24090 [(set (match_dup 0)
24091 (not:SI (match_dup 1)))]
24093 operands[0] = gen_lowpart (SImode, operands[0]);
24094 operands[1] = gen_lowpart (SImode, operands[1]);
24097 ;; RTL Peephole optimizations, run before sched2. These primarily look to
24098 ;; transform a complex memory operation into two memory to register operations.
24100 ;; Don't push memory operands
24102 [(set (match_operand:SWI 0 "push_operand")
24103 (match_operand:SWI 1 "memory_operand"))
24104 (match_scratch:SWI 2 "<r>")]
24105 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
24106 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
24107 [(set (match_dup 2) (match_dup 1))
24108 (set (match_dup 0) (match_dup 2))])
24110 ;; We need to handle SFmode only, because DFmode and XFmode are split to
24113 [(set (match_operand:SF 0 "push_operand")
24114 (match_operand:SF 1 "memory_operand"))
24115 (match_scratch:SF 2 "r")]
24116 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
24117 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
24118 [(set (match_dup 2) (match_dup 1))
24119 (set (match_dup 0) (match_dup 2))])
24121 ;; Don't move an immediate directly to memory when the instruction
24122 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
24124 [(match_scratch:SWI124 1 "<r>")
24125 (set (match_operand:SWI124 0 "memory_operand")
24127 "optimize_insn_for_speed_p ()
24128 && ((<MODE>mode == HImode
24129 && TARGET_LCP_STALL)
24130 || (!TARGET_USE_MOV0
24131 && TARGET_SPLIT_LONG_MOVES
24132 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
24133 && peep2_regno_dead_p (0, FLAGS_REG)"
24134 [(parallel [(set (match_dup 2) (const_int 0))
24135 (clobber (reg:CC FLAGS_REG))])
24136 (set (match_dup 0) (match_dup 1))]
24137 "operands[2] = gen_lowpart (SImode, operands[1]);")
24140 [(match_scratch:SWI124 2 "<r>")
24141 (set (match_operand:SWI124 0 "memory_operand")
24142 (match_operand:SWI124 1 "immediate_operand"))]
24143 "optimize_insn_for_speed_p ()
24144 && ((<MODE>mode == HImode
24145 && TARGET_LCP_STALL)
24146 || (TARGET_SPLIT_LONG_MOVES
24147 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
24148 [(set (match_dup 2) (match_dup 1))
24149 (set (match_dup 0) (match_dup 2))])
24151 ;; Don't compare memory with zero, load and use a test instead.
24153 [(set (match_operand 0 "flags_reg_operand")
24154 (match_operator 1 "compare_operator"
24155 [(match_operand:SI 2 "memory_operand")
24157 (match_scratch:SI 3 "r")]
24158 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
24159 [(set (match_dup 3) (match_dup 2))
24160 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
24162 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
24163 ;; Don't split NOTs with a displacement operand, because resulting XOR
24164 ;; will not be pairable anyway.
24166 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
24167 ;; represented using a modRM byte. The XOR replacement is long decoded,
24168 ;; so this split helps here as well.
24170 ;; Note: Can't do this as a regular split because we can't get proper
24171 ;; lifetime information then.
24174 [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
24175 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
24176 "optimize_insn_for_speed_p ()
24177 && ((TARGET_NOT_UNPAIRABLE
24178 && (!MEM_P (operands[0])
24179 || !memory_displacement_operand (operands[0], <MODE>mode)))
24180 || (TARGET_NOT_VECTORMODE
24181 && long_memory_operand (operands[0], <MODE>mode)))
24182 && peep2_regno_dead_p (0, FLAGS_REG)"
24183 [(parallel [(set (match_dup 0)
24184 (xor:SWI124 (match_dup 1) (const_int -1)))
24185 (clobber (reg:CC FLAGS_REG))])])
24187 ;; Non pairable "test imm, reg" instructions can be translated to
24188 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
24189 ;; byte opcode instead of two, have a short form for byte operands),
24190 ;; so do it for other CPUs as well. Given that the value was dead,
24191 ;; this should not create any new dependencies. Pass on the sub-word
24192 ;; versions if we're concerned about partial register stalls.
24195 [(set (match_operand 0 "flags_reg_operand")
24196 (match_operator 1 "compare_operator"
24197 [(and:SI (match_operand:SI 2 "register_operand")
24198 (match_operand:SI 3 "immediate_operand"))
24200 "ix86_match_ccmode (insn, CCNOmode)
24201 && (REGNO (operands[2]) != AX_REG
24202 || satisfies_constraint_K (operands[3]))
24203 && peep2_reg_dead_p (1, operands[2])"
24205 [(set (match_dup 0)
24206 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
24209 (and:SI (match_dup 2) (match_dup 3)))])])
24211 ;; We don't need to handle HImode case, because it will be promoted to SImode
24212 ;; on ! TARGET_PARTIAL_REG_STALL
24215 [(set (match_operand 0 "flags_reg_operand")
24216 (match_operator 1 "compare_operator"
24217 [(and:QI (match_operand:QI 2 "register_operand")
24218 (match_operand:QI 3 "immediate_operand"))
24220 "! TARGET_PARTIAL_REG_STALL
24221 && ix86_match_ccmode (insn, CCNOmode)
24222 && REGNO (operands[2]) != AX_REG
24223 && peep2_reg_dead_p (1, operands[2])"
24225 [(set (match_dup 0)
24226 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
24229 (and:QI (match_dup 2) (match_dup 3)))])])
24232 [(set (match_operand 0 "flags_reg_operand")
24233 (match_operator 1 "compare_operator"
24236 (match_operator:SWI248 4 "extract_operator"
24237 [(match_operand 2 "int248_register_operand")
24240 (match_operand 3 "const_int_operand"))
24242 "! TARGET_PARTIAL_REG_STALL
24243 && ix86_match_ccmode (insn, CCNOmode)
24244 && REGNO (operands[2]) != AX_REG
24245 && peep2_reg_dead_p (1, operands[2])"
24247 [(set (match_dup 0)
24251 (match_op_dup 4 [(match_dup 2)
24256 (set (zero_extract:SWI248 (match_dup 2)
24262 (match_op_dup 4 [(match_dup 2)
24265 (match_dup 3)) 0))])])
24267 ;; Don't do logical operations with memory inputs.
24269 [(match_scratch:SWI 2 "<r>")
24270 (parallel [(set (match_operand:SWI 0 "register_operand")
24271 (match_operator:SWI 3 "arith_or_logical_operator"
24273 (match_operand:SWI 1 "memory_operand")]))
24274 (clobber (reg:CC FLAGS_REG))])]
24275 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
24276 [(set (match_dup 2) (match_dup 1))
24277 (parallel [(set (match_dup 0)
24278 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
24279 (clobber (reg:CC FLAGS_REG))])])
24282 [(match_scratch:SWI 2 "<r>")
24283 (parallel [(set (match_operand:SWI 0 "register_operand")
24284 (match_operator:SWI 3 "arith_or_logical_operator"
24285 [(match_operand:SWI 1 "memory_operand")
24287 (clobber (reg:CC FLAGS_REG))])]
24288 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
24289 [(set (match_dup 2) (match_dup 1))
24290 (parallel [(set (match_dup 0)
24291 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
24292 (clobber (reg:CC FLAGS_REG))])])
24294 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when
24295 ;; the memory address refers to the destination of the load!
24298 [(set (match_operand:SWI 0 "general_reg_operand")
24299 (match_operand:SWI 1 "general_reg_operand"))
24300 (parallel [(set (match_dup 0)
24301 (match_operator:SWI 3 "commutative_operator"
24303 (match_operand:SWI 2 "memory_operand")]))
24304 (clobber (reg:CC FLAGS_REG))])]
24305 "REGNO (operands[0]) != REGNO (operands[1])
24306 && (<MODE>mode != QImode
24307 || any_QIreg_operand (operands[1], QImode))"
24308 [(set (match_dup 0) (match_dup 4))
24309 (parallel [(set (match_dup 0)
24310 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
24311 (clobber (reg:CC FLAGS_REG))])]
24314 = ix86_replace_reg_with_reg (operands[2], operands[0], operands[1]);
24318 [(set (match_operand 0 "mmx_reg_operand")
24319 (match_operand 1 "mmx_reg_operand"))
24321 (match_operator 3 "commutative_operator"
24323 (match_operand 2 "memory_operand")]))]
24324 "REGNO (operands[0]) != REGNO (operands[1])"
24325 [(set (match_dup 0) (match_dup 2))
24327 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
24330 [(set (match_operand 0 "sse_reg_operand")
24331 (match_operand 1 "sse_reg_operand"))
24333 (match_operator 3 "commutative_operator"
24335 (match_operand 2 "memory_operand")]))]
24336 "REGNO (operands[0]) != REGNO (operands[1])
24337 /* Punt if operands[1] is %[xy]mm16+ and AVX512BW is not enabled,
24338 as EVEX encoded vpadd[bw], vpmullw, vpmin[su][bw] and vpmax[su][bw]
24339 instructions require AVX512BW and AVX512VL, but with the original
24340 instructions it might require just AVX512VL.
24341 AVX512VL is implied from TARGET_HARD_REGNO_MODE_OK. */
24342 && (!EXT_REX_SSE_REGNO_P (REGNO (operands[1]))
24344 || GET_MODE_SIZE (GET_MODE_INNER (GET_MODE (operands[0]))) > 2
24345 || logic_operator (operands[3], VOIDmode))"
24346 [(set (match_dup 0) (match_dup 2))
24348 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
24350 ; Don't do logical operations with memory outputs
24352 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
24353 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
24354 ; the same decoder scheduling characteristics as the original.
24357 [(match_scratch:SWI 2 "<r>")
24358 (parallel [(set (match_operand:SWI 0 "memory_operand")
24359 (match_operator:SWI 3 "arith_or_logical_operator"
24361 (match_operand:SWI 1 "<nonmemory_operand>")]))
24362 (clobber (reg:CC FLAGS_REG))])]
24363 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
24364 [(set (match_dup 2) (match_dup 0))
24365 (parallel [(set (match_dup 2)
24366 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
24367 (clobber (reg:CC FLAGS_REG))])
24368 (set (match_dup 0) (match_dup 2))])
24371 [(match_scratch:SWI 2 "<r>")
24372 (parallel [(set (match_operand:SWI 0 "memory_operand")
24373 (match_operator:SWI 3 "arith_or_logical_operator"
24374 [(match_operand:SWI 1 "<nonmemory_operand>")
24376 (clobber (reg:CC FLAGS_REG))])]
24377 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
24378 [(set (match_dup 2) (match_dup 0))
24379 (parallel [(set (match_dup 2)
24380 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
24381 (clobber (reg:CC FLAGS_REG))])
24382 (set (match_dup 0) (match_dup 2))])
24384 ;; Attempt to use arith or logical operations with memory outputs with
24385 ;; setting of flags.
24387 [(set (match_operand:SWI 0 "register_operand")
24388 (match_operand:SWI 1 "memory_operand"))
24389 (parallel [(set (match_dup 0)
24390 (match_operator:SWI 3 "plusminuslogic_operator"
24392 (match_operand:SWI 2 "<nonmemory_operand>")]))
24393 (clobber (reg:CC FLAGS_REG))])
24394 (set (match_dup 1) (match_dup 0))
24395 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
24396 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24397 && peep2_reg_dead_p (4, operands[0])
24398 && !reg_overlap_mentioned_p (operands[0], operands[1])
24399 && !reg_overlap_mentioned_p (operands[0], operands[2])
24400 && (<MODE>mode != QImode
24401 || immediate_operand (operands[2], QImode)
24402 || any_QIreg_operand (operands[2], QImode))
24403 && ix86_match_ccmode (peep2_next_insn (3),
24404 (GET_CODE (operands[3]) == PLUS
24405 || GET_CODE (operands[3]) == MINUS)
24406 ? CCGOCmode : CCNOmode)"
24407 [(parallel [(set (match_dup 4) (match_dup 6))
24408 (set (match_dup 1) (match_dup 5))])]
24410 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
24412 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
24413 copy_rtx (operands[1]),
24416 = gen_rtx_COMPARE (GET_MODE (operands[4]),
24417 copy_rtx (operands[5]),
24421 ;; Likewise for cmpelim optimized pattern.
24423 [(set (match_operand:SWI 0 "register_operand")
24424 (match_operand:SWI 1 "memory_operand"))
24425 (parallel [(set (reg FLAGS_REG)
24426 (compare (match_operator:SWI 3 "plusminuslogic_operator"
24428 (match_operand:SWI 2 "<nonmemory_operand>")])
24430 (set (match_dup 0) (match_dup 3))])
24431 (set (match_dup 1) (match_dup 0))]
24432 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24433 && peep2_reg_dead_p (3, operands[0])
24434 && !reg_overlap_mentioned_p (operands[0], operands[1])
24435 && !reg_overlap_mentioned_p (operands[0], operands[2])
24436 && ix86_match_ccmode (peep2_next_insn (1),
24437 (GET_CODE (operands[3]) == PLUS
24438 || GET_CODE (operands[3]) == MINUS)
24439 ? CCGOCmode : CCNOmode)"
24440 [(parallel [(set (match_dup 4) (match_dup 6))
24441 (set (match_dup 1) (match_dup 5))])]
24443 operands[4] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
24445 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
24446 copy_rtx (operands[1]), operands[2]);
24448 = gen_rtx_COMPARE (GET_MODE (operands[4]), copy_rtx (operands[5]),
24452 ;; Likewise for instances where we have a lea pattern.
24454 [(set (match_operand:SWI 0 "register_operand")
24455 (match_operand:SWI 1 "memory_operand"))
24456 (set (match_operand:<LEAMODE> 3 "register_operand")
24457 (plus:<LEAMODE> (match_operand:<LEAMODE> 4 "register_operand")
24458 (match_operand:<LEAMODE> 2 "<nonmemory_operand>")))
24459 (set (match_dup 1) (match_operand:SWI 5 "register_operand"))
24460 (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
24461 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24462 && REGNO (operands[4]) == REGNO (operands[0])
24463 && REGNO (operands[5]) == REGNO (operands[3])
24464 && peep2_reg_dead_p (4, operands[3])
24465 && ((REGNO (operands[0]) == REGNO (operands[3]))
24466 || peep2_reg_dead_p (2, operands[0]))
24467 && !reg_overlap_mentioned_p (operands[0], operands[1])
24468 && !reg_overlap_mentioned_p (operands[3], operands[1])
24469 && !reg_overlap_mentioned_p (operands[0], operands[2])
24470 && (<MODE>mode != QImode
24471 || immediate_operand (operands[2], QImode)
24472 || any_QIreg_operand (operands[2], QImode))
24473 && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
24474 [(parallel [(set (match_dup 6) (match_dup 8))
24475 (set (match_dup 1) (match_dup 7))])]
24477 operands[6] = SET_DEST (PATTERN (peep2_next_insn (3)));
24479 = gen_rtx_PLUS (<MODE>mode,
24480 copy_rtx (operands[1]),
24481 gen_lowpart (<MODE>mode, operands[2]));
24483 = gen_rtx_COMPARE (GET_MODE (operands[6]),
24484 copy_rtx (operands[7]),
24489 [(parallel [(set (match_operand:SWI 0 "register_operand")
24490 (match_operator:SWI 2 "plusminuslogic_operator"
24492 (match_operand:SWI 1 "memory_operand")]))
24493 (clobber (reg:CC FLAGS_REG))])
24494 (set (match_dup 1) (match_dup 0))
24495 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
24496 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24497 && COMMUTATIVE_ARITH_P (operands[2])
24498 && peep2_reg_dead_p (3, operands[0])
24499 && !reg_overlap_mentioned_p (operands[0], operands[1])
24500 && ix86_match_ccmode (peep2_next_insn (2),
24501 GET_CODE (operands[2]) == PLUS
24502 ? CCGOCmode : CCNOmode)"
24503 [(parallel [(set (match_dup 3) (match_dup 5))
24504 (set (match_dup 1) (match_dup 4))])]
24506 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
24508 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
24509 copy_rtx (operands[1]),
24512 = gen_rtx_COMPARE (GET_MODE (operands[3]),
24513 copy_rtx (operands[4]),
24517 ;; Likewise for cmpelim optimized pattern.
24519 [(parallel [(set (reg FLAGS_REG)
24520 (compare (match_operator:SWI 2 "plusminuslogic_operator"
24521 [(match_operand:SWI 0 "register_operand")
24522 (match_operand:SWI 1 "memory_operand")])
24524 (set (match_dup 0) (match_dup 2))])
24525 (set (match_dup 1) (match_dup 0))]
24526 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24527 && COMMUTATIVE_ARITH_P (operands[2])
24528 && peep2_reg_dead_p (2, operands[0])
24529 && !reg_overlap_mentioned_p (operands[0], operands[1])
24530 && ix86_match_ccmode (peep2_next_insn (0),
24531 GET_CODE (operands[2]) == PLUS
24532 ? CCGOCmode : CCNOmode)"
24533 [(parallel [(set (match_dup 3) (match_dup 5))
24534 (set (match_dup 1) (match_dup 4))])]
24536 operands[3] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (0)), 0, 0));
24538 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
24539 copy_rtx (operands[1]), operands[0]);
24541 = gen_rtx_COMPARE (GET_MODE (operands[3]), copy_rtx (operands[4]),
24546 [(set (match_operand:SWI12 0 "register_operand")
24547 (match_operand:SWI12 1 "memory_operand"))
24548 (parallel [(set (match_operand:SI 4 "register_operand")
24549 (match_operator:SI 3 "plusminuslogic_operator"
24551 (match_operand:SI 2 "nonmemory_operand")]))
24552 (clobber (reg:CC FLAGS_REG))])
24553 (set (match_dup 1) (match_dup 0))
24554 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
24555 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24556 && REGNO (operands[0]) == REGNO (operands[4])
24557 && peep2_reg_dead_p (4, operands[0])
24558 && (<MODE>mode != QImode
24559 || immediate_operand (operands[2], SImode)
24560 || any_QIreg_operand (operands[2], SImode))
24561 && !reg_overlap_mentioned_p (operands[0], operands[1])
24562 && !reg_overlap_mentioned_p (operands[0], operands[2])
24563 && ix86_match_ccmode (peep2_next_insn (3),
24564 (GET_CODE (operands[3]) == PLUS
24565 || GET_CODE (operands[3]) == MINUS)
24566 ? CCGOCmode : CCNOmode)"
24567 [(parallel [(set (match_dup 5) (match_dup 7))
24568 (set (match_dup 1) (match_dup 6))])]
24570 operands[5] = SET_DEST (PATTERN (peep2_next_insn (3)));
24572 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
24573 copy_rtx (operands[1]),
24574 gen_lowpart (<MODE>mode, operands[2]));
24576 = gen_rtx_COMPARE (GET_MODE (operands[5]),
24577 copy_rtx (operands[6]),
24581 ;; peephole2 comes before regcprop, so deal also with a case that
24582 ;; would be cleaned up by regcprop.
24584 [(set (match_operand:SWI 0 "register_operand")
24585 (match_operand:SWI 1 "memory_operand"))
24586 (parallel [(set (match_dup 0)
24587 (match_operator:SWI 3 "plusminuslogic_operator"
24589 (match_operand:SWI 2 "<nonmemory_operand>")]))
24590 (clobber (reg:CC FLAGS_REG))])
24591 (set (match_operand:SWI 4 "register_operand") (match_dup 0))
24592 (set (match_dup 1) (match_dup 4))
24593 (set (reg FLAGS_REG) (compare (match_dup 4) (const_int 0)))]
24594 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24595 && peep2_reg_dead_p (3, operands[0])
24596 && peep2_reg_dead_p (5, operands[4])
24597 && !reg_overlap_mentioned_p (operands[0], operands[1])
24598 && !reg_overlap_mentioned_p (operands[0], operands[2])
24599 && !reg_overlap_mentioned_p (operands[4], operands[1])
24600 && (<MODE>mode != QImode
24601 || immediate_operand (operands[2], QImode)
24602 || any_QIreg_operand (operands[2], QImode))
24603 && ix86_match_ccmode (peep2_next_insn (4),
24604 (GET_CODE (operands[3]) == PLUS
24605 || GET_CODE (operands[3]) == MINUS)
24606 ? CCGOCmode : CCNOmode)"
24607 [(parallel [(set (match_dup 5) (match_dup 7))
24608 (set (match_dup 1) (match_dup 6))])]
24610 operands[5] = SET_DEST (PATTERN (peep2_next_insn (4)));
24612 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
24613 copy_rtx (operands[1]),
24616 = gen_rtx_COMPARE (GET_MODE (operands[5]),
24617 copy_rtx (operands[6]),
24622 [(set (match_operand:SWI12 0 "register_operand")
24623 (match_operand:SWI12 1 "memory_operand"))
24624 (parallel [(set (match_operand:SI 4 "register_operand")
24625 (match_operator:SI 3 "plusminuslogic_operator"
24627 (match_operand:SI 2 "nonmemory_operand")]))
24628 (clobber (reg:CC FLAGS_REG))])
24629 (set (match_operand:SWI12 5 "register_operand") (match_dup 0))
24630 (set (match_dup 1) (match_dup 5))
24631 (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
24632 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24633 && REGNO (operands[0]) == REGNO (operands[4])
24634 && peep2_reg_dead_p (3, operands[0])
24635 && peep2_reg_dead_p (5, operands[5])
24636 && (<MODE>mode != QImode
24637 || immediate_operand (operands[2], SImode)
24638 || any_QIreg_operand (operands[2], SImode))
24639 && !reg_overlap_mentioned_p (operands[0], operands[1])
24640 && !reg_overlap_mentioned_p (operands[0], operands[2])
24641 && !reg_overlap_mentioned_p (operands[5], operands[1])
24642 && ix86_match_ccmode (peep2_next_insn (4),
24643 (GET_CODE (operands[3]) == PLUS
24644 || GET_CODE (operands[3]) == MINUS)
24645 ? CCGOCmode : CCNOmode)"
24646 [(parallel [(set (match_dup 6) (match_dup 8))
24647 (set (match_dup 1) (match_dup 7))])]
24649 operands[6] = SET_DEST (PATTERN (peep2_next_insn (4)));
24651 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
24652 copy_rtx (operands[1]),
24653 gen_lowpart (<MODE>mode, operands[2]));
24655 = gen_rtx_COMPARE (GET_MODE (operands[6]),
24656 copy_rtx (operands[7]),
24660 ;; Likewise for cmpelim optimized pattern.
24662 [(set (match_operand:SWI 0 "register_operand")
24663 (match_operand:SWI 1 "memory_operand"))
24664 (parallel [(set (reg FLAGS_REG)
24665 (compare (match_operator:SWI 3 "plusminuslogic_operator"
24667 (match_operand:SWI 2 "<nonmemory_operand>")])
24669 (set (match_dup 0) (match_dup 3))])
24670 (set (match_operand:SWI 4 "register_operand") (match_dup 0))
24671 (set (match_dup 1) (match_dup 4))]
24672 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24673 && peep2_reg_dead_p (3, operands[0])
24674 && peep2_reg_dead_p (4, operands[4])
24675 && !reg_overlap_mentioned_p (operands[0], operands[1])
24676 && !reg_overlap_mentioned_p (operands[0], operands[2])
24677 && !reg_overlap_mentioned_p (operands[4], operands[1])
24678 && ix86_match_ccmode (peep2_next_insn (1),
24679 (GET_CODE (operands[3]) == PLUS
24680 || GET_CODE (operands[3]) == MINUS)
24681 ? CCGOCmode : CCNOmode)"
24682 [(parallel [(set (match_dup 5) (match_dup 7))
24683 (set (match_dup 1) (match_dup 6))])]
24685 operands[5] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
24687 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
24688 copy_rtx (operands[1]), operands[2]);
24690 = gen_rtx_COMPARE (GET_MODE (operands[5]), copy_rtx (operands[6]),
24694 ;; Special cases for xor, where (x ^= y) != 0 is (misoptimized)
24695 ;; into x = z; x ^= y; x != z
24697 [(set (match_operand:SWI 0 "register_operand")
24698 (match_operand:SWI 1 "memory_operand"))
24699 (set (match_operand:SWI 3 "register_operand") (match_dup 0))
24700 (parallel [(set (match_operand:SWI 4 "register_operand")
24701 (xor:SWI (match_dup 4)
24702 (match_operand:SWI 2 "<nonmemory_operand>")))
24703 (clobber (reg:CC FLAGS_REG))])
24704 (set (match_dup 1) (match_dup 4))
24705 (set (reg:CCZ FLAGS_REG)
24706 (compare:CCZ (match_operand:SWI 5 "register_operand")
24707 (match_operand:SWI 6 "<nonmemory_operand>")))]
24708 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24709 && (REGNO (operands[4]) == REGNO (operands[0])
24710 || REGNO (operands[4]) == REGNO (operands[3]))
24711 && (rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
24712 ? 3 : 0], operands[5])
24713 ? rtx_equal_p (operands[2], operands[6])
24714 : rtx_equal_p (operands[2], operands[5])
24715 && rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
24716 ? 3 : 0], operands[6]))
24717 && peep2_reg_dead_p (4, operands[4])
24718 && peep2_reg_dead_p (5, operands[REGNO (operands[4]) == REGNO (operands[0])
24720 && !reg_overlap_mentioned_p (operands[0], operands[1])
24721 && !reg_overlap_mentioned_p (operands[0], operands[2])
24722 && !reg_overlap_mentioned_p (operands[3], operands[0])
24723 && !reg_overlap_mentioned_p (operands[3], operands[1])
24724 && !reg_overlap_mentioned_p (operands[3], operands[2])
24725 && (<MODE>mode != QImode
24726 || immediate_operand (operands[2], QImode)
24727 || any_QIreg_operand (operands[2], QImode))"
24728 [(parallel [(set (match_dup 7) (match_dup 9))
24729 (set (match_dup 1) (match_dup 8))])]
24731 operands[7] = SET_DEST (PATTERN (peep2_next_insn (4)));
24732 operands[8] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
24735 = gen_rtx_COMPARE (GET_MODE (operands[7]),
24736 copy_rtx (operands[8]),
24741 [(set (match_operand:SWI12 0 "register_operand")
24742 (match_operand:SWI12 1 "memory_operand"))
24743 (set (match_operand:SWI12 3 "register_operand") (match_dup 0))
24744 (parallel [(set (match_operand:SI 4 "register_operand")
24745 (xor:SI (match_dup 4)
24746 (match_operand:SI 2 "<nonmemory_operand>")))
24747 (clobber (reg:CC FLAGS_REG))])
24748 (set (match_dup 1) (match_operand:SWI12 5 "register_operand"))
24749 (set (reg:CCZ FLAGS_REG)
24750 (compare:CCZ (match_operand:SWI12 6 "register_operand")
24751 (match_operand:SWI12 7 "<nonmemory_operand>")))]
24752 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24753 && (REGNO (operands[5]) == REGNO (operands[0])
24754 || REGNO (operands[5]) == REGNO (operands[3]))
24755 && REGNO (operands[5]) == REGNO (operands[4])
24756 && (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
24757 ? 3 : 0], operands[6])
24758 ? (REG_P (operands[2])
24759 ? REG_P (operands[7]) && REGNO (operands[2]) == REGNO (operands[7])
24760 : rtx_equal_p (operands[2], operands[7]))
24761 : (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
24762 ? 3 : 0], operands[7])
24763 && REG_P (operands[2])
24764 && REGNO (operands[2]) == REGNO (operands[6])))
24765 && peep2_reg_dead_p (4, operands[5])
24766 && peep2_reg_dead_p (5, operands[REGNO (operands[5]) == REGNO (operands[0])
24768 && !reg_overlap_mentioned_p (operands[0], operands[1])
24769 && !reg_overlap_mentioned_p (operands[0], operands[2])
24770 && !reg_overlap_mentioned_p (operands[3], operands[0])
24771 && !reg_overlap_mentioned_p (operands[3], operands[1])
24772 && !reg_overlap_mentioned_p (operands[3], operands[2])
24773 && (<MODE>mode != QImode
24774 || immediate_operand (operands[2], SImode)
24775 || any_QIreg_operand (operands[2], SImode))"
24776 [(parallel [(set (match_dup 8) (match_dup 10))
24777 (set (match_dup 1) (match_dup 9))])]
24779 operands[8] = SET_DEST (PATTERN (peep2_next_insn (4)));
24780 operands[9] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
24781 gen_lowpart (<MODE>mode, operands[2]));
24783 = gen_rtx_COMPARE (GET_MODE (operands[8]),
24784 copy_rtx (operands[9]),
24788 ;; Attempt to optimize away memory stores of values the memory already
24789 ;; has. See PR79593.
24791 [(set (match_operand 0 "register_operand")
24792 (match_operand 1 "memory_operand"))
24793 (set (match_operand 2 "memory_operand") (match_dup 0))]
24794 "!MEM_VOLATILE_P (operands[1])
24795 && !MEM_VOLATILE_P (operands[2])
24796 && rtx_equal_p (operands[1], operands[2])
24797 && !reg_overlap_mentioned_p (operands[0], operands[2])"
24798 [(set (match_dup 0) (match_dup 1))])
24800 ;; Attempt to always use XOR for zeroing registers (including FP modes).
24802 [(set (match_operand 0 "general_reg_operand")
24803 (match_operand 1 "const0_operand"))]
24804 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
24805 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
24806 && peep2_regno_dead_p (0, FLAGS_REG)"
24807 [(parallel [(set (match_dup 0) (const_int 0))
24808 (clobber (reg:CC FLAGS_REG))])]
24809 "operands[0] = gen_lowpart (word_mode, operands[0]);")
24812 [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
24814 "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
24815 && peep2_regno_dead_p (0, FLAGS_REG)"
24816 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
24817 (clobber (reg:CC FLAGS_REG))])])
24819 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
24821 [(set (match_operand:SWI248 0 "general_reg_operand")
24823 "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
24824 && peep2_regno_dead_p (0, FLAGS_REG)"
24825 [(parallel [(set (match_dup 0) (const_int -1))
24826 (clobber (reg:CC FLAGS_REG))])]
24828 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
24829 operands[0] = gen_lowpart (SImode, operands[0]);
24832 ;; Attempt to convert simple lea to add/shift.
24833 ;; These can be created by move expanders.
24834 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
24835 ;; relevant lea instructions were already split.
24838 [(set (match_operand:SWI48 0 "register_operand")
24839 (plus:SWI48 (match_dup 0)
24840 (match_operand:SWI48 1 "<nonmemory_operand>")))]
24842 && peep2_regno_dead_p (0, FLAGS_REG)"
24843 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
24844 (clobber (reg:CC FLAGS_REG))])])
24847 [(set (match_operand:SWI48 0 "register_operand")
24848 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
24851 && peep2_regno_dead_p (0, FLAGS_REG)"
24852 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
24853 (clobber (reg:CC FLAGS_REG))])])
24856 [(set (match_operand:DI 0 "register_operand")
24858 (plus:SI (match_operand:SI 1 "register_operand")
24859 (match_operand:SI 2 "nonmemory_operand"))))]
24860 "TARGET_64BIT && !TARGET_OPT_AGU
24861 && REGNO (operands[0]) == REGNO (operands[1])
24862 && peep2_regno_dead_p (0, FLAGS_REG)"
24863 [(parallel [(set (match_dup 0)
24864 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
24865 (clobber (reg:CC FLAGS_REG))])])
24868 [(set (match_operand:DI 0 "register_operand")
24870 (plus:SI (match_operand:SI 1 "nonmemory_operand")
24871 (match_operand:SI 2 "register_operand"))))]
24872 "TARGET_64BIT && !TARGET_OPT_AGU
24873 && REGNO (operands[0]) == REGNO (operands[2])
24874 && peep2_regno_dead_p (0, FLAGS_REG)"
24875 [(parallel [(set (match_dup 0)
24876 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
24877 (clobber (reg:CC FLAGS_REG))])])
24880 [(set (match_operand:SWI48 0 "register_operand")
24881 (mult:SWI48 (match_dup 0)
24882 (match_operand:SWI48 1 "const_int_operand")))]
24883 "pow2p_hwi (INTVAL (operands[1]))
24884 && peep2_regno_dead_p (0, FLAGS_REG)"
24885 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
24886 (clobber (reg:CC FLAGS_REG))])]
24887 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
24890 [(set (match_operand:DI 0 "register_operand")
24892 (mult:SI (match_operand:SI 1 "register_operand")
24893 (match_operand:SI 2 "const_int_operand"))))]
24895 && pow2p_hwi (INTVAL (operands[2]))
24896 && REGNO (operands[0]) == REGNO (operands[1])
24897 && peep2_regno_dead_p (0, FLAGS_REG)"
24898 [(parallel [(set (match_dup 0)
24899 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
24900 (clobber (reg:CC FLAGS_REG))])]
24901 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
24903 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
24904 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
24905 ;; On many CPUs it is also faster, since special hardware to avoid esp
24906 ;; dependencies is present.
24908 ;; While some of these conversions may be done using splitters, we use
24909 ;; peepholes in order to allow combine_stack_adjustments pass to see
24910 ;; nonobfuscated RTL.
24912 ;; Convert prologue esp subtractions to push.
24913 ;; We need register to push. In order to keep verify_flow_info happy we have
24915 ;; - use scratch and clobber it in order to avoid dependencies
24916 ;; - use already live register
24917 ;; We can't use the second way right now, since there is no reliable way how to
24918 ;; verify that given register is live. First choice will also most likely in
24919 ;; fewer dependencies. On the place of esp adjustments it is very likely that
24920 ;; call clobbered registers are dead. We may want to use base pointer as an
24921 ;; alternative when no register is available later.
24924 [(match_scratch:W 1 "r")
24925 (parallel [(set (reg:P SP_REG)
24926 (plus:P (reg:P SP_REG)
24927 (match_operand:P 0 "const_int_operand")))
24928 (clobber (reg:CC FLAGS_REG))
24929 (clobber (mem:BLK (scratch)))])]
24930 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
24931 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
24932 && !ix86_red_zone_used"
24933 [(clobber (match_dup 1))
24934 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
24935 (clobber (mem:BLK (scratch)))])])
24938 [(match_scratch:W 1 "r")
24939 (parallel [(set (reg:P SP_REG)
24940 (plus:P (reg:P SP_REG)
24941 (match_operand:P 0 "const_int_operand")))
24942 (clobber (reg:CC FLAGS_REG))
24943 (clobber (mem:BLK (scratch)))])]
24944 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
24945 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
24946 && !ix86_red_zone_used"
24947 [(clobber (match_dup 1))
24948 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
24949 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
24950 (clobber (mem:BLK (scratch)))])])
24952 ;; Convert esp subtractions to push.
24954 [(match_scratch:W 1 "r")
24955 (parallel [(set (reg:P SP_REG)
24956 (plus:P (reg:P SP_REG)
24957 (match_operand:P 0 "const_int_operand")))
24958 (clobber (reg:CC FLAGS_REG))])]
24959 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
24960 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
24961 && !ix86_red_zone_used"
24962 [(clobber (match_dup 1))
24963 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
24966 [(match_scratch:W 1 "r")
24967 (parallel [(set (reg:P SP_REG)
24968 (plus:P (reg:P SP_REG)
24969 (match_operand:P 0 "const_int_operand")))
24970 (clobber (reg:CC FLAGS_REG))])]
24971 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
24972 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
24973 && !ix86_red_zone_used"
24974 [(clobber (match_dup 1))
24975 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
24976 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
24978 ;; Convert epilogue deallocator to pop.
24980 [(match_scratch:W 1 "r")
24981 (parallel [(set (reg:P SP_REG)
24982 (plus:P (reg:P SP_REG)
24983 (match_operand:P 0 "const_int_operand")))
24984 (clobber (reg:CC FLAGS_REG))
24985 (clobber (mem:BLK (scratch)))])]
24986 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
24987 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
24988 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
24989 (clobber (mem:BLK (scratch)))])])
24991 ;; Two pops case is tricky, since pop causes dependency
24992 ;; on destination register. We use two registers if available.
24994 [(match_scratch:W 1 "r")
24995 (match_scratch:W 2 "r")
24996 (parallel [(set (reg:P SP_REG)
24997 (plus:P (reg:P SP_REG)
24998 (match_operand:P 0 "const_int_operand")))
24999 (clobber (reg:CC FLAGS_REG))
25000 (clobber (mem:BLK (scratch)))])]
25001 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
25002 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
25003 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25004 (clobber (mem:BLK (scratch)))])
25005 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
25008 [(match_scratch:W 1 "r")
25009 (parallel [(set (reg:P SP_REG)
25010 (plus:P (reg:P SP_REG)
25011 (match_operand:P 0 "const_int_operand")))
25012 (clobber (reg:CC FLAGS_REG))
25013 (clobber (mem:BLK (scratch)))])]
25014 "optimize_insn_for_size_p ()
25015 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
25016 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25017 (clobber (mem:BLK (scratch)))])
25018 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
25020 ;; Convert esp additions to pop.
25022 [(match_scratch:W 1 "r")
25023 (parallel [(set (reg:P SP_REG)
25024 (plus:P (reg:P SP_REG)
25025 (match_operand:P 0 "const_int_operand")))
25026 (clobber (reg:CC FLAGS_REG))])]
25027 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
25028 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
25030 ;; Two pops case is tricky, since pop causes dependency
25031 ;; on destination register. We use two registers if available.
25033 [(match_scratch:W 1 "r")
25034 (match_scratch:W 2 "r")
25035 (parallel [(set (reg:P SP_REG)
25036 (plus:P (reg:P SP_REG)
25037 (match_operand:P 0 "const_int_operand")))
25038 (clobber (reg:CC FLAGS_REG))])]
25039 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
25040 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25041 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
25044 [(match_scratch:W 1 "r")
25045 (parallel [(set (reg:P SP_REG)
25046 (plus:P (reg:P SP_REG)
25047 (match_operand:P 0 "const_int_operand")))
25048 (clobber (reg:CC FLAGS_REG))])]
25049 "optimize_insn_for_size_p ()
25050 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
25051 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25052 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
25054 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
25055 ;; required and register dies. Similarly for 128 to -128.
25057 [(set (match_operand 0 "flags_reg_operand")
25058 (match_operator 1 "compare_operator"
25059 [(match_operand 2 "register_operand")
25060 (match_operand 3 "const_int_operand")]))]
25061 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
25062 && incdec_operand (operands[3], GET_MODE (operands[3])))
25063 || (!TARGET_FUSE_CMP_AND_BRANCH
25064 && INTVAL (operands[3]) == 128))
25065 && ix86_match_ccmode (insn, CCGCmode)
25066 && peep2_reg_dead_p (1, operands[2])"
25067 [(parallel [(set (match_dup 0)
25068 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
25069 (clobber (match_dup 2))])])
25071 ;; Convert imul by three, five and nine into lea
25074 [(set (match_operand:SWI48 0 "register_operand")
25075 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
25076 (match_operand:SWI48 2 "const359_operand")))
25077 (clobber (reg:CC FLAGS_REG))])]
25078 "!TARGET_PARTIAL_REG_STALL
25079 || <MODE>mode == SImode
25080 || optimize_function_for_size_p (cfun)"
25081 [(set (match_dup 0)
25082 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
25084 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
25088 [(set (match_operand:SWI48 0 "register_operand")
25089 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
25090 (match_operand:SWI48 2 "const359_operand")))
25091 (clobber (reg:CC FLAGS_REG))])]
25092 "optimize_insn_for_speed_p ()
25093 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
25094 [(set (match_dup 0) (match_dup 1))
25096 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
25098 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
25100 ;; imul $32bit_imm, mem, reg is vector decoded, while
25101 ;; imul $32bit_imm, reg, reg is direct decoded.
25103 [(match_scratch:SWI48 3 "r")
25104 (parallel [(set (match_operand:SWI48 0 "register_operand")
25105 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
25106 (match_operand:SWI48 2 "immediate_operand")))
25107 (clobber (reg:CC FLAGS_REG))])]
25108 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
25109 && !satisfies_constraint_K (operands[2])"
25110 [(set (match_dup 3) (match_dup 1))
25111 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
25112 (clobber (reg:CC FLAGS_REG))])])
25115 [(match_scratch:SI 3 "r")
25116 (parallel [(set (match_operand:DI 0 "register_operand")
25118 (mult:SI (match_operand:SI 1 "memory_operand")
25119 (match_operand:SI 2 "immediate_operand"))))
25120 (clobber (reg:CC FLAGS_REG))])]
25122 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
25123 && !satisfies_constraint_K (operands[2])"
25124 [(set (match_dup 3) (match_dup 1))
25125 (parallel [(set (match_dup 0)
25126 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
25127 (clobber (reg:CC FLAGS_REG))])])
25129 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
25130 ;; Convert it into imul reg, reg
25131 ;; It would be better to force assembler to encode instruction using long
25132 ;; immediate, but there is apparently no way to do so.
25134 [(parallel [(set (match_operand:SWI248 0 "register_operand")
25136 (match_operand:SWI248 1 "nonimmediate_operand")
25137 (match_operand:SWI248 2 "const_int_operand")))
25138 (clobber (reg:CC FLAGS_REG))])
25139 (match_scratch:SWI248 3 "r")]
25140 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
25141 && satisfies_constraint_K (operands[2])"
25142 [(set (match_dup 3) (match_dup 2))
25143 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
25144 (clobber (reg:CC FLAGS_REG))])]
25146 if (!rtx_equal_p (operands[0], operands[1]))
25147 emit_move_insn (operands[0], operands[1]);
25150 ;; After splitting up read-modify operations, array accesses with memory
25151 ;; operands might end up in form:
25153 ;; movl 4(%esp), %edx
25155 ;; instead of pre-splitting:
25157 ;; addl 4(%esp), %eax
25159 ;; movl 4(%esp), %edx
25160 ;; leal (%edx,%eax,4), %eax
25163 [(match_scratch:W 5 "r")
25164 (parallel [(set (match_operand 0 "register_operand")
25165 (ashift (match_operand 1 "register_operand")
25166 (match_operand 2 "const_int_operand")))
25167 (clobber (reg:CC FLAGS_REG))])
25168 (parallel [(set (match_operand 3 "register_operand")
25169 (plus (match_dup 0)
25170 (match_operand 4 "x86_64_general_operand")))
25171 (clobber (reg:CC FLAGS_REG))])]
25172 "IN_RANGE (INTVAL (operands[2]), 1, 3)
25173 /* Validate MODE for lea. */
25174 && ((!TARGET_PARTIAL_REG_STALL
25175 && (GET_MODE (operands[0]) == QImode
25176 || GET_MODE (operands[0]) == HImode))
25177 || GET_MODE (operands[0]) == SImode
25178 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
25179 && (rtx_equal_p (operands[0], operands[3])
25180 || peep2_reg_dead_p (2, operands[0]))
25181 /* We reorder load and the shift. */
25182 && !reg_overlap_mentioned_p (operands[0], operands[4])"
25183 [(set (match_dup 5) (match_dup 4))
25184 (set (match_dup 0) (match_dup 1))]
25186 machine_mode op1mode = GET_MODE (operands[1]);
25187 machine_mode mode = op1mode == DImode ? DImode : SImode;
25188 int scale = 1 << INTVAL (operands[2]);
25189 rtx index = gen_lowpart (word_mode, operands[1]);
25190 rtx base = gen_lowpart (word_mode, operands[5]);
25191 rtx dest = gen_lowpart (mode, operands[3]);
25193 operands[1] = gen_rtx_PLUS (word_mode, base,
25194 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
25195 if (mode != word_mode)
25196 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
25198 operands[5] = base;
25199 if (op1mode != word_mode)
25200 operands[5] = gen_lowpart (op1mode, operands[5]);
25202 operands[0] = dest;
25205 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
25206 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
25207 ;; caught for use by garbage collectors and the like. Using an insn that
25208 ;; maps to SIGILL makes it more likely the program will rightfully die.
25209 ;; Keeping with tradition, "6" is in honor of #UD.
25210 (define_insn "trap"
25211 [(trap_if (const_int 1) (const_int 6))]
25214 #ifdef HAVE_AS_IX86_UD2
25217 return ASM_SHORT "0x0b0f";
25220 [(set_attr "length" "2")])
25223 [(unspec_volatile [(const_int 0)] UNSPECV_UD2)]
25226 #ifdef HAVE_AS_IX86_UD2
25229 return ASM_SHORT "0x0b0f";
25232 [(set_attr "length" "2")])
25234 (define_expand "prefetch"
25235 [(prefetch (match_operand 0 "address_operand")
25236 (match_operand:SI 1 "const_int_operand")
25237 (match_operand:SI 2 "const_int_operand"))]
25238 "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
25240 bool write = operands[1] != const0_rtx;
25241 int locality = INTVAL (operands[2]);
25243 gcc_assert (IN_RANGE (locality, 0, 3));
25245 /* Use 3dNOW prefetch in case we are asking for write prefetch not
25246 supported by SSE counterpart (non-SSE2 athlon machines) or the
25247 SSE prefetch is not available (K6 machines). Otherwise use SSE
25248 prefetch as it allows specifying of locality. */
25252 if (TARGET_PREFETCHWT1)
25253 operands[2] = GEN_INT (MAX (locality, 2));
25254 else if (TARGET_PRFCHW)
25255 operands[2] = GEN_INT (3);
25256 else if (TARGET_3DNOW && !TARGET_SSE2)
25257 operands[2] = GEN_INT (3);
25258 else if (TARGET_PREFETCH_SSE)
25259 operands[1] = const0_rtx;
25262 gcc_assert (TARGET_3DNOW);
25263 operands[2] = GEN_INT (3);
25268 if (TARGET_PREFETCH_SSE)
25272 gcc_assert (TARGET_3DNOW);
25273 operands[2] = GEN_INT (3);
25278 (define_insn "*prefetch_sse"
25279 [(prefetch (match_operand 0 "address_operand" "p")
25281 (match_operand:SI 1 "const_int_operand"))]
25282 "TARGET_PREFETCH_SSE"
25284 static const char * const patterns[4] = {
25285 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
25288 int locality = INTVAL (operands[1]);
25289 gcc_assert (IN_RANGE (locality, 0, 3));
25291 return patterns[locality];
25293 [(set_attr "type" "sse")
25294 (set_attr "atom_sse_attr" "prefetch")
25295 (set (attr "length_address")
25296 (symbol_ref "memory_address_length (operands[0], false)"))
25297 (set_attr "memory" "none")])
25299 (define_insn "*prefetch_3dnow"
25300 [(prefetch (match_operand 0 "address_operand" "p")
25301 (match_operand:SI 1 "const_int_operand")
25303 "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1"
25305 if (operands[1] == const0_rtx)
25306 return "prefetch\t%a0";
25308 return "prefetchw\t%a0";
25310 [(set_attr "type" "mmx")
25311 (set (attr "length_address")
25312 (symbol_ref "memory_address_length (operands[0], false)"))
25313 (set_attr "memory" "none")])
25315 (define_insn "*prefetch_prefetchwt1"
25316 [(prefetch (match_operand 0 "address_operand" "p")
25319 "TARGET_PREFETCHWT1"
25320 "prefetchwt1\t%a0";
25321 [(set_attr "type" "sse")
25322 (set (attr "length_address")
25323 (symbol_ref "memory_address_length (operands[0], false)"))
25324 (set_attr "memory" "none")])
25326 (define_insn "prefetchi"
25327 [(unspec_volatile [(match_operand 0 "local_func_symbolic_operand" "p")
25328 (match_operand:SI 1 "const_int_operand")]
25329 UNSPECV_PREFETCHI)]
25330 "TARGET_PREFETCHI && TARGET_64BIT"
25332 static const char * const patterns[2] = {
25333 "prefetchit1\t%0", "prefetchit0\t%0"
25336 int locality = INTVAL (operands[1]);
25337 gcc_assert (IN_RANGE (locality, 2, 3));
25339 return patterns[locality - 2];
25341 [(set_attr "type" "sse")
25342 (set (attr "length_address")
25343 (symbol_ref "memory_address_length (operands[0], false)"))
25344 (set_attr "memory" "none")])
25346 (define_expand "stack_protect_set"
25347 [(match_operand 0 "memory_operand")
25348 (match_operand 1 "memory_operand")]
25351 emit_insn (gen_stack_protect_set_1
25352 (ptr_mode, operands[0], operands[1]));
25356 (define_insn "@stack_protect_set_1_<mode>"
25357 [(set (match_operand:PTR 0 "memory_operand" "=m")
25358 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
25360 (set (match_scratch:PTR 2 "=&r") (const_int 0))
25361 (clobber (reg:CC FLAGS_REG))]
25364 output_asm_insn ("mov{<imodesuffix>}\t{%1, %2|%2, %1}", operands);
25365 output_asm_insn ("mov{<imodesuffix>}\t{%2, %0|%0, %2}", operands);
25366 return "xor{l}\t%k2, %k2";
25368 [(set_attr "type" "multi")])
25370 ;; Patterns and peephole2s to optimize stack_protect_set_1_<mode>
25371 ;; immediately followed by *mov{s,d}i_internal to the same register,
25372 ;; where we can avoid the xor{l} above. We don't split this, so that
25373 ;; scheduling or anything else doesn't separate the *stack_protect_set*
25374 ;; pattern from the set of the register that overwrites the register
25375 ;; with a new value.
25376 (define_insn "*stack_protect_set_2_<mode>"
25377 [(set (match_operand:PTR 0 "memory_operand" "=m")
25378 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
25380 (set (match_operand:SI 1 "register_operand" "=&r")
25381 (match_operand:SI 2 "general_operand" "g"))
25382 (clobber (reg:CC FLAGS_REG))]
25384 && !reg_overlap_mentioned_p (operands[1], operands[2])"
25386 output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
25387 output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
25388 if (pic_32bit_operand (operands[2], SImode)
25389 || ix86_use_lea_for_mov (insn, operands + 1))
25390 return "lea{l}\t{%E2, %1|%1, %E2}";
25392 return "mov{l}\t{%2, %1|%1, %2}";
25394 [(set_attr "type" "multi")
25395 (set_attr "length" "24")])
25398 [(parallel [(set (match_operand:PTR 0 "memory_operand")
25399 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
25401 (set (match_operand:PTR 2 "general_reg_operand") (const_int 0))
25402 (clobber (reg:CC FLAGS_REG))])
25403 (set (match_operand:SI 3 "general_reg_operand")
25404 (match_operand:SI 4))]
25405 "REGNO (operands[2]) == REGNO (operands[3])
25406 && general_operand (operands[4], SImode)
25407 && (general_reg_operand (operands[4], SImode)
25408 || memory_operand (operands[4], SImode)
25409 || immediate_operand (operands[4], SImode))
25410 && !reg_overlap_mentioned_p (operands[3], operands[4])"
25411 [(parallel [(set (match_dup 0)
25412 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
25413 (set (match_dup 3) (match_dup 4))
25414 (clobber (reg:CC FLAGS_REG))])])
25416 (define_insn "*stack_protect_set_3"
25417 [(set (match_operand:DI 0 "memory_operand" "=m,m,m")
25418 (unspec:DI [(match_operand:DI 3 "memory_operand" "m,m,m")]
25420 (set (match_operand:DI 1 "register_operand" "=&r,r,r")
25421 (match_operand:DI 2 "general_operand" "Z,rem,i"))
25422 (clobber (reg:CC FLAGS_REG))]
25424 && reload_completed
25425 && !reg_overlap_mentioned_p (operands[1], operands[2])"
25427 output_asm_insn ("mov{q}\t{%3, %1|%1, %3}", operands);
25428 output_asm_insn ("mov{q}\t{%1, %0|%0, %1}", operands);
25429 if (pic_32bit_operand (operands[2], DImode))
25430 return "lea{q}\t{%E2, %1|%1, %E2}";
25431 else if (which_alternative == 0)
25432 return "mov{l}\t{%k2, %k1|%k1, %k2}";
25433 else if (which_alternative == 2)
25434 return "movabs{q}\t{%2, %1|%1, %2}";
25435 else if (ix86_use_lea_for_mov (insn, operands + 1))
25436 return "lea{q}\t{%E2, %1|%1, %E2}";
25438 return "mov{q}\t{%2, %1|%1, %2}";
25440 [(set_attr "type" "multi")
25441 (set_attr "length" "24")])
25444 [(parallel [(set (match_operand:DI 0 "memory_operand")
25445 (unspec:DI [(match_operand:DI 1 "memory_operand")]
25447 (set (match_operand:DI 2 "general_reg_operand") (const_int 0))
25448 (clobber (reg:CC FLAGS_REG))])
25449 (set (match_dup 2) (match_operand:DI 3))]
25451 && general_operand (operands[3], DImode)
25452 && (general_reg_operand (operands[3], DImode)
25453 || memory_operand (operands[3], DImode)
25454 || x86_64_zext_immediate_operand (operands[3], DImode)
25455 || x86_64_immediate_operand (operands[3], DImode)
25456 || (CONSTANT_P (operands[3])
25457 && (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[3]))))
25458 && !reg_overlap_mentioned_p (operands[2], operands[3])"
25459 [(parallel [(set (match_dup 0)
25460 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
25461 (set (match_dup 2) (match_dup 3))
25462 (clobber (reg:CC FLAGS_REG))])])
25464 (define_expand "stack_protect_test"
25465 [(match_operand 0 "memory_operand")
25466 (match_operand 1 "memory_operand")
25470 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
25472 emit_insn (gen_stack_protect_test_1
25473 (ptr_mode, flags, operands[0], operands[1]));
25475 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
25476 flags, const0_rtx, operands[2]));
25480 (define_insn "@stack_protect_test_1_<mode>"
25481 [(set (match_operand:CCZ 0 "flags_reg_operand")
25482 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
25483 (match_operand:PTR 2 "memory_operand" "m")]
25485 (clobber (match_scratch:PTR 3 "=&r"))]
25488 output_asm_insn ("mov{<imodesuffix>}\t{%1, %3|%3, %1}", operands);
25489 return "sub{<imodesuffix>}\t{%2, %3|%3, %2}";
25491 [(set_attr "type" "multi")])
25493 (define_insn "sse4_2_crc32<mode>"
25494 [(set (match_operand:SI 0 "register_operand" "=r")
25496 [(match_operand:SI 1 "register_operand" "0")
25497 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
25500 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
25501 [(set_attr "type" "sselog1")
25502 (set_attr "prefix_rep" "1")
25503 (set_attr "prefix_extra" "1")
25504 (set (attr "prefix_data16")
25505 (if_then_else (match_operand:HI 2)
25507 (const_string "*")))
25508 (set (attr "prefix_rex")
25509 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
25511 (const_string "*")))
25512 (set_attr "mode" "SI")])
25514 (define_insn "sse4_2_crc32di"
25515 [(set (match_operand:DI 0 "register_operand" "=r")
25518 [(match_operand:SI 1 "register_operand" "0")
25519 (match_operand:DI 2 "nonimmediate_operand" "rm")]
25521 "TARGET_64BIT && TARGET_CRC32"
25522 "crc32{q}\t{%2, %0|%0, %2}"
25523 [(set_attr "type" "sselog1")
25524 (set_attr "prefix_rep" "1")
25525 (set_attr "prefix_extra" "1")
25526 (set_attr "mode" "DI")])
25528 (define_insn "rdpmc"
25529 [(set (match_operand:DI 0 "register_operand" "=A")
25530 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
25534 [(set_attr "type" "other")
25535 (set_attr "length" "2")])
25537 (define_insn "rdpmc_rex64"
25538 [(set (match_operand:DI 0 "register_operand" "=a")
25539 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
25541 (set (match_operand:DI 1 "register_operand" "=d")
25542 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
25545 [(set_attr "type" "other")
25546 (set_attr "length" "2")])
25548 (define_insn "rdtsc"
25549 [(set (match_operand:DI 0 "register_operand" "=A")
25550 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
25553 [(set_attr "type" "other")
25554 (set_attr "length" "2")])
25556 (define_insn "rdtsc_rex64"
25557 [(set (match_operand:DI 0 "register_operand" "=a")
25558 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
25559 (set (match_operand:DI 1 "register_operand" "=d")
25560 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
25563 [(set_attr "type" "other")
25564 (set_attr "length" "2")])
25566 (define_insn "rdtscp"
25567 [(set (match_operand:DI 0 "register_operand" "=A")
25568 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
25569 (set (match_operand:SI 1 "register_operand" "=c")
25570 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
25573 [(set_attr "type" "other")
25574 (set_attr "length" "3")])
25576 (define_insn "rdtscp_rex64"
25577 [(set (match_operand:DI 0 "register_operand" "=a")
25578 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
25579 (set (match_operand:DI 1 "register_operand" "=d")
25580 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
25581 (set (match_operand:SI 2 "register_operand" "=c")
25582 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
25585 [(set_attr "type" "other")
25586 (set_attr "length" "3")])
25588 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25590 ;; FXSR, XSAVE and XSAVEOPT instructions
25592 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25594 (define_insn "fxsave"
25595 [(set (match_operand:BLK 0 "memory_operand" "=m")
25596 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
25599 [(set_attr "type" "other")
25600 (set_attr "memory" "store")
25601 (set (attr "length")
25602 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25604 (define_insn "fxsave64"
25605 [(set (match_operand:BLK 0 "memory_operand" "=m")
25606 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
25607 "TARGET_64BIT && TARGET_FXSR"
25609 [(set_attr "type" "other")
25610 (set_attr "memory" "store")
25611 (set (attr "length")
25612 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
25614 (define_insn "fxrstor"
25615 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
25619 [(set_attr "type" "other")
25620 (set_attr "memory" "load")
25621 (set (attr "length")
25622 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25624 (define_insn "fxrstor64"
25625 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
25626 UNSPECV_FXRSTOR64)]
25627 "TARGET_64BIT && TARGET_FXSR"
25629 [(set_attr "type" "other")
25630 (set_attr "memory" "load")
25631 (set (attr "length")
25632 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
25634 (define_int_iterator ANY_XSAVE
25636 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
25637 (UNSPECV_XSAVEC "TARGET_XSAVEC")
25638 (UNSPECV_XSAVES "TARGET_XSAVES")])
25640 (define_int_iterator ANY_XSAVE64
25642 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
25643 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
25644 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
25646 (define_int_attr xsave
25647 [(UNSPECV_XSAVE "xsave")
25648 (UNSPECV_XSAVE64 "xsave64")
25649 (UNSPECV_XSAVEOPT "xsaveopt")
25650 (UNSPECV_XSAVEOPT64 "xsaveopt64")
25651 (UNSPECV_XSAVEC "xsavec")
25652 (UNSPECV_XSAVEC64 "xsavec64")
25653 (UNSPECV_XSAVES "xsaves")
25654 (UNSPECV_XSAVES64 "xsaves64")])
25656 (define_int_iterator ANY_XRSTOR
25658 (UNSPECV_XRSTORS "TARGET_XSAVES")])
25660 (define_int_iterator ANY_XRSTOR64
25662 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
25664 (define_int_attr xrstor
25665 [(UNSPECV_XRSTOR "xrstor")
25666 (UNSPECV_XRSTOR64 "xrstor")
25667 (UNSPECV_XRSTORS "xrstors")
25668 (UNSPECV_XRSTORS64 "xrstors")])
25670 (define_insn "<xsave>"
25671 [(set (match_operand:BLK 0 "memory_operand" "=m")
25672 (unspec_volatile:BLK
25673 [(match_operand:DI 1 "register_operand" "A")]
25675 "!TARGET_64BIT && TARGET_XSAVE"
25677 [(set_attr "type" "other")
25678 (set_attr "memory" "store")
25679 (set (attr "length")
25680 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25682 (define_insn "<xsave>_rex64"
25683 [(set (match_operand:BLK 0 "memory_operand" "=m")
25684 (unspec_volatile:BLK
25685 [(match_operand:SI 1 "register_operand" "a")
25686 (match_operand:SI 2 "register_operand" "d")]
25688 "TARGET_64BIT && TARGET_XSAVE"
25690 [(set_attr "type" "other")
25691 (set_attr "memory" "store")
25692 (set (attr "length")
25693 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25695 (define_insn "<xsave>"
25696 [(set (match_operand:BLK 0 "memory_operand" "=m")
25697 (unspec_volatile:BLK
25698 [(match_operand:SI 1 "register_operand" "a")
25699 (match_operand:SI 2 "register_operand" "d")]
25701 "TARGET_64BIT && TARGET_XSAVE"
25703 [(set_attr "type" "other")
25704 (set_attr "memory" "store")
25705 (set (attr "length")
25706 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
25708 (define_insn "<xrstor>"
25709 [(unspec_volatile:BLK
25710 [(match_operand:BLK 0 "memory_operand" "m")
25711 (match_operand:DI 1 "register_operand" "A")]
25713 "!TARGET_64BIT && TARGET_XSAVE"
25715 [(set_attr "type" "other")
25716 (set_attr "memory" "load")
25717 (set (attr "length")
25718 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25720 (define_insn "<xrstor>_rex64"
25721 [(unspec_volatile:BLK
25722 [(match_operand:BLK 0 "memory_operand" "m")
25723 (match_operand:SI 1 "register_operand" "a")
25724 (match_operand:SI 2 "register_operand" "d")]
25726 "TARGET_64BIT && TARGET_XSAVE"
25728 [(set_attr "type" "other")
25729 (set_attr "memory" "load")
25730 (set (attr "length")
25731 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25733 (define_insn "<xrstor>64"
25734 [(unspec_volatile:BLK
25735 [(match_operand:BLK 0 "memory_operand" "m")
25736 (match_operand:SI 1 "register_operand" "a")
25737 (match_operand:SI 2 "register_operand" "d")]
25739 "TARGET_64BIT && TARGET_XSAVE"
25741 [(set_attr "type" "other")
25742 (set_attr "memory" "load")
25743 (set (attr "length")
25744 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
25746 (define_insn "xsetbv"
25747 [(unspec_volatile:SI
25748 [(match_operand:SI 0 "register_operand" "c")
25749 (match_operand:DI 1 "register_operand" "A")]
25751 "!TARGET_64BIT && TARGET_XSAVE"
25753 [(set_attr "type" "other")])
25755 (define_insn "xsetbv_rex64"
25756 [(unspec_volatile:SI
25757 [(match_operand:SI 0 "register_operand" "c")
25758 (match_operand:SI 1 "register_operand" "a")
25759 (match_operand:SI 2 "register_operand" "d")]
25761 "TARGET_64BIT && TARGET_XSAVE"
25763 [(set_attr "type" "other")])
25765 (define_insn "xgetbv"
25766 [(set (match_operand:DI 0 "register_operand" "=A")
25767 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
25769 "!TARGET_64BIT && TARGET_XSAVE"
25771 [(set_attr "type" "other")])
25773 (define_insn "xgetbv_rex64"
25774 [(set (match_operand:DI 0 "register_operand" "=a")
25775 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
25777 (set (match_operand:DI 1 "register_operand" "=d")
25778 (unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))]
25779 "TARGET_64BIT && TARGET_XSAVE"
25781 [(set_attr "type" "other")])
25783 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25785 ;; Floating-point instructions for atomic compound assignments
25787 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25789 ; Clobber all floating-point registers on environment save and restore
25790 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
25791 (define_insn "fnstenv"
25792 [(set (match_operand:BLK 0 "memory_operand" "=m")
25793 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
25794 (clobber (reg:XF ST0_REG))
25795 (clobber (reg:XF ST1_REG))
25796 (clobber (reg:XF ST2_REG))
25797 (clobber (reg:XF ST3_REG))
25798 (clobber (reg:XF ST4_REG))
25799 (clobber (reg:XF ST5_REG))
25800 (clobber (reg:XF ST6_REG))
25801 (clobber (reg:XF ST7_REG))]
25804 [(set_attr "type" "other")
25805 (set_attr "memory" "store")
25806 (set (attr "length")
25807 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
25809 (define_insn "fldenv"
25810 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
25812 (clobber (reg:XF ST0_REG))
25813 (clobber (reg:XF ST1_REG))
25814 (clobber (reg:XF ST2_REG))
25815 (clobber (reg:XF ST3_REG))
25816 (clobber (reg:XF ST4_REG))
25817 (clobber (reg:XF ST5_REG))
25818 (clobber (reg:XF ST6_REG))
25819 (clobber (reg:XF ST7_REG))]
25822 [(set_attr "type" "other")
25823 (set_attr "memory" "load")
25824 (set (attr "length")
25825 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
25827 (define_insn "fnstsw"
25828 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
25829 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
25832 [(set_attr "type" "other,other")
25833 (set_attr "memory" "none,store")
25834 (set (attr "length")
25835 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
25837 (define_insn "fnclex"
25838 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
25841 [(set_attr "type" "other")
25842 (set_attr "memory" "none")
25843 (set_attr "length" "2")])
25845 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25847 ;; LWP instructions
25849 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25851 (define_insn "@lwp_llwpcb<mode>"
25852 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
25853 UNSPECV_LLWP_INTRINSIC)]
25856 [(set_attr "type" "lwp")
25857 (set_attr "mode" "<MODE>")
25858 (set_attr "length" "5")])
25860 (define_insn "@lwp_slwpcb<mode>"
25861 [(set (match_operand:P 0 "register_operand" "=r")
25862 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
25865 [(set_attr "type" "lwp")
25866 (set_attr "mode" "<MODE>")
25867 (set_attr "length" "5")])
25869 (define_insn "@lwp_lwpval<mode>"
25870 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
25871 (match_operand:SI 1 "nonimmediate_operand" "rm")
25872 (match_operand:SI 2 "const_int_operand")]
25873 UNSPECV_LWPVAL_INTRINSIC)]
25875 "lwpval\t{%2, %1, %0|%0, %1, %2}"
25876 [(set_attr "type" "lwp")
25877 (set_attr "mode" "<MODE>")
25878 (set (attr "length")
25879 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
25881 (define_insn "@lwp_lwpins<mode>"
25882 [(set (reg:CCC FLAGS_REG)
25883 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
25884 (match_operand:SI 1 "nonimmediate_operand" "rm")
25885 (match_operand:SI 2 "const_int_operand")]
25886 UNSPECV_LWPINS_INTRINSIC))]
25888 "lwpins\t{%2, %1, %0|%0, %1, %2}"
25889 [(set_attr "type" "lwp")
25890 (set_attr "mode" "<MODE>")
25891 (set (attr "length")
25892 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
25894 (define_int_iterator RDFSGSBASE
25898 (define_int_iterator WRFSGSBASE
25902 (define_int_attr fsgs
25903 [(UNSPECV_RDFSBASE "fs")
25904 (UNSPECV_RDGSBASE "gs")
25905 (UNSPECV_WRFSBASE "fs")
25906 (UNSPECV_WRGSBASE "gs")])
25908 (define_insn "rd<fsgs>base<mode>"
25909 [(set (match_operand:SWI48 0 "register_operand" "=r")
25910 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
25911 "TARGET_64BIT && TARGET_FSGSBASE"
25913 [(set_attr "type" "other")
25914 (set_attr "prefix_extra" "2")])
25916 (define_insn "wr<fsgs>base<mode>"
25917 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
25919 "TARGET_64BIT && TARGET_FSGSBASE"
25921 [(set_attr "type" "other")
25922 (set_attr "prefix_extra" "2")])
25924 (define_insn "ptwrite<mode>"
25925 [(unspec_volatile [(match_operand:SWI48 0 "nonimmediate_operand" "rm")]
25929 [(set_attr "type" "other")
25930 (set_attr "prefix_extra" "2")])
25932 (define_insn "@rdrand<mode>"
25933 [(set (match_operand:SWI248 0 "register_operand" "=r")
25934 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
25935 (set (reg:CCC FLAGS_REG)
25936 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
25939 [(set_attr "type" "other")
25940 (set_attr "prefix_extra" "1")])
25942 (define_insn "@rdseed<mode>"
25943 [(set (match_operand:SWI248 0 "register_operand" "=r")
25944 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
25945 (set (reg:CCC FLAGS_REG)
25946 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
25949 [(set_attr "type" "other")
25950 (set_attr "prefix_extra" "1")])
25952 (define_expand "pause"
25953 [(set (match_dup 0)
25954 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
25957 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
25958 MEM_VOLATILE_P (operands[0]) = 1;
25961 ;; Use "rep; nop", instead of "pause", to support older assemblers.
25962 ;; They have the same encoding.
25963 (define_insn "*pause"
25964 [(set (match_operand:BLK 0)
25965 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
25968 [(set_attr "length" "2")
25969 (set_attr "memory" "unknown")])
25971 ;; CET instructions
25972 (define_insn "@rdssp<mode>"
25973 [(set (match_operand:SWI48 0 "register_operand" "=r")
25974 (unspec_volatile:SWI48 [(match_operand:SWI48 1 "register_operand" "0")]
25975 UNSPECV_NOP_RDSSP))]
25976 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
25977 "rdssp<mskmodesuffix>\t%0"
25978 [(set_attr "length" "6")
25979 (set_attr "type" "other")])
25981 (define_insn "@incssp<mode>"
25982 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
25984 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
25985 "incssp<mskmodesuffix>\t%0"
25986 [(set_attr "length" "4")
25987 (set_attr "type" "other")])
25989 (define_insn "saveprevssp"
25990 [(unspec_volatile [(const_int 0)] UNSPECV_SAVEPREVSSP)]
25993 [(set_attr "length" "5")
25994 (set_attr "type" "other")])
25996 (define_insn "rstorssp"
25997 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")]
26001 [(set_attr "length" "5")
26002 (set_attr "type" "other")])
26004 (define_insn "@wrss<mode>"
26005 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
26006 (match_operand:SWI48 1 "memory_operand" "m")]
26009 "wrss<mskmodesuffix>\t%0, %1"
26010 [(set_attr "length" "3")
26011 (set_attr "type" "other")])
26013 (define_insn "@wruss<mode>"
26014 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
26015 (match_operand:SWI48 1 "memory_operand" "m")]
26018 "wruss<mskmodesuffix>\t%0, %1"
26019 [(set_attr "length" "4")
26020 (set_attr "type" "other")])
26022 (define_insn "setssbsy"
26023 [(unspec_volatile [(const_int 0)] UNSPECV_SETSSBSY)]
26026 [(set_attr "length" "4")
26027 (set_attr "type" "other")])
26029 (define_insn "clrssbsy"
26030 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")]
26034 [(set_attr "length" "4")
26035 (set_attr "type" "other")])
26037 (define_insn "nop_endbr"
26038 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]
26039 "(flag_cf_protection & CF_BRANCH)"
26041 return TARGET_64BIT ? "endbr64" : "endbr32";
26043 [(set_attr "length" "4")
26044 (set_attr "length_immediate" "0")
26045 (set_attr "modrm" "0")])
26048 (define_expand "xbegin"
26049 [(set (match_operand:SI 0 "register_operand")
26050 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
26053 rtx_code_label *label = gen_label_rtx ();
26055 /* xbegin is emitted as jump_insn, so reload won't be able
26056 to reload its operand. Force the value into AX hard register. */
26057 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
26058 emit_move_insn (ax_reg, constm1_rtx);
26060 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
26062 emit_label (label);
26063 LABEL_NUSES (label) = 1;
26065 emit_move_insn (operands[0], ax_reg);
26070 (define_insn "xbegin_1"
26072 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
26074 (label_ref (match_operand 1))
26076 (set (match_operand:SI 0 "register_operand" "+a")
26077 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
26080 [(set_attr "type" "other")
26081 (set_attr "length" "6")])
26083 (define_insn "xend"
26084 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
26087 [(set_attr "type" "other")
26088 (set_attr "length" "3")])
26090 (define_insn "xabort"
26091 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand")]
26095 [(set_attr "type" "other")
26096 (set_attr "length" "3")])
26098 (define_expand "xtest"
26099 [(set (match_operand:QI 0 "register_operand")
26100 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
26103 emit_insn (gen_xtest_1 ());
26105 ix86_expand_setcc (operands[0], NE,
26106 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
26110 (define_insn "xtest_1"
26111 [(set (reg:CCZ FLAGS_REG)
26112 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
26115 [(set_attr "type" "other")
26116 (set_attr "length" "3")])
26118 (define_insn "clwb"
26119 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
26123 [(set_attr "type" "sse")
26124 (set_attr "atom_sse_attr" "fence")
26125 (set_attr "memory" "unknown")])
26127 (define_insn "clflushopt"
26128 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
26129 UNSPECV_CLFLUSHOPT)]
26130 "TARGET_CLFLUSHOPT"
26132 [(set_attr "type" "sse")
26133 (set_attr "atom_sse_attr" "fence")
26134 (set_attr "memory" "unknown")])
26136 ;; MONITORX and MWAITX
26137 (define_insn "mwaitx"
26138 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
26139 (match_operand:SI 1 "register_operand" "a")
26140 (match_operand:SI 2 "register_operand" "b")]
26143 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
26144 ;; Since 32bit register operands are implicitly zero extended to 64bit,
26145 ;; we only need to set up 32bit registers.
26147 [(set_attr "length" "3")])
26149 (define_insn "@monitorx_<mode>"
26150 [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
26151 (match_operand:SI 1 "register_operand" "c")
26152 (match_operand:SI 2 "register_operand" "d")]
26155 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
26156 ;; RCX and RDX are used. Since 32bit register operands are implicitly
26157 ;; zero extended to 64bit, we only need to set up 32bit registers.
26159 [(set (attr "length")
26160 (symbol_ref ("(Pmode != word_mode) + 3")))])
26163 (define_insn "@clzero_<mode>"
26164 [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
26168 [(set_attr "length" "3")
26169 (set_attr "memory" "unknown")])
26171 ;; RDPKRU and WRPKRU
26173 (define_expand "rdpkru"
26175 [(set (match_operand:SI 0 "register_operand")
26176 (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
26177 (set (match_dup 2) (const_int 0))])]
26180 operands[1] = force_reg (SImode, const0_rtx);
26181 operands[2] = gen_reg_rtx (SImode);
26184 (define_insn "*rdpkru"
26185 [(set (match_operand:SI 0 "register_operand" "=a")
26186 (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
26188 (set (match_operand:SI 1 "register_operand" "=d")
26192 [(set_attr "type" "other")])
26194 (define_expand "wrpkru"
26195 [(unspec_volatile:SI
26196 [(match_operand:SI 0 "register_operand")
26197 (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
26200 operands[1] = force_reg (SImode, const0_rtx);
26201 operands[2] = force_reg (SImode, const0_rtx);
26204 (define_insn "*wrpkru"
26205 [(unspec_volatile:SI
26206 [(match_operand:SI 0 "register_operand" "a")
26207 (match_operand:SI 1 "register_operand" "d")
26208 (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
26211 [(set_attr "type" "other")])
26213 (define_insn "rdpid"
26214 [(set (match_operand:SI 0 "register_operand" "=r")
26215 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDPID))]
26216 "!TARGET_64BIT && TARGET_RDPID"
26218 [(set_attr "type" "other")])
26220 (define_insn "rdpid_rex64"
26221 [(set (match_operand:DI 0 "register_operand" "=r")
26222 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPID))]
26223 "TARGET_64BIT && TARGET_RDPID"
26225 [(set_attr "type" "other")])
26227 ;; Intirinsics for > i486
26229 (define_insn "wbinvd"
26230 [(unspec_volatile [(const_int 0)] UNSPECV_WBINVD)]
26233 [(set_attr "type" "other")])
26235 (define_insn "wbnoinvd"
26236 [(unspec_volatile [(const_int 0)] UNSPECV_WBNOINVD)]
26239 [(set_attr "type" "other")])
26241 ;; MOVDIRI and MOVDIR64B
26243 (define_insn "movdiri<mode>"
26244 [(set (match_operand:SWI48 0 "memory_operand" "=m")
26245 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")]
26248 "movdiri\t{%1, %0|%0, %1}"
26249 [(set_attr "type" "other")])
26251 (define_insn "@movdir64b_<mode>"
26252 [(set (mem:XI (match_operand:P 0 "register_operand" "r"))
26253 (unspec:XI [(match_operand:XI 1 "memory_operand" "m")]
26254 UNSPEC_MOVDIR64B))]
26256 "movdir64b\t{%1, %0|%0, %1}"
26257 [(set_attr "type" "other")])
26260 (define_int_iterator TSXLDTRK [UNSPECV_XSUSLDTRK UNSPECV_XRESLDTRK])
26261 (define_int_attr tsxldtrk [(UNSPECV_XSUSLDTRK "xsusldtrk")
26262 (UNSPECV_XRESLDTRK "xresldtrk")])
26263 (define_insn "<tsxldtrk>"
26264 [(unspec_volatile [(const_int 0)] TSXLDTRK)]
26267 [(set_attr "type" "other")
26268 (set_attr "length" "4")])
26270 ;; ENQCMD and ENQCMDS
26272 (define_int_iterator ENQCMD [UNSPECV_ENQCMD UNSPECV_ENQCMDS])
26273 (define_int_attr enqcmd_sfx [(UNSPECV_ENQCMD "") (UNSPECV_ENQCMDS "s")])
26275 (define_insn "@enqcmd<enqcmd_sfx>_<mode>"
26276 [(set (reg:CCZ FLAGS_REG)
26277 (unspec_volatile:CCZ [(match_operand:P 0 "register_operand" "r")
26278 (match_operand:XI 1 "memory_operand" "m")]
26281 "enqcmd<enqcmd_sfx>\t{%1, %0|%0, %1}"
26282 [(set_attr "type" "other")])
26285 (define_int_iterator UINTR [UNSPECV_CLUI UNSPECV_STUI])
26286 (define_int_attr uintr [(UNSPECV_CLUI "clui") (UNSPECV_STUI "stui")])
26288 (define_insn "<uintr>"
26289 [(unspec_volatile [(const_int 0)] UINTR)]
26290 "TARGET_UINTR && TARGET_64BIT"
26292 [(set_attr "type" "other")
26293 (set_attr "length" "4")])
26295 (define_insn "testui"
26296 [(set (reg:CCC FLAGS_REG)
26297 (unspec_volatile:CCC [(const_int 0)] UNSPECV_TESTUI))]
26298 "TARGET_UINTR && TARGET_64BIT"
26300 [(set_attr "type" "other")
26301 (set_attr "length" "4")])
26303 (define_insn "senduipi"
26305 [(match_operand:DI 0 "register_operand" "r")]
26307 "TARGET_UINTR && TARGET_64BIT"
26309 [(set_attr "type" "other")
26310 (set_attr "length" "4")])
26314 (define_insn "umwait"
26315 [(set (reg:CCC FLAGS_REG)
26316 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26317 (match_operand:DI 1 "register_operand" "A")]
26319 "!TARGET_64BIT && TARGET_WAITPKG"
26321 [(set_attr "length" "3")])
26323 (define_insn "umwait_rex64"
26324 [(set (reg:CCC FLAGS_REG)
26325 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26326 (match_operand:SI 1 "register_operand" "a")
26327 (match_operand:SI 2 "register_operand" "d")]
26329 "TARGET_64BIT && TARGET_WAITPKG"
26331 [(set_attr "length" "3")])
26333 (define_insn "@umonitor_<mode>"
26334 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
26338 [(set (attr "length")
26339 (symbol_ref ("(Pmode != word_mode) + 3")))])
26341 (define_insn "tpause"
26342 [(set (reg:CCC FLAGS_REG)
26343 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26344 (match_operand:DI 1 "register_operand" "A")]
26346 "!TARGET_64BIT && TARGET_WAITPKG"
26348 [(set_attr "length" "3")])
26350 (define_insn "tpause_rex64"
26351 [(set (reg:CCC FLAGS_REG)
26352 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26353 (match_operand:SI 1 "register_operand" "a")
26354 (match_operand:SI 2 "register_operand" "d")]
26356 "TARGET_64BIT && TARGET_WAITPKG"
26358 [(set_attr "length" "3")])
26360 (define_insn "cldemote"
26361 [(unspec_volatile[(match_operand 0 "address_operand" "p")]
26365 [(set_attr "type" "other")
26366 (set_attr "memory" "unknown")])
26368 (define_insn "speculation_barrier"
26369 [(unspec_volatile [(const_int 0)] UNSPECV_SPECULATION_BARRIER)]
26372 [(set_attr "type" "other")
26373 (set_attr "length" "3")])
26375 (define_insn "serialize"
26376 [(unspec_volatile [(const_int 0)] UNSPECV_SERIALIZE)]
26379 [(set_attr "type" "other")
26380 (set_attr "length" "3")])
26382 (define_insn "patchable_area"
26383 [(unspec_volatile [(match_operand 0 "const_int_operand")
26384 (match_operand 1 "const_int_operand")]
26385 UNSPECV_PATCHABLE_AREA)]
26388 ix86_output_patchable_area (INTVAL (operands[0]),
26389 INTVAL (operands[1]) != 0);
26392 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
26393 (set_attr "length_immediate" "0")
26394 (set_attr "modrm" "0")])
26396 (define_insn "hreset"
26397 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")]
26401 [(set_attr "type" "other")
26402 (set_attr "length" "4")])
26404 ;; Spaceship optimization
26405 (define_expand "spaceship<mode>3"
26406 [(match_operand:SI 0 "register_operand")
26407 (match_operand:MODEF 1 "cmp_fp_expander_operand")
26408 (match_operand:MODEF 2 "cmp_fp_expander_operand")]
26409 "(TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
26410 && (TARGET_CMOVE || (TARGET_SAHF && TARGET_USE_SAHF))"
26412 ix86_expand_fp_spaceship (operands[0], operands[1], operands[2]);
26416 (define_expand "spaceshipxf3"
26417 [(match_operand:SI 0 "register_operand")
26418 (match_operand:XF 1 "nonmemory_operand")
26419 (match_operand:XF 2 "nonmemory_operand")]
26420 "TARGET_80387 && (TARGET_CMOVE || (TARGET_SAHF && TARGET_USE_SAHF))"
26422 ix86_expand_fp_spaceship (operands[0], operands[1], operands[2]);
26426 ;; Defined because the generic expand_builtin_issignaling for XFmode
26427 ;; only tests for sNaNs, but i387 treats also pseudo numbers as always
26429 (define_expand "issignalingxf2"
26430 [(match_operand:SI 0 "register_operand")
26431 (match_operand:XF 1 "general_operand")]
26434 rtx temp = operands[1];
26437 rtx mem = assign_stack_temp (XFmode, GET_MODE_SIZE (XFmode));
26438 emit_move_insn (mem, temp);
26441 rtx ex = adjust_address (temp, HImode, 8);
26442 rtx hi = adjust_address (temp, SImode, 4);
26443 rtx lo = adjust_address (temp, SImode, 0);
26444 rtx val = GEN_INT (HOST_WIDE_INT_M1U << 30);
26445 rtx mask = GEN_INT (0x7fff);
26446 rtx bit = GEN_INT (HOST_WIDE_INT_1U << 30);
26448 ((ex & mask) && (int) hi >= 0)
26449 || ((ex & mask) == mask && ((hi ^ bit) | ((lo | -lo) >> 31)) > val). */
26450 rtx nlo = expand_unop (SImode, neg_optab, lo, NULL_RTX, 0);
26451 lo = expand_binop (SImode, ior_optab, lo, nlo,
26452 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26453 lo = expand_shift (RSHIFT_EXPR, SImode, lo, 31, NULL_RTX, 1);
26454 temp = expand_binop (SImode, xor_optab, hi, bit,
26455 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26456 temp = expand_binop (SImode, ior_optab, temp, lo,
26457 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26458 temp = emit_store_flag_force (gen_reg_rtx (SImode), GTU, temp, val,
26460 ex = expand_binop (HImode, and_optab, ex, mask,
26461 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26462 rtx temp2 = emit_store_flag_force (gen_reg_rtx (SImode), NE,
26463 ex, const0_rtx, SImode, 1, 1);
26464 ex = emit_store_flag_force (gen_reg_rtx (SImode), EQ,
26465 ex, mask, HImode, 1, 1);
26466 temp = expand_binop (SImode, and_optab, temp, ex,
26467 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26468 rtx temp3 = emit_store_flag_force (gen_reg_rtx (SImode), GE,
26469 hi, const0_rtx, SImode, 0, 1);
26470 temp2 = expand_binop (SImode, and_optab, temp2, temp3,
26471 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26472 temp = expand_binop (SImode, ior_optab, temp, temp2,
26473 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26474 emit_move_insn (operands[0], temp);
26480 (include "sync.md")